refactor(agent): own model selection on each agent

This commit is contained in:
_Kerman committed 2026-10-20 21:09:09 +08:00
1 parent 639602e63a
commit a9c006f9c3
237 files changed
+1051 -1734

No files matched your search

-3
View File
@@ -40,8 +40,6 @@ flowchart LR
cfg --> plugin_dsh_base_user_questions
plugin_dsh_base_agent["agent<br/>@deepseek-ai/dsh-agent"]
cfg --> plugin_dsh_base_agent
plugin_dsh_base_agent_model["agent-model<br/>@deepseek-ai/dsh-agent-model"]
cfg --> plugin_dsh_base_agent_model
plugin_dsh_base_plugin_package_inventory_deepseek["plugin-package-inventory-deepseek<br/>@deepseek-ai/dsh-plugin-package-inventory-deepseek"]
cfg --> plugin_dsh_base_plugin_package_inventory_deepseek
plugin_dsh_base_agent_default_model["agent-default-model<br/>@deepseek-ai/dsh-agent-default-model"]
@@ -220,7 +218,6 @@ flowchart LR
| `session-title-llm` | `@deepseek-ai/dsh-session-title-first-prompt-llm` |
| `user-questions` | `@deepseek-ai/dsh-user-questions` |
| `agent` | `@deepseek-ai/dsh-agent` |
| `agent-model` | `@deepseek-ai/dsh-agent-model` |
| `plugin-package-inventory-deepseek` | `@deepseek-ai/dsh-plugin-package-inventory-deepseek` |
| `agent-default-model` | `@deepseek-ai/dsh-agent-default-model` |
| `jobs` | `@deepseek-ai/dsh-jobs-local` |
-1
View File
@@ -1270,7 +1270,6 @@ describe.skipIf(!existsSync(dshBin))('dsh BUILT bin (node lib/bin.js, no tsx)',
['tools', '@deepseek-ai/dsh-tools'],
['mcp-resources', '@deepseek-ai/dsh-mcp-resources'],
['agent', '@deepseek-ai/dsh-agent'],
['agent-model', '@deepseek-ai/dsh-agent-model'],
['llm-retry', '@deepseek-ai/dsh-llm-retry'],
['jobs', '@deepseek-ai/dsh-jobs-local'],
['agent-loop', '@deepseek-ai/dsh-agent-loop'],
+2 -1
View File
@@ -5,7 +5,7 @@ import { boot, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot'
import { SessionId } from '@deepseek-ai/dsh-session'
import type {} from '@deepseek-ai/dsh-skill'
import type {} from '@deepseek-ai/dsh-tools'
import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
const overlayPath = process.argv[2]
if (overlayPath === undefined) throw new Error('dsh-badge snapshot requires an overlay path')
@@ -31,6 +31,7 @@ try {
id: agentId,
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'idle',
send: () => {},
-1
View File
@@ -12,7 +12,6 @@
"@deepseek-ai/dsh-llm-replay": "workspace:*",
"@deepseek-ai/cordis": "workspace:~",
"@deepseek-ai/dsh-agent": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*",
"@deepseek-ai/dsh-agent-loop": "workspace:*",
"@deepseek-ai/dsh-agent-loop-testkit": "workspace:*",
"@deepseek-ai/dsh-agent-preset-registry": "workspace:*",
@@ -4,7 +4,6 @@ import { performance } from 'node:perf_hooks'
import { scheduler } from 'node:timers/promises'
import { Context } from '@deepseek-ai/cordis'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import { agentPresetProjectionDefinition } from '@deepseek-ai/dsh-agent-preset-registry'
import SessionStore, {
@@ -162,7 +161,6 @@ class SessionBenchmarkHost {
else {
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SessionStore)
}
await installProjectionSet(ctx)
+2 -2
View File
@@ -27,8 +27,8 @@
en: f270fd4ca334d417
zh: 3c789548e555508e
/deepseek-harness-architecture/session-log:
en: 5e5803bf920e775c
zh: c159b74a74aa34fa
en: 8a7f19b95d426c99
zh: d5bb0538404e20ea
/deepseek-harness-architecture/capability-seams:
en: a5bc20c3f2a1b370
zh: 91773a281410b2f4
+1 -1
View File
@@ -123,7 +123,7 @@ Session consumers know only the current logical format. Header-only `stat` and `
**Model-visible means logged.** Every model request must be reconstructable from the log. New model-visible inputs require session events. Plugins changing existing message content register [pure message projections](subsystems/session.md#plugin-owned-message-projections); detached readers supply the same definitions explicitly. Tool changes are capability-independent; [Session tool history](../packages/core/session/README.md) supplies provider declarations.
**Projection seam.** `dsh-session-projection` owns `ctx.sessionProjections`: registered units fold committed events incrementally, and carriers batch cropped client views with `snapshot()`. Domain services await registration during activation, retain private handles, and expose business methods for other plugins. Releasing registration removes global participation; retained handles continue folding Session events. `AgentRegistry` owns turn and step state and exposes `turnBoundaryOf(session)` ([registration lifecycle](../packages/session/session-projection/README.md)). `dsh-agent-model` owns `modelSelection`.
**Projection seam.** `dsh-session-projection` owns `ctx.sessionProjections`: registered units fold committed events incrementally, and carriers batch cropped client views with `snapshot()`. Domain services await registration during activation, retain private handles, and expose business methods for other plugins. Releasing registration removes global participation; retained handles continue folding Session events. `AgentRegistry` owns turn and step state and exposes `turnBoundaryOf(session)` ([registration lifecycle](../packages/session/session-projection/README.md)). `AgentLoop` owns `modelSelection` and constructs each Agent’s `model` instance alongside its inbox.
[Working directories](subsystems/working-directory.md) supply user context and execution paths without changing original project identity, sandbox write roots, or existing process directories.
+1 -1
View File
@@ -127,7 +127,7 @@ Session 消费方只了解当前逻辑格式。仅 header 的 `stat` 与 `list`
**模型可见即已记录。** 每个模型请求都必须能从日志重建。新增模型可见输入需要会话事件。修改现有消息内容的插件注册[纯消息投影](subsystems/session.zh.md#plugin-owned-message-projections),独立读取器显式传入相同的处理器。 工具变更不依赖能力;[Session 工具历史](../packages/core/session/README.zh.md)提供提供方声明。
**投影 seam。** `dsh-session-projection` 提供 `ctx.sessionProjections`:已注册单元增量折叠已提交事件,载体通过 `snapshot()` 批量取得裁剪后的客户端视图。领域服务在激活时等待注册完成,在内部保留句柄,并向其他插件提供业务方法。释放注册会移除全局参与关系;已有句柄仍可继续折叠 Session 事件。`AgentRegistry` 持有轮次和步骤状态,并提供 `turnBoundaryOf(session)`([注册生命周期](../packages/session/session-projection/README.zh.md))。 `dsh-agent-model` 持有 `modelSelection`。
**投影 seam。** `dsh-session-projection` 提供 `ctx.sessionProjections`:已注册单元增量折叠已提交事件,载体通过 `snapshot()` 批量取得裁剪后的客户端视图。领域服务在激活时等待注册完成,在内部保留句柄,并向其他插件提供业务方法。释放注册会移除全局参与关系;已有句柄仍可继续折叠 Session 事件。`AgentRegistry` 持有轮次和步骤状态,并提供 `turnBoundaryOf(session)`([注册生命周期](../packages/session/session-projection/README.zh.md))。 `AgentLoop` 持有 `modelSelection`,并与 inbox 一起构建每个 Agent 的 `model` 实例。
[工作目录](subsystems/working-directory.zh.md) 提供用户上下文和执行路径,不改变原始项目标识、沙箱写入根目录或已有进程目录。
+2 -2
View File
@@ -6,5 +6,5 @@
en: 41d772192075e133
zh: 5ef3da69b4de1d8a
/capability-seams-and-core-services:
en: b6d09bcd8359cbd2
zh: b64ec0217ca2bd3f
en: 753b3da3abc6aeea
zh: aab02ec16c3f744b
-9
View File
@@ -191,8 +191,6 @@ flowchart LR
pkg_skill_office["skill-office"]
svc_agents["ctx.agents<br/>Agent service"]
pkg_acp["acp"]
pkg_agent_model["agent-model"]
svc_agentModel["ctx.agentModel<br/>Session model selection"]
svc_agentDefaultModel["ctx.agentDefaultModel<br/>Default Agent model selection"]
svc_agentLoop["ctx.agentLoop<br/>Concrete loop driver"]
pkg_base["base"]
@@ -302,7 +300,6 @@ flowchart LR
pkg_agent --> svc_agents
pkg_agent_default_model --> svc_agentDefaultModel
pkg_agent_loop --> svc_agentLoop
pkg_agent_model --> svc_agentModel
pkg_agent_preset_registry --> svc_agentPresets
pkg_api_gateway --> svc_typertGateway
pkg_api_job_controller --> svc_jobController
@@ -463,11 +460,6 @@ flowchart LR
svc_agentDefaultModel --> pkg_headless
svc_agentLoop --> pkg_base
svc_agentLoop --> pkg_sdk_minimal
svc_agentModel --> pkg_acp
svc_agentModel --> pkg_agent_loop
svc_agentModel --> pkg_api_session_controller
svc_agentModel --> pkg_headless
svc_agentModel --> pkg_sdk_jsonrpc_server
svc_agentTeams --> pkg_experimental_tool_agent_team
svc_agents --> pkg_acp
svc_agents --> pkg_agent_loop
@@ -694,7 +686,6 @@ flowchart LR
| `ctx.sessionProjectionCache` | `core` | [`session-projection-cache`](../packages/session/session-projection-cache) | - | [`api-session-controller`](../packages/api/session-controller), [`session-query`](../packages/session-query/session-query), [`session-reference`](../packages/context/session-reference) | - | Durably checkpoints projection unit states per session (throttled + turn/end/detach mandatory points), serves cached projection views, and accelerates prepared-Session projection hydration. |
| `ctx.skills` | `seam` | [`skill`](../packages/skill/skill) | [`sandbox-windows-acl`](../packages/sandbox/sandbox-windows-acl), [`skill-badge`](../packages/experimental/skill-badge), [`skill-filesystem`](../packages/skill/skill-filesystem), [`skill-office`](../packages/skill/skill-office) | [`tool-skill`](../packages/skill/tool-skill) | - | Merges provider skill catalogs; tool-skill renders the session-prefix catalog and loads complete skill bodies. |
| `ctx.agents` | `core` | [`agent`](../packages/core/agent) | - | [`agent-loop`](../packages/core/agent-loop), [`acp`](../packages/acp/acp), [`subagent`](../packages/subagent/subagent) | - | Owns live Agent handles, the create/resume factory seam, and process-local initiator propagation. |
| `ctx.agentModel` | `core` | [`agent-model`](../packages/core/agent-model) | - | [`agent-loop`](../packages/core/agent-loop), [`api-session-controller`](../packages/api/session-controller), [`acp`](../packages/acp/acp), [`sdk-jsonrpc-server`](../packages/sdk/server), [`headless`](../packages/bundle/headless) | - | Reads and records Session model choices; owns the modelSelection projection and optional scoped route-switch notices. |
| `ctx.agentDefaultModel` | `core` | [`agent-default-model`](../packages/core/agent-default-model) | - | [`api-session-controller`](../packages/api/session-controller), [`headless`](../packages/bundle/headless) | - | Reads the default ModelSelection from volatile Config and saves selections through the profile editor. |
| `ctx.agentLoop` | `bundle` | [`agent-loop`](../packages/core/agent-loop) | - | [`base`](../packages/bundle/base), [`sdk-minimal`](../packages/bundle/sdk-minimal) | - | The one concrete loop plugin; extension packages depend on dsh-agent events and services, not on this package. |
| `ctx.schedule` | `core` | [`schedule`](../packages/schedule/schedule) | - | - | - | Stores tasks independently of Session activation and queues due messages in the original Session. |
-12
View File
@@ -193,10 +193,6 @@ flowchart LR
pkg_skill_office["skill-office"]
svc_agents["ctx.agents<br/>Agent service"]
pkg_acp["acp"]
pkg_agent_model["agent-model"]
svc_agentModel["ctx.agentModel<br/>Session model selection"]
pkg_agent_controller["agent-controller"]
svc_agentController["ctx.agentController<br/>Outside-message delivery"]
svc_agentDefaultModel["ctx.agentDefaultModel<br/>Default Agent model selection"]
svc_agentLoop["ctx.agentLoop<br/>Concrete loop driver"]
pkg_base["base"]
@@ -306,7 +302,6 @@ flowchart LR
pkg_agent --> svc_agents
pkg_agent_default_model --> svc_agentDefaultModel
pkg_agent_loop --> svc_agentLoop
pkg_agent_model --> svc_agentModel
pkg_agent_preset_registry --> svc_agentPresets
pkg_api_gateway --> svc_typertGateway
pkg_api_job_controller --> svc_jobController
@@ -467,11 +462,6 @@ flowchart LR
svc_agentDefaultModel --> pkg_headless
svc_agentLoop --> pkg_base
svc_agentLoop --> pkg_sdk_minimal
svc_agentModel --> pkg_acp
svc_agentModel --> pkg_agent_loop
svc_agentModel --> pkg_api_session_controller
svc_agentModel --> pkg_headless
svc_agentModel --> pkg_sdk_jsonrpc_server
svc_agentTeams --> pkg_experimental_tool_agent_team
svc_agents --> pkg_acp
svc_agents --> pkg_agent_loop
@@ -698,8 +688,6 @@ flowchart LR
| `ctx.sessionProjectionCache` | `core` | [`session-projection-cache`](../packages/session/session-projection-cache) | - | [`api-session-controller`](../packages/api/session-controller), [`session-query`](../packages/session-query/session-query), [`session-reference`](../packages/context/session-reference) | - | 按会话持久保存投影单元状态的检查点(节流检查点,以及轮次/结束/分离时的必选检查点),提供缓存投影视图,并加速 prepared Session 的投影恢复。 |
| `ctx.skills` | `seam` | [`skill`](../packages/skill/skill) | [`sandbox-windows-acl`](../packages/sandbox/sandbox-windows-acl), [`skill-badge`](../packages/experimental/skill-badge), [`skill-filesystem`](../packages/skill/skill-filesystem), [`skill-office`](../packages/skill/skill-office) | [`tool-skill`](../packages/skill/tool-skill) | - | 合并提供方的 skill(技能)目录;tool-skill 渲染会话前缀目录,并加载完整的 skill 正文。 |
| `ctx.agents` | `core` | [`agent`](../packages/core/agent) | - | [`agent-loop`](../packages/core/agent-loop), [`acp`](../packages/acp/acp), [`subagent`](../packages/subagent/subagent) | - | 拥有实时 Agent 句柄、创建/恢复工厂 seam,以及进程本地的发起方传播。 |
| `ctx.agentModel` | `core` | [`agent-model`](../packages/core/agent-model) | - | [`agent-loop`](../packages/core/agent-loop), [`api-session-controller`](../packages/api/session-controller), [`acp`](../packages/acp/acp), [`sdk-jsonrpc-server`](../packages/sdk/server), [`headless`](../packages/bundle/headless) | - | 读取并记录 Session 模型选择;持有 modelSelection 投影与可选的作用域内路由切换提示。 |
| `ctx.agentController` | `core` | [`agent-controller`](../packages/core/agent-controller) | - | [`api-session-controller`](../packages/api/session-controller) | - | 准备发送方代表他人送来的消息,经 agent-controller/admission 阶段接纳后放入收件箱,每个 Agent 逐条处理。 |
| `ctx.agentDefaultModel` | `core` | [`agent-default-model`](../packages/core/agent-default-model) | - | [`api-session-controller`](../packages/api/session-controller), [`headless`](../packages/bundle/headless) | - | Reads the default ModelSelection from volatile Config and saves selections through the profile editor. |
| `ctx.agentLoop` | `bundle` | [`agent-loop`](../packages/core/agent-loop) | - | [`base`](../packages/bundle/base), [`sdk-minimal`](../packages/bundle/sdk-minimal) | - | 唯一的具体循环插件;扩展包依赖 dsh-agent 的事件和服务,而不依赖此包。 |
| `ctx.schedule` | `core` | [`schedule`](../packages/schedule/schedule) | - | - | - | 独立于 Session 的加载状态存储任务,并将到期消息排入原 Session。 |
+10 -11
View File
@@ -14,9 +14,9 @@ Each package entry labels its data with three identifiers: `inject` lists the se
## `@deepseek-ai/dsh-acp`
- `inject`: `agents` · `llm` · `sessionPersistence` · `agentModel` · `sessions`
- `inject`: `agents` · `llm` · `sessionPersistence` · `sessions`
- `refs`: `Stream` (`@agentclientprotocol/sdk`)
- `source`: [`packages/acp/acp/src/index.ts:75`](../packages/acp/acp/src/index.ts)
- `source`: [`packages/acp/acp/src/index.ts:74`](../packages/acp/acp/src/index.ts)
```ts config-catalog
/** Plugin config: the provider/model selection used for each ACP-created agent. */
@@ -94,9 +94,9 @@ export interface Config {
## `@deepseek-ai/dsh-agent-loop`
- `inject`: `agentModel` · `agents` · `sessions` · `llm` · `tools` · `systemPrompt` · `sessionProjections`
- `inject`: `agents` · `sessions` · `llm` · `tools` · `systemPrompt` · `sessionProjections`
- `refs`: [`AgentOptions`](subsystems/core.md) · [`SessionId`](subsystems/core.md) · `Volatile` (`@deepseek-ai/cosmokit`)
- `source`: [`packages/core/agent-loop/src/index.ts:251`](../packages/core/agent-loop/src/index.ts)
- `source`: [`packages/core/agent-loop/src/index.ts:253`](../packages/core/agent-loop/src/index.ts)
```ts config-catalog
/** Agent-loop plugin configuration. */
@@ -225,8 +225,8 @@ export interface Config {
## `@deepseek-ai/dsh-api-session-controller`
- `inject`: `agentDefaultModel` · `agents` · `attachments` · `fileUploads` · `fs` · `llm` · `remoteAccess` · `sessions` · `sessionProjections` · `agentModel` · `sessionQuery` · `typert` · `workspaceRegistry`
- `source`: [`packages/api/session-controller/src/index.ts:94`](../packages/api/session-controller/src/index.ts)
- `inject`: `agentDefaultModel` · `agents` · `attachments` · `fileUploads` · `fs` · `llm` · `remoteAccess` · `sessions` · `sessionProjections` · `sessionQuery` · `typert` · `workspaceRegistry`
- `source`: [`packages/api/session-controller/src/index.ts:93`](../packages/api/session-controller/src/index.ts)
```ts config-catalog
/** Session Controller deployment policy. */
@@ -1488,9 +1488,9 @@ export interface Config {
## `@deepseek-ai/dsh-headless`
- `inject`: `agentDefaultModel` · `agents` · `agentModel` · `sessions`
- `inject`: `agentDefaultModel` · `agents` · `sessions`
- `refs`: [`ApprovalPolicy`](subsystems/approval.md)
- `source`: [`packages/bundle/headless/src/index.ts:49`](../packages/bundle/headless/src/index.ts)
- `source`: [`packages/bundle/headless/src/index.ts:48`](../packages/bundle/headless/src/index.ts)
```ts config-catalog
/** Plugin config: the task and run options resolved from this app's injected provider service. */
@@ -2841,9 +2841,9 @@ export interface Config {
## `@deepseek-ai/dsh-sdk-jsonrpc-server`
- `inject`: `agents` · `agentModel` · `workingDirectory`
- `inject`: `agents` · `workingDirectory`
- `refs`: `Readable` (`node:stream`) · `Writable` (`node:stream`)
- `source`: [`packages/sdk/server/src/index.ts:25`](../packages/sdk/server/src/index.ts)
- `source`: [`packages/sdk/server/src/index.ts:24`](../packages/sdk/server/src/index.ts)
```ts config-catalog
/** JSON-RPC deployment config plus runtime-only test hooks. */
@@ -4698,7 +4698,6 @@ These load from a `cordis.yml` entry with no `config:` block; they declare no co
| --- | --- | --- |
| `@deepseek-ai/dsh-acp-app` | `cmdlineArgs` | [`packages/bundle/acp-app/src/index.ts`](../packages/bundle/acp-app/src/index.ts) |
| `@deepseek-ai/dsh-agent` | `sessionProjections` | [`packages/core/agent/src/index.ts`](../packages/core/agent/src/index.ts) |
| `@deepseek-ai/dsh-agent-model` | `sessionProjections` | [`packages/core/agent-model/src/index.ts`](../packages/core/agent-model/src/index.ts) |
| `@deepseek-ai/dsh-api-account-controller` | `deepseekAccount` · `agents` | [`packages/api/account-controller/src/index.ts`](../packages/api/account-controller/src/index.ts) |
| `@deepseek-ai/dsh-api-remote-access` | — | [`packages/api/remote-access/src/index.ts`](../packages/api/remote-access/src/index.ts) |
| `@deepseek-ai/dsh-api-remotes` | `typertGateway` | [`packages/api/remotes/src/index.ts`](../packages/api/remotes/src/index.ts) |
+10 -11
View File
@@ -16,9 +16,9 @@
## `@deepseek-ai/dsh-acp`
- `inject`: `agents` · `llm` · `sessionPersistence` · `agentModel` · `sessions`
- `inject`: `agents` · `llm` · `sessionPersistence` · `sessions`
- `refs`: `Stream` (`@agentclientprotocol/sdk`)
- `source`: [`packages/acp/acp/src/index.ts:75`](../packages/acp/acp/src/index.ts)
- `source`: [`packages/acp/acp/src/index.ts:74`](../packages/acp/acp/src/index.ts)
```ts config-catalog
/** Plugin config: the provider/model selection used for each ACP-created agent. */
@@ -96,9 +96,9 @@ export interface Config {
## `@deepseek-ai/dsh-agent-loop`
- `inject`: `agentModel` · `agents` · `sessions` · `llm` · `tools` · `systemPrompt` · `sessionProjections`
- `inject`: `agents` · `sessions` · `llm` · `tools` · `systemPrompt` · `sessionProjections`
- `refs`: [`AgentOptions`](subsystems/core.zh.md) · [`SessionId`](subsystems/core.zh.md) · `Volatile` (`@deepseek-ai/cosmokit`)
- `source`: [`packages/core/agent-loop/src/index.ts:251`](../packages/core/agent-loop/src/index.ts)
- `source`: [`packages/core/agent-loop/src/index.ts:253`](../packages/core/agent-loop/src/index.ts)
```ts config-catalog
/** Agent-loop plugin configuration. */
@@ -227,8 +227,8 @@ export interface Config {
## `@deepseek-ai/dsh-api-session-controller`
- `inject`: `agentDefaultModel` · `agents` · `attachments` · `fileUploads` · `fs` · `llm` · `remoteAccess` · `sessions` · `sessionProjections` · `agentModel` · `sessionQuery` · `typert` · `workspaceRegistry`
- `source`: [`packages/api/session-controller/src/index.ts:94`](../packages/api/session-controller/src/index.ts)
- `inject`: `agentDefaultModel` · `agents` · `attachments` · `fileUploads` · `fs` · `llm` · `remoteAccess` · `sessions` · `sessionProjections` · `sessionQuery` · `typert` · `workspaceRegistry`
- `source`: [`packages/api/session-controller/src/index.ts:93`](../packages/api/session-controller/src/index.ts)
```ts config-catalog
/** Session Controller deployment policy. */
@@ -1490,9 +1490,9 @@ export interface Config {
## `@deepseek-ai/dsh-headless`
- `inject`: `agentDefaultModel` · `agents` · `agentModel` · `sessions`
- `inject`: `agentDefaultModel` · `agents` · `sessions`
- `refs`: [`ApprovalPolicy`](subsystems/approval.zh.md)
- `source`: [`packages/bundle/headless/src/index.ts:49`](../packages/bundle/headless/src/index.ts)
- `source`: [`packages/bundle/headless/src/index.ts:48`](../packages/bundle/headless/src/index.ts)
```ts config-catalog
/** Plugin config: the task and run options resolved from this app's injected provider service. */
@@ -2843,9 +2843,9 @@ export interface Config {
## `@deepseek-ai/dsh-sdk-jsonrpc-server`
- `inject`: `agents` · `agentModel` · `workingDirectory`
- `inject`: `agents` · `workingDirectory`
- `refs`: `Readable` (`node:stream`) · `Writable` (`node:stream`)
- `source`: [`packages/sdk/server/src/index.ts:25`](../packages/sdk/server/src/index.ts)
- `source`: [`packages/sdk/server/src/index.ts:24`](../packages/sdk/server/src/index.ts)
```ts config-catalog
/** JSON-RPC deployment config plus runtime-only test hooks. */
@@ -4700,7 +4700,6 @@ export interface Config {
| --- | --- | --- |
| `@deepseek-ai/dsh-acp-app` | `cmdlineArgs` | [`packages/bundle/acp-app/src/index.ts`](../packages/bundle/acp-app/src/index.ts) |
| `@deepseek-ai/dsh-agent` | `sessionProjections` | [`packages/core/agent/src/index.ts`](../packages/core/agent/src/index.ts) |
| `@deepseek-ai/dsh-agent-model` | `sessionProjections` | [`packages/core/agent-model/src/index.ts`](../packages/core/agent-model/src/index.ts) |
| `@deepseek-ai/dsh-api-account-controller` | `deepseekAccount` · `agents` | [`packages/api/account-controller/src/index.ts`](../packages/api/account-controller/src/index.ts) |
| `@deepseek-ai/dsh-api-remote-access` | — | [`packages/api/remote-access/src/index.ts`](../packages/api/remote-access/src/index.ts) |
| `@deepseek-ai/dsh-api-remotes` | `typertGateway` | [`packages/api/remotes/src/index.ts`](../packages/api/remotes/src/index.ts) |
+3 -3
View File
@@ -8,6 +8,6 @@
/event-producer-and-consumer-matrix:
en: 19f30fda81e73345
zh: a8505006244f5619
/event-producer-and-consumer-matrix/events-outside-the-current-harness-api-catalog:
en: 6a87a4da78bd7170
zh: 45b1dc20d153587f
/event-producer-and-consumer-matrix/non-harness-or-undeclared-event-strings-seen-in-package-source:
en: 96dc0ff1580e5741
zh: 96dc0ff1580e5741
+14 -14
View File
@@ -8,19 +8,19 @@ This matrix shows which packages dispatch each harness-owned event and which pac
<!-- BEGIN GENERATED event-producer-consumer:events -->
| Event | Mode | Declared in | Dispatchers | Listeners |
| --- | --- | --- | --- | --- |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:197`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:199`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent-preset/selected` | `emit` | [`packages/preset/agent-preset-registry/src/types.ts:66`](../packages/preset/agent-preset-registry/src/types.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`) | [`cua`](../packages/experimental/cua), `remotes` |
| `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:376`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` |
| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:267`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | `agent-team`, `browser-use-runtime`, `claude-code-mods`, [`cua`](../packages/experimental/cua), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:276`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `claude-code-mods`, [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:406`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`deepseek-account`](../packages/credentials/deepseek-account), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), `server`, `session-controller`, [`session-telemetry`](../packages/session/session-telemetry), [`subagent`](../packages/subagent/subagent) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:305`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:313`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/inserted` | `emit` | [`packages/core/agent/src/runtime-types.ts:294`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
| `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:327`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent-instructions`](../packages/context/agent-instructions), [`agent-model`](../packages/core/agent-model), `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `session-controller`, [`session-reference`](../packages/context/session-reference), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-skill`](../packages/skill/tool-skill) |
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:366`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) |
| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:286`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:394`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:399`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` |
| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | `agent-team`, `browser-use-runtime`, `claude-code-mods`, [`cua`](../packages/experimental/cua), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:299`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `claude-code-mods`, [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:429`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`deepseek-account`](../packages/credentials/deepseek-account), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), `server`, `session-controller`, [`session-telemetry`](../packages/session/session-telemetry), [`subagent`](../packages/subagent/subagent) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:328`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:336`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/inserted` | `emit` | [`packages/core/agent/src/runtime-types.ts:317`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
| `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:350`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `session-controller`, [`session-reference`](../packages/context/session-reference), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-skill`](../packages/skill/tool-skill) |
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:389`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) |
| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:309`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:417`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:599`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:579`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:606`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
@@ -93,7 +93,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| `workspace/session-stop` | `parallel` | [`packages/workspace/workspace/src/index.ts:147`](../packages/workspace/workspace/src/index.ts) | [`workspace`](../packages/workspace/workspace) (`parallel`) | [`agent`](../packages/core/agent), [`jobs`](../packages/jobs/jobs), [`schedule`](../packages/schedule/schedule), [`subagent`](../packages/subagent/subagent) |
<!-- END GENERATED event-producer-consumer:events -->
## Events outside the current Harness API catalog
## Non-harness or undeclared event strings seen in package source
<!-- BEGIN GENERATED event-producer-consumer:undeclared -->
| Event string | Dispatchers | Listeners |
@@ -103,7 +103,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
| `internal/dispatch` | - | [`terminal-bash`](../packages/terminal/terminal-bash) |
| `internal/plugin` | - | `computer-use-cua-driver-native`, `inspector`, `loader`, [`lsp-stdio`](../packages/lsp/lsp-stdio), [`mcp-client`](../packages/mcp/mcp-client), `modules` |
| `internal/service` | - | `gateway` |
| `internal/status` | - | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), `inspector`, `translator`, [`web`](../packages/web/web) |
| `internal/status` | - | [`agent`](../packages/core/agent), `inspector`, `translator`, [`web`](../packages/web/web) |
| `internal/update` | - | [`app-boot`](../packages/boot/app-boot) |
| `loader/volatile-update` | - | [`cua`](../packages/experimental/cua), [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), [`plugin-market`](../packages/boot/plugin-market), `product-analytics`, `speech-to-text` |
| `slots/changed` | `ui-renderer` (`emit`) | - |
+14 -14
View File
@@ -10,19 +10,19 @@
<!-- BEGIN GENERATED event-producer-consumer:events -->
| Event | Mode | Declared in | Dispatchers | Listeners |
| --- | --- | --- | --- | --- |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:197`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent-loop/config-start-failed` | `emit` | [`packages/core/agent-loop/src/index.ts:199`](../packages/core/agent-loop/src/index.ts) | [`agent-loop`](../packages/core/agent-loop) (`events.dispatch`) | - |
| `agent-preset/selected` | `emit` | [`packages/preset/agent-preset-registry/src/types.ts:66`](../packages/preset/agent-preset-registry/src/types.ts) | [`agent-preset-registry`](../packages/preset/agent-preset-registry) (`emit`) | [`cua`](../packages/experimental/cua), `remotes` |
| `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:376`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` |
| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:267`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | `agent-team`, `browser-use-runtime`, `claude-code-mods`, [`cua`](../packages/experimental/cua), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:276`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `claude-code-mods`, [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:406`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`deepseek-account`](../packages/credentials/deepseek-account), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), `server`, `session-controller`, [`session-telemetry`](../packages/session/session-telemetry), [`subagent`](../packages/subagent/subagent) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:305`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:313`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/inserted` | `emit` | [`packages/core/agent/src/runtime-types.ts:294`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
| `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:327`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent-instructions`](../packages/context/agent-instructions), [`agent-model`](../packages/core/agent-model), `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `session-controller`, [`session-reference`](../packages/context/session-reference), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-skill`](../packages/skill/tool-skill) |
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:366`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) |
| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:286`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:394`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `agent/assistant-stream` | `emit` | [`packages/core/agent/src/runtime-types.ts:399`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`headless`](../packages/bundle/headless), `session-controller` |
| `agent/created` | `serial` | [`packages/core/agent/src/runtime-types.ts:290`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`serial`) | `agent-team`, `browser-use-runtime`, `claude-code-mods`, [`cua`](../packages/experimental/cua), [`file-reference-local`](../packages/context/file-reference-local), [`goal`](../packages/goal/goal), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`loader-smoke`](../packages/test-support/loader-smoke), `session-controller`, `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/disposed` | `emit` | [`packages/core/agent/src/runtime-types.ts:299`](../packages/core/agent/src/runtime-types.ts) | [`agent`](../packages/core/agent) (`events.dispatch`) | [`agent-loop`](../packages/core/agent-loop), `claude-code-mods`, [`file-reference-local`](../packages/context/file-reference-local), [`goal-round-driver`](../packages/goal/goal-round-driver), `session-controller`, [`subagent`](../packages/subagent/subagent), `tool-agent-team`, [`tool-subagent`](../packages/subagent/tool-subagent) |
| `agent/error` | `emit` | [`packages/core/agent/src/runtime-types.ts:429`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`deepseek-account`](../packages/credentials/deepseek-account), [`goal-round-driver`](../packages/goal/goal-round-driver), [`headless`](../packages/bundle/headless), `server`, `session-controller`, [`session-telemetry`](../packages/session/session-telemetry), [`subagent`](../packages/subagent/subagent) |
| `agent/inbox/claimed` | `emit` | [`packages/core/agent/src/runtime-types.ts:328`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`tool-jobs`](../packages/jobs/tool-jobs), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/discarded` | `emit` | [`packages/core/agent/src/runtime-types.ts:336`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions) |
| `agent/inbox/inserted` | `emit` | [`packages/core/agent/src/runtime-types.ts:317`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`goal-round-driver`](../packages/goal/goal-round-driver), [`subagent`](../packages/subagent/subagent) |
| `agent/pre-step` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:350`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`agent`](../packages/core/agent), [`agent-instructions`](../packages/context/agent-instructions), `claude-code-mods`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`plan-mode`](../packages/plan/plan-mode), [`repeat-tool-reminder`](../packages/guard/repeat-tool-reminder), [`session-checkpoint-policy`](../packages/session/session-checkpoint-policy), `session-controller`, [`session-reference`](../packages/context/session-reference), [`time-context`](../packages/context/time-context), [`tmux-context`](../packages/context/tmux-context), [`tool-skill`](../packages/skill/tool-skill) |
| `agent/request-error` | `waterfall` | [`packages/core/agent/src/runtime-types.ts:389`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`waterfall`) | [`compaction-basic`](../packages/compaction/compaction-basic), [`compaction-image-offload`](../packages/compaction/compaction-image-offload), [`llm-retry`](../packages/llm/llm-retry) |
| `agent/status` | `emit` | [`packages/core/agent/src/runtime-types.ts:309`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`emit`) | [`acp`](../packages/acp/acp), `agent-team`, [`compaction-basic`](../packages/compaction/compaction-basic), [`goal-round-driver`](../packages/goal/goal-round-driver), `server`, `session-controller` |
| `agent/turn-stopping` | `serial` | [`packages/core/agent/src/runtime-types.ts:417`](../packages/core/agent/src/runtime-types.ts) | [`agent-loop`](../packages/core/agent-loop) (`serial`) | [`hooks-claude-code`](../packages/experimental/hooks-claude-code), [`hooks-codex`](../packages/experimental/hooks-codex), [`workspace-changes`](../packages/deliverables/workspace-changes) |
| `api-session/activity` | `emit` | [`packages/api/session-controller/src/types.ts:599`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/added` | `emit` | [`packages/api/session-controller/src/types.ts:579`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:606`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
@@ -95,7 +95,7 @@
| `workspace/session-stop` | `parallel` | [`packages/workspace/workspace/src/index.ts:147`](../packages/workspace/workspace/src/index.ts) | [`workspace`](../packages/workspace/workspace) (`parallel`) | [`agent`](../packages/core/agent), [`jobs`](../packages/jobs/jobs), [`schedule`](../packages/schedule/schedule), [`subagent`](../packages/subagent/subagent) |
<!-- END GENERATED event-producer-consumer:events -->
## 当前 Harness API 目录之外的事件
## Non-harness or undeclared event strings seen in package source
<!-- BEGIN GENERATED event-producer-consumer:undeclared -->
| Event string | Dispatchers | Listeners |
@@ -105,7 +105,7 @@
| `internal/dispatch` | - | [`terminal-bash`](../packages/terminal/terminal-bash) |
| `internal/plugin` | - | `computer-use-cua-driver-native`, `inspector`, `loader`, [`lsp-stdio`](../packages/lsp/lsp-stdio), [`mcp-client`](../packages/mcp/mcp-client), `modules` |
| `internal/service` | - | `gateway` |
| `internal/status` | - | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), `inspector`, `translator`, [`web`](../packages/web/web) |
| `internal/status` | - | [`agent`](../packages/core/agent), `inspector`, `translator`, [`web`](../packages/web/web) |
| `internal/update` | - | [`app-boot`](../packages/boot/app-boot) |
| `loader/volatile-update` | - | [`cua`](../packages/experimental/cua), [`llm-deepseek`](../packages/llm/llm-deepseek), [`llm-pi-ai`](../packages/llm/llm-pi-ai), [`plugin-market`](../packages/boot/plugin-market), `product-analytics`, `speech-to-text` |
| `slots/changed` | `ui-renderer` (`emit`) | - |
+6 -18
View File
@@ -43,7 +43,6 @@ flowchart TD
pkg_agent["agent"]
pkg_agent_default_model["agent-default-model"]
pkg_agent_loop["agent-loop"]
pkg_agent_model["agent-model"]
pkg_agent_tool_presentation["agent-tool-presentation"]
pkg_scope["scope"]
pkg_session["session"]
@@ -643,10 +642,6 @@ flowchart TD
pkg_llm_retry --> pkg_timeout
pkg_agent_default_model --> pkg_agent
pkg_agent_default_model --> pkg_llm
pkg_agent_model --> pkg_agent
pkg_agent_model --> pkg_llm
pkg_agent_model --> pkg_session
pkg_agent_model --> pkg_session_projection
pkg_goal --> pkg_agent
pkg_goal --> pkg_brand
pkg_goal --> pkg_llm
@@ -825,7 +820,6 @@ flowchart TD
pkg_terminal_bash --> pkg_terminal
pkg_terminal_bash --> pkg_working_directory
pkg_agent_loop --> pkg_agent
pkg_agent_loop --> pkg_agent_model
pkg_agent_loop --> pkg_llm
pkg_agent_loop --> pkg_scope
pkg_agent_loop --> pkg_session
@@ -1148,7 +1142,6 @@ flowchart TD
pkg_subprocess_ssh --> pkg_subprocess_local
pkg_agent_loop_testkit --> pkg_agent
pkg_agent_loop_testkit --> pkg_agent_loop
pkg_agent_loop_testkit --> pkg_agent_model
pkg_agent_loop_testkit --> pkg_fs_local
pkg_agent_loop_testkit --> pkg_llm
pkg_agent_loop_testkit --> pkg_session
@@ -1187,7 +1180,6 @@ flowchart TD
pkg_session_query_sqlite --> pkg_session_persistence
pkg_session_query_sqlite --> pkg_session_query
pkg_acp --> pkg_agent
pkg_acp --> pkg_agent_model
pkg_acp --> pkg_attachment
pkg_acp --> pkg_llm
pkg_acp --> pkg_mcp_client
@@ -1280,7 +1272,6 @@ flowchart TD
pkg_tool_subagent_control --> pkg_tools
pkg_api_session_controller --> pkg_agent
pkg_api_session_controller --> pkg_agent_default_model
pkg_api_session_controller --> pkg_agent_model
pkg_api_session_controller --> pkg_agent_preset_registry
pkg_api_session_controller --> pkg_api_gateway
pkg_api_session_controller --> pkg_attachment
@@ -1316,7 +1307,6 @@ flowchart TD
pkg_plugin_market --> pkg_typert_protocol
pkg_headless --> pkg_agent
pkg_headless --> pkg_agent_default_model
pkg_headless --> pkg_agent_model
pkg_headless --> pkg_fs
pkg_headless --> pkg_llm
pkg_headless --> pkg_permission_presets
@@ -1435,7 +1425,6 @@ flowchart TD
pkg_tool_schedule --> pkg_subagent
pkg_tool_schedule --> pkg_tools
pkg_sdk_jsonrpc_server --> pkg_agent
pkg_sdk_jsonrpc_server --> pkg_agent_model
pkg_sdk_jsonrpc_server --> pkg_attachment
pkg_sdk_jsonrpc_server --> pkg_llm
pkg_sdk_jsonrpc_server --> pkg_llm_deepseek_api_key
@@ -1663,7 +1652,6 @@ flowchart TD
| [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key) | `llm` | [`credentials`](../packages/credentials/credentials), [`launch-environment`](../packages/util/launch-environment), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek) |
| [`llm-retry`](../packages/llm/llm-retry) | `llm` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`timeout`](../packages/util/timeout) |
| [`agent-default-model`](../packages/core/agent-default-model) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm) |
| [`agent-model`](../packages/core/agent-model) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection) |
| [`goal`](../packages/goal/goal) | `goal` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`typert-protocol`](../packages/typert/protocol) |
| [`file-reference`](../packages/context/file-reference) | `context` | [`agent`](../packages/core/agent) |
| [`harness-dev-context`](../packages/context/harness-dev-context) | `context` | [`agent`](../packages/core/agent), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt) |
@@ -1701,7 +1689,7 @@ flowchart TD
| [`bash-sandbox`](../packages/shell/bash-sandbox) | `shell` | [`bash-local`](../packages/shell/bash-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`shell`](../packages/shell/shell) |
| [`pwsh-sandbox`](../packages/shell/pwsh-sandbox) | `shell` | [`pwsh-local`](../packages/shell/pwsh-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`shell`](../packages/shell/shell) |
| [`terminal-bash`](../packages/terminal/terminal-bash) | `terminal` | [`agent`](../packages/core/agent), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess), [`terminal`](../packages/terminal/terminal), [`working-directory`](../packages/session/working-directory) |
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`agent-tool-presentation`](../packages/core/agent-tool-presentation) | `core` | [`tools`](../packages/core/tools) |
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
@@ -1762,11 +1750,11 @@ flowchart TD
| [`fs-ssh`](../packages/ssh/fs-ssh) | `ssh` | [`fs`](../packages/fs/fs), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`ssh`](../packages/ssh/ssh) |
| [`sandbox-ssh`](../packages/ssh/sandbox-ssh) | `ssh` | [`sandbox`](../packages/sandbox/sandbox), [`ssh`](../packages/ssh/ssh) |
| [`subprocess-ssh`](../packages/ssh/subprocess-ssh) | `ssh` | [`ssh`](../packages/ssh/ssh), [`subprocess`](../packages/subprocess/subprocess), [`subprocess-local`](../packages/subprocess/subprocess-local) |
| [`agent-loop-testkit`](../packages/test-support/agent-loop-testkit) | `test-support` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`agent-model`](../packages/core/agent-model), [`fs-local`](../packages/fs/fs-local), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
| [`agent-loop-testkit`](../packages/test-support/agent-loop-testkit) | `test-support` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`fs-local`](../packages/fs/fs-local), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-query`](../packages/session-query/session-query), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`user-approval`](../packages/interaction/user-approval), [`util-time`](../packages/util/time), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`spill-policy`](../packages/spill/spill-policy) | `spill` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) |
| [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | `session-query` | [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query) |
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`mcp-client`](../packages/mcp/mcp-client), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`token-meter`](../packages/llm/token-meter), [`user-approval`](../packages/interaction/user-approval) |
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`mcp-client`](../packages/mcp/mcp-client), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`token-meter`](../packages/llm/token-meter), [`user-approval`](../packages/interaction/user-approval) |
| [`plugin-manager`](../packages/boot/plugin-manager) | `boot` | [`brand`](../packages/util/brand), [`hmr`](../packages/boot/hmr), [`host-plugin-inventory`](../packages/host/plugin-inventory), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`user-approval`](../packages/interaction/user-approval) |
| [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner) | `compaction` | [`compaction`](../packages/compaction/compaction), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
| [`experimental-browser-use-runtime`](../packages/experimental/browser-use-runtime) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`mcp-client`](../packages/mcp/mcp-client), [`scope`](../packages/core/scope), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
@@ -1781,9 +1769,9 @@ flowchart TD
| [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process) | `subagent` | [`subagent`](../packages/subagent/subagent) |
| [`tool-subagent`](../packages/subagent/tool-subagent) | `subagent` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`tool-subagent-control`](../packages/subagent/tool-subagent-control) | `subagent` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-controller`](../packages/core/agent-controller), [`agent-default-model`](../packages/core/agent-default-model), [`agent-model`](../packages/core/agent-model), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-file-upload`](../packages/client/file-upload), [`commands`](../packages/interaction/commands), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`native-command`](../packages/util/native-command), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`settings`](../packages/settings/settings), [`skill`](../packages/skill/skill), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-time`](../packages/util/time), [`util-values`](../packages/util/values), [`util-workspace-path`](../packages/util/workspace-path), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-file-upload`](../packages/client/file-upload), [`commands`](../packages/interaction/commands), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`native-command`](../packages/util/native-command), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`settings`](../packages/settings/settings), [`skill`](../packages/skill/skill), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-time`](../packages/util/time), [`util-values`](../packages/util/values), [`util-workspace-path`](../packages/util/workspace-path), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`plugin-market`](../packages/boot/plugin-market) | `boot` | [`plugin-manager`](../packages/boot/plugin-manager), [`settings`](../packages/settings/settings), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-model`](../packages/core/agent-model), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`subagent`](../packages/subagent/subagent), [`user-approval`](../packages/interaction/user-approval) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`subagent`](../packages/subagent/subagent), [`user-approval`](../packages/interaction/user-approval) |
| [`compaction-basic`](../packages/compaction/compaction-basic) | `compaction` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
| [`session-reference`](../packages/context/session-reference) | `context` | [`agent`](../packages/core/agent), [`compaction`](../packages/compaction/compaction), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`spill`](../packages/spill/spill), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`typert-protocol`](../packages/typert/protocol) |
| [`experimental-agent-team`](../packages/experimental/agent-team) | `experimental` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`subagent`](../packages/subagent/subagent) |
@@ -1799,5 +1787,5 @@ flowchart TD
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`api-gateway`](../packages/api/gateway), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-hmr`](../packages/client/hmr), [`client-modules`](../packages/client/modules), [`client-store`](../packages/client/store), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`client-web`](../packages/client/web), [`remote-mock`](../packages/test-support/remote-mock), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol) |
| [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |
| [`tool-schedule`](../packages/schedule/tool-schedule) | `schedule` | [`llm`](../packages/llm/llm), [`schedule`](../packages/schedule/schedule), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions), [`working-directory`](../packages/session/working-directory) |
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions), [`working-directory`](../packages/session/working-directory) |
<!-- END GENERATED module-graph:packages -->
+6 -18
View File
@@ -45,7 +45,6 @@ flowchart TD
pkg_agent["agent"]
pkg_agent_default_model["agent-default-model"]
pkg_agent_loop["agent-loop"]
pkg_agent_model["agent-model"]
pkg_agent_tool_presentation["agent-tool-presentation"]
pkg_scope["scope"]
pkg_session["session"]
@@ -645,10 +644,6 @@ flowchart TD
pkg_llm_retry --> pkg_timeout
pkg_agent_default_model --> pkg_agent
pkg_agent_default_model --> pkg_llm
pkg_agent_model --> pkg_agent
pkg_agent_model --> pkg_llm
pkg_agent_model --> pkg_session
pkg_agent_model --> pkg_session_projection
pkg_goal --> pkg_agent
pkg_goal --> pkg_brand
pkg_goal --> pkg_llm
@@ -827,7 +822,6 @@ flowchart TD
pkg_terminal_bash --> pkg_terminal
pkg_terminal_bash --> pkg_working_directory
pkg_agent_loop --> pkg_agent
pkg_agent_loop --> pkg_agent_model
pkg_agent_loop --> pkg_llm
pkg_agent_loop --> pkg_scope
pkg_agent_loop --> pkg_session
@@ -1150,7 +1144,6 @@ flowchart TD
pkg_subprocess_ssh --> pkg_subprocess_local
pkg_agent_loop_testkit --> pkg_agent
pkg_agent_loop_testkit --> pkg_agent_loop
pkg_agent_loop_testkit --> pkg_agent_model
pkg_agent_loop_testkit --> pkg_fs_local
pkg_agent_loop_testkit --> pkg_llm
pkg_agent_loop_testkit --> pkg_session
@@ -1189,7 +1182,6 @@ flowchart TD
pkg_session_query_sqlite --> pkg_session_persistence
pkg_session_query_sqlite --> pkg_session_query
pkg_acp --> pkg_agent
pkg_acp --> pkg_agent_model
pkg_acp --> pkg_attachment
pkg_acp --> pkg_llm
pkg_acp --> pkg_mcp_client
@@ -1282,7 +1274,6 @@ flowchart TD
pkg_tool_subagent_control --> pkg_tools
pkg_api_session_controller --> pkg_agent
pkg_api_session_controller --> pkg_agent_default_model
pkg_api_session_controller --> pkg_agent_model
pkg_api_session_controller --> pkg_agent_preset_registry
pkg_api_session_controller --> pkg_api_gateway
pkg_api_session_controller --> pkg_attachment
@@ -1318,7 +1309,6 @@ flowchart TD
pkg_plugin_market --> pkg_typert_protocol
pkg_headless --> pkg_agent
pkg_headless --> pkg_agent_default_model
pkg_headless --> pkg_agent_model
pkg_headless --> pkg_fs
pkg_headless --> pkg_llm
pkg_headless --> pkg_permission_presets
@@ -1437,7 +1427,6 @@ flowchart TD
pkg_tool_schedule --> pkg_subagent
pkg_tool_schedule --> pkg_tools
pkg_sdk_jsonrpc_server --> pkg_agent
pkg_sdk_jsonrpc_server --> pkg_agent_model
pkg_sdk_jsonrpc_server --> pkg_attachment
pkg_sdk_jsonrpc_server --> pkg_llm
pkg_sdk_jsonrpc_server --> pkg_llm_deepseek_api_key
@@ -1665,7 +1654,6 @@ flowchart TD
| [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key) | `llm` | [`credentials`](../packages/credentials/credentials), [`launch-environment`](../packages/util/launch-environment), [`llm`](../packages/llm/llm), [`llm-deepseek`](../packages/llm/llm-deepseek) |
| [`llm-retry`](../packages/llm/llm-retry) | `llm` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`timeout`](../packages/util/timeout) |
| [`agent-default-model`](../packages/core/agent-default-model) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm) |
| [`agent-model`](../packages/core/agent-model) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection) |
| [`goal`](../packages/goal/goal) | `goal` | [`agent`](../packages/core/agent), [`brand`](../packages/util/brand), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`typert-protocol`](../packages/typert/protocol) |
| [`file-reference`](../packages/context/file-reference) | `context` | [`agent`](../packages/core/agent) |
| [`harness-dev-context`](../packages/context/harness-dev-context) | `context` | [`agent`](../packages/core/agent), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt) |
@@ -1703,7 +1691,7 @@ flowchart TD
| [`bash-sandbox`](../packages/shell/bash-sandbox) | `shell` | [`bash-local`](../packages/shell/bash-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`shell`](../packages/shell/shell) |
| [`pwsh-sandbox`](../packages/shell/pwsh-sandbox) | `shell` | [`pwsh-local`](../packages/shell/pwsh-local), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`shell`](../packages/shell/shell) |
| [`terminal-bash`](../packages/terminal/terminal-bash) | `terminal` | [`agent`](../packages/core/agent), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`subprocess`](../packages/subprocess/subprocess), [`terminal`](../packages/terminal/terminal), [`working-directory`](../packages/session/working-directory) |
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`agent-loop`](../packages/core/agent-loop) | `core` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`agent-tool-presentation`](../packages/core/agent-tool-presentation) | `core` | [`tools`](../packages/core/tools) |
| [`tool-goal`](../packages/goal/tool-goal) | `goal` | [`agent`](../packages/core/agent), [`goal`](../packages/goal/goal), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`tool-fs`](../packages/fs/tool-fs) | `fs` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`user-approval`](../packages/interaction/user-approval), [`working-directory`](../packages/session/working-directory) |
@@ -1764,11 +1752,11 @@ flowchart TD
| [`fs-ssh`](../packages/ssh/fs-ssh) | `ssh` | [`fs`](../packages/fs/fs), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`ssh`](../packages/ssh/ssh) |
| [`sandbox-ssh`](../packages/ssh/sandbox-ssh) | `ssh` | [`sandbox`](../packages/sandbox/sandbox), [`ssh`](../packages/ssh/ssh) |
| [`subprocess-ssh`](../packages/ssh/subprocess-ssh) | `ssh` | [`ssh`](../packages/ssh/ssh), [`subprocess`](../packages/subprocess/subprocess), [`subprocess-local`](../packages/subprocess/subprocess-local) |
| [`agent-loop-testkit`](../packages/test-support/agent-loop-testkit) | `test-support` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`agent-model`](../packages/core/agent-model), [`fs-local`](../packages/fs/fs-local), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
| [`agent-loop-testkit`](../packages/test-support/agent-loop-testkit) | `test-support` | [`agent`](../packages/core/agent), [`agent-loop`](../packages/core/agent-loop), [`fs-local`](../packages/fs/fs-local), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
| [`subagent`](../packages/subagent/subagent) | `subagent` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-query`](../packages/session-query/session-query), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`user-approval`](../packages/interaction/user-approval), [`util-time`](../packages/util/time), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`spill-policy`](../packages/spill/spill-policy) | `spill` | [`attachment`](../packages/attachment/attachment), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`spill`](../packages/spill/spill), [`token-meter`](../packages/llm/token-meter), [`tools`](../packages/core/tools) |
| [`session-query-sqlite`](../packages/session-query/session-query-sqlite) | `session-query` | [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-query`](../packages/session-query/session-query) |
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`mcp-client`](../packages/mcp/mcp-client), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`token-meter`](../packages/llm/token-meter), [`user-approval`](../packages/interaction/user-approval) |
| [`acp`](../packages/acp/acp) | `acp` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`mcp-client`](../packages/mcp/mcp-client), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`token-meter`](../packages/llm/token-meter), [`user-approval`](../packages/interaction/user-approval) |
| [`plugin-manager`](../packages/boot/plugin-manager) | `boot` | [`brand`](../packages/util/brand), [`hmr`](../packages/boot/hmr), [`host-plugin-inventory`](../packages/host/plugin-inventory), [`sandbox`](../packages/sandbox/sandbox), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol), [`user-approval`](../packages/interaction/user-approval) |
| [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner) | `compaction` | [`compaction`](../packages/compaction/compaction), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
| [`experimental-browser-use-runtime`](../packages/experimental/browser-use-runtime) | `experimental` | [`agent`](../packages/core/agent), [`browser-use`](../packages/browser-use/browser-use), [`mcp-client`](../packages/mcp/mcp-client), [`scope`](../packages/core/scope), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools), [`working-directory`](../packages/session/working-directory) |
@@ -1783,9 +1771,9 @@ flowchart TD
| [`subagent-spawn-in-process`](../packages/subagent/subagent-spawn-in-process) | `subagent` | [`subagent`](../packages/subagent/subagent) |
| [`tool-subagent`](../packages/subagent/tool-subagent) | `subagent` | [`agent`](../packages/core/agent), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`llm`](../packages/llm/llm), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`tools`](../packages/core/tools) |
| [`tool-subagent-control`](../packages/subagent/tool-subagent-control) | `subagent` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-controller`](../packages/core/agent-controller), [`agent-default-model`](../packages/core/agent-default-model), [`agent-model`](../packages/core/agent-model), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-file-upload`](../packages/client/file-upload), [`commands`](../packages/interaction/commands), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`native-command`](../packages/util/native-command), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`settings`](../packages/settings/settings), [`skill`](../packages/skill/skill), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-time`](../packages/util/time), [`util-values`](../packages/util/values), [`util-workspace-path`](../packages/util/workspace-path), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`api-session-controller`](../packages/api/session-controller) | `api` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-preset-registry`](../packages/preset/agent-preset-registry), [`api-gateway`](../packages/api/gateway), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-file-upload`](../packages/client/file-upload), [`commands`](../packages/interaction/commands), [`credentials`](../packages/credentials/credentials), [`file-reference`](../packages/context/file-reference), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`native-command`](../packages/util/native-command), [`scope`](../packages/core/scope), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`settings`](../packages/settings/settings), [`skill`](../packages/skill/skill), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol), [`typert-registry`](../packages/typert/registry), [`util-time`](../packages/util/time), [`util-values`](../packages/util/values), [`util-workspace-path`](../packages/util/workspace-path), [`working-directory`](../packages/session/working-directory), [`workspace`](../packages/workspace/workspace) |
| [`plugin-market`](../packages/boot/plugin-market) | `boot` | [`plugin-manager`](../packages/boot/plugin-manager), [`settings`](../packages/settings/settings), [`subprocess`](../packages/subprocess/subprocess), [`tools`](../packages/core/tools), [`typert-protocol`](../packages/typert/protocol) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`agent-model`](../packages/core/agent-model), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`subagent`](../packages/subagent/subagent), [`user-approval`](../packages/interaction/user-approval) |
| [`headless`](../packages/bundle/headless) | `bundle` | [`agent`](../packages/core/agent), [`agent-default-model`](../packages/core/agent-default-model), [`fs`](../packages/fs/fs), [`llm`](../packages/llm/llm), [`permission-presets`](../packages/interaction/permission-presets), [`sandbox-policy`](../packages/sandbox/sandbox-policy), [`session`](../packages/core/session), [`session-query`](../packages/session-query/session-query), [`subagent`](../packages/subagent/subagent), [`user-approval`](../packages/interaction/user-approval) |
| [`compaction-basic`](../packages/compaction/compaction-basic) | `compaction` | [`agent`](../packages/core/agent), [`commands`](../packages/interaction/commands), [`compaction`](../packages/compaction/compaction), [`compaction-tool-result-pruner`](../packages/compaction/compaction-tool-result-pruner), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`token-meter`](../packages/llm/token-meter) |
| [`session-reference`](../packages/context/session-reference) | `context` | [`agent`](../packages/core/agent), [`compaction`](../packages/compaction/compaction), [`llm`](../packages/llm/llm), [`output-retention`](../packages/util/output-retention), [`session`](../packages/core/session), [`session-projection`](../packages/session/session-projection), [`session-projection-cache`](../packages/session/session-projection-cache), [`session-query`](../packages/session-query/session-query), [`session-title`](../packages/session/session-title), [`spill`](../packages/spill/spill), [`subagent`](../packages/subagent/subagent), [`system-prompt`](../packages/core/system-prompt), [`typert-protocol`](../packages/typert/protocol) |
| [`experimental-agent-team`](../packages/experimental/agent-team) | `experimental` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`session`](../packages/core/session), [`session-persistence`](../packages/session/session-persistence), [`session-projection`](../packages/session/session-projection), [`subagent`](../packages/subagent/subagent) |
@@ -1801,5 +1789,5 @@ flowchart TD
| [`client-test-runtime`](../packages/test-support/client-runtime) | `test-support` | [`api-gateway`](../packages/api/gateway), [`api-session-controller`](../packages/api/session-controller), [`api-workspace-controller`](../packages/api/workspace-controller), [`attachment`](../packages/attachment/attachment), [`client-connection`](../packages/client/connection), [`client-hmr`](../packages/client/hmr), [`client-modules`](../packages/client/modules), [`client-store`](../packages/client/store), [`client-ui-chat`](../packages/client/ui-chat), [`client-ui-conversation`](../packages/client/ui-conversation), [`client-ui-renderer`](../packages/client/ui-renderer), [`client-ui-session`](../packages/client/ui-session), [`client-ui-settings`](../packages/client/ui-settings), [`client-ui-slots`](../packages/client/ui-slots), [`client-web`](../packages/client/web), [`remote-mock`](../packages/test-support/remote-mock), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`typert-protocol`](../packages/typert/protocol) |
| [`subagent-dsh-sdk`](../packages/subagent/subagent-dsh-sdk) | `subagent` | [`agent`](../packages/core/agent), [`llm`](../packages/llm/llm), [`sdk-client`](../packages/sdk/client), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`subprocess`](../packages/subprocess/subprocess) |
| [`tool-schedule`](../packages/schedule/tool-schedule) | `schedule` | [`llm`](../packages/llm/llm), [`schedule`](../packages/schedule/schedule), [`subagent`](../packages/subagent/subagent), [`tools`](../packages/core/tools) |
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`agent-model`](../packages/core/agent-model), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions), [`working-directory`](../packages/session/working-directory) |
| [`sdk-jsonrpc-server`](../packages/sdk/server) | `sdk` | [`agent`](../packages/core/agent), [`attachment`](../packages/attachment/attachment), [`llm`](../packages/llm/llm), [`llm-deepseek-api-key`](../packages/llm/llm-deepseek-api-key), [`schedule`](../packages/schedule/schedule), [`scope`](../packages/core/scope), [`sdk-protocol`](../packages/sdk/protocol), [`session`](../packages/core/session), [`subagent`](../packages/subagent/subagent), [`user-questions`](../packages/interaction/user-questions), [`working-directory`](../packages/session/working-directory) |
<!-- END GENERATED module-graph:packages -->
+6 -6
View File
@@ -21,8 +21,8 @@
en: 9188862058c6986b
zh: 9188862058c6986b
/session-persistence-event-catalog/events/agent/agent-inbox-spliced-log-only:
en: 825bef0fa148788c
zh: 26c4e5d564c7af14
en: 481727894895b43b
zh: 098bc9788bf88968
/session-persistence-event-catalog/events/agent-preset:
en: 49891ca9be5ac123
zh: 49891ca9be5ac123
@@ -141,8 +141,8 @@
en: 9edf4ef31e60e880
zh: 9edf4ef31e60e880
/session-persistence-event-catalog/events/model/model-selection-log-only:
en: 7cec7fcca2fde7be
zh: 5952ada542599c75
en: c2a60ec7d297ed79
zh: a2f6b2d3c733ce96
/session-persistence-event-catalog/events/permission:
en: 19917bc5438e60af
zh: 19917bc5438e60af
@@ -1524,8 +1524,8 @@
en: 8a9199b1784c70f5
zh: 76c98bc74686fda0
/session-persistence-event-catalog/resolved-persistence-types/inserted-outcome-removedcount-start:
en: 60afe0b0ffb06f19
zh: b223f77cb78ee702
en: 346d884a7a74e48d
zh: 646ac1021f9ca920
/session-persistence-event-catalog/resolved-persistence-types/interrupted-message-step-stream:
en: ec10cd8e9c202a81
zh: e08f859bcb13f0d4
+3 -3
View File
@@ -185,7 +185,7 @@ Sources: [`packages/core/session/src/types.ts:432`](../packages/core/session/src
}
```
Source: [`packages/core/agent/src/types.ts:95`](../packages/core/agent/src/types.ts)
Source: [`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
### `agent-preset/*`
@@ -700,7 +700,7 @@ Source: [`packages/llm/llm-retry/src/types.ts:11`](../packages/llm/llm-retry/src
'model/selection': ModelSelection
```
Source: [`packages/core/agent/src/types.ts:106`](../packages/core/agent/src/types.ts)
Source: [`packages/core/agent/src/types.ts:121`](../packages/core/agent/src/types.ts)
### `permission/*`
@@ -6377,7 +6377,7 @@ Sources: [`packages/core/session/src/types.ts:428`](../packages/core/session/src
SHA-256: `fa106c5b33b657e8ef16e8cbf39f3b7d44e5cbcdf4f9303d9db6410f28951e42`
Sources: [`packages/core/agent/src/types.ts:95`](../packages/core/agent/src/types.ts)
Sources: [`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
| Property | Presence | Type |
|---|---|---|
+3 -3
View File
@@ -187,7 +187,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
}
```
来源:[`packages/core/agent/src/types.ts:95`](../packages/core/agent/src/types.ts)
来源:[`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
### `agent-preset/*`
@@ -702,7 +702,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
'model/selection': ModelSelection
```
来源:[`packages/core/agent/src/types.ts:106`](../packages/core/agent/src/types.ts)
来源:[`packages/core/agent/src/types.ts:121`](../packages/core/agent/src/types.ts)
### `permission/*`
@@ -6379,7 +6379,7 @@ SHA-256: `17d1afb770d9941936130996da00dc86782cfef731d8d6526162c301256a4ac3`
SHA-256: `fa106c5b33b657e8ef16e8cbf39f3b7d44e5cbcdf4f9303d9db6410f28951e42`
来源:[`packages/core/agent/src/types.ts:95`](../packages/core/agent/src/types.ts)
来源:[`packages/core/agent/src/types.ts:110`](../packages/core/agent/src/types.ts)
| 属性 | 存在性 | 类型 |
|---|---|---|
+1 -1
View File
@@ -26079,7 +26079,7 @@
"digest": "fa106c5b33b657e8ef16e8cbf39f3b7d44e5cbcdf4f9303d9db6410f28951e42",
"names": [],
"sources": [
"packages/core/agent/src/types.ts:95"
"packages/core/agent/src/types.ts:110"
]
},
{
+2 -2
View File
@@ -12,8 +12,8 @@
en: ab09a38b4e1f0883
zh: 81e2d14c4036ab6c
/core/the-agent-handle:
en: 5eb475191d723505
zh: 5f4dd4fa9e9a88f0
en: 6ee15fec81bc0686
zh: b6f3fcd48823ea75
/core/initiating-agent:
en: 6c8c47ac78de2dde
zh: c9d527a25a85d1d9
+28 -41
View File
@@ -65,6 +65,8 @@ interface Agent {
readonly options: AgentOptions
/** The live session this agent drives; its log is the durable source of truth. */
readonly session: Session
/** Agent-owned access to durable model selection for future steps. */
readonly model: Model
/** Agent-owned access to durable pending work. */
readonly inbox: Inbox
/** The current lifecycle state, mirrored on every `agent/status` transition. */
@@ -212,7 +214,31 @@ interface AgentOptions {
Step preparation requires `provider` and `model` before prompt assembly. The deprecated `agent/request` hook may change request controls but must preserve that route. An explicit `reasoningEffort` seeds the first request on that route; exact-model resolution validates it, while omission allows the adapter default to materialize. When present, `maxTokens` must be a positive safe integer and caps every conversation-model request; omission allows the exact-model adapter default to materialize before the request header, or otherwise leaves provider behavior unchanged. An agent-scoped `deployment:persona-prefix` prompt section may shadow the global default persona.
`dsh-agent-model` registers `modelSelection` on `ctx.sessionProjections`. `model/selection` records a complete choice without entering model history. A matching request header clears `pending`; the latest request remains `lastUsed`. Adapter-defaulted effort is omitted so later requests resolve the default again. `next` is null only before either a choice or a request is recorded; in that case `AgentOptions` supplies the route. The [model-selection package](../../packages/core/agent-model/README.md) describes selection precedence and resume policy.
`AgentLoop` registers `modelSelection` on `ctx.sessionProjections` and exposes selection operations through each `agent.model` instance. `model/selection` records a complete choice without entering model history. A matching request header clears `pending`; the latest request remains `lastUsed`. Adapter-defaulted effort is omitted so later requests resolve the default again. `next` is null only before either a choice or a request is recorded; in that case `AgentOptions` supplies the route. The [Agent model API](../../packages/core/agent/README.md) describes selection precedence and resume policy.
```ts type-equiv
/** Agent-owned access to the model choice for future steps. */
interface Model {
/**
* Resolve the choice for the next step to begin preparation. Recorded choices
* take precedence over the last request and then the Agent's live options.
* This read neither starts a step nor changes an already-prepared step.
* @returns a detached choice, or undefined when no source names both provider and model.
*/
current(): Readonly<ModelSelection> | undefined
/**
* Replace the next step's complete selection. Omitted effort follows adapter
* defaults without inheriting a previous effort or resolving defaults here.
* An equal recorded choice is a no-op; an options-only fallback is
* always recorded. Callers own model availability and capability validation.
* The append uses the Session's existing persistence and failure guarantees.
* @param selection - complete provider, model, and optional explicit effort.
*/
select(selection: Readonly<ModelSelection>): void
}
```
```ts type-equiv
/** Complete provider, model, and optional reasoning effort chosen for one Session's model steps. */
@@ -228,7 +254,7 @@ interface ModelSelection {
```ts type-equiv
/**
* Durable model-selection fold for one Session. An effort the adapter
* Durable model-selection state for one Session. An effort the adapter
* defaulted on a recorded request is omitted, so later requests resolve the
* default again instead of pinning it as a choice.
*/
@@ -544,45 +570,6 @@ Types: [SessionHeader](persistence.md)
Source: [`packages/core/agent-loop/src/index.ts`](../../packages/core/agent-loop/src/index.ts)
<a id="ctxagentmodel--agentmodel"></a>
### `ctx.agentModel` — `AgentModel`
Read and record Session model choices without resolving adapter defaults.
```ts cordis-catalog
/**
* Resolve the choice for the next step to begin preparation. Recorded choices
* take precedence over the last request and then the Agent's live options.
* This read neither starts a step nor changes an already-prepared step.
* @param agent - Agent whose Session and fallback options are read.
* @returns a detached choice, or undefined when no source names both provider and model.
*/
resolveForNextStep(agent: Agent): Readonly<ModelSelection> | undefined
/**
* Replace the next step's complete selection. Omitted effort follows adapter
* defaults. An equal recorded choice is a no-op; an options-only fallback is
* always recorded. Callers own model availability and capability validation.
* The append uses the Session's existing persistence and failure guarantees.
* @param agent - Agent whose Session receives the model/selection event.
* @param selection - complete provider, model, and optional explicit effort.
*/
select(agent: Agent, selection: Readonly<ModelSelection>): void
/**
* Apply an explicit deployment route, including on Session resume. An omitted
* effort inherits the current explicit effort only for the same route;
* otherwise it follows adapter defaults. Call only when the entry point
* explicitly overrides recorded selection, not for ordinary resume fallback.
* @param agent - Agent whose Session receives the configured choice.
* @param selection - complete configured provider/model and optional effort.
*/
applyConfiguredRoute(agent: Agent, selection: Readonly<ModelSelection>): void
```
Source: [`packages/core/agent-model/src/service.ts`](../../packages/core/agent-model/src/service.ts)
<a id="ctxagentpresets--agentpresetregistry"></a>
### `ctx.agentPresets` — `AgentPresetRegistry`
+28 -41
View File
@@ -69,6 +69,8 @@ interface Agent {
readonly options: AgentOptions
/** The live session this agent drives; its log is the durable source of truth. */
readonly session: Session
/** Agent-owned access to durable model selection for future steps. */
readonly model: Model
/** Agent-owned access to durable pending work. */
readonly inbox: Inbox
/** The current lifecycle state, mirrored on every `agent/status` transition. */
@@ -216,7 +218,31 @@ interface AgentOptions {
步骤准备在提示词组装前要求 `provider` 与 `model` 都存在。已弃用的 `agent/request` hook 可以更改请求控制参数,但必须保留该路由。显式 `reasoningEffort` 会为该路由的首次请求提供初始值;确切模型解析会校验该值,省略时则允许填入适配器默认值。提供 `maxTokens` 时,它必须是正安全整数,并限制每次对话模型请求的输出;省略时,系统会在写入请求 header 前填入确切模型的适配器默认值,否则提供方行为保持不变。agent 作用域的 `deployment:persona-prefix` 提示词段落可以遮蔽全局默认 persona。
`dsh-agent-model` 在 `ctx.sessionProjections` 上注册 `modelSelection`。`model/selection` 记录完整选择,但不进入模型历史。匹配的请求头会清除 `pending`,最近请求仍保留为 `lastUsed`。适配器默认的推理强度会被省略,使后续请求重新解析默认值。只有尚未记录选择或请求时,`next` 才为 null,此时由 `AgentOptions` 提供路由。[模型选择包](../../packages/core/agent-model/README.zh.md)说明选择优先级与恢复策略。
`AgentLoop` 在 `ctx.sessionProjections` 上注册 `modelSelection`,并通过每个 `agent.model` 实例提供选择操作。`model/selection` 记录完整选择,但不进入模型历史。匹配的请求头会清除 `pending`,最近请求仍保留为 `lastUsed`。适配器默认的推理强度会被省略,使后续请求重新解析默认值。只有尚未记录选择或请求时,`next` 才为 null,此时由 `AgentOptions` 提供路由。[Agent 模型 API](../../packages/core/agent/README.zh.md)说明选择优先级与恢复策略。
```ts type-equiv
/** Agent-owned access to the model choice for future steps. */
interface Model {
/**
* Resolve the choice for the next step to begin preparation. Recorded choices
* take precedence over the last request and then the Agent's live options.
* This read neither starts a step nor changes an already-prepared step.
* @returns a detached choice, or undefined when no source names both provider and model.
*/
current(): Readonly<ModelSelection> | undefined
/**
* Replace the next step's complete selection. Omitted effort follows adapter
* defaults without inheriting a previous effort or resolving defaults here.
* An equal recorded choice is a no-op; an options-only fallback is
* always recorded. Callers own model availability and capability validation.
* The append uses the Session's existing persistence and failure guarantees.
* @param selection - complete provider, model, and optional explicit effort.
*/
select(selection: Readonly<ModelSelection>): void
}
```
```ts type-equiv
/** Complete provider, model, and optional reasoning effort chosen for one Session's model steps. */
@@ -232,7 +258,7 @@ interface ModelSelection {
```ts type-equiv
/**
* Durable model-selection fold for one Session. An effort the adapter
* Durable model-selection state for one Session. An effort the adapter
* defaulted on a recorded request is omitted, so later requests resolve the
* default again instead of pinning it as a choice.
*/
@@ -556,45 +582,6 @@ Types: [SessionHeader](persistence.zh.md)
Source: [`packages/core/agent-loop/src/index.ts`](../../packages/core/agent-loop/src/index.ts)
<a id="ctxagentmodel--agentmodel"></a>
### `ctx.agentModel` — `AgentModel`
Read and record Session model choices without resolving adapter defaults.
```ts cordis-catalog
/**
* Resolve the choice for the next step to begin preparation. Recorded choices
* take precedence over the last request and then the Agent's live options.
* This read neither starts a step nor changes an already-prepared step.
* @param agent - Agent whose Session and fallback options are read.
* @returns a detached choice, or undefined when no source names both provider and model.
*/
resolveForNextStep(agent: Agent): Readonly<ModelSelection> | undefined
/**
* Replace the next step's complete selection. Omitted effort follows adapter
* defaults. An equal recorded choice is a no-op; an options-only fallback is
* always recorded. Callers own model availability and capability validation.
* The append uses the Session's existing persistence and failure guarantees.
* @param agent - Agent whose Session receives the model/selection event.
* @param selection - complete provider, model, and optional explicit effort.
*/
select(agent: Agent, selection: Readonly<ModelSelection>): void
/**
* Apply an explicit deployment route, including on Session resume. An omitted
* effort inherits the current explicit effort only for the same route;
* otherwise it follows adapter defaults. Call only when the entry point
* explicitly overrides recorded selection, not for ordinary resume fallback.
* @param agent - Agent whose Session receives the configured choice.
* @param selection - complete configured provider/model and optional effort.
*/
applyConfiguredRoute(agent: Agent, selection: Readonly<ModelSelection>): void
```
Source: [`packages/core/agent-model/src/service.ts`](../../packages/core/agent-model/src/service.ts)
<a id="ctxagentpresets--agentpresetregistry"></a>
### `ctx.agentPresets` — `AgentPresetRegistry`
@@ -9,8 +9,8 @@
en: ac99540fa45af789
zh: 68b33ea8d0063615
/session-model-selection-applies-at-the-next-step/change:
en: 438e301c5fed424b
zh: 164d70fed66fcd45
en: 5ab837106ca3bd0c
zh: 5a6d2e65f3cdb191
/session-model-selection-applies-at-the-next-step/migration:
en: 32a29602f2487011
zh: ae596527ef1c97b3
en: 5fdebcef986b671a
zh: 5ec5bfc9cf6fa443
@@ -11,18 +11,18 @@ English | [中文](guide.zh.md)
ACP model and reasoning changes take effect at the next model step, including a tool continuation in the current turn. Previously, ACP pinned the selection for the complete prompt turn. A prepared step and its retries retain their captured selection. Image admission checks the route selected when admission begins; a later option change can select a different route before the step starts.
`dsh-agent-model` provides `ctx.agentModel` and owns the durable `modelSelection` projection. The API Session controller no longer registers it. Programmatic resume restores recorded choices, including unused selections, before falling back to `AgentOptions`. Configured Agent-loop resumes, headless adoption, and SDK resume record their deployment route; an omitted effort preserves saved explicit effort only for the same route.
`AgentLoop` owns the durable `modelSelection` projection and constructs an `AgentModel` instance on each Agent’s `model` property. The API Session controller no longer registers it. Programmatic resume restores recorded choices, including unused selections, before falling back to `AgentOptions`. Configured Agent-loop resumes, headless adoption, and SDK resume record their deployment route; an omitted effort preserves saved explicit effort only for the same route.
Plugins must select provider, model, and optional explicit reasoning effort before prompt assembly. `agent/request` is deprecated. Existing listeners still run on each main-loop request attempt and can adjust other controls, but cannot change provider or model, or add, change, or clear reasoning effort. Absent effort still resolves through adapter defaults on each attempt. Auxiliary calls such as compaction do not dispatch this event. `installModelSelection` and `ModelSelectionRef` are removed.
Plugins must select provider, model, and optional explicit reasoning effort before prompt assembly. `agent/request` is deprecated. Existing listeners still run on each main-loop request attempt and can adjust other controls, but cannot change provider or model, or add, change, or clear reasoning effort. Absent effort still resolves through adapter defaults on each attempt. Auxiliary calls such as compaction do not dispatch this event. `installModelSelection` now installs only the switch-notice listener; its selection argument and `ModelSelectionRef` are removed.
The client projection and Host state types move to `dsh-agent-model/types`; the API package no longer exports them.
The client projection and Host state types move to `dsh-agent/types`; the API package no longer exports them.
## Migration
1. In custom Cordis compositions, mount `dsh-session-projection` and `dsh-agent-model`. Consumers inject `agentModel`; shipped bundles include it.
2. Replace mutable references and selection hooks with `ctx.agentModel.select(agent, selection)` after validation. Read with `resolveForNextStep(agent)`. Replace switch-notice helpers by importing the `@deepseek-ai/dsh-agent-model/notice` plugin and awaiting `agentCtx.plugin(ModelSwitchNotice)` in Agent setup. Do not add `agent/request` listeners.
1. In custom Cordis compositions, mount `dsh-session-projection` with `dsh-agent-loop`. The loop constructs `agent.model`; consumers need no separate model-selection service.
2. Replace mutable references and selection hooks with `agent.model.select(selection)` after validation. Read with `current()`. Keep `installModelSelection(agentCtx)` in Agent setup for switch notices and remove its old selection argument. Do not add `agent/request` listeners.
3. Set the output cap through `AgentOptions.maxTokens`. Other per-request control overrides have no replacement API; retain an existing listener where that behavior is still required.
4. To override a saved route during programmatic resume, call `ctx.agentModel.applyConfiguredRoute(agent, selection)` in the Agent setup callback. Supplying `agentOptions` alone provides only a fallback for a Session without a selection or request.
4. To override a saved route during programmatic resume, merge the configured selection with the saved explicit effort only when the route is unchanged and the configuration omits effort, then call `agent.model.select(selection)` in the Agent setup callback. Supplying `agentOptions` alone provides only a fallback for a Session without a selection or request.
5. Pass the captured `Readonly<ModelSelection>` in `agent/pre-step.callConfig`, including explicit effort when selected; `AssembleContext.callConfig` carries the same selection. Direct `SessionReferenceResolver.prepare()` callers pass the route as the fourth argument, before the optional signal.
6. ACP controllers that require one model throughout a turn must wait for the active prompt to finish before changing its options. Verify that a mid-turn change is recorded as `model/selection`, the next step uses it, and resume retains an unused choice.
7. Import `ModelSelectionProjection` from `@deepseek-ai/dsh-agent-model/types`, replacing Agent/API package aliases. `ModelSelection` remains in `dsh-agent/types`. Replace named Host state imports with `SessionProjectionStateMap['modelSelection']` after importing the new `/types` module; ordinary reads use `resolveForNextStep()`. Effort values use `ReasoningEffortId` from `dsh-llm/brand`.
7. Import `ModelSelectionProjection` from `@deepseek-ai/dsh-agent/types`, replacing API package aliases. `ModelSelection` remains in `dsh-agent/types`. Import `ModelSelectionProjectionState` from `@deepseek-ai/dsh-agent` only when implementing a driver; ordinary reads use `agent.model.current()`. Effort values use `ReasoningEffortId` from `dsh-llm/brand`.
@@ -11,18 +11,18 @@ description: "Session 模型选择在步骤准备时固定,投影类型移至
ACP(Agent Client Protocol)的模型与推理强度变更从下一个模型步骤开始生效,包括当前轮次的工具后续步骤。此前,ACP 会在整个提示词轮次中固定选择。已准备的步骤及其重试保留捕获的选择。图片准入检查准入开始时选择的路由;后续选项变更可能在步骤开始前选中另一条路由。
`dsh-agent-model` 提供 `ctx.agentModel`,并拥有持久 `modelSelection` 投影。API Session 控制器不再注册该投影。程序化恢复优先还原记录中的选择,包括尚未使用的选择,然后才回退到 `AgentOptions`。配置式 Agent-loop 恢复、headless 接管与 SDK 恢复会记录各自的部署路由;省略推理强度时,仅在路由相同的情况下保留已保存的显式强度。
`AgentLoop` 拥有持久 `modelSelection` 投影,并为每个 Agent 的 `model` 属性构建一个 `AgentModel` 实例。API Session 控制器不再注册该投影。程序化恢复优先还原记录中的选择,包括尚未使用的选择,然后才回退到 `AgentOptions`。配置式 Agent-loop 恢复、headless 接管与 SDK 恢复会记录各自的部署路由;省略推理强度时,仅在路由相同的情况下保留已保存的显式强度。
插件必须在提示词组装前选定提供方、模型及可选的显式推理强度。`agent/request` 已弃用。现有监听器仍在主循环的每次请求尝试中运行,可以调整其他控制参数,但不能改变提供方或模型,也不能添加、修改或清除推理强度。未指定的强度仍在每次尝试时通过适配器默认值解析。压缩等辅助调用不会分发该事件。`installModelSelection` 与 `ModelSelectionRef` 已移除。
插件必须在提示词组装前选定提供方、模型及可选的显式推理强度。`agent/request` 已弃用。现有监听器仍在主循环的每次请求尝试中运行,可以调整其他控制参数,但不能改变提供方或模型,也不能添加、修改或清除推理强度。未指定的强度仍在每次尝试时通过适配器默认值解析。压缩等辅助调用不会分发该事件。`installModelSelection` 现在只安装切换提示监听器;其选择参数与 `ModelSelectionRef` 已移除。
客户端投影与 Host 状态类型移至 `dsh-agent-model/types`;API 包不再导出这些类型。
客户端投影与 Host 状态类型移至 `dsh-agent/types`;API 包不再导出这些类型。
## 迁移
1. 在自定义 Cordis 组合中挂载 `dsh-session-projection` 与 `dsh-agent-model`。消费方注入 `agentModel`;随附 bundle 已包含该服务。
2. 将可变引用与选择 hook 替换为校验后的 `ctx.agentModel.select(agent, selection)`,使用 `resolveForNextStep(agent)` 读取选择。将切换提示 helper 替换为导入 `@deepseek-ai/dsh-agent-model/notice` 插件,并在 Agent setup 中等待 `agentCtx.plugin(ModelSwitchNotice)`。不要添加 `agent/request` 监听器。
1. 在自定义 Cordis 组合中将 `dsh-session-projection` 与 `dsh-agent-loop` 一起挂载。循环构建 `agent.model`;消费方不需要独立的模型选择服务。
2. 将可变引用与选择 hook 替换为校验后的 `agent.model.select(selection)`,使用 `current()` 读取选择。在 Agent setup 中保留 `installModelSelection(agentCtx)` 以提供切换提示,并移除原来的选择参数。不要添加 `agent/request` 监听器。
3. 通过 `AgentOptions.maxTokens` 设置输出上限。其他逐请求控制参数覆盖没有替代 API;仍需要该行为时,保留现有监听器。
4. 要在程序化恢复时覆盖已保存路由,在 Agent setup 回调中调用 `ctx.agentModel.applyConfiguredRoute(agent, selection)`。仅提供 `agentOptions` 时,它只为没有选择或请求记录的 Session 提供回退值。
4. 要在程序化恢复时覆盖已保存路由,先形成配置选择,仅在路由不变且配置省略强度时保留已保存的显式强度,再在 Agent setup 回调中调用 `agent.model.select(selection)`。仅提供 `agentOptions` 时,它只为没有选择或请求记录的 Session 提供回退值。
5. 通过 `agent/pre-step.callConfig` 传入捕获的 `Readonly<ModelSelection>`,包含已选定的显式强度;`AssembleContext.callConfig` 携带同一选择。直接调用 `SessionReferenceResolver.prepare()` 时,将路由作为第四个参数,放在可选信号之前。
6. 要求整轮使用同一个模型的 ACP 控制器,必须等待活跃提示词完成后再更改选项。验证轮次中的变更被记录为 `model/selection`、下一个步骤使用该选择,且恢复保留尚未使用的选择。
7. 从 `@deepseek-ai/dsh-agent-model/types` 导入 `ModelSelectionProjection`,替换 Agent/API 包别名。`ModelSelection` 仍位于 `dsh-agent/types`。导入新 `/types` 模块后,将具名 Host 状态导入替换为 `SessionProjectionStateMap['modelSelection']`;普通读取使用 `resolveForNextStep()`。强度值使用 `dsh-llm/brand` 中的 `ReasoningEffortId`。
7. 从 `@deepseek-ai/dsh-agent/types` 导入 `ModelSelectionProjection`,替换 API 包别名。`ModelSelection` 仍位于 `dsh-agent/types`。仅在实现驱动器时从 `@deepseek-ai/dsh-agent` 导入 `ModelSelectionProjectionState`;普通读取使用 `agent.model.current()`。强度值使用 `dsh-llm/brand` 中的 `ReasoningEffortId`。
+2 -4
View File
@@ -40,8 +40,7 @@
"@deepseek-ai/dsh-session": "workspace:*",
"@deepseek-ai/dsh-session-persistence": "workspace:*",
"@deepseek-ai/dsh-token-meter": "workspace:*",
"@deepseek-ai/dsh-user-approval": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-user-approval": "workspace:*"
},
"peerDependenciesMeta": {
"@deepseek-ai/dsh-token-meter": {
@@ -63,7 +62,6 @@
"@deepseek-ai/dsh-subagent": "workspace:*",
"@deepseek-ai/dsh-token-meter": "workspace:*",
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-user-approval": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-user-approval": "workspace:*"
}
}
+1 -2
View File
@@ -16,7 +16,6 @@ import { realpath } from 'node:fs/promises'
import { isAbsolute, resolve } from 'node:path'
import { Readable, Writable } from 'node:stream'
import Schema from '@deepseek-ai/schemastery'
import type {} from '@deepseek-ai/dsh-agent-model'
import { brandString } from '@deepseek-ai/dsh-brand'
import { errorChain } from '@deepseek-ai/dsh-llm'
import {
@@ -59,7 +58,7 @@ const DEFAULT_SESSION_LIST_PAGE_SIZE = 100
export const name = 'acp'
/** Core services required by the standard automation controls. */
export const inject = ['agents', 'llm', 'sessionPersistence', 'agentModel', 'sessions']
export const inject = ['agents', 'llm', 'sessionPersistence', 'sessions']
/** Preserve invalid-parameter detail in the SDK wire error message. */
function invalidParams(detail: string): RequestError {
+5 -7
View File
@@ -1,8 +1,7 @@
/** Standard ACP session configuration over one Agent's model selection. */
import type { SessionConfigOption, SessionConfigValueId } from '@agentclientprotocol/sdk'
import { type Agent, type ModelSelection } from '@deepseek-ai/dsh-agent'
import type { AgentModel } from '@deepseek-ai/dsh-agent-model'
import { type Model, type ModelSelection } from '@deepseek-ai/dsh-agent'
import { ReasoningEffortId, type LlmCallConfig, type LlmRuntime } from '@deepseek-ai/dsh-llm'
const MODEL_CONFIG_ID = 'model'
@@ -39,8 +38,7 @@ export class AcpModelControl {
constructor(
private readonly llm: LlmRuntime,
private readonly agentModel: AgentModel,
private readonly agent: Agent,
private readonly model: Model,
) {}
/**
@@ -48,7 +46,7 @@ export class AcpModelControl {
* @returns a detached selection, or undefined when neither the Session nor the deployment names a route.
*/
current(): ModelSelection | undefined {
return this.agentModel.resolveForNextStep(this.agent)
return this.model.current()
}
/**
@@ -77,7 +75,7 @@ export class AcpModelControl {
const selected = state.choices.get(value)
if (selected === undefined) throw new AcpModelConfigError(`unknown model option: ${value}`)
await this.resolveSelection(selected, signal)
this.agentModel.select(this.agent, selected)
this.model.select(selected)
} else if (configId === REASONING_CONFIG_ID) {
const info = await this.llm.resolveModelInfo(current.provider, current.model, signal)
const providerDefault = value === PROVIDER_DEFAULT_REASONING_VALUE
@@ -88,7 +86,7 @@ export class AcpModelControl {
) {
throw new AcpModelConfigError(`unknown reasoning effort for ${current.provider}/${current.model}: ${value}`)
}
this.agentModel.select(this.agent, await this.resolveSelection({
this.model.select(await this.resolveSelection({
provider: current.provider,
model: current.model,
...providerDefault ? {} : { reasoningEffort: ReasoningEffortId(value) },
+3 -3
View File
@@ -11,7 +11,7 @@ import {
type StopReason,
} from '@agentclientprotocol/sdk'
import type { Agent, AgentHandle, AgentOptions, AgentStatus } from '@deepseek-ai/dsh-agent'
import * as ModelSwitchNotice from '@deepseek-ai/dsh-agent-model/notice'
import { installModelSelection } from '@deepseek-ai/dsh-agent'
import { createUserMessage, errorChain, type UserMessage } from '@deepseek-ai/dsh-llm'
import { type Session, type SessionEvent, type SessionId, type TurnEndReason } from '@deepseek-ai/dsh-session'
import { AcpContentError, admitAcpPrompt } from './content.ts'
@@ -80,7 +80,7 @@ function internalError(detail: string): RequestError {
* @param options - workspace and MCP servers requested for the session.
*/
async function composeAgent(agentCtx: Context, options: AcpSessionBuildOptions): Promise<void> {
await agentCtx.plugin(ModelSwitchNotice)
installModelSelection(agentCtx)
await mountAcpMcpServers(agentCtx, options.mcpServers, options.cwd)
}
@@ -103,7 +103,7 @@ export class AcpSession {
private readonly notify: (notification: SessionNotification) => Promise<void>,
) {
this.agent = handle.agent
this.modelControl = new AcpModelControl(ctx.llm, ctx.agentModel, handle.agent)
this.modelControl = new AcpModelControl(ctx.llm, handle.agent.model)
this.disposeAgent = () => handle.dispose()
}
+1 -1
View File
@@ -862,7 +862,7 @@ describe('automation-only ACP bridge', () => {
expect(created.configOptions).toEqual([])
const agent = harness.ctx.agents.get(SessionId(created.sessionId))!
harness.ctx.agentModel.select(agent, { provider: 'mock', model: 'mock' })
agent.model.select({ provider: 'mock', model: 'mock' })
await expect(harness.client.prompt({
sessionId: created.sessionId,
prompt: [{ type: 'text', text: 'route me' }],
+6 -5
View File
@@ -1,6 +1,6 @@
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry, { type Agent, type ModelSelection } from '@deepseek-ai/dsh-agent'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { AgentModel, modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import AgentRegistry, { type ModelSelection } from '@deepseek-ai/dsh-agent'
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { describe, expect, it, onTestFinished, vi } from 'vitest'
@@ -40,11 +40,12 @@ async function createControl(runtime: LlmRuntime, initial?: ModelSelection) {
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const session = ctx.sessions.create(SessionId('model-control'))
const agent = { id: session.id, session, options: initial ?? {} } as Agent
return { control: new AcpModelControl(runtime, ctx.agentModel, agent), session }
const options = initial ?? {}
const projection = await ctx.sessionProjections.register(modelSelectionProjectionDefinition)
const model = new AgentModel(() => projection.stateOf(session), session, options)
return { control: new AcpModelControl(runtime, model), session }
}
describe('ACP model configuration control', () => {
-3
View File
@@ -40,9 +40,6 @@
},
{
"path": "../../interaction/user-approval"
},
{
"path": "../../core/agent-model"
}
]
}
@@ -1,7 +1,7 @@
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import type { Agent } from '@deepseek-ai/dsh-agent'
import type { JobAppendOptions, JobHandle, JobOutcome } from '@deepseek-ai/dsh-jobs'
import LocalJobRegistry from '@deepseek-ai/dsh-jobs-local'
@@ -26,6 +26,7 @@ export async function registerAgent(ctx: Context, rawId: string): Promise<Agent
id,
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'idle',
ctx: scopeFiber.ctx,
@@ -2,7 +2,7 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { describe, expect, it } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import type { Agent } from '@deepseek-ai/dsh-agent'
import { JobId } from '@deepseek-ai/dsh-jobs'
import LocalJobRegistry from '@deepseek-ai/dsh-jobs-local'
@@ -231,6 +231,7 @@ describe('JobController', () => {
id: session.id,
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'idle',
ctx,
@@ -21,8 +21,8 @@
en: 41bdda1ac32df558
zh: aa5d0e325924066b
/session-controller/session-media-references:
en: 2f5524fbfc9446e4
zh: f72c0bc9607007ae
en: 9449c5c3a53031c6
zh: 68d8ad0d3632983a
/session-controller/configuration:
en: 5ae2b340c630897f
zh: 1ffbd61ecf302ec2
+1 -1
View File
@@ -90,7 +90,7 @@ References keep local Session data, scoped Contexts, and history streams alive,
GUI model selection requires the exact provider/model pair in the available catalog; unavailable choices reject with `session/model-unavailable`. Prompt admission retains the saved route without a catalog availability gate, so request execution reports missing credentials or unavailable models. `initializeDefaultModel()` saves the first available account model after login when no other provider has a configured API key; credential checks use configured references independently of model availability. A provider with no available models rejects initialization with `session/provider-models-unavailable`. Availability never substitutes another model or rewrites a Session selection.
A successful `selectModel` response acknowledges the recorded Session selection without waiting for the default profile setting to save. The Agent registry owns its projection; a change applies to the next step while a prepared step retains its captured choice. Default saves run in the background in submission order; a failure logs a warning and leaves the Session selection intact. A Session with no recorded selection or request reads the last successfully saved default through live `AgentOptions` accessors. An explicit choice is recorded even when it equals that default.
A successful `selectModel` response acknowledges the recorded Session selection without waiting for the default profile setting to save. The loop registers its projection; a change applies to the next step while a prepared step retains its captured choice. Default saves run in the background in submission order; a failure logs a warning and leaves the Session selection intact. A Session with no recorded selection or request reads the last successfully saved default through live `AgentOptions` accessors. An explicit choice is recorded even when it equals that default.
-----
+1 -1
View File
@@ -90,7 +90,7 @@ Client 的首次 `follow`、重连首屏与 `loadOlder()` 至少请求 50 条以
GUI 模型选择要求确切提供方/模型对出现在可用目录中;不可用的选择以 `session/model-unavailable` 拒绝。提示词准入保留已保存的路由,不按目录可用性阻断发送,由请求执行报告凭据缺失或模型不可用。`initializeDefaultModel()` 在账号登录后、其他提供方均未配置 API key 时,将第一个可用账号模型保存为默认模型;凭据检查使用已配置的引用,不依赖模型是否可用。提供方没有可用模型时,初始化以 `session/provider-models-unavailable` 拒绝。可用性变化不会替换模型或改写会话选择。
`selectModel` 成功返回表示会话模型选择已记录,不等待默认 profile 设置保存。Agent 注册表拥有该投影;变更从下一个步骤开始生效,已准备的步骤保留捕获的选择。默认设置在后台按提交顺序保存;保存失败会记录警告,并保留会话选择。尚未记录选择或请求的会话通过 `AgentOptions` 的动态访问器读取最近一次成功保存的默认值。显式选择即使与默认值相同也会记录。
`selectModel` 成功返回表示会话模型选择已记录,不等待默认 profile 设置保存。循环注册该投影;变更从下一个步骤开始生效,已准备的步骤保留捕获的选择。默认设置在后台按提交顺序保存;保存失败会记录警告,并保留会话选择。尚未记录选择或请求的会话通过 `AgentOptions` 的动态访问器读取最近一次成功保存的默认值。显式选择即使与默认值相同也会记录。
-----
+2 -4
View File
@@ -108,8 +108,7 @@
"@deepseek-ai/dsh-util-values": "workspace:*",
"@deepseek-ai/dsh-util-workspace-path": "workspace:*",
"@deepseek-ai/dsh-workspace": "workspace:*",
"@deepseek-ai/dsh-working-directory": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-working-directory": "workspace:*"
},
"peerDependenciesMeta": {
"@deepseek-ai/dsh-session-persistence": {
@@ -167,7 +166,6 @@
"@deepseek-ai/dsh-util-workspace-path": "workspace:*",
"@deepseek-ai/dsh-workspace": "workspace:*",
"@types/mime-types": "^3.0.1",
"@deepseek-ai/dsh-working-directory": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-working-directory": "workspace:*"
}
}
+3 -3
View File
@@ -5,7 +5,7 @@ import { mkdir } from 'node:fs/promises'
import type { Context } from '@deepseek-ai/cordis'
import type { Agent, AgentOptions, AgentSetup } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-default-model'
import * as ModelSwitchNotice from '@deepseek-ai/dsh-agent-model/notice'
import { installModelSelection } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-preset-registry'
import { brandString } from '@deepseek-ai/dsh-brand'
import type { Session, SessionId } from '@deepseek-ai/dsh-session'
@@ -306,13 +306,13 @@ export class ApiSessionAgentController {
async composeAgent(presetId: string | undefined): Promise<ApiSessionComposition> {
const presets = this.ctx.get('agentPresets')
if (presets === undefined) {
return { setup: async (agentCtx) => { await agentCtx.plugin(ModelSwitchNotice) } }
return { setup: (agentCtx) => { installModelSelection(agentCtx) } }
}
const resolvedId = (await presets.resolve(presetId)).id
return {
agentPreset: resolvedId,
setup: async (agentCtx) => {
await agentCtx.plugin(ModelSwitchNotice)
installModelSelection(agentCtx)
await presets.mount(agentCtx, resolvedId)
},
}
@@ -173,7 +173,7 @@ export class SessionCommandController {
? {}
: { reasoningEffort: resolved.reasoningEffort }),
}
this.ctx.agentModel.select(agent, selected)
agent.model.select(selected)
void this.ctx.agentDefaultModel.saveSelection(selected).catch((error: unknown) => {
this.ctx.logger.warn(
`session-controller: model selection changed for the Session but the default was not saved: ${String(error)}`,
@@ -323,7 +323,7 @@ export class SessionCommandController {
const admit = async (): Promise<SessionPromptValue> => {
try {
if (hasImage) {
const current = this.ctx.agentModel.resolveForNextStep(agent)
const current = agent.model.current()
if (current !== undefined) {
const model = await this.ctx.llm.resolveModelInfo(current.provider, current.model)
if (model.inputModalities !== undefined && !model.inputModalities.includes('image')) {
@@ -3,7 +3,6 @@
import { hostname } from 'node:os'
import { resolve } from 'node:path'
import type { Agent } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-model'
import type {} from '@deepseek-ai/dsh-fs'
import { Context, Service } from '@deepseek-ai/cordis'
import z from '@deepseek-ai/schemastery'
@@ -127,7 +126,6 @@ export class SessionController extends TypertRemoteService {
'remoteAccess',
'sessions',
'sessionProjections',
'agentModel',
'sessionQuery',
'typert',
'workspaceRegistry',
+1 -1
View File
@@ -1,6 +1,6 @@
/** Browser-safe request, result, and lifecycle vocabulary for the Session Remote service. */
import type {} from '@deepseek-ai/dsh-agent-model/types'
import type {} from '@deepseek-ai/dsh-agent/types'
import type { NativeFileApplication } from '@deepseek-ai/dsh-native-command/types'
import type {
AttachmentIdType, ImageAttachmentLimits, ImageAttachmentRef, ImageMediaType,
@@ -2,7 +2,7 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import { unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
import type { Session } from '@deepseek-ai/dsh-session'
import type {} from '@deepseek-ai/dsh-workspace'
@@ -31,6 +31,7 @@ async function liveAgent(ctx: Context, session: Session): Promise<Agent> {
id: session.id,
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'idle',
ctx,
@@ -17,7 +17,7 @@ import { subagentIdentityProjectionDefinition } from '@deepseek-ai/dsh-subagent/
import { describe, expect, it, vi } from 'vitest'
import { ApiSessionAgentController } from '../src/agent.ts'
import { SessionCommandController } from '../src/commands.ts'
import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
import { installSessionReadTestServices, testSessionPersistence } from './test-remote.ts'
declare module '@deepseek-ai/dsh-llm' {
@@ -92,6 +92,7 @@ async function commandHarness(
send: vi.fn(),
inject: vi.fn(),
session,
model: unsupportedModel(),
inbox,
status: 'running',
ctx,
@@ -1,9 +1,9 @@
import { AgentModel, modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { Context, FiberState } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
import type { Agent } from '@deepseek-ai/dsh-agent'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import AttachmentStore, { AttachmentId } from '@deepseek-ai/dsh-attachment'
import type {
FileAttachmentRef, ImageAttachmentRef, SaveFileAttachment, SaveFileStreamAttachment,
@@ -38,7 +38,6 @@ async function uploadHarness(origin?: 'subagent'): Promise<{
onTestFinished(() => ctx.fiber.dispose())
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
await ctx.plugin(CommandRuntime)
const session = ctx.sessions.create(SESSION, {
@@ -46,14 +45,17 @@ async function uploadHarness(origin?: 'subagent'): Promise<{
})
const inbox = createInboxStub()
const followup = vi.fn()
const options = { provider: 'fixture', model: 'fixture-model' }
const projection = await ctx.sessionProjections.register(modelSelectionProjectionDefinition)
const agent = {
id: session.id,
options: { provider: 'fixture', model: 'fixture-model' },
options,
whenIdle: vi.fn(() => Promise.resolve()),
runMaintenance: async () => { throw new Error('unexpected maintenance') },
send: vi.fn(),
inject: vi.fn(),
session,
model: new AgentModel(() => projection.stateOf(session), session, options),
inbox,
status: 'idle',
ctx,
@@ -2,7 +2,6 @@ import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import SessionStore, { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset } from '@deepseek-ai/dsh-session'
import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session'
@@ -26,7 +25,6 @@ describe('SessionController facade', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = SessionId('controller-session')
const header: SessionHeader = {
@@ -3,6 +3,7 @@
* metadata-only listing, Agent-free history reads, subagent ownership
* isolation, and prompt failure mapping.
*/
import { AgentModel, modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { SESSION_FORMAT_VERSION, SessionLogOffset, SessionSeq } from '@deepseek-ai/dsh-session'
@@ -17,8 +18,7 @@ import { createUserMessage, MessageId } from '@deepseek-ai/dsh-llm'
import { snapshotSubagentDescriptor } from '@deepseek-ai/dsh-subagent'
import { createInboxStub, mountAgentLoopTestDependencies, mountAgentLoopTestHarness } from '@deepseek-ai/dsh-agent-loop-testkit'
import type { Agent, Inbox } from '@deepseek-ai/dsh-agent'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import type { SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
import AttachmentStore from '@deepseek-ai/dsh-attachment'
import type { SessionPromptRequest, SessionRequestId } from '../src/types.ts'
import {
@@ -84,7 +84,6 @@ describe('sessions.list cold merge', () => {
try {
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const historical = header('format-historical', 100)
const current = header('format-current', 200)
@@ -251,7 +250,6 @@ describe('attached updatedAt tracks human prompts', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const remote = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'p', model: 'm' }), cwd: '/tmp' })
await new Promise(resolve => setTimeout(resolve, 0))
@@ -397,7 +395,6 @@ describe('Remote Agent and Session lookup policy', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const remote = await createSessionTestRemote(ctx, {
defaultModelSelection: () => ({ provider: 'p', model: 'm' }),
@@ -419,7 +416,6 @@ describe('Remote Agent and Session lookup policy', () => {
await ctx.plugin(TypertRegistry)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = sid('session-remote-cold')
const meta = header(sessionId, 1000)
@@ -461,7 +457,6 @@ describe('Remote Agent and Session lookup policy', () => {
await ctx.plugin(TypertRegistry)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const coldId = sid('session-remote-cold-child')
const coldMeta = header(coldId, 1000, {
@@ -507,7 +502,6 @@ describe('Remote Agent and Session lookup policy', () => {
await ctx.plugin(TypertRegistry)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = sid('session-remote-resumed-child')
const meta = header(sessionId, 1000)
@@ -544,7 +538,6 @@ describe('subagent ownership fence', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = sid('session-child')
const meta = header('session-child', 1000, {
@@ -624,7 +617,6 @@ describe('subagent ownership fence', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = sid('session-legacy-child')
const meta = header('session-legacy-child', 1000, {
@@ -663,7 +655,6 @@ describe('subagent ownership fence', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const parentSession = ctx.sessions.create(sid('session-parent'), { meta: { cwd: '/proj' } })
const parent = { id: parentSession.id, session: parentSession, status: 'idle', ctx } as Agent
@@ -724,7 +715,6 @@ describe('subagent ownership fence', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const session = ctx.sessions.create(sid('session-ordinary-fork'), {
seed: [{
@@ -737,9 +727,14 @@ describe('subagent ownership fence', () => {
inheritedEventCount: SessionLogOffset(1),
})
const followup = vi.fn()
const agent = {
id: session.id, session, inbox: inboxFor(), status: 'idle', ctx, followup,
} as unknown as Agent
const agent: Agent = {
id: session.id, session, model: await modelFor(ctx, session),
options: { provider: 'p', model: 'm' },
inbox: inboxFor(), status: 'idle', ctx, followup,
cancel: vi.fn(), whenIdle: () => Promise.resolve(),
runMaintenance: async () => { throw new Error('unexpected maintenance') },
send: vi.fn(), inject: vi.fn(), steer: vi.fn(),
}
await ctx.agents.register(agent)
const remote = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'p', model: 'm' }), cwd: '/tmp' })
@@ -756,13 +751,17 @@ describe('subagent ownership fence', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const session = ctx.sessions.create(sid('session-browser-zone'), { meta: { cwd: '/proj' } })
const followup = vi.fn()
const agent = {
id: session.id, session, inbox: inboxFor(), status: 'idle', ctx, followup,
} as unknown as Agent
const agent: Agent = {
id: session.id, session, model: await modelFor(ctx, session),
options: { provider: 'p', model: 'm' },
inbox: inboxFor(), status: 'idle', ctx, followup,
cancel: vi.fn(), whenIdle: () => Promise.resolve(),
runMaintenance: async () => { throw new Error('unexpected maintenance') },
send: vi.fn(), inject: vi.fn(), steer: vi.fn(),
}
await ctx.agents.register(agent)
const remote = await createSessionTestRemote(ctx, {
defaultModelSelection: () => ({ provider: 'p', model: 'm' }),
@@ -829,7 +828,6 @@ describe('degenerate composition (no persistence, no factory)', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const remote = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'p', model: 'm' }), cwd: '/tmp' })
@@ -852,7 +850,6 @@ describe('degenerate composition (no persistence, no factory)', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const inspect = vi.fn()
const stat = vi.fn(() => Promise.resolve(undefined))
@@ -875,25 +872,31 @@ describe('degenerate composition (no persistence, no factory)', () => {
})
})
async function modelFor(ctx: Context, session: Session): Promise<AgentModel> {
const projection = await ctx.sessionProjections.register(modelSelectionProjectionDefinition)
return new AgentModel(() => projection.stateOf(session), session, { provider: 'p', model: 'm' })
}
describe('sessions.prompt synchronous rejection', () => {
it('rejects content without non-whitespace text or an attachment before delivery or Session events', async () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const session = ctx.sessions.create(sid('session-empty-prompt'))
const options = { provider: 'p', model: 'm' }
const followup = vi.fn()
const steer = vi.fn()
await ctx.agents.register({
id: session.id,
options: { provider: 'p', model: 'm' },
options,
whenIdle: vi.fn(() => Promise.resolve()),
runMaintenance: async () => { throw new Error('unexpected maintenance') },
send: vi.fn(),
inject: vi.fn(),
cancel: vi.fn(),
session,
model: await modelFor(ctx, session),
inbox: inboxFor(),
status: 'idle',
ctx,
@@ -984,7 +987,6 @@ describe('sessions.prompt synchronous rejection', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const session = ctx.sessions.create(sid('session-throwing'))
// A live structural stub whose delivery verbs throw synchronously, the
@@ -992,12 +994,17 @@ describe('sessions.prompt synchronous rejection', () => {
await ctx.agents.register({
id: session.id,
session,
model: await modelFor(ctx, session),
inbox: inboxFor(),
status: 'idle',
ctx,
options: { provider: 'p', model: 'm' },
cancel: vi.fn(), whenIdle: () => Promise.resolve(),
runMaintenance: async () => { throw new Error('unexpected maintenance') },
send: vi.fn(), inject: vi.fn(),
followup: () => { throw new Error('agent "session-throwing" lifecycle disposed') },
steer: () => { throw new Error('agent "session-throwing" lifecycle disposed') },
} as unknown as Agent)
})
const remote = await createSessionTestRemote(ctx, { defaultModelSelection: () => ({ provider: 'p', model: 'm' }), cwd: '/tmp' })
for (const mode of ['queue', 'steer'] as const) {
@@ -1019,7 +1026,6 @@ describe('sessions.prompt synchronous rejection', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const sessionId = sid('race-resume')
const meta: SessionHeader = header('race-resume', 1000)
@@ -6,7 +6,6 @@ import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent, AgentHandle, CreateAgentOptions } from '@deepseek-ai/dsh-agent'
import { mountAgentLoopTestDependencies, mountAgentLoopTestHarness } from '@deepseek-ai/dsh-agent-loop-testkit'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { BasicCompactionEngine } from '@deepseek-ai/dsh-compaction-basic'
import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
import { ToolCallId, createMessage, createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm'
@@ -34,7 +33,6 @@ async function composed(workspaces: readonly Workspace[] = []): Promise<Context>
await ctx.plugin(SessionStore)
await ctx.plugin(SystemPrompt, { personaPrefix: '' })
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
installSessionReadTestServices(ctx)
ctx.provide('workspaceRegistry', { list: () => workspaces, archivedSessionIds: [] } as never)
@@ -665,7 +663,7 @@ describe('sessions.fork', () => {
const child = ctx.agents.get(response.value.sessionId)
if (child === undefined) throw new Error('fork did not publish the child agent')
expect(child.session.snapshotEvents().slice(0, child.session.inheritedEventCount)).toEqual(inherited)
expect(ctx.agentModel.resolveForNextStep(child)).toEqual({
expect(child.model.current()).toEqual({
provider: 'inherited-provider', model: 'inherited-model', reasoningEffort: 'high',
})
await ctx.fiber.dispose()
@@ -4,6 +4,7 @@
* catalog injection, unavailable-model refusals, and the prompt-assembly
* boundary for a running selection change.
*/
import { AgentModel, modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import { createInboxStub } from '@deepseek-ai/dsh-agent-loop-testkit'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
@@ -11,7 +12,6 @@ import { describe, expect, it, vi, onTestFinished } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry from '@deepseek-ai/dsh-agent'
import type { Agent } from '@deepseek-ai/dsh-agent'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import AttachmentStore from '@deepseek-ai/dsh-attachment'
import LlmRuntime, { LlmAdapter, ReasoningEffortId } from '@deepseek-ai/dsh-llm'
import type {
@@ -99,7 +99,6 @@ async function harness(logged?: {
await ctx.plugin(SystemPrompt, { personaPrefix: '' })
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
ctx.llm.registerAdapter(['deepseek-official'], new CatalogAdapter('DeepSeek', [
{ provider: 'deepseek-official', id: 'deepseek-chat', name: 'DeepSeek Chat' },
@@ -128,13 +127,16 @@ async function harness(logged?: {
reason: 'initial',
})
}
const projection = await ctx.sessionProjections.register(modelSelectionProjectionDefinition)
const options = {
get provider() { return ctx.agentDefaultModel.currentSelection().provider },
get model() { return ctx.agentDefaultModel.currentSelection().model },
get reasoningEffort() { return ctx.agentDefaultModel.currentSelection().reasoningEffort },
}
const agent = {
id: session.id,
options: {
get provider() { return ctx.agentDefaultModel.currentSelection().provider },
get model() { return ctx.agentDefaultModel.currentSelection().model },
get reasoningEffort() { return ctx.agentDefaultModel.currentSelection().reasoningEffort },
},
options,
model: new AgentModel(() => projection.stateOf(session), session, options),
session,
status: 'running',
ctx,
@@ -520,7 +522,7 @@ describe('Web session model selection', () => {
model: 'deepseek-reasoner',
reasoningEffort: 'max',
})
expect(ctx.agentModel.resolveForNextStep(agent)).toEqual(selected.selected)
expect(agent.model.current()).toEqual(selected.selected)
expect(agent.session.snapshotEvents().at(-1)).toMatchObject({
type: 'model/selection', data: selected.selected,
})
@@ -581,7 +583,10 @@ describe('Web session model selection', () => {
ctx.agents.setFactory({
async createAgent(ownerCtx, options) {
const session = ctx.sessions.create(options.sessionId)
const agent: Agent = { ...template, id: session.id, session, ctx: ownerCtx, options: options.agentOptions ?? {} }
const agentOptions = options.agentOptions ?? {}
const projection = await ownerCtx.sessionProjections.register(modelSelectionProjectionDefinition)
const model = new AgentModel(() => projection.stateOf(session), session, agentOptions)
const agent: Agent = { ...template, id: session.id, session, ctx: ownerCtx, options: agentOptions, model }
await options.setup?.(ownerCtx, agent)
await ctx.agents.register(agent)
return { agent, dispose: () => Promise.resolve() }
@@ -591,9 +596,9 @@ describe('Web session model selection', () => {
const first = expectValue(await remote.create({ cwd: '/tmp' }))
const second = expectValue(await remote.create({ cwd: '/tmp' }))
const agent = ctx.agents.get(first.sessionId)!
expect(ctx.agentModel.resolveForNextStep(agent)).toEqual(stored)
expect(agent.model.current()).toEqual(stored)
stored = { provider: 'deepseek-official', model: 'deepseek-reasoner' }
expect(ctx.agentModel.resolveForNextStep(agent)).toEqual(stored)
expect(agent.model.current()).toEqual(stored)
const selection = { ...stored, reasoningEffort: ReasoningEffortId('high') }
// The explicit selection is identical to the live fallback, including effort.
stored = selection
@@ -601,7 +606,7 @@ describe('Web session model selection', () => {
expect(agent.session.snapshotEvents().filter(event => event.type === 'model/selection'))
.toMatchObject([{ data: selection }])
expectValue(await remote.selectModel({ sessionId: second.sessionId, provider: 'deepseek-official', model: 'deepseek-chat' }))
expect(ctx.agentModel.resolveForNextStep(agent)).toEqual(selection)
expect(agent.model.current()).toEqual(selection)
expect(currentSelection(ctx, first.sessionId)).toEqual(selection)
})
@@ -634,7 +639,7 @@ describe('Web session model selection', () => {
cwd: '/tmp',
})
expect(ctx.agentModel.resolveForNextStep(agent))
expect(agent.model.current())
.toEqual({ provider: 'deepseek-official', model: 'deepseek-chat' })
await ctx.fiber.dispose()
})
@@ -31,7 +31,6 @@ import {
mountAgentLoopTestDependencies,
mountAgentLoopTestHarness,
} from '@deepseek-ai/dsh-agent-loop-testkit'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { createSessionTestRemote, testSessionPersistence, type TestSessionRemote } from './test-remote.ts'
const ownedContexts = new Set<Context>()
@@ -163,7 +162,6 @@ describe('session.history projections block', () => {
const ctx = new Context()
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const parent = ctx.sessions.create(SessionId('wire-seed-parent'), { meta: { cwd: '/workspace' } })
parent.append('turn/start', { turn: 1 })
@@ -581,7 +579,6 @@ describe('session.list projections column', () => {
await ctx.plugin(StorageDomain, { backend: 'json' })
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
await ctx.sessionProjections.register(privatePromptUnit())
await ctx.plugin(SessionProjectionCache, { writeEveryEvents: 100, writeIntervalMs: 60_000 })
@@ -637,7 +634,6 @@ describe('session.list projections column', () => {
await ctx.plugin(StorageDomain, { backend: 'json' })
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
await ctx.sessionProjections.register(titleProjectionDefinition)
await ctx.plugin(SessionProjectionCache, { writeEveryEvents: 100, writeIntervalMs: 60_000 })
@@ -11,65 +11,24 @@
"src/remote-events.ts"
],
"references": [
{
"path": "../../../vendor/cordis"
},
{
"path": "../gateway/tsconfig.client.json"
},
{
"path": "../../attachment/attachment"
},
{
"path": "../../client/connection/tsconfig.client.json"
},
{
"path": "../../client/file-upload/tsconfig.client.json"
},
{
"path": "../../client/store"
},
{
"path": "../../context/file-reference"
},
{
"path": "../../core/session"
},
{
"path": "../../jobs/jobs"
},
{
"path": "../../llm/llm"
},
{
"path": "../../session/session-projection"
},
{
"path": "../../session/session-title"
},
{
"path": "../../subagent/subagent"
},
{
"path": "../../util/brand"
},
{
"path": "../../util/crypto"
},
{
"path": "../../util/workspace-path"
},
{
"path": "../../workspace/workspace"
},
{
"path": "../../typert/protocol"
},
{
"path": "../../util/native-command"
},
{
"path": "../../core/agent-model"
}
{ "path": "../../../vendor/cordis" },
{ "path": "../gateway/tsconfig.client.json" },
{ "path": "../../attachment/attachment" },
{ "path": "../../client/connection/tsconfig.client.json" },
{ "path": "../../client/file-upload/tsconfig.client.json" },
{ "path": "../../client/store" },
{ "path": "../../context/file-reference" },
{ "path": "../../core/session" },
{ "path": "../../jobs/jobs" },
{ "path": "../../llm/llm" },
{ "path": "../../session/session-projection" },
{ "path": "../../session/session-title" },
{ "path": "../../subagent/subagent" },
{ "path": "../../util/brand" },
{ "path": "../../util/crypto" },
{ "path": "../../util/workspace-path" },
{ "path": "../../workspace/workspace" },
{ "path": "../../typert/protocol" },
{ "path": "../../util/native-command" }
]
}
@@ -114,9 +114,6 @@
},
{
"path": "../../session/working-directory"
},
{
"path": "../../core/agent-model"
}
]
}
-3
View File
@@ -82,9 +82,6 @@
- id: agent
name: '@deepseek-ai/dsh-agent'
- id: agent-model
name: '@deepseek-ai/dsh-agent-model'
- id: plugin-package-inventory-deepseek
name: '@deepseek-ai/dsh-plugin-package-inventory-deepseek'
+1 -3
View File
@@ -128,14 +128,12 @@
"@deepseek-ai/dsh-otel": "workspace:*",
"@deepseek-ai/dsh-working-directory": "workspace:*",
"@deepseek-ai/dsh-tool-working-directory": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*",
"@deepseek-ai/dsh-web-deepseek-api": "workspace:*"
},
"peerDependencies": {
"@deepseek-ai/cordis": "workspace:~"
},
"devDependencies": {
"@deepseek-ai/cordis": "workspace:~",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/cordis": "workspace:~"
}
}
-3
View File
@@ -16,9 +16,6 @@
},
{
"path": "../../settings/settings"
},
{
"path": "../../core/agent-model"
}
]
}
+2 -4
View File
@@ -58,8 +58,7 @@
"@deepseek-ai/dsh-permission-presets": "workspace:*",
"@deepseek-ai/dsh-sandbox-policy": "workspace:*",
"@deepseek-ai/dsh-subagent": "workspace:*",
"@deepseek-ai/dsh-user-approval": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-user-approval": "workspace:*"
},
"devDependencies": {
"@deepseek-ai/cordis": "workspace:~",
@@ -75,8 +74,7 @@
"@deepseek-ai/dsh-permission-presets": "workspace:*",
"@deepseek-ai/dsh-sandbox-policy": "workspace:*",
"@deepseek-ai/dsh-subagent": "workspace:*",
"@deepseek-ai/dsh-user-approval": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-user-approval": "workspace:*"
},
"peerDependenciesMeta": {
"@deepseek-ai/dsh-permission-presets": {
+14 -6
View File
@@ -16,8 +16,7 @@ import z from '@deepseek-ai/schemastery'
import { brandString } from '@deepseek-ai/dsh-brand'
import type { Agent, AgentOptions } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-default-model'
import type {} from '@deepseek-ai/dsh-agent-model'
import * as ModelSwitchNotice from '@deepseek-ai/dsh-agent-model/notice'
import { installModelSelection } from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-fs'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import { APPROVAL_POLICIES, setApprovalPolicy, type ApprovalPolicy } from '@deepseek-ai/dsh-user-approval'
@@ -43,7 +42,7 @@ import { projectJsonRun, boundJsonLine } from './json-stream.ts'
export const name = 'headless-runner'
/** Core services required before the one-shot turn can start. */
export const inject = ['agentDefaultModel', 'agents', 'agentModel', 'sessions']
export const inject = ['agentDefaultModel', 'agents', 'sessions']
/** Plugin config: the task and run options resolved from this app's injected provider service. */
export interface Config {
@@ -370,10 +369,19 @@ async function run(ctx: Context, config: Config, io: HeadlessIo): Promise<void>
// host plane and the agent reads them from the global layer. A deployment
// that DOES configure one has to join it here first
// (@deepseek-ai/dsh-agent-preset-registry README, "Composing a child agent").
const setup = async (agentCtx: Context, agent: Agent): Promise<void> => {
const setup = (agentCtx: Context, agent: Agent): void => {
// A resumed Session continues with this run's configured model.
if (config.sessionId !== undefined) ctx.agentModel.applyConfiguredRoute(agent, selection)
await agentCtx.plugin(ModelSwitchNotice)
if (config.sessionId !== undefined) {
const previous = agent.model.current()
const configured = { ...selection }
if (configured.reasoningEffort === undefined && previous !== undefined
&& previous.provider === configured.provider && previous.model === configured.model
&& previous.reasoningEffort !== undefined) {
configured.reasoningEffort = previous.reasoningEffort
}
agent.model.select(configured)
}
installModelSelection(agentCtx)
}
const sessionId = brandString<SessionId>(config.sessionId ?? `session-${randomUUID()}`)
const fs = ctx.get('fs')
@@ -20,8 +20,8 @@ import SandboxPolicyService from '@deepseek-ai/dsh-sandbox-policy'
import ApprovalService, { setApprovalPolicy, type ApprovalPolicy } from '@deepseek-ai/dsh-user-approval'
import type { Session, SessionId, UserMessage } from '@deepseek-ai/dsh-session'
import { SessionQueryError } from '@deepseek-ai/dsh-session-query'
import { AgentModel, modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import { createInboxStub, provideWorkingDirectoryFixture } from '@deepseek-ai/dsh-agent-loop-testkit'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { apply, Config } from '../src/index.ts'
import SubagentRuntime from '@deepseek-ai/dsh-subagent'
import { internals } from '../src/runner-internals.ts'
@@ -165,9 +165,12 @@ async function bench(script: Script, options: BenchOptions = {}): Promise<{
const inbox = createInboxStub()
let idle = Promise.resolve()
let running = false
const agentOptions = createOptions.agentOptions ?? {}
const projection = await ownerCtx.sessionProjections.register(modelSelectionProjectionDefinition)
const agent: Agent = {
id: session.id,
options: createOptions.agentOptions ?? {},
options: agentOptions,
model: new AgentModel(() => projection.stateOf(session), session, agentOptions),
session,
inbox,
get status() { return running ? 'running' : 'idle' },
@@ -196,7 +199,6 @@ async function bench(script: Script, options: BenchOptions = {}): Promise<{
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
await ctx.plugin(AgentDefaultModelConfig, { provider: 'test-provider', model: 'test-model' })
ctx.agents.setFactory({
@@ -876,7 +878,7 @@ describe('headless runner', () => {
it.each(['test-model', 'other-model'])('restores explicit effort only for the declared route (%s)', async (savedModel) => {
const test = await bench({
afterPrompt(session, message, agent) {
expect(test.ctx.agentModel.resolveForNextStep(agent)).toEqual({
expect(agent.model.current()).toEqual({
provider: 'test-provider', model: 'test-model',
...savedModel === 'test-model' ? { reasoningEffort: 'high' } : {},
})
-3
View File
@@ -41,9 +41,6 @@
{
"path": "../../subagent/subagent"
},
{
"path": "../../core/agent-model"
},
{
"path": "../../interaction/permission-presets"
},
@@ -126,8 +126,6 @@
- id: agent
name: '@deepseek-ai/dsh-agent'
- id: agent-model
name: '@deepseek-ai/dsh-agent-model'
- id: llm-retry
name: '@deepseek-ai/dsh-llm-retry'
+2 -4
View File
@@ -68,14 +68,12 @@
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-working-directory": "workspace:*",
"@deepseek-ai/dsh-tool-working-directory": "workspace:*",
"@deepseek-ai/dsh-fs-local": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-fs-local": "workspace:*"
},
"peerDependencies": {
"@deepseek-ai/cordis": "workspace:~"
},
"devDependencies": {
"@deepseek-ai/cordis": "workspace:~",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/cordis": "workspace:~"
}
}
@@ -55,7 +55,6 @@ describe('dsh-sdk-minimal bundle', () => {
['tools', '@deepseek-ai/dsh-tools'],
['mcp-resources', '@deepseek-ai/dsh-mcp-resources'],
['agent', '@deepseek-ai/dsh-agent'],
['agent-model', '@deepseek-ai/dsh-agent-model'],
['llm-retry', '@deepseek-ai/dsh-llm-retry'],
['jobs', '@deepseek-ai/dsh-jobs-local'],
['agent-loop', '@deepseek-ai/dsh-agent-loop'],
@@ -10,9 +10,6 @@
"references": [
{
"path": "../../../vendor/cordis"
},
{
"path": "../../core/agent-model"
}
]
}
+1 -2
View File
@@ -96,8 +96,7 @@
"@deepseek-ai/dsh-agent": "workspace:*",
"@deepseek-ai/dsh-settings": "workspace:*",
"@deepseek-ai/dsh-client-shortcuts": "workspace:*",
"@deepseek-ai/dsh-client-product-analytics": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-client-product-analytics": "workspace:*"
},
"files": [
"locale/*.json",
@@ -14,7 +14,7 @@ import type {
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { TranslateNS } from '@deepseek-ai/dsh-client-locale/client'
import type { InboxState } from '@deepseek-ai/dsh-agent/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent-model/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent/types'
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store'
import type {
DraftAttachmentId, DraftAttachmentSerializationResult, DraftInitializationOptions, DraftInitializationResult, InputTriggerController,
@@ -104,9 +104,6 @@
},
{
"path": "../product-analytics/tsconfig.client.json"
},
{
"path": "../../core/agent-model"
}
],
"exclude": [
@@ -66,8 +66,7 @@
"@deepseek-ai/dsh-client-ui-renderer": "workspace:*",
"@deepseek-ai/dsh-client-ui-session": "workspace:*",
"clsx": "^2.1.1",
"@deepseek-ai/dsh-client-product-analytics": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-client-product-analytics": "workspace:*"
},
"files": [
"locale/*.json",
@@ -4,7 +4,7 @@
* Session's durable selection projection, then submit through the same
* selectModel call. A switch made in either entry updates this shared state.
*/
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent-model/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent/types'
import type { TrackProductEvent } from '@deepseek-ai/dsh-client-product-analytics/client'
import type {
ModelCatalogFailure, ModelProviderGroup, ModelSelection,
@@ -16,7 +16,7 @@ import { LocaleRuntime } from '@deepseek-ai/dsh-client-locale/client'
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'
import { RemoteError, TestRemote } from '@deepseek-ai/dsh-client-test-runtime'
import type { ModelSelection } from '@deepseek-ai/dsh-agent/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent-model/types'
import type { ModelSelectionProjection } from '@deepseek-ai/dsh-agent/types'
import { ReasoningEffortId } from '@deepseek-ai/dsh-llm/brand'
import type { CommandContribution, PopupSelectSpec, SelectOption } from '@deepseek-ai/dsh-client-ui-commands/client'
import type { ModelSelectInjected } from '../src/client/slots.ts'
@@ -58,9 +58,6 @@
},
{
"path": "../product-analytics/tsconfig.client.json"
},
{
"path": "../../core/agent-model"
}
]
}
@@ -212,7 +212,7 @@ describe('CBR-001: a real-loop checkpoint is a valid boundary on both sides', ()
provider: 'unconfigured-agent-fallback',
model: 'unconfigured-agent-fallback',
})
ctx.agentModel.select(agent, { provider: 'mock', model: 'mock' })
agent.model.select({ provider: 'mock', model: 'mock' })
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'do a routed multi-step task' }], source: { kind: 'user' } }))
await waitForIdle(ctx, agent)
@@ -397,7 +397,7 @@ describe('context-overflow recovery across the real loop and compaction-basic',
},
})
ctx.agentModel.select(agent, { provider: 'mock', model: 'mock' })
agent.model.select({ provider: 'mock', model: 'mock' })
agent.followup(createUserMessage({ content: [{ type: 'text', text: 'continue from history' }], source: { kind: 'user' } }))
await agent.whenIdle()
@@ -59,7 +59,6 @@
"@deepseek-ai/dsh-system-prompt": "workspace:*",
"@deepseek-ai/dsh-tool-fs": "workspace:*",
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-working-directory": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-working-directory": "workspace:*"
}
}
@@ -58,7 +58,6 @@ import {
mountAgentLoopTestDependencies,
mountAgentLoopTestHarness,
} from '@deepseek-ai/dsh-agent-loop-testkit'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
declare module '@deepseek-ai/dsh-llm' {
interface MessageSourceMap {
@@ -4279,7 +4278,6 @@ describe('dynamic nested workspace context injection', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -57,7 +57,6 @@
"@deepseek-ai/dsh-subprocess-local": "workspace:*",
"@deepseek-ai/dsh-system-prompt": "workspace:*",
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*",
"@deepseek-ai/dsh-util-time": "workspace:*"
}
}
@@ -9,8 +9,7 @@ import AgentRegistry, { agentEvents, type Agent } from '@deepseek-ai/dsh-agent'
import { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { unsupportedInbox, mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import { unsupportedModel, unsupportedInbox, mountAgentLoopTestDependencies } from '@deepseek-ai/dsh-agent-loop-testkit'
import * as timeContext from '@deepseek-ai/dsh-time-context'
import type { Config } from '@deepseek-ai/dsh-time-context'
@@ -41,7 +40,6 @@ afterEach(() => {
async function mount(config: Config = {}) {
const ctx = new Context()
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const fiber = await ctx.plugin(timeContext, config)
return { ctx, fiber }
@@ -52,6 +50,7 @@ function sessionAgent(session: Session, id = 'agent'): Agent {
id: SessionId(id),
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'running',
ctx: new Context(),
@@ -385,7 +384,6 @@ describe('configuration and lifecycle', () => {
it('fails loud for an invalid explicit zone or an unavailable process zone', async () => {
const invalid = new Context()
await invalid.plugin(SessionProjectionRegistry)
await invalid.plugin(AgentModelPlugin)
await invalid.plugin(AgentRegistry)
await expect(invalid.plugin(timeContext, { timeZone: 'Not/A_Real_Zone' })).rejects.toThrow(
/invalid IANA timeZone/,
@@ -396,7 +394,6 @@ describe('configuration and lifecycle', () => {
})
const unresolved = new Context()
await unresolved.plugin(SessionProjectionRegistry)
await unresolved.plugin(AgentModelPlugin)
await unresolved.plugin(AgentRegistry)
await expect(unresolved.plugin(timeContext, {})).rejects.toThrow(/failed to resolve the system time zone/)
})
@@ -536,7 +533,6 @@ describe('real Loader export path', () => {
const ctx = new Context()
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(AgentRegistry)
const plugin = loader.unwrapExports(timeContext) as Parameters<Context['plugin']>[0]
await ctx.plugin(plugin)
@@ -8,7 +8,7 @@ import { ShellExecutor } from '@deepseek-ai/dsh-shell'
import type { ShellExecRequest, ShellExecSpec, ShellExecution, ShellRunResult } from '@deepseek-ai/dsh-shell'
import * as tmuxContext from '@deepseek-ai/dsh-tmux-context'
import type { Config } from '@deepseek-ai/dsh-tmux-context'
import { mountAgentLoopTestDependencies, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import { unsupportedModel, mountAgentLoopTestDependencies, unsupportedInbox } from '@deepseek-ai/dsh-agent-loop-testkit'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
@@ -111,6 +111,7 @@ function sessionAgent(session: Session, id = 'agent'): Agent {
id: SessionId(id),
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'running',
ctx: new Context(),
+2 -2
View File
@@ -15,8 +15,8 @@
en: 1eb35b015a6c423f
zh: a8a3dceee2c9e943
/packages-core/packages:
en: 67a6cc9ad66e7196
zh: 77ca2120b5b19038
en: 083b59ee474230e8
zh: f11c7bc21bbcdbe6
/packages-core/related-documentation:
en: dfe5990edf146a91
zh: b64e4b2d812286d4
-1
View File
@@ -30,7 +30,6 @@ Use the core packages to build or extend an agent that records durable session h
| [`tools/`](tools/README.md) | The tool registry and guarded execution pipeline the loop dispatches through | `ctx.tools` |
| [`agent-tool-presentation/`](agent-tool-presentation/README.md) | Per-agent tool-presentation selector for presets | no ctx key |
| [`agent/`](agent/README.md) | The `Agent` handle plugins program against, plus its live registry and events | `ctx.agents` |
| [`agent-model/`](agent-model/README.md) | Durable Session model selection and optional scoped switch notices | `ctx.agentModel` |
| [`agent-default-model/`](agent-default-model/README.md) | The deployment default model selection entry points apply to fresh agents | `ctx.agentDefaultModel` |
| [`agent-loop/`](agent-loop/README.md) | The default agent driver: creates agents and runs the turn and step lifecycle | `ctx.agentLoop` |
-1
View File
@@ -30,7 +30,6 @@ kind: "package-group"
| [`tools/`](tools/README.zh.md) | 供循环分发使用的工具注册表与带防护机制的执行流水线 | `ctx.tools` |
| [`agent-tool-presentation/`](agent-tool-presentation/README.zh.md) | 为 preset 提供按 agent 的工具呈现方式选择器 | 无 ctx key |
| [`agent/`](agent/README.zh.md) | 供插件编程使用的 `Agent` 句柄,以及其实时注册表与事件 | `ctx.agents` |
| [`agent-model/`](agent-model/README.zh.md) | 持久 Session 模型选择与可选的作用域切换提示 | `ctx.agentModel` |
| [`agent-default-model/`](agent-default-model/README.zh.md) | 入口对全新 agent 应用的部署默认模型选择 | `ctx.agentDefaultModel` |
| [`agent-loop/`](agent-loop/README.zh.md) | 默认 agent 驱动器:创建 agent 并运行轮次与步骤生命周期 | `ctx.agentLoop` |
@@ -9,8 +9,8 @@
en: 87e9d106cedbbe08
zh: 5eb47e4bd7f5b51d
/deepseek-ai-dsh-agent-default-model/summary:
en: 0a14206daf366b59
zh: 8e163fa67aa3774c
en: dc7c382d4d976acf
zh: e82750291510148f
/deepseek-ai-dsh-agent-default-model/table-of-contents:
en: d152484eb41ac6b4
zh: 09388d293f9be9cb
@@ -45,8 +45,8 @@
en: 814ad1a657587419
zh: 5c1968a55beb1af4
/deepseek-ai-dsh-agent-default-model/known-limitations-and-deferred-work:
en: 7cafbd9a83d14852
zh: 2c298c1a671ec00f
en: d2d7ade906d7b24a
zh: b79f12617cd1e009
/deepseek-ai-dsh-agent-default-model/known-limitations-and-deferred-work/dev-note:
en: e67f633dc6fe7773
zh: 3bb0c20c93f16f98
+2 -2
View File
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
## Summary
Give newly created agents a shared default provider and model when their sessions do not specify one. Provider, model, and reasoning effort are live Config fields. Saved selections update the active profile patch and apply to subsequent reads; per-session selection belongs to the [model-selection service](../agent-model/README.md).
Give newly created agents a shared default provider and model when their sessions do not specify one. Provider, model, and reasoning effort are live Config fields. Saved selections update the active profile patch and apply to subsequent reads; per-session selection belongs to the [Agent model API](../agent/README.md).
## Table of Contents
@@ -112,7 +112,7 @@ Changing the default affects only agents that subsequently resolve from it. An e
These limits define the service's scope. They are current package constraints, not a task backlog.
- **One process-wide default** — the service owns a single default; per-session model selection belongs to the [model-selection service](../agent-model/README.md).
- **One process-wide default** — the service owns a single default; per-session model selection belongs to the [Agent model API](../agent/README.md).
- **Persistence requires a profile configuration editor** — without it, saving a default does not retain the selection.
<a id="dev-note"></a>
@@ -9,7 +9,7 @@ kind: "package-reference"
## 概述
为会话未指定模型的新 agent 提供共享默认 provider 和模型。Provider、模型和推理强度都是即时 Config 字段。保存的选择更新当前 profile patch,并用于后续读取;会话级选择由[模型选择服务](../agent-model/README.zh.md) 负责。
为会话未指定模型的新 agent 提供共享默认 provider 和模型。Provider、模型和推理强度都是即时 Config 字段。保存的选择更新当前 profile patch,并用于后续读取;会话级选择由[Agent 模型 API](../agent/README.zh.md) 负责。
## 目录
@@ -112,7 +112,7 @@ await ctx.agentDefaultModel.saveSelection({ provider, model, reasoningEffort: 'h
这些限制界定该服务的范围。它们是当前包约束,不是任务积压。
- **单一的进程级默认值**——该服务只拥有一个默认值;按会话的模型选择由[模型选择服务](../agent-model/README.zh.md) 负责。
- **单一的进程级默认值**——该服务只拥有一个默认值;按会话的模型选择由[Agent 模型 API](../agent/README.zh.md) 负责。
- **持久化需要 profile 配置编辑器**——没有编辑器时,保存默认值不会保留选择。
<a id="dev-note"></a>
+4 -4
View File
@@ -33,8 +33,8 @@
en: 030202c112f89366
zh: 621d53ed755cafa3
/deepseek-ai-dsh-agent-loop/understand-the-implementation/request-headers-and-adapter-defaults:
en: 158382cfe3cbf499
zh: b4e6de5a50fd3a65
en: 022f90db2ebe58f6
zh: d4374b5ffb132442
/deepseek-ai-dsh-agent-loop/understand-the-implementation/source-map:
en: 2a8b93869eb5a2f9
zh: ddab8e738d188a61
@@ -45,8 +45,8 @@
en: 3c5721bc00a0bbf4
zh: 711f832343ffbb75
/deepseek-ai-dsh-agent-loop/understand-the-implementation/turn-and-step-flow:
en: 28939261ccc7defe
zh: 9d157a321307ebd4
en: 4926502ada48be6b
zh: 7b3ab909f771d2a2
/deepseek-ai-dsh-agent-loop/understand-the-implementation/failure-and-cancellation:
en: eea56903c4ff82f5
zh: c0d5abb5767780ed
+2 -2
View File
@@ -92,7 +92,7 @@ The package is the one concrete implementation of the public `Agent` contract. I
### Request headers and adapter defaults
Before prompt assembly, the loop calls `ctx.agentModel.resolveForNextStep()` and captures provider, model, and optional explicit reasoning effort for the step and its retries. `AssembleContext.callConfig` and `agent/pre-step.callConfig` carry that selection; prompt variables use its route. The deprecated `agent/request` hook remains available to existing listeners and may replace other controls such as sampling. Changing provider or model, or adding, changing, or clearing reasoning effort rejects the step before input is committed. A later recorded choice applies to the next step, including a tool continuation in the same turn.
Before prompt assembly, the loop calls `agent.model.current()` and captures provider, model, and optional explicit reasoning effort for the step and its retries. `AssembleContext.callConfig` and `agent/pre-step.callConfig` carry that selection; prompt variables use its route. The deprecated `agent/request` hook remains available to existing listeners and may replace other controls such as sampling. Changing provider or model, or adding, changing, or clearing reasoning effort rejects the step before input is committed. A later recorded choice applies to the next step, including a tool continuation in the same turn.
After `agent/request`, `ctx.llm.prepareCall()` validates adapter-owned fields and resolves reasoning-effort and output-token defaults under the active turn signal. The loop retains that exact adapter through resolution, `request/header` logging, and dispatch. It writes a full header for the first request, a changed envelope (config or tools — the prompt is not part of the header), an explicit message-series start, a request after a surface replacement or image-offload decision, and resume; unchanged steps, retries, and ordinary later turns in the same series inherit the latest header, and an in-history prompt append is not a replacement, so the request that follows it inherits the header too. Beside the header, the loop logs `request/context` — provider, model, `contextWindow`, and the route's `systemPromptUpdate` mode from `prepareCall()` — only when one of those differs from the latest snapshot. Before the next waterfall, the loop removes adapter-default fields so the current route resolves them again, while explicit settings persist. An unhandled route still fails with `NO_ADAPTER`.
@@ -121,7 +121,7 @@ The loop is the production acquisition point for session write handles. When `ct
### Turn and step flow
The driver owns one agent for its lifetime and runs inside `ctx.agents.withInitiator(agent, ...)`. `AgentLoop` registers the standard `inbox` projection for its service lifetime, so cold reads work before any Agent exists and after all Agents unload. Its package-internal `ReactLoopInbox` uses that shared projection for structural commands and loop-only claims. At a turn boundary it opens the durable turn, then atomically claims pending next-step input plus one queued prompt; between steps it claims only next-step input. The driver assembles the prompt and tools and runs `agent/pre-step`; the fallback projects runtime context after listeners run. A rejected decision or empty first batch opens no step. On the first attempt after acceptance, `step/start` precedes the `agent/request` waterfall and `prepareCall()`; neither async phase sees the pending system prompt or accepted users committed to history, and cancellation during either commits neither. For every attempt, the loop then synchronously reconciles the rendered prompt against the surviving `system/message` nodes using the prepared call capability, refreshes registered runtime facts without reassembling the bound prompt or tools, appends the accepted `user/message` batch only on the first attempt with its owned context candidate replaced in place, and restores removed runtime context, logs the header and context as needed, and derives and freezes the request before streaming through that bound prepared call. Retries reuse the same rendered assembly without repeating assembly, `agent/pre-step`, or user admission. Reconciliation sees pre-step and retry compaction; a broken series consolidates the prompt at the head rather than appending an update after already-committed users. The request is `header.config`, `deriveMessages()`, and `header.tools`; it carries no `system` field. Each model attempt emits one process-local `start`, emits every `chunk` only after the matching durable assistant-frame settlement, and emits exactly one terminal `end`; final assembly or message-append failure settles it as `aborted`, while `committed` follows the durable `assistant/message`. Each successful model call appends one message anchor, and a cancelled stream appends an `interrupted: true` anchor with the delivered prefix so the next request contains what the user saw. Within a step, exclusive calls form barriers and parallel-safe calls use the bounded rolling pool; policy, durable results... (line truncated to 2000 chars)
The driver owns one agent for its lifetime and runs inside `ctx.agents.withInitiator(agent, ...)`. `AgentLoop` registers the standard `inbox` projection for its service lifetime, so cold reads work before any Agent exists and after all Agents unload. It also owns `modelSelection` and constructs an `AgentModel` for each Agent, with the public [Model API](../agent/README.md#model-selection). Its package-internal `ReactLoopInbox` uses that shared projection for structural commands and loop-only claims. At a turn boundary it opens the durable turn, then atomically claims pending next-step input plus one queued prompt; between steps it claims only next-step input. The driver assembles the prompt and tools and runs `agent/pre-step`; the fallback projects runtime context after listeners run. A rejected decision or empty first batch opens no step. On the first attempt after acceptance, `step/start` precedes the `agent/request` waterfall and `prepareCall()`; neither async phase sees the pending system prompt or accepted users committed to history, and cancellation during either commits neither. For every attempt, the loop then synchronously reconciles the rendered prompt against the surviving `system/message` nodes using the prepared call capability, refreshes registered runtime facts without reassembling the bound prompt or tools, appends the accepted `user/message` batch only on the first attempt with its owned context candidate replaced in place, and restores removed runtime context, logs the header and context as needed, and derives and freezes the request before streaming through that bound prepared call. Retries reuse the same rendered assembly without repeating assembly, `agent/pre-step`, or user admission. Reconciliation sees pre-step and retry compaction; a broken series consolidates the prompt at the head rather than appending an update after already-committed users. The request is `header.config`, `deriveMessages()`, and `header.tools`; it carries no `system` field. Each model attempt emits one process-local `start`, emits every `chunk` only after the matching durable assistant-frame settlement, and emits exactly one terminal `end`; final assembly or message-append failure settles it as `aborted`, while `committed` follows the durable `assistant/message`. Each successful model call appends one message anchor, and a cancelled stream appends an `interrupted: true` anchor with the delivered prefix so the next request contains what the user saw. Within a step, exclusive calls form barriers and parallel-safe calls use the bounded rolling pool; policy, durable results... (line truncated to 2000 chars)
Prompt admission uses the actual `prepareCall()` result, not the preceding `request/context`. With no system node, even an empty prompt is appended (reserving node 0 without a wire message). On an incapable route or at a new request series, a non-empty rendering is consolidated at the first system node: each non-empty later system node receives a logged per-node empty replacement, then the head is rewritten if needed. Dormant empty tails need no replacement and do not determine the effective text. Consolidation applies even when the latest effective text is unchanged. On a continuing `in-history` series, an unchanged effective prompt produces no event and a non-empty change appends. An empty rendering clears every non-empty later system node through a logged per-node empty replacement, then empties the head if needed, regardless of route or series state. No older instructions remain model-visible. An empty head with no active later system node means no prompt; repeated clears and resume leave it empty. A restored non-empty prompt follows the same route/series rule: a continuing capable route may append it, while an incapable route or new series refills the head. A step starts a series when the pre-step decision declares `startsRequestSeries` or `session.surface.contentGeneration` changed since attachment or the last request (a replacement or image-offload decision). Visible tool-schema changes force prompt consolidation only when the prepared route lacks `toolUpdate`. Routes supporting both tool and system-prompt updates can append a changed prompt and activate added tools without rewriting earlier messages. If another admission condition replaces a system node, the request starts a new series with current tool declarations. Resume and a provider or model swap alone continue the series; the prepared route still governs admission. Per-node empty replacements preserve intervening history without a surface delete operation.
+2 -2
View File
@@ -92,7 +92,7 @@ const handle = await ctx.agents.create({
### 请求 header 与适配器默认值
循环在提示词组装前调用 `ctx.agentModel.resolveForNextStep()`,并为该步骤及其重试捕获提供方、模型及可选的显式推理强度。`AssembleContext.callConfig` 与 `agent/pre-step.callConfig` 携带该选择;提示词变量使用其中的路由。已弃用的 `agent/request` hook 仍可供现有监听器使用,可以替换采样等其他控制参数。改变提供方或模型,或添加、修改、清除推理强度,都会在提交输入前拒绝该步骤。之后记录的选择从下一个步骤开始生效,包括同一轮次中的工具后续步骤。
循环在提示词组装前调用 `agent.model.current()`,并为该步骤及其重试捕获提供方、模型及可选的显式推理强度。`AssembleContext.callConfig` 与 `agent/pre-step.callConfig` 携带该选择;提示词变量使用其中的路由。已弃用的 `agent/request` hook 仍可供现有监听器使用,可以替换采样等其他控制参数。改变提供方或模型,或添加、修改、清除推理强度,都会在提交输入前拒绝该步骤。之后记录的选择从下一个步骤开始生效,包括同一轮次中的工具后续步骤。
`agent/request` 返回后,`ctx.llm.prepareCall()` 会在活跃轮次信号下校验适配器持有的字段,并解析推理强度和输出 token 默认值。循环会在解析、`request/header` 记录与分派期间保留同一个适配器。循环会为首次请求、变化的 envelope(配置或工具——提示词不属于 header)、显式消息序列起点、surface 替换或图片省略决定后的请求及恢复写入完整 header;同一序列内内容未变的步骤、重试与普通后续轮次继承最新 header,历史内追加提示词不是替换,因此紧随其后的请求同样继承 header。在 header 之外,循环还会记录 `request/context`——提供方、模型、`contextWindow` 以及来自 `prepareCall()` 的路由 `systemPromptUpdate` 模式——且仅在其中任何一项与最新快照不同时记录。下一次 waterfall 分发前,循环移除适配器默认字段,使当前路由重新解析它们;显式设置则保留。未处理的路由仍以 `NO_ADAPTER` 失败。
@@ -121,7 +121,7 @@ loop 在发布工厂前等待 inbox 与轮次边界注册完成,并将句柄
### 轮次与步骤流程
驱动器在其整个生命周期内拥有一个 agent,并在 `ctx.agents.withInitiator(agent, ...)` 内运行。`AgentLoop` 在服务生命周期内注册标准 `inbox` 投影,因此冷读取在没有 Agent 和所有 Agent 卸载后都可用。其包内部 `ReactLoopInbox` 使用该共享投影执行结构化命令与仅供 loop 使用的领取操作。在轮次边界,它先打开持久轮次,再原子领取待处理的 next-step 输入与一条排队提示词;在步骤之间则只领取 next-step 输入。驱动器组装提示词与工具,并运行 `agent/pre-step`;fallback 在监听器执行后投影运行时上下文。被拒绝的决定或空的首批输入不打开步骤。接纳后的首次尝试先记录 `step/start`,再运行 `agent/request` waterfall 与 `prepareCall()`;这两个异步阶段都看不到待提交的系统提示词与已接纳用户消息进入历史,在任一阶段取消都不会提交这两者。每次尝试时,循环随后依据已准备调用的能力,同步将渲染后的提示词与存活的 `system/message` 节点协调一致、刷新已注册运行时事实而不重新组装绑定的提示词或工具、仅在首次尝试追加已接纳的 `user/message` 批次并原位替换循环自有上下文候选、恢复被移除的运行时上下文、按需记录 header 与 context,再派生并冻结请求,通过该绑定的已准备调用发起流式请求。重试复用同一份已渲染组装结果,不重复组装、`agent/pre-step` 或用户消息准入。协调过程可见 pre-step 与重试中的压缩;序列中断时将提示词归并到头部,而非在已提交用户消息之后追加更新。请求由 `header.config`、`deriveMessages()` 与 `header.tools` 构成,不携带 `system` 字段。每次模型尝试会发出一个进程本地 `start`,仅在匹配的持久 assistant-frame 结算之后发出各个 `chunk`,并恰好发出一个终态 `end`;最终组装或消息追加失败时以 `aborted` 结算,`committed` 则出现在持久 `assistant/message` 之后。每次成功的模型调用都恰好追加一个 message 锚点,被取消的流则追加带 `interrupted: true` 的锚点并携带已交付前缀,使下一次请求包含用户看到的内容。在步骤内,独占调用形成屏障,并行安全调用使用有界滚动池;策略、持久结果与结果上下文保持模型顺序。
驱动器在其整个生命周期内拥有一个 agent,并在 `ctx.agents.withInitiator(agent, ...)` 内运行。`AgentLoop` 在服务生命周期内注册标准 `inbox` 投影,因此冷读取在没有 Agent 和所有 Agent 卸载后都可用。它还拥有 `modelSelection`,并为每个 Agent 构建 `AgentModel`,实现公开的 [Model API](../agent/README.zh.md#model-selection)。其包内部 `ReactLoopInbox` 使用该共享投影执行结构化命令与仅供 loop 使用的领取操作。在轮次边界,它先打开持久轮次,再原子领取待处理的 next-step 输入与一条排队提示词;在步骤之间则只领取 next-step 输入。驱动器组装提示词与工具,并运行 `agent/pre-step`;fallback 在监听器执行后投影运行时上下文。被拒绝的决定或空的首批输入不打开步骤。接纳后的首次尝试先记录 `step/start`,再运行 `agent/request` waterfall 与 `prepareCall()`;这两个异步阶段都看不到待提交的系统提示词与已接纳用户消息进入历史,在任一阶段取消都不会提交这两者。每次尝试时,循环随后依据已准备调用的能力,同步将渲染后的提示词与存活的 `system/message` 节点协调一致、刷新已注册运行时事实而不重新组装绑定的提示词或工具、仅在首次尝试追加已接纳的 `user/message` 批次并原位替换循环自有上下文候选、恢复被移除的运行时上下文、按需记录 header 与 context,再派生并冻结请求,通过该绑定的已准备调用发起流式请求。重试复用同一份已渲染组装结果,不重复组装、`agent/pre-step` 或用户消息准入。协调过程可见 pre-step 与重试中的压缩;序列中断时将提示词归并到头部,而非在已提交用户消息之后追加更新。请求由 `header.config`、`deriveMessages()` 与 `header.tools` 构成,不携带 `system` 字段。每次模型尝试会发出一个进程本地 `start`,仅在匹配的持久 assistant-frame 结算之后发出各个 `chunk`,并恰好发出一个终态 `end`;最终组装或消息追加失败时以 `aborted` 结算,`committed` 则出现在持久 `assistant/message` 之后。每次成功的模型调用都恰好追加一个 message 锚点,被取消的流则追加带 `interrupted: true` 的锚点并携带已交付前缀,使下一次请求包含用户看到的内容。在步骤内,独占调用形成屏障,并行安全调用使用有界滚动池;策略、持久结果与结果上下文保持模型顺序。
提示词准入依据实际的 `prepareCall()` 结果,而非先前的 `request/context`。没有系统节点时,即使提示词为空也追加(预留第 0 号节点,但不产生协议消息)。在不具备能力的路由上或新请求序列开始时,非空渲染文本归并到首个系统节点:每个非空的后续系统节点分别收到有日志记录的空内容替换,随后按需重写头节点。未生效的空尾节点无需替换,也不决定有效文本。即使最新有效文本未变,也执行归并。延续中的 `in-history` 序列在有效提示词不变时不产生事件,非空变更则追加。无论路由或序列状态如何,空渲染文本都会通过有日志记录的逐节点空内容替换清除每个非空的后续系统节点,再按需清空头节点。模型不会继续看到旧指令。空头节点且没有生效的后续系统节点表示没有提示词;重复清除与恢复会话都保持为空。重新提供的非空提示词遵循同一路由/序列规则:延续中的具备能力路由可以追加它,不具备能力的路由或新序列则重新填充头节点。以下情况开启序列:pre-step 决定声明 `startsRequestSeries`,或 `session.surface.contentGeneration` 自附接或上次请求以来发生变化(替换或图片省略决定)。仅当已准备路由未声明 `toolUpdate` 时,可见工具 schema 变化才强制归并提示词。同时支持工具和系统提示词更新的路由可以追加变更后的提示词并激活新增工具,无需改写此前消息。如果其他准入条件替换系统节点,请求会以当前工具声明开启新序列。恢复与单纯的提供方或模型切换都延续序列;准入仍由已准备的路由决定。逐节点的空内容替换保留其间历史,无需 surface 删除操作。
+2 -4
View File
@@ -36,8 +36,7 @@
"@deepseek-ai/dsh-session-persistence": "workspace:*",
"@deepseek-ai/dsh-session-projection": "workspace:*",
"@deepseek-ai/dsh-system-prompt": "workspace:*",
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-tools": "workspace:*"
},
"dependencies": {
"@deepseek-ai/dsh-brand": "workspace:*",
@@ -57,7 +56,6 @@
"@deepseek-ai/dsh-session-persistence-jsonl": "workspace:*",
"@deepseek-ai/dsh-session-projection": "workspace:*",
"@deepseek-ai/dsh-system-prompt": "workspace:*",
"@deepseek-ai/dsh-tools": "workspace:*",
"@deepseek-ai/dsh-agent-model": "workspace:*"
"@deepseek-ai/dsh-tools": "workspace:*"
}
}
+9 -5
View File
@@ -11,13 +11,14 @@ import type {
AgentOptions,
AgentStatus,
CancelOptions,
InboxTarget,
ModelSelection,
ModelSelectionProjectionState,
InboxTarget,
InboxState,
PreStepDecision,
RequestErrorAction,
} from '@deepseek-ai/dsh-agent'
import { agentEvents, assembleContextFor } from '@deepseek-ai/dsh-agent'
import { AgentModel, agentEvents, assembleContextFor } from '@deepseek-ai/dsh-agent'
import type { GenerateOptions, LlmCallConfig, Message, PreparedLlmCall } from '@deepseek-ai/dsh-llm'
import {
LlmError,
@@ -98,6 +99,7 @@ function abortedCancelCause(signal: AbortSignal): AgentCancelCause | undefined {
/** Drives one session through turn and step boundaries. */
export class ReactLoopAgent implements Agent {
readonly model: AgentModel
readonly inbox: ReactLoopInbox
private phase: Phase
private activityDone: Promise<void> = Promise.resolve()
@@ -126,6 +128,7 @@ export class ReactLoopAgent implements Agent {
public readonly id: SessionId,
public readonly options: AgentOptions,
public readonly session: Session,
readModel: () => ModelSelectionProjectionState,
readInbox: () => InboxState,
lastTurn: number,
) {
@@ -133,6 +136,7 @@ export class ReactLoopAgent implements Agent {
this.dispatch = agentEvents(loopCtx, this)
this.scope = createScope(loopCtx, this)
this.ctx = this.scope.ctx
this.model = new AgentModel(readModel, session, options)
this.inbox = new ReactLoopInbox(readInbox, session, this.dispatch)
this.phase = { kind: 'idle', lastTurn }
this.runtimeContext = new RuntimeContextProjection(this.ctx, session)
@@ -271,7 +275,7 @@ export class ReactLoopAgent implements Agent {
if (this.phase.kind !== 'running') throw new Error(`agent "${this.id}": pre-step outside running phase`)
const signal = this.phase.abort.signal
const claimed = this.inbox.claim(target, position.turn)
const selection = this.loopCtx.agentModel.resolveForNextStep(this)
const selection = this.model.current()
if (selection === undefined) {
throw new Error(`agent "${this.id}" has no provider/model: set AgentOptions.provider and AgentOptions.model or record a model selection`)
}
@@ -592,10 +596,10 @@ export class ReactLoopAgent implements Agent {
)
signal.throwIfAborted()
if (proposedConfig.provider !== selection.provider || proposedConfig.model !== selection.model) {
throw new Error(`agent "${this.id}": agent/request proposed "${proposedConfig.provider}/${proposedConfig.model}" after step preparation fixed "${selection.provider}/${selection.model}"; use ctx.agentModel.select() before step preparation`)
throw new Error(`agent "${this.id}": agent/request proposed "${proposedConfig.provider}/${proposedConfig.model}" after step preparation fixed "${selection.provider}/${selection.model}"; use agent.model.select() before step preparation`)
}
if (proposedConfig.reasoningEffort !== selection.reasoningEffort) {
throw new Error(`agent "${this.id}": agent/request proposed reasoning effort "${proposedConfig.reasoningEffort ?? 'adapter default'}" after step preparation fixed "${selection.reasoningEffort ?? 'adapter default'}"; use ctx.agentModel.select() before step preparation`)
throw new Error(`agent "${this.id}": agent/request proposed reasoning effort "${proposedConfig.reasoningEffort ?? 'adapter default'}" after step preparation fixed "${selection.reasoningEffort ?? 'adapter default'}"; use agent.model.select() before step preparation`)
}
let config: LlmCallConfig
let preparedCall: PreparedLlmCall | undefined
+23 -7
View File
@@ -19,9 +19,11 @@ import type {
CreateAgentOptions,
ResumeAgentOptions,
SessionStartSource,
ModelSelection,
ModelSelectionProjectionState,
InboxState,
} from '@deepseek-ai/dsh-agent'
import type {} from '@deepseek-ai/dsh-agent-model'
import { modelSelectionProjectionDefinition } from '@deepseek-ai/dsh-agent'
import { errorChain, ReasoningEffortId } from '@deepseek-ai/dsh-llm'
import { interruptedTurnClosers, SessionLogOffset, SessionPreparation } from '@deepseek-ai/dsh-session'
import type { Session, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
@@ -287,7 +289,7 @@ function validateConfiguredAgents(agents: Config['agents']): void {
/** Concrete agent factory and driver service. */
export class AgentLoop extends Service implements AgentFactory {
static inject = ['agentModel', 'agents', 'sessions', 'llm', 'tools', 'systemPrompt', 'sessionProjections']
static inject = ['agents', 'sessions', 'llm', 'tools', 'systemPrompt', 'sessionProjections']
/** Runtime schema for declarative agents. */
static Config: z<{ agents?: Config['agents']; maxParallelToolCalls?: number }, Config> = z.object({
@@ -309,6 +311,7 @@ export class AgentLoop extends Service implements AgentFactory {
private readonly ownership: FactoryOwnership
/** Plain holder prevents Cordis from re-tracing the factory's dependency context through a caller shadow. */
private readonly runtime: { ctx: Context }
private modelProjectionHandle!: ProjectionHandle<ModelSelectionProjectionState>
private inboxProjectionHandle!: ProjectionHandle<InboxState>
constructor(ctx: Context, config: Config) {
@@ -326,8 +329,9 @@ export class AgentLoop extends Service implements AgentFactory {
protected async [Service.init](): Promise<void> {
const ctx = this.runtime.ctx
const ownership = this.ownership
// The inbox remains readable until agent teardown finishes.
// Agent projections remain readable until teardown finishes.
ctx.effect(() => () => ownership.dispose(), 'agentLoop.transactions()')
this.modelProjectionHandle = await ctx.sessionProjections.register(modelSelectionProjectionDefinition)
this.inboxProjectionHandle = await ctx.sessionProjections.register(inboxProjectionDefinition)
ctx.effect(() => ctx.agents.setFactory(this), 'agentLoop.setFactory()')
ctx.systemPrompt.variable('provider', context => context.callConfig?.provider ?? context.agent?.options.provider)
@@ -368,9 +372,15 @@ export class AgentLoop extends Service implements AgentFactory {
private applyConfiguredRoute(agent: Agent, options: AgentOptions): void {
const { provider, model, reasoningEffort } = options
if (provider && model) this.runtime.ctx.agentModel.applyConfiguredRoute(agent, {
provider, model, ...reasoningEffort === undefined ? {} : { reasoningEffort },
})
if (!provider || !model) return
const previous = agent.model.current()
const selection: ModelSelection = { provider, model, ...reasoningEffort === undefined ? {} : { reasoningEffort } }
if (selection.reasoningEffort === undefined && previous !== undefined
&& previous.provider === selection.provider && previous.model === selection.model
&& previous.reasoningEffort !== undefined) {
selection.reasoningEffort = previous.reasoningEffort
}
agent.model.select(selection)
}
/** Report a contained declarative-start failure to identity-bound consumers. */
@@ -556,10 +566,16 @@ export class AgentLoop extends Service implements AgentFactory {
}
}
const untrack = this.ownership.track(dispose)
const modelProjectionHandle = this.modelProjectionHandle
const inboxProjectionHandle = this.inboxProjectionHandle
try {
unfollowOwner = ownerCtx.effect(function* () {
const created = machine = new ReactLoopAgent(loopCtx, id, options, session, () => inboxProjectionHandle.stateOf(session), lastTurn)
const created = machine = new ReactLoopAgent(
loopCtx, id, options, session,
() => modelProjectionHandle.stateOf(session),
() => inboxProjectionHandle.stateOf(session),
lastTurn,
)
machineReady.resolve()
// Adopt the scope on its original fiber so it cannot unload before teardown.
// A loop already unloading during minting owns the provisional scope itself.
@@ -2,7 +2,6 @@ import { describe, expect, it } from 'vitest'
import { Context, type Fiber } from '@deepseek-ai/cordis'
import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import LlmRuntime, { createUserMessage, ToolCallId, LlmAdapter } from '@deepseek-ai/dsh-llm'
import type { GenerateOptions, StreamChunk } from '@deepseek-ai/dsh-llm'
@@ -24,7 +23,6 @@ async function harness(adapter: LlmAdapter): Promise<Harness> {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
const agentsFiber = await ctx.plugin(AgentRegistry)
@@ -126,7 +124,6 @@ describe('AgentLoop initiator scope', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -388,7 +385,6 @@ describe('AgentLoop initiator scope', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -3,7 +3,6 @@ import { describe, expect, it, vi } from 'vitest'
import { Context } from '@deepseek-ai/cordis'
import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import LlmRuntime from '@deepseek-ai/dsh-llm'
import type { MessageSource } from '@deepseek-ai/dsh-llm'
@@ -25,7 +24,6 @@ async function harness(adapter: MockAdapter): Promise<Context> {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -16,7 +16,6 @@ import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
import ToolRuntime, { defineContentToolFixture, TOOL_ABORTED_BEFORE_DISPATCH } from '@deepseek-ai/dsh-tools'
import AgentRegistry, { type Agent, type AgentCancelCause } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts'
@@ -29,7 +28,6 @@ async function harness(adapter: MockAdapter) {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -828,7 +826,6 @@ describe('Agent.cancel()', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -15,7 +15,6 @@ import type { SessionHandle } from '@deepseek-ai/dsh-session-persistence'
import * as JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
import AgentLoop, { CONFIGURED_AGENT_IDENTITIES_KEY } from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, textResponse } from './mock-adapter.ts'
@@ -41,7 +40,6 @@ async function makeCoreContext(): Promise<Context> {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -373,7 +371,6 @@ describe('config-driven session id', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -397,7 +394,6 @@ describe('config-driven session id', () => {
await ctx1.plugin(LlmRuntime)
await ctx1.plugin(SessionStore)
await ctx1.plugin(SessionProjectionRegistry)
await ctx1.plugin(AgentModelPlugin)
await ctx1.plugin(SystemPrompt)
await ctx1.plugin(ToolRuntime)
await ctx1.plugin(AgentRegistry)
@@ -421,7 +417,6 @@ describe('config-driven session id', () => {
await ctx2.plugin(LlmRuntime)
await ctx2.plugin(SessionStore)
await ctx2.plugin(SessionProjectionRegistry)
await ctx2.plugin(AgentModelPlugin)
await ctx2.plugin(SystemPrompt)
await ctx2.plugin(ToolRuntime)
await ctx2.plugin(AgentRegistry)
@@ -448,7 +443,6 @@ describe('config-driven session id', () => {
await ctx1.plugin(LlmRuntime)
await ctx1.plugin(SessionStore)
await ctx1.plugin(SessionProjectionRegistry)
await ctx1.plugin(AgentModelPlugin)
await ctx1.plugin(SystemPrompt)
await ctx1.plugin(ToolRuntime)
await ctx1.plugin(AgentRegistry)
@@ -467,7 +461,6 @@ describe('config-driven session id', () => {
await ctx2.plugin(LlmRuntime)
await ctx2.plugin(SessionStore)
await ctx2.plugin(SessionProjectionRegistry)
await ctx2.plugin(AgentModelPlugin)
await ctx2.plugin(SystemPrompt)
await ctx2.plugin(ToolRuntime)
await ctx2.plugin(AgentRegistry)
@@ -500,7 +493,7 @@ describe('config-driven session id', () => {
const h1 = await ctx1.agents.create({ sessionId: SessionId('sticky-route'), agentOptions: { provider: 'mock', model: 'mock' } })
h1.agent.followup(createUserMessage({ content: [{ type: 'text', text: 'remember me' }], source: { kind: 'user' } }))
await waitForIdle(ctx1, h1.agent)
ctx1.agentModel.select(h1.agent, { provider: 'mock', model: 'mock', reasoningEffort: ReasoningEffortId('high') })
h1.agent.model.select({ provider: 'mock', model: 'mock', reasoningEffort: ReasoningEffortId('high') })
await h1.dispose()
await ctx1.fiber.dispose()
@@ -509,7 +502,7 @@ describe('config-driven session id', () => {
await ctx2.plugin(AgentLoop, { agents: [{ id: SessionId('main'), ...route, resumeSessionId: SessionId('sticky-route') }] })
await expect.poll(() => ctx2.agents.get(SessionId('sticky-route')), { timeout: 5_000 }).toBeDefined()
const resumed = ctx2.agents.get(SessionId('sticky-route'))!
expect(ctx2.agentModel.resolveForNextStep(resumed)).toEqual(expected)
expect(resumed.model.current()).toEqual(expected)
expect(resumed.session.snapshotEvents().filter(event => event.type === 'model/selection')).toHaveLength(1 + appended)
await ctx2.fiber.dispose()
})
@@ -521,7 +514,6 @@ describe('config-driven session id', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -7,7 +7,6 @@ import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
import ToolRuntime, { defineContentToolFixture, type PostToolDecision } from '@deepseek-ai/dsh-tools'
import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts'
@@ -28,7 +27,6 @@ async function harness(adapter: MockAdapter) {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -460,7 +458,7 @@ describe('adapter registration, routing, and accepted-input ownership', () => {
const ctx = await harness(adapter)
const agent = await ctx.agentLoop.create(SessionId('a1'), {})
ctx.agentModel.select(agent, { provider: 'mock', model: 'mock' })
agent.model.select({ provider: 'mock', model: 'mock' })
send(agent, 'go')
await waitForIdle(ctx, agent)
@@ -576,7 +574,6 @@ describe('turn numbering continues across seeded sessions', () => {
await ctx2.plugin(LlmRuntime)
await ctx2.plugin(SessionStore)
await ctx2.plugin(SessionProjectionRegistry)
await ctx2.plugin(AgentModelPlugin)
await ctx2.plugin(SystemPrompt)
await ctx2.plugin(ToolRuntime)
await ctx2.plugin(AgentRegistry)
@@ -1293,7 +1290,6 @@ describe('disposal and cancellation during pre-step assembly', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1344,7 +1340,6 @@ describe('disposal and cancellation during pre-step assembly', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1395,7 +1390,6 @@ describe('disposal and cancellation during pre-step assembly', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1442,7 +1436,6 @@ describe('disposal and cancellation during pre-step assembly', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1491,7 +1484,6 @@ describe('disposal and cancellation during pre-step assembly', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -9,7 +9,6 @@ import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
import AgentRegistry, { type Agent } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts'
@@ -28,7 +27,6 @@ async function harness(adapter: MockAdapter) {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1,3 +1,4 @@
import { unsupportedModel } from '@deepseek-ai/dsh-agent-loop-testkit'
import { Context } from '@deepseek-ai/cordis'
import { agentEvents, type Agent } from '@deepseek-ai/dsh-agent'
import { createUserMessage, freezeMessage } from '@deepseek-ai/dsh-llm'
@@ -25,6 +26,7 @@ function stubAgent(rawId: string, overrides: Partial<Agent> = {}): Agent {
id,
options: {},
session,
model: unsupportedModel(),
inbox: unsupportedInbox(),
status: 'idle',
ctx,
@@ -17,7 +17,6 @@ import AgentRegistry, {
} from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, textResponse, toolCallResponse } from './mock-adapter.ts'
@@ -46,7 +45,6 @@ async function harness(adapter: MockAdapter) {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
+2 -6
View File
@@ -9,7 +9,6 @@ import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
import AgentRegistry, { type Agent, type AssistantStreamFrame } from '@deepseek-ai/dsh-agent'
import AgentLoop from '@deepseek-ai/dsh-agent-loop'
import * as AgentModelPlugin from '@deepseek-ai/dsh-agent-model'
import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
import { MockAdapter, maxTokensResponse, textResponse, toolCallResponse } from './mock-adapter.ts'
@@ -34,7 +33,6 @@ async function harness(adapter: MockAdapter, persona = '') {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt, { personaPrefix: persona })
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -608,7 +606,7 @@ describe('agent loop', () => {
const adapter = new MockAdapter([textResponse('ok')])
const ctx = await harness(adapter, 'You run on {{model}}.')
const agent = await ctx.agentLoop.create(SessionId('a-recorded-model'), {})
ctx.agentModel.select(agent, { provider: 'mock', model: 'mock' })
agent.model.select({ provider: 'mock', model: 'mock' })
send(agent, 'hi')
await waitForIdle(ctx, agent)
@@ -1316,7 +1314,7 @@ describe('agent loop', () => {
.toEqual([])
expect(agent.session.snapshotEvents().at(-1)).toMatchObject({
type: 'turn/end', data: { reason: { kind: 'error', error: {
message: `agent "a1": agent/request proposed "${field === 'provider' ? 'other/mock' : 'mock/other'}" after step preparation fixed "mock/mock"; use ctx.agentModel.select() before step preparation`,
message: `agent "a1": agent/request proposed "${field === 'provider' ? 'other/mock' : 'mock/other'}" after step preparation fixed "mock/mock"; use agent.model.select() before step preparation`,
} } },
})
})
@@ -1905,7 +1903,6 @@ describe('agent loop', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
@@ -1936,7 +1933,6 @@ describe('agent loop', () => {
await ctx.plugin(LlmRuntime)
await ctx.plugin(SessionStore)
await ctx.plugin(SessionProjectionRegistry)
await ctx.plugin(AgentModelPlugin)
await ctx.plugin(SystemPrompt)
await ctx.plugin(ToolRuntime)
await ctx.plugin(AgentRegistry)
Loaded 100 of 237 files, more files were not shown because too many files have changed in this diff. Show more