mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
fix(subagent): narrow provider route defaults
This commit is contained in:
+2
-2
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-18-model-selected-subagent-routes.md
|
||||
2026-08-18-model-selected-subagent-routes.md: ffaccb27de8a9735b60266bfb995227fa8a4cec9
|
||||
2026-08-18-model-selected-subagent-routes.zh.md: a102609e84edbba112d6845e86c3c4ba0254e0e6
|
||||
2026-08-18-model-selected-subagent-routes.md: bf4788b141370933197d9ec1a1ad3c8e76a6740c
|
||||
2026-08-18-model-selected-subagent-routes.zh.md: 1d83e2e91ffe87fff7f8e9d1988320cb2bb8f2f7
|
||||
|
||||
@@ -14,7 +14,7 @@ The model also needs a bounded way to discover live providers and model-owned ef
|
||||
|
||||
`dsh-tool-subagent` exposes optional `provider`, `model`, and `reasoning_effort` fields only when its instance enables `enableModelSelection`, or its Agent-scoped `modelSelectionSettings` instance resolves an enabled Session decision, and the bound subagent provider advertises `SubagentCapabilities.agentOptions`. No route allowlist is required. Registered LLM provider routes are available for child selection; this tool does not add a second authorization policy over the deployment's LLM registry. Disabled instances omit and reject model-facing selection, while configured `Config.agentOptions` remain deployment-owned defaults. Either selection mode against a provider without the capability fails the plugin mount.
|
||||
|
||||
Provider and model form one route and must be supplied together. An effort may be supplied alone when configured, parent, or provider-owned values provide the effective route. Static `provider.agentRouteDefaults`, when present, establish the provider/model/reasoning baseline; `Config.agentOptions` and model arguments overlay it before route-aware effort clearing. Providers without static defaults use compatible fields from the parent Agent's latest logged request selection, with creation options supplying the fallback before its first request and retaining the configured output-token limit. Reasoning-effort identifiers remain adapter-owned. An unchanged route inherits an omitted effort only from the selected baseline; changing provider or model without naming an effort clears the lower layer's route-owned value so the selected model resolves its own default. `AgentOptions` carries the resulting effort into the child loop, whose request header logs the effective value. A continuable descriptor records it with the resolved provider and model so a child that has not logged its first request can cold-resume with the same selection.
|
||||
Provider and model form one route and must be supplied together. An effort may be supplied alone when configured, parent, or provider-owned route defaults provide the effective route. Static `provider.agentRouteDefaults`, when present, establish the provider/model baseline; `Config.agentOptions` and model arguments overlay it before route-aware effort clearing. Providers without static defaults use compatible fields from the parent Agent's latest logged request selection, with creation options supplying the fallback before its first request and retaining the configured output-token limit. Reasoning-effort identifiers remain adapter-owned. An unchanged route inherits an omitted effort only from the selected baseline; changing provider or model without naming an effort clears the lower layer's route-owned value so the selected model resolves its own default. `AgentOptions` carries the resulting effort into the child loop, whose request header logs the effective value. A continuable descriptor records it with the resolved provider and model so a child that has not logged its first request can cold-resume with the same selection.
|
||||
|
||||
An explicit or configured provider, model, or effort resolves through `ctx.llm.resolveCallConfig()` after the provider baseline and request precedence are complete. Providers with static route defaults suppress parent-effort inheritance when the request omits effort, preserving the selected model's default. The LLM lookup owns provider registration, exact-model metadata, reasoning-effort validation, and adapter defaults. After the asynchronous lookup, the tool checks cancellation and confirms the same provider instance remains registered before creating a child or background job, so HMR cannot combine one provider's defaults with another provider's process. Calls with no model-facing selection and no configured route fields preserve the existing provider path without requiring the optional LLM service.
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ Status: implemented
|
||||
|
||||
只有实例启用 `enableModelSelection`,或其 Agent 作用域的 `modelSelectionSettings` 实例解析出已启用的 Session 决定,且绑定的 subagent 提供方声明 `SubagentCapabilities.agentOptions` 时,`dsh-tool-subagent` 才公开可选的 `provider`、`model` 与 `reasoning_effort` 字段,不要求配置路由允许列表。已注册的 LLM 提供方路由都可供子级选择;本工具不会在部署的 LLM 注册表之上增加第二套授权策略。禁用的实例会省略并拒绝面向模型的选择,而配置的 `Config.agentOptions` 仍是部署方所有的默认值。如果提供方缺少该能力,任一种选择模式都会使插件挂载失败。
|
||||
|
||||
提供方与模型共同组成一条路由,必须一起提供。如果配置值、父级值或提供方自有值能够提供生效路由,则可以只提供推理强度。静态的 `provider.agentRouteDefaults` 在存在时构成 provider/model/reasoning 基线;`Config.agentOptions` 与模型参数会在路由相关强度清除之前覆盖它。没有静态默认值的提供方会使用父 Agent 最新记录请求中的兼容字段,首个请求之前由创建选项提供回退,并保留其中配置的输出 token 上限。推理强度 ID 仍由 adapter 所有。只有所选基线的路由不变时才会继承省略的强度;更换提供方或模型但没有指定强度时,会清除下层路由自有的值,使所选模型解析自己的默认值。`AgentOptions` 把结果强度传入子级循环,其请求 header 会记录生效值。可继续描述符会把它与解析后的提供方和模型一同记录,使尚未写入首个请求的子级能以相同选择冷恢复。
|
||||
提供方与模型共同组成一条路由,必须一起提供。如果配置值、父级值或提供方持有的路由默认值能够提供生效路由,则可以只提供推理强度。静态的 `provider.agentRouteDefaults` 在存在时构成 provider/model 基线;`Config.agentOptions` 与模型参数会在路由相关强度清除之前覆盖它。没有静态默认值的提供方会使用父 Agent 最新记录请求中的兼容字段,首个请求之前由创建选项提供回退,并保留其中配置的输出 token 上限。推理强度 ID 仍由 adapter 所有。只有所选基线的路由不变时才会继承省略的强度;更换提供方或模型但没有指定强度时,会清除下层路由自有的值,使所选模型解析自己的默认值。`AgentOptions` 把结果强度传入子级循环,其请求 header 会记录生效值。可继续描述符会把它与解析后的提供方和模型一同记录,使尚未写入首个请求的子级能以相同选择冷恢复。
|
||||
|
||||
显式或配置的提供方、模型或强度会在提供方基线与请求优先级完成后,通过 `ctx.llm.resolveCallConfig()` 解析。具有静态路由默认值的提供方会在请求省略强度时禁止继承父级强度,从而保留所选模型的默认值。LLM 查询负责提供方注册、精确模型元数据、推理强度校验和 adapter 默认值。异步查询完成后、创建子级或后台 job 之前,工具会再次检查取消状态,并确认同一个提供方实例仍处于注册状态,因此 HMR 不会把一个提供方的默认值与另一个提供方的进程组合。既没有面向模型的选择、也没有配置路由字段的调用会保留原有提供方路径,不要求可选 LLM 服务存在。
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/subsystems/subagent.md
|
||||
subagent.md: 7ec3e66c4f52dbc364cb3d85763a659602499b9d
|
||||
subagent.zh.md: 158f20a06670143ed681f66c16ff6abb5de4a0cb
|
||||
subagent.md: 3377a32e7aded329dbd238e0b12cb53ab949e925
|
||||
subagent.zh.md: ce842abc6286c2402bd9d1426e148cfbc7b51529
|
||||
|
||||
@@ -443,12 +443,12 @@ interface SubagentProvider {
|
||||
*/
|
||||
readonly inheritsParentContext: boolean
|
||||
/**
|
||||
* Optional static provider-owned route defaults for one-shot Agent options.
|
||||
* Consumers merge tool/model overrides over these values before preflight;
|
||||
* providers whose missing route fields derive from the parent omit it.
|
||||
* The value is detached immutable data and requires `agentOptions` support.
|
||||
* Optional static provider-owned provider/model route for one-shot Agent
|
||||
* options. Consumers merge tool/model overrides over these values before
|
||||
* preflight; providers whose route derives from the parent omit it. The value
|
||||
* is detached immutable data and requires `agentOptions` support.
|
||||
*/
|
||||
readonly agentRouteDefaults?: Readonly<Pick<AgentOptions, 'provider' | 'model' | 'reasoningEffort'>>
|
||||
readonly agentRouteDefaults?: Readonly<{ provider: string; model: string }>
|
||||
/**
|
||||
* Establish a ONE-SHOT child and return its handle after publication.
|
||||
* The service has already validated that every requested start-time
|
||||
|
||||
@@ -447,12 +447,12 @@ interface SubagentProvider {
|
||||
*/
|
||||
readonly inheritsParentContext: boolean
|
||||
/**
|
||||
* Optional static provider-owned route defaults for one-shot Agent options.
|
||||
* Consumers merge tool/model overrides over these values before preflight;
|
||||
* providers whose missing route fields derive from the parent omit it.
|
||||
* The value is detached immutable data and requires `agentOptions` support.
|
||||
* Optional static provider-owned provider/model route for one-shot Agent
|
||||
* options. Consumers merge tool/model overrides over these values before
|
||||
* preflight; providers whose route derives from the parent omit it. The value
|
||||
* is detached immutable data and requires `agentOptions` support.
|
||||
*/
|
||||
readonly agentRouteDefaults?: Readonly<Pick<AgentOptions, 'provider' | 'model' | 'reasoningEffort'>>
|
||||
readonly agentRouteDefaults?: Readonly<{ provider: string; model: string }>
|
||||
/**
|
||||
* Establish a ONE-SHOT child and return its handle after publication.
|
||||
* The service has already validated that every requested start-time
|
||||
|
||||
@@ -4971,7 +4971,7 @@ export const TYPE_API: readonly TypeApiEntry[] = [
|
||||
},
|
||||
{
|
||||
name: 'SubagentProvider',
|
||||
declaration: 'export interface SubagentProvider {\n readonly name: string;\n readonly capabilities: SubagentCapabilities;\n readonly inheritsParentContext: boolean;\n readonly agentRouteDefaults?: Readonly<Pick<AgentOptions, \'provider\' | \'model\' | \'reasoningEffort\'>>;\n start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>;\n prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>;\n}',
|
||||
declaration: 'export interface SubagentProvider {\n readonly name: string;\n readonly capabilities: SubagentCapabilities;\n readonly inheritsParentContext: boolean;\n readonly agentRouteDefaults?: Readonly<{\n provider: string;\n model: string;\n }>;\n start(request: ResolvedSubagentStartRequest): Promise<SubagentRun>;\n prepareContinuable?(request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>;\n}',
|
||||
},
|
||||
{
|
||||
name: 'SubagentReportDelivery',
|
||||
|
||||
@@ -132,7 +132,7 @@ function resolveSdkRoute(config: ResolvedConfig, requested: AgentOptions | undef
|
||||
*/
|
||||
class SdkSubagentProvider implements SubagentProvider {
|
||||
readonly capabilities = SDK_START_CAPABILITIES
|
||||
readonly agentRouteDefaults: Readonly<Pick<AgentOptions, 'provider' | 'model'>>
|
||||
readonly agentRouteDefaults: Readonly<{ provider: string; model: string }>
|
||||
// Context contract: an out-of-process SDK child starts fresh — no parent conversation crosses the process boundary.
|
||||
readonly inheritsParentContext = false
|
||||
|
||||
|
||||
@@ -309,12 +309,12 @@ export interface SubagentProvider {
|
||||
*/
|
||||
readonly inheritsParentContext: boolean
|
||||
/**
|
||||
* Optional static provider-owned route defaults for one-shot Agent options.
|
||||
* Consumers merge tool/model overrides over these values before preflight;
|
||||
* providers whose missing route fields derive from the parent omit it.
|
||||
* The value is detached immutable data and requires `agentOptions` support.
|
||||
* Optional static provider-owned provider/model route for one-shot Agent
|
||||
* options. Consumers merge tool/model overrides over these values before
|
||||
* preflight; providers whose route derives from the parent omit it. The value
|
||||
* is detached immutable data and requires `agentOptions` support.
|
||||
*/
|
||||
readonly agentRouteDefaults?: Readonly<Pick<AgentOptions, 'provider' | 'model' | 'reasoningEffort'>>
|
||||
readonly agentRouteDefaults?: Readonly<{ provider: string; model: string }>
|
||||
/**
|
||||
* Establish a ONE-SHOT child and return its handle after publication.
|
||||
* The service has already validated that every requested start-time
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/subagent/tool-subagent/README.md
|
||||
README.md: efbd70b445b4b203305eb893d9ddf4155ffb1e61
|
||||
README.zh.md: 253dfb2df9d343a6ee4d0f07126d11c976d11e55
|
||||
README.md: a35ec3a6007c94fe83338dfd2c8a1cfd9fa0bc7e
|
||||
README.zh.md: 82ab0fe625b93b0c54cf954e8180b444213bf149
|
||||
|
||||
@@ -6,7 +6,7 @@ The model-facing delegation tool over one configured `ctx.subagents` provider. C
|
||||
|
||||
## Provider selection and lifecycle
|
||||
|
||||
Each plugin instance binds one subagent transport `provider` to one `toolName`; the model cannot change that transport. Load another distinctly named instance to expose another transport. `enableModelSelection: true`, or an enabled Host preference when `modelSelectionSettings: true`, requires that provider's child `agentOptions` capability and exposes optional child LLM `provider`, `model`, and `reasoning_effort` fields without additional route configuration. A call may supply a complete provider/model pair, or only an effort when configured, parent, or provider-owned defaults supply the effective route. Static `provider.agentRouteDefaults`, when present, form the provider/model/reasoning baseline; tool config and model fields overlay it before route-aware effort merging and exact-route preflight. Providers without those defaults retain compatible missing values from the parent's latest logged request selection, falling back to its creation options before the first request and retaining its configured `maxTokens`. Changing provider or model without naming an effort clears the lower layer's route-owned effort so the selected model resolves its default.
|
||||
Each plugin instance binds one subagent transport `provider` to one `toolName`; the model cannot change that transport. Load another distinctly named instance to expose another transport. `enableModelSelection: true`, or an enabled Host preference when `modelSelectionSettings: true`, requires that provider's child `agentOptions` capability and exposes optional child LLM `provider`, `model`, and `reasoning_effort` fields without additional route configuration. A call may supply a complete provider/model pair, or only an effort when configured, parent, or provider-owned route defaults supply the effective route. Static `provider.agentRouteDefaults`, when present, form the provider/model baseline; tool config and model fields overlay it before route-aware effort merging and exact-route preflight. Providers without those defaults retain compatible missing values from the parent's latest logged request selection, falling back to its creation options before the first request and retaining its configured `maxTokens`. Changing provider or model without naming an effort clears the lower layer's route-owned effort so the selected model resolves its default.
|
||||
|
||||
The delegation tool registers only while its subagent provider exists, avoiding sibling load-order and provider-reload dependencies. When model selection is enabled, its optional fields remain visible without `ctx.llm`; a call that selects a route rejects if the service is unavailable. When disabled, the schema omits those fields and execution rejects a forced selection. Configured `agentOptions` remain deployment-owned child defaults independently of this model-facing switch. Adapter catalog and topology changes do not rewrite or re-register the tool. Its description follows `provider.inheritsParentContext`: fresh children require standalone prompts, while forked children already see completed parent turns.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## 提供方选择与生命周期
|
||||
|
||||
每个插件实例把一个 subagent 传输 `provider` 绑定到一个 `toolName`;模型不能改变该传输。如需公开另一种传输,请加载另一个名称不同的实例。`enableModelSelection: true`,或 `modelSelectionSettings: true` 时已启用的 Host 偏好,都要求该提供方具备子级 `agentOptions` 能力,并且无需额外路由配置即可公开可选的子 agent LLM `provider`、`model` 与 `reasoning_effort` 字段。调用可以提供完整的提供方/模型对;当配置值、父 Agent 值或提供方持有的默认值能够提供生效路由时,也可以只提供推理强度。静态的 `provider.agentRouteDefaults` 在存在时构成 provider/model/reasoning 基线;工具配置与模型字段会在路由相关强度合并和确切路由预检前覆盖它。没有这些默认值的提供方会从父 Agent 最新记录的请求选择中保留兼容的缺失值;首个请求之前回退到其创建选项,并保留其中配置的 `maxTokens`。如果更换提供方或模型但没有指定强度,则清除下层路由所属的强度,使所选模型解析自己的默认值。
|
||||
每个插件实例把一个 subagent 传输 `provider` 绑定到一个 `toolName`;模型不能改变该传输。如需公开另一种传输,请加载另一个名称不同的实例。`enableModelSelection: true`,或 `modelSelectionSettings: true` 时已启用的 Host 偏好,都要求该提供方具备子级 `agentOptions` 能力,并且无需额外路由配置即可公开可选的子 agent LLM `provider`、`model` 与 `reasoning_effort` 字段。调用可以提供完整的提供方/模型对;当配置值、父 Agent 值或提供方持有的路由默认值能够提供生效路由时,也可以只提供推理强度。静态的 `provider.agentRouteDefaults` 在存在时构成 provider/model 基线;工具配置与模型字段会在路由相关强度合并和确切路由预检前覆盖它。没有这些默认值的提供方会从父 Agent 最新记录的请求选择中保留兼容的缺失值;首个请求之前回退到其创建选项,并保留其中配置的 `maxTokens`。如果更换提供方或模型但没有指定强度,则清除下层路由所属的强度,使所选模型解析自己的默认值。
|
||||
|
||||
委派工具只在其 subagent 提供方存在时注册,从而避免对同级加载顺序和提供方重新加载的依赖。启用模型选择时,即使没有 `ctx.llm`,可选字段仍然可见;选择路由的调用会在该服务缺失时失败。禁用时,schema 会省略这些字段,执行阶段也会拒绝强制传入的选择。配置的 `agentOptions` 仍是部署方所有的子级默认值,不受这个面向模型的开关影响。adapter 目录和拓扑变化不会改写或重新注册工具。工具描述遵循 `provider.inheritsParentContext`:新建子 agent(智能体)需要独立提示词,而 fork 子 agent 已能看到父级已完成轮次。
|
||||
|
||||
|
||||
@@ -412,7 +412,7 @@ export function apply(ctx: Context, config: Config): void {
|
||||
reasoning_effort: {
|
||||
type: 'string' as const,
|
||||
description: providerRouteDefaults !== undefined
|
||||
? 'Adapter-owned reasoning effort for the effective child route. Omit to use a compatible configured/provider effort or the selected model\'s default.'
|
||||
? 'Adapter-owned reasoning effort for the effective child route. Omit to use a compatible configured effort or the selected model\'s default.'
|
||||
: 'Adapter-owned reasoning effort for the effective child route. Omit to inherit a compatible configured/parent effort or use a newly selected model\'s default.',
|
||||
},
|
||||
} : {},
|
||||
|
||||
Reference in New Issue
Block a user