Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
f9e3400
feat(sdk-java): Add the W0a Managed Workspace binding contract (#12681)
wenshao Sep 25, 2026
9534a52
perf(cli): keep running in place when env files only hold model crede…
tanzhenxin Sep 25, 2026
ab61e04
feat(cli): Mount the v2 tool operations on the Managed Runtime worker…
doudouOUC Sep 25, 2026
790bd83
perf(cli): halve fresh-startup time to typeable and cut RSS by 60% (#…
tanzhenxin Sep 25, 2026
58f0c80
fix(cli): make the Agent Team teammate tab transcript scrollable in V…
yiliang114 Sep 25, 2026
5cbce6d
fix(cli): restore ripgrep exec bit on managed npm update activation (…
yiliang114 Sep 25, 2026
1ad5c9b
fix(cli): notify when the Linux clipboard tool is found but its query…
yiliang114 Sep 25, 2026
c9a9a8a
fix(core): rank PreToolUse permissionDecision most-restrictive in hoo…
yiliang114 Sep 25, 2026
0c80184
perf(serve): coalesce in-flight extension status loads (#12638)
callmeYe Sep 25, 2026
e96b720
feat(cli): Define the managed-context/1 envelope contract (#12700)
wenshao Sep 25, 2026
f6155f0
feat(serve): add guarded Hosted Runtime foundations (#12691)
doudouOUC Sep 25, 2026
34246c6
feat(managed-agent): Spring control plane and dual-path WebShell (#12…
doudouOUC Sep 25, 2026
be1a0a1
feat(serve): support model and reasoning selection at session creatio…
callmeYe Sep 25, 2026
8d8d8ba
feat(core): add durable Managed Session journal and failover
cursoragent Sep 25, 2026
13a83be
fix(core): complete durable session recovery safeguards
Sep 25, 2026
fed812e
codex: address PR review feedback (#12693)
Sep 25, 2026
ec66bb8
codex: address PR review feedback (#12693)
Sep 25, 2026
69a9b67
codex: fix CI failure on PR #12693
Sep 25, 2026
37de228
codex: address PR review feedback (#12693)
Sep 25, 2026
fb0d199
docs: separate managed session foundation design
Sep 25, 2026
1443597
Merge remote-tracking branch 'origin/main' into codex/review-12693
Sep 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/.size-baseline
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
35955 release.yml
44285 repo-hygiene.yml
1079 scorecard-monthly.yml
12011 sdk-java.yml
16542 sdk-java.yml
3886 sdk-python.yml
5595 security-checks.yml
6777 serve-ab-publish.yml
Expand Down
25 changes: 23 additions & 2 deletions .github/workflows/sdk-java.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
paths:
- 'packages/sdk-java/**'
- 'packages/core/src/config/approval-modes.json'
- 'packages/core/src/managed-runtime/contracts/managed-session-store-v1.fixtures.json'
- 'packages/cli/src/commands/serve.ts'
- 'packages/cli/src/serve/**'
- 'packages/cli/src/acp-integration/**'
Expand All @@ -27,6 +28,7 @@ on:
paths:
- 'packages/sdk-java/**'
- 'packages/core/src/config/approval-modes.json'
- 'packages/core/src/managed-runtime/contracts/managed-session-store-v1.fixtures.json'
- 'packages/cli/src/commands/serve.ts'
- 'packages/cli/src/serve/**'
- 'packages/cli/src/acp-integration/**'
Expand Down Expand Up @@ -185,7 +187,7 @@ jobs:
run: 'mvn --batch-mode --no-transfer-progress -DskipTests -Dgpg.skip=true package'

mysql-integration:
name: 'Runtime Broker MariaDB / Java 21'
name: 'Runtime Broker and Managed Agent MariaDB / Java 21'
runs-on: 'ubuntu-latest'
timeout-minutes: 15
services:
Expand All @@ -211,7 +213,10 @@ jobs:
distribution: 'temurin'
java-version: '21'
cache: 'maven'
cache-dependency-path: 'packages/sdk-java/runtime-broker/pom.xml'
cache-dependency-path: |-
packages/sdk-java/qwencode/pom.xml
packages/sdk-java/runtime-broker/pom.xml
packages/sdk-java/managed-agent-server/pom.xml
settings-path: '${{ runner.temp }}/setup-java-m2'

- name: 'Run Runtime Broker MySQL integration tests'
Expand All @@ -223,6 +228,22 @@ jobs:
-Dmysql.url='jdbc:mysql://127.0.0.1:3306/runtime_broker_test?allowPublicKeyRetrieval=true&useSSL=false'
-Dmysql.user=root -Dmysql.password=runtime-broker clean verify

- name: 'Install Managed Agent dependencies'
env:
MAVEN_ARGS: '--settings ${{ runner.temp }}/setup-java-m2/settings.xml --toolchains ${{ runner.temp }}/setup-java-m2/toolchains.xml'
run: |-
mvn --batch-mode --no-transfer-progress -f packages/sdk-java/qwencode/pom.xml -DskipTests -Dgpg.skip=true -Dmaven.javadoc.skip=true install
mvn --batch-mode --no-transfer-progress -f packages/sdk-java/runtime-broker/pom.xml -DskipTests install

- name: 'Run Managed Agent tests, Checkstyle, and MySQL integration'
working-directory: 'packages/sdk-java/managed-agent-server'
env:
MAVEN_ARGS: '--settings ${{ runner.temp }}/setup-java-m2/settings.xml --toolchains ${{ runner.temp }}/setup-java-m2/toolchains.xml'
run: >-
mvn --batch-mode --no-transfer-progress -Pmysql-integration
-Dmysql.url='jdbc:mysql://127.0.0.1:3306/managed_agent_test?createDatabaseIfNotExist=true&allowPublicKeyRetrieval=true&useSSL=false'
-Dmysql.user=root -Dmysql.password=runtime-broker clean verify checkstyle:check

daemon-e2e:
name: 'Real daemon E2E / Java 11'
runs-on: '${{ (github.repository == ''QwenLM/qwen-code'' && vars.MAINTAINER_ECS_RUNNER_DISABLED != ''true'' && (github.event_name == ''push'' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON(''["OWNER","MEMBER","COLLABORATOR"]''), github.event.pull_request.author_association))) && fromJSON(''["self-hosted", "linux", "x64", "ecs-qwen"]'') || ''ubuntu-latest'' }}'
Expand Down
92 changes: 92 additions & 0 deletions docs/design/2026-09-15-task-session-startup-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Model and reasoning selection at session creation

[English](2026-09-15-task-session-startup-config.md) | [简体中文](2026-09-15-task-session-startup-config.zh-CN.md)

Tracking: [#11944](https://github.com/QwenLM/qwen-code/issues/11944), independent PR 4.
Status: implemented on this branch; not yet merged. Baseline: `39b22efb6f` (2026-09-20).

## Goal

An external caller can start a new session with the same model and reasoning
selection as a user selecting them in the composer before sending a prompt.
Creation applies the selection only to that session, without saving shared
defaults. Subsequent prompts, manual changes, reload, fallback, skills and
restoration retain ordinary session behavior. The selection is not automatically
cleared after the first turn.

## Contract

Ordinary and standalone creation accept optional
`startupConfig: { modelServiceId, reasoningEffort? }`. `modelServiceId` is required;
`reasoningEffort` is optional. Omission selects only the model, without calling the
reasoning setter or substituting `default`, so models without reasoning controls
are supported. Explicit reasoning uses the existing `ReasoningSelection` values, including
`default` and `none`, with the composer's existing validation and application
semantics. Unknown properties, a simultaneous legacy `modelServiceId`, and explicit
`sessionScope: 'single'` are rejected. Ordinary startup configuration implies
`sessionScope: 'thread'`. Omission preserves the legacy API unchanged.

The daemon advertises `session_startup_config`. The TypeScript SDK checks this
capability and supports REST and daemon ACP HTTP/WS mappings. Direct child ACP,
load/resume and the `create_sub_session` tool schema are outside this PR.

Success returns `modelApplied: true` and `startupConfigApplied`, describing the
canonical current model selector, requested reasoning selection and effective
reasoning state when reasoning was explicitly requested. Model-only requests
return only the confirmed model selector in `startupConfigApplied`; they do not
claim to have applied a reasoning choice. This acknowledges preparation, not an
immutable lifetime policy.
Malformed requests are rejected before workspace mutations. Invalid selections
fail creation rather than running the initial prompt with a different selection.
Existing authentication, ownership, timeout and uncertain-outcome errors retain
their semantics.

## Implementation

The current UI prepares an ordinary session by creating and attaching it, setting
the model, setting reasoning, and then submitting the prompt. Reuse these existing
setters with model persistence disabled and reasoning `persist: false`.

Ordinary bridge creation applies and confirms both selections before returning.
Standalone preparation happens after managed binding commit (which authenticates
the deferred workspace) and before release or initial-prompt admission. A failed
preparation follows existing owned-session cleanup without killing siblings in
the shared child. A definite standalone selection rejection removes the owned
recording so the same id can be retried, with best-effort empty-directory cleanup.
Timeouts and channel failures retain the existing uncertain-outcome recovery;
cleanup whose outcome cannot be confirmed enters existing containment. SDK
confirmation mismatch after a readable success response is reported directly,
without recovery/adoption.
Startup selection emits session state changes, not a shared
`settings_changed` event.

Use the existing model route parser and config-option result for confirmation.
Do not add a second provider reasoning model. All daemon routes continue to use
their resolved workspace runtime and owner.

## Scope decisions

This supersedes the earlier lifetime-isolation proposal attached to issue #11944.
There is no `startupPinned`, persistent policy record, recording schema change,
strict restore protocol, fallback restriction, mutation gate or UI modification.
There is no promise to select the route before `Config.initialize` or initial
authentication: preparation follows the existing UI ordering. Shared defaults
remain unchanged by this startup operation; later manual operations retain their
existing persistence semantics. The other three PRs are not dependencies.

## Acceptance

- Compare actual provider requests from composer-equivalent preparation and the
new creation API, including tool-loop continuation requests.
- Cover model-only creation on models without reasoning controls, explicit tiers,
`default`, `none`, unsupported choices and shared `none`
with requested `high`.
- Confirm standalone commit → selection → release → prompt ordering; preparation
failures admit zero prompts.
- Verify unchanged user/workspace settings and siblings, no default-change event,
ordinary second-turn/manual-change behavior and legacy creation compatibility.
- Cover unsupported daemons, invalid requests, workspace ownership, disconnects
and cleanup failures.
- Run build, typecheck, bundle, focused package tests and E2E; distinguish
controlled-provider evidence from real external-provider validation. Finish two
consecutive clean full-diff self-audit passes.
60 changes: 60 additions & 0 deletions docs/design/2026-09-15-task-session-startup-config.zh-CN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 新建会话时选择模型与思考强度

[English](2026-09-15-task-session-startup-config.md) | [简体中文](2026-09-15-task-session-startup-config.zh-CN.md)

跟踪:[#11944](https://github.com/QwenLM/qwen-code/issues/11944),独立 PR 4。
状态:已在本分支实现,尚未合并。基线:`39b22efb6f`(2026-09-20)。

## 目标

外部调用方可以指定模型和思考强度发起新会话,效果等同于用户在输入框中选择后发送提问。
创建操作只设置本会话,不保存共享默认值。后续提问、人工切换、reload、fallback、skill 和恢复沿用普通会话行为。
首轮结束后不会自动清除选择。

## 契约

普通及 standalone 创建接受可选的 `startupConfig: { modelServiceId, reasoningEffort? }`。
`modelServiceId` 必填,`reasoningEffort` 可选。省略时只选择模型,不调用思考强度 setter,也不自动补 `default`,因此支持没有思考强度控件的模型。显式思考强度复用现有 `ReasoningSelection`,包括 `default`、`none`,
校验和应用语义与输入框一致。拒绝未知字段、同时提供旧的顶层 `modelServiceId`、显式
`sessionScope: 'single'`。普通会话的启动配置隐含 `sessionScope: 'thread'`。省略对象完全保留旧 API。

daemon 声明 `session_startup_config` 能力。TypeScript SDK 检查能力并支持 REST 与 daemon ACP HTTP/WS 映射。
直接子进程 ACP、load/resume 和 `create_sub_session` 工具 schema 不在本 PR 范围内。

成功返回 `modelApplied: true` 和 `startupConfigApplied`,描述当前规范模型选择符;仅显式请求思考强度时才包含请求档位及实际思考状态。
仅指定模型时,`startupConfigApplied` 只返回已确认的模型选择符,不声称应用过思考强度选择。
这表示启动准备完成,不代表整个生命周期内不可变。结构错误在任何工作区变更之前拒绝。
不合法的选择使创建失败,不允许初始提问使用不同配置执行。
认证、归属、超时与结果不确定错误保留既有语义。

## 实现

当前 UI 先创建并 attach 普通会话,再设置模型、设置思考强度,最后发送 prompt。
复用这些已有 setter,关闭模型持久化并使用 reasoning `persist: false`。

普通 bridge 创建在返回之前应用并确认组合。standalone 在 managed binding commit 完成延迟认证后、
release 和首条 prompt 放行前准备组合。准备失败沿用已有的本次会话清理,不关闭共享子进程里的其他会话。
确定的 standalone 选择拒绝会删除本次持久记录,使同一 ID 可重试,并尽力清理空输出目录。
超时和断连保持既有的结果不确定恢复语义;清理无法确认时进入原有隔离流程。
SDK 收到可读的成功响应但确认不匹配时直接报错,不触发恢复或采用该会话。
启动选择只发送会话状态变更,不发送共享 `settings_changed` 事件。

复用模型路由解析和 config-option 返回值进行确认,不引入第二套 provider reasoning 模型。
所有 daemon 路由继续使用已解析的 workspace runtime 和 owner。

## 范围取舍

本文替代 issue #11944 中先前的生命周期隔离提案。
不引入 `startupPinned`、持久策略记录、recording schema 变更、严格恢复协议、fallback 限制、变更门禁或 UI 修改。
不承诺在 `Config.initialize` 或初始认证前选择路由;准备顺序与现有 UI 相同。
本次启动操作不修改共享默认设置;之后人工操作保持现有持久化语义。其他三个 PR 不是依赖。

## 验收

- 比较输入框等效准备流程与新创建 API 的实际 provider 请求,包含工具循环的后续请求。
- 覆盖不支持思考强度控件的模型仅指定模型创建、显式档位、`default`、`none`、不支持的选择,以及共享为 `none`、请求为 `high`。
- 验证 standalone commit → 配置 → release → prompt 顺序;准备失败时 prompt 次数为零。
- 验证用户/工作区设置和兄弟会话不变、不产生默认值变更事件、第二轮和人工修改沿用现状、legacy 创建兼容。
- 覆盖旧 daemon、非法请求、工作区归属、断连和清理失败。
- 运行 build、typecheck、bundle、聚焦包测试及 E2E;区分受控 provider 与真实外部 provider 验证证据。
完成两轮连续干净的完整 diff 自审。
Loading
Loading