You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
摘要
子代理(subagent)的模型路由继承自父代理的
AgentOptions(dsh-subagent的resolveChildAgentOptions),而 Web 会话里父代理的options.provider在创建时被固化为默认模型选择(agentDefaultModel)。父代理实际运行所用的模型则是会话级选择(会话内切换的模型,记录在 session 的 request header / in-process 选择表里,selectionFor的优先级:in-process 选择 → 会话日志 → 默认)。两条链不一致:当会话运行在第三方 provider(自建网关/兼容 API)而默认选择仍是官方路由时,父代理一切正常,但模型一调用子代理,子代理就按默认路由deepseek-official解析凭据(找DEEPSEEK_API_KEY),用户根本没有该 key →llm-deepseek: no API key for provider route "deepseek-official"。这正是 #117 的现象:第三方 API 下,模型调用子代理必失败。根因(源码定位,rc.6)
dsh-host-apiproxy/lib/index.jsL1708-1714:Web 会话创建/恢复时的 seed options——options.provider从此固化。selectionFor()(L1750-1773):父代理实际每轮请求用的模型解析优先级是in-process 选择 →
agent.session.requestHeader()?.config(会话里选过的模型)→默认选择。会话级切换只落在这一层,不回写
parent.options。dsh-subagent/lib/types/child-agent.jsresolveChildAgentOptions()(L51-62):dsh-llm-deepseek/lib/index.jsresolveApiKey()(L740-750):子代理按deepseek-official路由解析apiKeyEnv(默认DEEPSEEK_API_KEY),credentials 服务与启动环境都没有该 ref → 抛
MISSING_CREDENTIAL。第三方用户的 key 存在他们自己的网关 ref 下,永远匹配不上。
链路总结:会话级模型选择(父代理实际路线)≠
parent.options(创建时的默认路线)→ 子代理继承后者 → 路由到默认 provider → 凭据解析必然落空。复现步骤
deepseek-official(不配DEEPSEEK_API_KEY,或配一个不存在的值)。llm-deepseek: no API key for provider route "deepseek-official"; store DEEPSEEK_API_KEY ...(子代理BUG #117 原报错)。
建议修复
方案 A(推荐)· 继承父代理的"有效模型"而非创建时 options:在
resolveChildAgentOptions(或驱动器调用点)处,按与父代理一致的优先级解析父代理当前有效的 provider/model(in-process 选择 → session request header → 默认选择)再传给子代理。改动集中在dsh-subagent一处,语义正确:子代理永远跟随父代理此刻实际在用的路线。方案 B · 会话级选择同步回写 options:每次
session.selectModel/in-process 选择变更时同步更新parent.options.provider/model,使 options 始终等于有效路线。改动面更广(要处理回写与持久化一致性),不如 A 干净。方案 C(缓解)· 子代理报错信息补充实际路由与继承来源:即使短期不修,
MISSING_CREDENTIAL时提示"该路由来自父代理创建时的默认模型选择,当前会话运行的是 X",可大幅减少定位时间。影响
环境
验证材料
First analysis of discussion #117. Happy to open a PR with fix option A.
All reactions