diff --git a/docs/subsystems/subagent.md b/docs/subsystems/subagent.md
index a6910315b3..b54ce57175 100644
--- a/docs/subsystems/subagent.md
+++ b/docs/subsystems/subagent.md
@@ -406,14 +406,6 @@ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnp
Host settings owner that records Session authorization before the first model request.
-```ts cordis-catalog
-/**
- * Read a detached selection preference for the next fresh top-level Session.
- * @returns the enabled state and exact allowed routes.
- */
-current(): SubagentModelSelectionSettings
-```
-
Source: [`packages/subagent/tool-subagent/src/model-selection-settings.ts`](../../packages/subagent/tool-subagent/src/model-selection-settings.ts)
diff --git a/docs/subsystems/subagent.zh.md b/docs/subsystems/subagent.zh.md
index 8c4a34cd1a..0ca87c8503 100644
--- a/docs/subsystems/subagent.zh.md
+++ b/docs/subsystems/subagent.zh.md
@@ -408,14 +408,6 @@ Generated from source by `scripts/gen-cordis-catalog.ts` (verified fresh by `pnp
Host settings owner that records Session authorization before the first model request.
-```ts cordis-catalog
-/**
- * Read a detached selection preference for the next fresh top-level Session.
- * @returns the enabled state and exact allowed routes.
- */
-current(): SubagentModelSelectionSettings
-```
-
Source: [`packages/subagent/tool-subagent/src/model-selection-settings.ts`](../../packages/subagent/tool-subagent/src/model-selection-settings.ts)
diff --git a/docs/tool-catalog.i18n.yaml b/docs/tool-catalog.i18n.yaml
index 72364bdbef..4381738a1e 100644
--- a/docs/tool-catalog.i18n.yaml
+++ b/docs/tool-catalog.i18n.yaml
@@ -9,8 +9,8 @@
en: 6cc2cd9ced70bb09
zh: 1c0e6cb4ba2ed637
/tool-schema-catalog/tool-package-map:
- en: e4b330276e8729aa
- zh: 3f781cb32fd16d81
+ en: 6db10eb3e60a3015
+ zh: 721026cb011ca99e
/tool-schema-catalog/deepseek-ai-dsh-plugin-manager:
en: e0143916bb634762
zh: e0143916bb634762
@@ -225,8 +225,8 @@
en: 841abe0dd5913ea7
zh: 841abe0dd5913ea7
/tool-schema-catalog/deepseek-ai-dsh-tool-subagent/list-subagent-models:
- en: 6872bee11fccb6c8
- zh: 230f2d443dc5d9a6
+ en: 207228068bc61885
+ zh: 36e9344ee1af8869
/tool-schema-catalog/deepseek-ai-dsh-tool-subagent/subagent:
en: 5bcfcf9ca4117096
zh: 38cb646632b457b2
diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md
index 0ca8251ffd..077253129f 100644
--- a/docs/tool-catalog.md
+++ b/docs/tool-catalog.md
@@ -37,7 +37,7 @@ This table connects model-visible tool names to the plugin package and service s
| `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`, `ctx.workflowEngine`, `ctx.subagents`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents every fresh round)` | `tool/call`, `tool/result`, `workflow and child session events during execution` | - | A fixed foreground workflow starts one fresh structured child per round; the model selects only the immutable objective and an optional round cap. |
| `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.workingDirectory`, `ctx.tools`, `ctx.agents`, `ctx.skills` | `tool/call`, `tool/result`, `user/message replacement catalogs via agent.inject()` | - | - |
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`, `session_event_search`, `session_event_trace`, `session_search`, `session_trace` | `ctx.tools`, `ctx.systemPrompt`, `ctx.sessionQuery`, `a calling Agent for workspace authority` | `tool/call`, `tool/result` | - | The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies. |
-| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`, `subagent` | `ctx.tools`, `ctx.subagents`, `ctx.systemPrompt`, `ctx.llm for model discovery and selected-route validation` | `tool/call`, `tool/result`, `child session events through the chosen provider` | `subagent`, `subagent_fork` | The load-time `toolName` selects the delegation name (default `subagent`); `modelSelection` adds optional route fields. The independent `/list-models` plugin registers discovery. Web and Desktop presets mount discovery, enable spawn route fields, and leave `subagent_fork` route fields disabled. The Host settings service records authorization for each new top-level Session; child Sessions inherit it. Without a recorded policy, discovery and explicit selection permit only the current parent route. Every delegation returns a child id promptly; local children accept follow-ups, while external backends report their single execution automatically. |
+| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`, `subagent` | `ctx.tools`, `ctx.subagents`, `ctx.systemPrompt`, `ctx.sessionProjections`, `ctx.llm for model discovery and selected-route validation` | `tool/call`, `tool/result`, `child session events through the chosen provider` | `subagent`, `subagent_fork` | The load-time `toolName` selects the delegation name (default `subagent`); `modelSelection` adds optional route fields. The independent `/list-models` plugin registers discovery. Web and Desktop presets mount discovery, enable spawn route fields, and leave `subagent_fork` route fields disabled. The Host settings service records authorization for each new top-level Session; child Sessions inherit it. Without a recorded policy, discovery and explicit selection permit only the current parent route. Every delegation returns a child id promptly; local children accept follow-ups, while external backends report their single execution automatically. |
| `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`, `list_agents`, `send_message` | `ctx.tools`, `ctx.subagents`, `ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`, `tool/result`, `child session events through ctx.subagents` | - | The globally named discovery, interruption, and local-message tools over managed subagents: provider-bound `tool-subagent` instances register distinct delegation tools, while this package registers `send_message` and `interrupt_agent` once, plus `list_agents` from its separately loaded `/list-agents` plugin (whose catalog rows use the sessionProjections and live Agent registries). |
| `@deepseek-ai/dsh-tool-jobs` | `job_kill`, `job_list`, `job_output` | `ctx.tools`, `ctx.jobs`, `ctx.systemPrompt` | `tool/call`, `tool/result`, `user/message via agent.inject() for background completion notices` | - | The kind-agnostic background-job controller: background bash commands and PTY sends are read, listed, and killed through the same three tools. Loading the plugin attaches the controller that arms producers' `ctx.jobs.start()`. |
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `interrupt_agent`, `list_agents`, `send_message`, `spawn_teammate`, `team_task_create`, `team_task_get`, `team_task_list`, `team_task_update`, `wait_agent` | `ctx.tools`, `ctx.systemPrompt`, `ctx.agentTeams`, `an exact live Team member Agent` | `tool/call`, `team/member`, `team/task`, `agent/inbox/spliced`, `user/message on inbox claim`, `tool/result` | - | All nine tools are scoped to implicit Team Leads and durable teammates. The shipped dsh-base bundle keeps the package disabled; the documented Agent Teams profile patch enables it while disabling the legacy continuable-child control names. |
@@ -2017,7 +2017,7 @@ The five read-only tools hide provider cursors and authorize every result from t
### `list_subagent_models`
-Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation.
+Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation.
```json
{
diff --git a/docs/tool-catalog.zh.md b/docs/tool-catalog.zh.md
index 230ebbb0b3..cafe401972 100644
--- a/docs/tool-catalog.zh.md
+++ b/docs/tool-catalog.zh.md
@@ -41,7 +41,7 @@
| `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`、`ctx.workflowEngine`、`ctx.subagents`、`ctx.systemPrompt`、`a calling Agent (exec.agent parents every fresh round)` | `tool/call`、`tool/result`、`workflow and child session events during execution` | - | 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 |
| `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.workingDirectory`、`ctx.tools`、`ctx.agents`、`ctx.skills` | `tool/call`、`tool/result`、`user/message replacement catalogs via agent.inject()` | - | - |
| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`、`session_event_search`、`session_event_trace`、`session_search`、`session_trace` | `ctx.tools`、`ctx.systemPrompt`、`ctx.sessionQuery`、`a calling Agent for workspace authority` | `tool/call`、`tool/result` | - | 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 |
-| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`、`subagent` | `ctx.tools`、`ctx.subagents`、`ctx.systemPrompt`、`用于模型发现和所选路由校验的 ctx.llm` | `tool/call`、`tool/result`、`child session events through the chosen provider` | `subagent`、`subagent_fork` | 加载时的 `toolName` 选择委派名称(默认为 `subagent`);`modelSelection` 增加可选路由字段。独立的 `/list-models` 插件注册发现工具。Web 与 Desktop preset 挂载发现工具,启用 spawn 路由字段,并为 `subagent_fork` 保持路由字段关闭。Host 设置服务为每个新顶层 Session 记录授权;子 Session 继承该授权。没有已记录策略时,发现和显式选择只允许当前父级路由。每次委派都会立即返回子代理 id;本地子代理接受后续消息,外部后端自动汇报单次执行结果。 |
+| `@deepseek-ai/dsh-tool-subagent` | `list_subagent_models`、`subagent` | `ctx.tools`、`ctx.subagents`、`ctx.systemPrompt`、`ctx.sessionProjections`、`用于模型发现和所选路由校验的 ctx.llm` | `tool/call`、`tool/result`、`child session events through the chosen provider` | `subagent`、`subagent_fork` | 加载时的 `toolName` 选择委派名称(默认为 `subagent`);`modelSelection` 增加可选路由字段。独立的 `/list-models` 插件注册发现工具。Web 与 Desktop preset 挂载发现工具,启用 spawn 路由字段,并为 `subagent_fork` 保持路由字段关闭。Host 设置服务为每个新顶层 Session 记录授权;子 Session 继承该授权。没有已记录策略时,发现和显式选择只允许当前父级路由。每次委派都会立即返回子代理 id;本地子代理接受后续消息,外部后端自动汇报单次执行结果。 |
| `@deepseek-ai/dsh-tool-subagent-control` | `interrupt_agent`、`list_agents`、`send_message` | `ctx.tools`、`ctx.subagents`、`ctx.agents and ctx.sessionProjections (list_agents only)` | `tool/call`、`tool/result`、`child session events through ctx.subagents` | - | 这些是用于发现、中断托管 subagent 和向本地子代理发送消息的全局命名工具:绑定提供方的 `tool-subagent` 实例注册不同的委派工具;本包注册一次 `send_message` 和 `interrupt_agent`,另由 `list_agents` 通过单独加载的 `/list-agents` 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。 |
| `@deepseek-ai/dsh-tool-jobs` | `job_kill`、`job_list`、`job_output` | `ctx.tools`、`ctx.jobs`、`ctx.systemPrompt` | `tool/call`、`tool/result`、`user/message via agent.inject() for background completion notices` | - | 与任务种类无关的后台任务控制器:后台 bash 命令与 PTY 发送 都通过相同的 3 个工具读取、列出和终止。加载该插件会挂接控制器,从而启用生产方的 `ctx.jobs.start()`。 |
| `@deepseek-ai/dsh-experimental-tool-agent-team` | `interrupt_agent`、`list_agents`、`send_message`、`spawn_teammate`、`team_task_create`、`team_task_get`、`team_task_list`、`team_task_update`、`wait_agent` | `ctx.tools`、`ctx.systemPrompt`、`ctx.agentTeams`、`an exact live Team member Agent` | `tool/call`、`team/member`、`team/task`、`agent/inbox/spliced`、`user/message on inbox claim`、`tool/result` | - | 这 9 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 |
@@ -2023,7 +2023,7 @@ lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,
### `list_subagent_models`
-查询 subagent 可用的模型,不更改当前 Agent。无参数:提供方;`provider`:允许的模型;`provider` + `model`:该模型及其推理强度。将返回的 id 用于委派。
+查询 subagent 可用的模型,不更改当前 Agent。无参数:提供方;`provider`:允许的模型;`provider` + `model`:该模型及其推理强度。选择子级提供方和模型前先在此查询选项,再将返回的 id 用于委派。
```json
{
diff --git a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.i18n.yaml b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.i18n.yaml
index 5cc66aa405..565e20541f 100644
--- a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.i18n.yaml
+++ b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.i18n.yaml
@@ -9,8 +9,8 @@
en: c54f686a434d8b84
zh: f32b63140d9b2dda
/separate-subagent-model-selection-configuration/change:
- en: 6773f124a0ff9f6a
- zh: 99213e0ba2caff35
+ en: 3d948fe459b20e23
+ zh: cb3c924d9fde2432
/separate-subagent-model-selection-configuration/migration:
en: b83bd0256fb89c92
zh: 5b14cf7cfa9677b3
diff --git a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.md b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.md
index 72411e4bc9..d76f6f28e1 100644
--- a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.md
+++ b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.md
@@ -11,6 +11,8 @@ English | [中文](guide.zh.md)
`@deepseek-ai/dsh-tool-subagent` replaces `modelSelectionSettings` with `modelSelection`, which controls only optional child route fields. The tool no longer registers `list_subagent_models` or samples user settings. The Host `/model-selection-settings` service records authorization during Agent creation, including Sessions created before delegation tools are mounted. Existing Sessions keep their recorded policy; installing tools later does not resample settings. Shipped Web and Desktop presets include the independent discovery plugin and keep fork route fields disabled. Custom fork tools may enable them.
+A Host with model selection enabled and an empty allowed-model list rejects every fresh top-level Session, including those without delegation tools. The settings UI prevents saving that combination; configurations written directly must supply a non-empty list or disable selection.
+
## Migration
1. In custom `cordis.yml`, patches, or direct plugin configuration, rename `modelSelectionSettings: true` to `modelSelection: true` on delegation tools that expose route arguments.
diff --git a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.zh.md b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.zh.md
index f312728181..336e18d4ee 100644
--- a/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.zh.md
+++ b/docs/upgrade-guide/v0.2.1-alpha.2/subagent-model-selection-composition/guide.zh.md
@@ -11,6 +11,8 @@ description: 自定义 subagent 组合必须分离路由字段、模型发现和
`@deepseek-ai/dsh-tool-subagent` 将 `modelSelectionSettings` 替换为 `modelSelection`,该选项只控制可选子级路由字段。工具不再注册 `list_subagent_models` 或采样用户设置。Host 的 `/model-selection-settings` 服务在 Agent 创建时记录授权,包括在委派工具挂载前创建的 Session。已有 Session 保留已记录策略;之后安装工具不会重新采样设置。随附 Web 与 Desktop preset 包含独立发现插件,并为 fork 保持路由字段关闭。自定义 fork 工具可以启用这些字段。
+Host 启用模型选择但允许模型列表为空时,会拒绝创建所有新的顶层 Session,包括未挂载委派工具的 Session。设置界面不允许保存这种组合;直接写入的配置必须提供非空列表或关闭模型选择。
+
## 迁移
1. 在自定义 `cordis.yml`、patch 或直接插件配置中,将公开路由参数的委派工具的 `modelSelectionSettings: true` 改为 `modelSelection: true`。
diff --git a/packages/extensions/tool-cordis/src/api-catalog.ts b/packages/extensions/tool-cordis/src/api-catalog.ts
index 6fb7b5084b..850553cae0 100644
--- a/packages/extensions/tool-cordis/src/api-catalog.ts
+++ b/packages/extensions/tool-cordis/src/api-catalog.ts
@@ -2958,14 +2958,7 @@ export const SERVICE_API: readonly ServiceApiEntry[] = [
key: 'subagentModelSelection',
summary: 'Host settings owner that records Session authorization before the first model request.',
description: 'Host settings owner that records Session authorization before the first model request.',
- methods: [
- {
- signature: 'current(): SubagentModelSelectionSettings',
- description: 'Read a detached selection preference for the next fresh top-level Session.',
- parameters: [],
- returns: 'the enabled state and exact allowed routes.',
- },
- ],
+ methods: [],
},
{
key: 'subagents',
diff --git a/packages/subagent/tool-subagent/README.i18n.yaml b/packages/subagent/tool-subagent/README.i18n.yaml
index 621428968a..1290c018fe 100644
--- a/packages/subagent/tool-subagent/README.i18n.yaml
+++ b/packages/subagent/tool-subagent/README.i18n.yaml
@@ -69,8 +69,8 @@
en: a4ca31b9cbacda6b
zh: 91ac3e0784a14697
/deepseek-ai-dsh-tool-subagent/model-experience/model-selection-and-discovery/what-the-model-sees:
- en: 192670f899eb74f5
- zh: 06eac751268c3a9d
+ en: 9cf8be0502db31dd
+ zh: 16eebce205f12364
/deepseek-ai-dsh-tool-subagent/model-experience/model-selection-and-discovery/token-effect:
en: 4fa61dc9a52259a2
zh: bc51ac3b1a1cc6ad
diff --git a/packages/subagent/tool-subagent/README.md b/packages/subagent/tool-subagent/README.md
index 46be412d92..1a4f3b3677 100644
--- a/packages/subagent/tool-subagent/README.md
+++ b/packages/subagent/tool-subagent/README.md
@@ -152,7 +152,7 @@ Prefix-stable while provider instances and their configuration are unchanged. Ad
#### What the model sees
-The independent `list_subagent_models` definition reads the calling Session’s route policy, falling back to the current parent route when no policy is recorded. Calls reject while the optional `ctx.llm` service is unavailable. With a recorded policy, provider model lists intersect the advertised catalog with the Session’s authorized routes. Without one, they resolve only the current parent model, even if the catalog omits it. Exact-model queries accept authorized ids absent from the catalog; unauthorized provider/model lookups fail before adapter access. Catalog or exact-model lookup failures and cancellation reject the call. Execution independently enforces the same policy.
+The independent `list_subagent_models` definition reads the calling Session’s route policy, falling back to the current parent route when no policy is recorded. Calls reject while the optional `ctx.llm` service is unavailable. With a recorded policy, provider model lists intersect the advertised catalog with the Session’s authorized routes. Without one, they resolve only the current parent model, even if the catalog omits it. The discovery tool’s own description instructs the model to query options before selecting a child route; omitting or filtering out discovery removes that guidance. Exact-model queries accept authorized ids absent from the catalog; unauthorized provider/model lookups fail before adapter access. Catalog or exact-model lookup failures and cancellation reject the call. Execution independently enforces the same policy.
#### Token effect
diff --git a/packages/subagent/tool-subagent/README.zh.md b/packages/subagent/tool-subagent/README.zh.md
index d1b9c788e1..5a14b36b6f 100644
--- a/packages/subagent/tool-subagent/README.zh.md
+++ b/packages/subagent/tool-subagent/README.zh.md
@@ -152,7 +152,7 @@ kind: "package-reference"
#### 模型看到什么
-独立的 `list_subagent_models` 定义读取调用 Session 的路由策略,没有已记录策略时使用当前父级路由。可选的 `ctx.llm` 服务不可用时,调用会被拒绝。有已记录策略时,提供方模型列表取公布目录与 Session 授权路由的交集。没有策略时,只解析当前父级模型,即使目录未列出它。精确模型查询允许已授权但目录未列出的 ID;未授权的提供方/模型查询会在访问适配器前失败。目录或精确模型查询失败以及取消都会使调用被拒绝。执行过程独立强制同一策略。
+独立的 `list_subagent_models` 定义读取调用 Session 的路由策略,没有已记录策略时使用当前父级路由。可选的 `ctx.llm` 服务不可用时,调用会被拒绝。有已记录策略时,提供方模型列表取公布目录与 Session 授权路由的交集。没有策略时,只解析当前父级模型,即使目录未列出它。发现工具自身的描述要求模型在选择子级路由前查询选项;未挂载或过滤掉发现工具时,这段指导也不会出现。精确模型查询允许已授权但目录未列出的 ID;未授权的提供方/模型查询会在访问适配器前失败。目录或精确模型查询失败以及取消都会使调用被拒绝。执行过程独立强制同一策略。
#### Token 影响
diff --git a/packages/subagent/tool-subagent/src/index.ts b/packages/subagent/tool-subagent/src/index.ts
index b7c95a8e1a..03a5fbe514 100644
--- a/packages/subagent/tool-subagent/src/index.ts
+++ b/packages/subagent/tool-subagent/src/index.ts
@@ -193,8 +193,8 @@ export async function apply(ctx: Context, config: Config): Promise {
const wording = providerWording(subagentProvider.inheritsParentContext)
const providerRouteDefaults = subagentProvider.agentRouteDefaults
const selectionDescription = providerRouteDefaults !== undefined
- ? ' Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to this backend\'s route defaults. When the effective route changes, an omitted `reasoning_effort` uses the model\'s default.'
- : ' Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model\'s default.'
+ ? ' Supply `provider` and `model` together. Omitted values use child defaults, falling back to this backend\'s route defaults. When the effective route changes, an omitted `reasoning_effort` uses the model\'s default.'
+ : ' Supply `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model\'s default.'
const definition = defineTool({
name: toolName,
description: wording.description
@@ -202,7 +202,10 @@ export async function apply(ctx: Context, config: Config): Promise {
+ (subagentProvider.prepareContinuable !== undefined
? ' The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes.'
: ' The completion notice includes its final answer. This backend does not accept follow-up messages.')
- + (modelSelectionEnabled ? selectionDescription : ''),
+ + (modelSelectionEnabled ? selectionDescription : '')
+ + (modelSelectionEnabled && subagentProvider.inheritsParentContext
+ ? ' Changing the route can prevent provider-side reuse of the inherited conversation prefix.'
+ : ''),
parameters: {
cwd: {
type: 'string',
diff --git a/packages/subagent/tool-subagent/src/list-models.ts b/packages/subagent/tool-subagent/src/list-models.ts
index 4a81c568f6..f220c85e32 100644
--- a/packages/subagent/tool-subagent/src/list-models.ts
+++ b/packages/subagent/tool-subagent/src/list-models.ts
@@ -109,7 +109,7 @@ export function apply(ctx: Context): void {
description:
'Inspect subagent models without changing the current Agent. No arguments: providers; '
+ '`provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. '
- + 'Use returned ids for delegation.',
+ + 'Inspect options here before selecting a child provider and model; use returned ids for delegation.',
parameters: {
provider: {
type: 'string',
diff --git a/packages/subagent/tool-subagent/src/model-selection-settings.ts b/packages/subagent/tool-subagent/src/model-selection-settings.ts
index 9e4907556b..a7954c3850 100644
--- a/packages/subagent/tool-subagent/src/model-selection-settings.ts
+++ b/packages/subagent/tool-subagent/src/model-selection-settings.ts
@@ -72,7 +72,7 @@ export class SubagentModelSelectionConfig extends Service {
* Read a detached selection preference for the next fresh top-level Session.
* @returns the enabled state and exact allowed routes.
*/
- current(): SubagentModelSelectionSettings {
+ private current(): SubagentModelSelectionSettings {
const enabled = this.config.enabled.get()
const allowedModels = this.config.allowedModels.get()
assertAllowedModelRoutes(allowedModels)
diff --git a/packages/subagent/tool-subagent/src/model-selection-state.ts b/packages/subagent/tool-subagent/src/model-selection-state.ts
index 221ef5a8f6..26516749bd 100644
--- a/packages/subagent/tool-subagent/src/model-selection-state.ts
+++ b/packages/subagent/tool-subagent/src/model-selection-state.ts
@@ -33,7 +33,10 @@ const modelSelectionPolicySchema: zod.ZodType = zod.
model: zod.string().min(1),
}).strict()).min(1).nullable()
-/** Host-only projection of the durable model-selection policy. */
+/**
+ * Host-only projection of the durable model-selection policy.
+ * Each independently mounted consumer registers this shared definition; the registry reference-counts it.
+ */
export const subagentModelSelectionProjectionDefinition = {
key: 'subagentModelSelectionPolicy',
stateVersion: 1,
diff --git a/packages/subagent/tool-subagent/src/model-selection.ts b/packages/subagent/tool-subagent/src/model-selection.ts
index 04f4d33b5f..911901a2ce 100644
--- a/packages/subagent/tool-subagent/src/model-selection.ts
+++ b/packages/subagent/tool-subagent/src/model-selection.ts
@@ -152,7 +152,10 @@ export function assertAllowedModelSelection(
? provider === parentOptions.provider && model === parentOptions.model
: policy.routes.some(route => route.provider === provider && route.model === model)
if (allowed) return
- throw new Error(`child LLM route "${provider}/${model}" is not allowed for this Session`)
+ throw new Error(`child LLM route "${provider}/${model}" is not allowed for this Session`
+ + (policy === undefined
+ ? '; without a recorded model-selection policy, explicit selection (including reasoning_effort) is limited to the parent route'
+ : ''))
}
/**
diff --git a/packages/subagent/tool-subagent/tests/model-selection-settings.spec.ts b/packages/subagent/tool-subagent/tests/model-selection-settings.spec.ts
index 0718087bb6..1b2b11390a 100644
--- a/packages/subagent/tool-subagent/tests/model-selection-settings.spec.ts
+++ b/packages/subagent/tool-subagent/tests/model-selection-settings.spec.ts
@@ -78,51 +78,62 @@ async function createAgent(ctx: Context, id: string, options: {
return handle.agent
}
+let policySessionCounter = 0
+
+/** Observe settings through the policy captured by a fresh top-level Agent. */
+async function capturePolicy(ctx: Context) {
+ const { agent } = await ctx.agents.create({ sessionId: SessionId(`settings-policy-${++policySessionCounter}`) })
+ return subagentModelSelectionPolicy(ctx.sessionProjections, agent.session)
+}
+
describe('SubagentModelSelectionConfig', () => {
it('uses the composed default without a settings provider', async () => {
const ctx = ownContext(new Context())
- await mountAgentLoopTestDependencies(ctx)
+ await mountAgentLoopTestDependencies(ctx, { workingDirectory: true })
+ await ctx.plugin(AgentLoop, { agents: [] })
await ctx.plugin(SubagentModelSelectionConfig, { enabled: true, allowedModels: ALLOWED_MODELS })
- expect(ctx.subagentModelSelection.current()).toEqual({ enabled: true, allowedModels: ALLOWED_MODELS })
+ expect(await capturePolicy(ctx)).toEqual(ALLOWED_MODELS)
await ctx.fiber.dispose()
})
it('defaults off and follows the validated user layer', async () => {
const ctx = ownContext(new Context())
- await mountAgentLoopTestDependencies(ctx)
+ await mountAgentLoopTestDependencies(ctx, { workingDirectory: true })
+ await ctx.plugin(AgentLoop, { agents: [] })
selectionConfigs.set(ctx, await liveConfig(ctx, SubagentModelSelectionConfig))
- expect(ctx.subagentModelSelection.current()).toEqual({ enabled: false, allowedModels: [] })
+ expect(await capturePolicy(ctx)).toBeUndefined()
await selectionConfigs.get(ctx)!.update({
enabled: true,
allowedModels: ALLOWED_MODELS,
})
- expect(ctx.subagentModelSelection.current()).toEqual({ enabled: true, allowedModels: ALLOWED_MODELS })
+ expect(await capturePolicy(ctx)).toEqual(ALLOWED_MODELS)
await ctx.fiber.dispose()
})
it('rejects duplicate routes, enabled empty settings, and an empty durable policy', async () => {
const ctx = ownContext(new Context())
- await mountAgentLoopTestDependencies(ctx)
+ await mountAgentLoopTestDependencies(ctx, { workingDirectory: true })
+ await ctx.plugin(AgentLoop, { agents: [] })
selectionConfigs.set(ctx, await liveConfig(ctx, SubagentModelSelectionConfig))
ctx.sessionProjections.register(subagentModelSelectionProjectionDefinition)
- // A stored policy the service cannot apply fails when it is read, not when the profile row is written.
+ // File-written invalid settings reject Agent creation even without delegation tools.
await selectionConfigs.get(ctx)!.update({ allowedModels: [...ALLOWED_MODELS, ...ALLOWED_MODELS] })
- expect(() => ctx.subagentModelSelection.current()).toThrow('repeats route "alpha/fast-model"')
+ await expect(capturePolicy(ctx)).rejects.toThrow('repeats route "alpha/fast-model"')
await selectionConfigs.get(ctx)!.update({ enabled: true, allowedModels: [] })
- expect(() => ctx.subagentModelSelection.current()).toThrow('enabled subagent model selection requires at least one allowed model')
+ await expect(capturePolicy(ctx)).rejects.toThrow('enabled subagent model selection requires at least one allowed model')
await selectionConfigs.get(ctx)!.update({
enabled: false,
allowedModels: ALLOWED_MODELS,
})
- expect(ctx.subagentModelSelection.current()).toEqual({ enabled: false, allowedModels: ALLOWED_MODELS })
+ expect(await capturePolicy(ctx)).toBeUndefined()
await selectionConfigs.get(ctx)!.update({ allowedModels: [] })
- expect(ctx.subagentModelSelection.current()).toEqual({ enabled: false, allowedModels: [] })
+ expect(await capturePolicy(ctx)).toBeUndefined()
const invalid = Session.create(SessionId('empty-policy'))
invalid.append('subagent/model-selection-policy', { allowedModels: [] })
diff --git a/packages/subagent/tool-subagent/tests/model-selection.spec.ts b/packages/subagent/tool-subagent/tests/model-selection.spec.ts
index 183f1f52f8..6a437cea37 100644
--- a/packages/subagent/tool-subagent/tests/model-selection.spec.ts
+++ b/packages/subagent/tool-subagent/tests/model-selection.spec.ts
@@ -12,6 +12,7 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter } from '../../../core/agent-loop/tests/mock-adapter.ts'
import * as mock from './scripted-provider.ts'
import * as tool from '../src/index.ts'
+import * as ListModels from '../src/list-models.ts'
import {
assertAllowedModelRoutes,
assertAllowedModelSelection,
@@ -121,7 +122,8 @@ describe('dsh-tool-subagent model selection', () => {
'provider',
'reasoning_effort',
])
- expect(schema.description).toContain('list_subagent_models')
+ expect(schema.description).not.toContain('list_subagent_models')
+ expect(schema.description).not.toContain('Changing the route can prevent provider-side reuse')
expect(ctx.tools.get('list_subagent_models', agent)).toBeDefined()
expect(schema.description).not.toContain('alpha')
@@ -159,6 +161,43 @@ describe('dsh-tool-subagent model selection', () => {
}
})
+ it('shows discovery guidance only while its tool is visible, regardless of mount order', async () => {
+ const ctx = await setup({ provider: 'mock', modelSelection: true })
+ const agent = modelSelectionSetupAgent(ctx)
+ const descriptions = () => ctx.tools.schemas(agent).map(schema => schema.description).join('\n')
+ const guidance = 'Inspect options here before selecting a child provider and model'
+ expect(descriptions()).not.toContain(guidance)
+ expect(descriptions()).not.toContain('list_subagent_models')
+
+ const discovery = await ctx.plugin(ListModels)
+ expect(descriptions()).toContain(guidance)
+ const restore = agent.ctx.tools.restrict({ deny: ['list_subagent_models'] })
+ expect(descriptions()).not.toContain(guidance)
+ restore()
+ expect(descriptions()).toContain(guidance)
+ await discovery.dispose()
+ expect(descriptions()).not.toContain(guidance)
+ })
+
+ it.each(['configured', 'provider'] as const)('explains effort-only denial on a %s route without Session authorization', async (source) => {
+ const defaults = { provider: 'alpha', model: 'configured-model' }
+ const start = vi.fn()
+ const ctx = await setup({
+ provider: 'mock', modelSelection: true,
+ parentAgentOptions: { provider: 'alpha', model: 'parent-model' },
+ ...source === 'configured' ? { agentOptions: defaults } : {},
+ }, {
+ onStart: start,
+ ...source === 'provider' ? { agentRouteDefaults: defaults } : {},
+ })
+ const result = await callSubagent(ctx, {
+ description: 'adjust effort', prompt: 'work', reasoning_effort: 'low',
+ })
+ expect(result.isError).toBe(true)
+ expect(text(result)).toContain('without a recorded model-selection policy, explicit selection (including reasoning_effort) is limited to the parent route')
+ expect(start).not.toHaveBeenCalled()
+ })
+
it('keeps settings-owned route fields visible but rejects other routes without a Session policy', async () => {
const ctx = await setup({
provider: 'mock',
@@ -170,7 +209,8 @@ describe('dsh-tool-subagent model selection', () => {
const schema = ctx.tools.schemas(agent).find(entry => entry.name === 'subagent')!
const props = (schema.parameters as { properties?: Record }).properties ?? {}
expect(Object.keys(props).sort()).toEqual(['cwd', 'description', 'model', 'prompt', 'provider', 'reasoning_effort'])
- expect(schema.description).toContain('list_subagent_models')
+ expect(schema.description).not.toContain('list_subagent_models')
+ expect(schema.description).not.toContain('Changing the route can prevent provider-side reuse')
expect(ctx.tools.get('list_subagent_models', agent)).toBeDefined()
const result = await callSubagent(ctx, {
@@ -505,7 +545,8 @@ describe('dsh-tool-subagent model selection', () => {
const agent = modelSelectionSetupAgent(ctx)
const schema = ctx.tools.schemas(agent).find(entry => entry.name === 'subagent')!
expect(schema.description).toContain('inherits this conversation')
- expect(schema.description).toContain('list_subagent_models')
+ expect(schema.description).not.toContain('list_subagent_models')
+ expect(schema.description).toContain('Changing the route can prevent provider-side reuse of the inherited conversation prefix.')
const allowed = await callSubagent(ctx, {
description: 'fork work', prompt: 'do it', provider: 'alpha', model: 'fast-model', reasoning_effort: 'low',
diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts
index 3f3288a6b8..df595823fe 100644
--- a/scripts/gen-tool-catalog.ts
+++ b/scripts/gen-tool-catalog.ts
@@ -511,7 +511,7 @@ const TOOL_PACKAGES: ToolPackage[] = [
list_subagent_models: 'packages/subagent/tool-subagent/src/list-models.ts',
subagent: 'packages/subagent/tool-subagent/src/index.ts',
},
- requires: ['ctx.tools', 'ctx.subagents', 'ctx.systemPrompt', 'ctx.llm for model discovery and selected-route validation'],
+ requires: ['ctx.tools', 'ctx.subagents', 'ctx.systemPrompt', 'ctx.sessionProjections', 'ctx.llm for model discovery and selected-route validation'],
writes: ['tool/call', 'tool/result', 'child session events through the chosen provider'],
shippedNames: ['subagent', 'subagent_fork'],
async mount(ctx) {
diff --git a/snapshots/sdk/subagent-dsh-sdk-dynamic-route/tool-schemas.expected.json b/snapshots/sdk/subagent-dsh-sdk-dynamic-route/tool-schemas.expected.json
index 85e10ae4f2..28da314b29 100644
--- a/snapshots/sdk/subagent-dsh-sdk-dynamic-route/tool-schemas.expected.json
+++ b/snapshots/sdk/subagent-dsh-sdk-dynamic-route/tool-schemas.expected.json
@@ -262,7 +262,7 @@
},
{
"name": "list_subagent_models",
- "description": "Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation.",
+ "description": "Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation.",
"parameters": {
"type": "object",
"properties": {
@@ -356,7 +356,7 @@
},
{
"name": "subagent",
- "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The completion notice includes its final answer. This backend does not accept follow-up messages. Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to this backend's route defaults. When the effective route changes, an omitted `reasoning_effort` uses the model's default.",
+ "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The completion notice includes its final answer. This backend does not accept follow-up messages. Supply `provider` and `model` together. Omitted values use child defaults, falling back to this backend's route defaults. When the effective route changes, an omitted `reasoning_effort` uses the model's default.",
"parameters": {
"type": "object",
"properties": {
diff --git a/snapshots/web/fresh-round-trip/tool-schemas.expected.json b/snapshots/web/fresh-round-trip/tool-schemas.expected.json
index 34cc3505b3..d97f06bdb1 100644
--- a/snapshots/web/fresh-round-trip/tool-schemas.expected.json
+++ b/snapshots/web/fresh-round-trip/tool-schemas.expected.json
@@ -325,7 +325,7 @@
},
{
"name": "list_subagent_models",
- "description": "Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation.",
+ "description": "Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation.",
"parameters": {
"type": "object",
"properties": {
@@ -719,7 +719,7 @@
},
{
"name": "subagent",
- "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default.",
+ "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Supply `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default.",
"parameters": {
"type": "object",
"properties": {
diff --git a/snapshots/web/official-subagent-bundle/system-prompt.expected.md b/snapshots/web/official-subagent-bundle/system-prompt.expected.md
index bf81e7f52a..778c016948 100644
--- a/snapshots/web/official-subagent-bundle/system-prompt.expected.md
+++ b/snapshots/web/official-subagent-bundle/system-prompt.expected.md
@@ -158,7 +158,7 @@ interface ToolArgsMap {
/** children (default) lists direct children, which accept send_message in any status. descendants lists the whole tree below you with each entry's parent session id and depth; entries deeper than 1 accept only interrupt_agent. */
scope?: "children" | "descendants";
} & Record;
- /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation. */
+ /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation. */
list_subagent_models: {
/** Registered LLM provider id. */
provider?: string;
@@ -288,7 +288,7 @@ interface ToolArgsMap {
/** The exact skill name from the available skills list. */
name: string;
} & Record;
- /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
+ /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Supply `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
subagent: {
/** Initial child working directory. Relative paths use your current directory; omitted inherits it. Later directory changes in either agent are independent. */
cwd?: string;
diff --git a/snapshots/web/optional-string-editor/system-prompt.expected.md b/snapshots/web/optional-string-editor/system-prompt.expected.md
index d1d3f1d372..1670257a1e 100644
--- a/snapshots/web/optional-string-editor/system-prompt.expected.md
+++ b/snapshots/web/optional-string-editor/system-prompt.expected.md
@@ -158,7 +158,7 @@ interface ToolArgsMap {
/** children (default) lists direct children, which accept send_message in any status. descendants lists the whole tree below you with each entry's parent session id and depth; entries deeper than 1 accept only interrupt_agent. */
scope?: "children" | "descendants";
} & Record;
- /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation. */
+ /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation. */
list_subagent_models: {
/** Registered LLM provider id. */
provider?: string;
@@ -305,7 +305,7 @@ interface ToolArgsMap {
/** Optional parameter of `view` command when `path` points to a file. If omitted or null, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [11, 12] will show lines 11 and 12. Indexing at 1 to start. Setting `[start_line, -1]` shows all lines from `start_line` to the end of the file. */
view_range?: number[] | null;
} & Record;
- /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
+ /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Supply `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
subagent: {
/** Initial child working directory. Relative paths use your current directory; omitted inherits it. Later directory changes in either agent are independent. */
cwd?: string;
diff --git a/snapshots/web/ptc-round/system-prompt.expected.md b/snapshots/web/ptc-round/system-prompt.expected.md
index 8818cb5cce..28e71009d3 100644
--- a/snapshots/web/ptc-round/system-prompt.expected.md
+++ b/snapshots/web/ptc-round/system-prompt.expected.md
@@ -158,7 +158,7 @@ interface ToolArgsMap {
/** children (default) lists direct children, which accept send_message in any status. descendants lists the whole tree below you with each entry's parent session id and depth; entries deeper than 1 accept only interrupt_agent. */
scope?: "children" | "descendants";
} & Record;
- /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Use returned ids for delegation. */
+ /** Inspect subagent models without changing the current Agent. No arguments: providers; `provider`: allowed models; `provider` + `model`: that model and its reasoning efforts. Inspect options here before selecting a child provider and model; use returned ids for delegation. */
list_subagent_models: {
/** Registered LLM provider id. */
provider?: string;
@@ -288,7 +288,7 @@ interface ToolArgsMap {
/** The exact skill name from the available skills list. */
name: string;
} & Record;
- /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Inspect options with `list_subagent_models` before setting `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
+ /** Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. This tool starts an independently managed subagent and immediately returns its id. The runtime notifies you when it finishes. The child reports results with `send_message`; use `send_message` to steer it while running or continue its conversation after it finishes. Supply `provider` and `model` together. Omitted values use child defaults, falling back to compatible parent values. When the effective route changes, an omitted `reasoning_effort` uses the model's default. */
subagent: {
/** Initial child working directory. Relative paths use your current directory; omitted inherits it. Later directory changes in either agent are independent. */
cwd?: string;