Deepseek Harness DeepSeek Harness 架构 English | 中文 改动 packages/ 下的任何内容之前,请先阅读本文。本文假定你已了解 Cordis;如果尚未了解,请先阅读 入门 或 教程 。 建议使用 agent(智能体)探索代码库并理解其架构。 Cordis Cordis 是 dsh 底层的框架:插件向共享上下文贡献服务、类型化事件和可逆的副作用。产品的每一部分都是插件,包括模型适配器、工具注册表、会话日志,以及 agent loop(智能体循环)本身,因此每个都可以从配置替换。 不存在需要打补丁的特权内核:扩展 dsh 的方式是把插件挂载到其他插件旁边,而各项注册都是副作用,会在其插件卸载时撤销。 Profile 与组合包 运行中的 dsh 是一棵插件树,由启动时按序叠加的各层组合而成。 profile 是存放在 Harness home 中的具名组装。它列出自己叠放的组合包,存放自己安装的树外插件,并保存用户自己的 cordis.patch.yml 。 web 、 headless 、 sdk 、 sdk-minimal 和 acp 作为模板随发行版交付。 组合包 是 Cordis 配置项及其挂载代码的分发格式,因此它插入的内容始终可被其上各层 patch。 两者都在各自的 package.json 中通过 dsh 字段声明自己: dsh.profile 列出一个 profile 的组合包, dsh.bundle 指向一个组合包的 patch 文件。 dsh-base 是 web 、 headless 、 sdk 与 acp profile 的共享第一层:模型适配器、工具、持久化、沙箱与审批策略、设置、凭据、遥测。 dsh-web-app 增加浏览器应用, dsh-headless 增加不带服务器的一次性运行器, dsh-sdk-app 增加 SDK JSON-RPC 服务器, dsh-acp-app 增加仅用于自动化的 ACP 服务器。 dsh-sdk-minimal 是刻意保留的例外:一个组合包拥有完整的显式 SDK 配置树,不应用 dsh-base 。 各层按此顺序应用在空条目列表之上:先按 profile 列出的顺序应用每个组合包,然后是 profile 的 cordis.patch.yml ,然后是 home 级的那份,最后是任意 --patch overlay。一条 patch 按 id 定位某个条目并替换其整个 config,或插入新条目。 自定义 profile 默认实时重载 patch。随附的 web profile 使用实时重载; headless 、 sdk 、 sdk-minimal 和 acp 则只在启动时应用一次所有配置层,因为一次性应用或 stdio 应用拥有工作之后,替换其依赖会破坏该生命周期。 要查看你的机器启动的配置树: dsh --profile web --dump-config 它打印出的任何条目,都可以由你自己的 patch 替换。 组装机制见 app-boot ;配置字段见生成的 配置目录 。 应用启动 所有受支持的 Node 应用都从 dsh CLI 与具名 profile 启动。随附应用是 dsh web (刻意为 --profile web 保留的别名)、 dsh --profile headless 、 dsh --profile sdk 、 dsh --profile sdk-minimal 与 dsh --profile acp 。TypeScript SDK 会解析其同版本 dsh 依赖并选择 sdk ;自定义插件组合继续由 profile 与有序 patch 文件表达,而不是另一个可执行文件或内联应用树。 sdk-minimal 是位于同一 launcher 后的仓库自有独立组合包,而不是由调用方提供的 Cordis 配置树。 Vendored CLI、仅用于构建和测试的可执行文件、进程内直接挂载插件以及私有浏览器 WebWorker 预览都不属于 Harness 应用启动器。 verify-application-entrypoints 将每个包 bin、可执行源码与根 demo 归入显式类别,并拒绝任何绕过 dsh 的 Node 应用路径。 Python SDK 遵循相同的应用架构。其运行时 wheel 把普通 dsh CLI 打包为 deepseek-harness-sdk-runtime-- ,客户端默认以显式 Harness home 启动 dsh --profile sdk 。极简示例选择随附的 sdk-minimal profile。Python 暴露 profile 选择与有序 patch 文件,而不是完整 Cordis 树;持久外部插件通过 dsh plugin 安装。已删除的私有直读配置载体没有兼容 bin 或回退 parser。 核心包 以下是向 Cordis 树贡献内容的部分核心包。 包 职责 ctx 键 core/session 仅追加的 SessionEvent 日志和内存存储 ctx.sessions core/system-prompt 提示词片段与工具 schema 的组装 ctx.systemPrompt core/tools 作用域化的工具注册表和带把关的执行流水线 ctx.tools core/agent Agent 接口、活跃 agent 注册表和 agent/* 事件 ctx.agents core/agent-loop 实现该接口的默认驱动器 ctx.agentLoop core/scope 按 agent 划分作用域的注册原语 库,无 ctx 键 llm/llm 消息与流式词汇表,以及适配器 seam ctx.llm webhook/webhook 已认证 delivery 的分派和 Workspace Session 创建 ctx.webhookRuntime 事件 事件就是扩展点,而选对事件域是大多数改动的第一个决定。 会话事件 是追加到日志并通过 session/event 广播的持久事实。当某个事实必须在重新加载后仍然存在时,使用它。 Agent 事件 ( agent/* )携带活跃 Agent :inbox、步骤、状态、请求、验证、续跑。要观察或拦截进行中的工作时,使用它。 能力事件 无需导入循环即可向某个 seam( fs/* 、 tools/* 、 telemetry/* )附加策略和适配器。 事件映射 列出每个事件的生产方与消费方。 轮次流程 一个 步骤 是一次模型请求加上它调用的工具。一个 轮次 包含零个或多个步骤:它在领取首条输入之前打开,并在不再欠下任何工作时关闭。 turn/start claim next-step input plus one queued message assemble prompt sections + tool schemas -> agent/pre-step reject | enter(messages, startsRequestSeries?) reject, or a first enter rewritten empty -> close the turn with no step step/start append entered messages as user/message derive model history from the log agent/request -> llm/stream -> assistant/chunk* -> assistant/message tool/call* -> tools/pre-execute -> tools/execute -> tools/post-execute -> tool/result* step/end tools owe another request, or next-step input arrived -> claim -> next step -> agent/turn-stopping turn/end turn/* 、 step/* 、 user/message 、 assistant/* 和 tool/* 是持久会话事件;其余是分属三个事件域的实时扩展点。 agent/pre-step 、 agent/request 、 llm/stream 和三个 tools/* 事件是 waterfall(瀑布式事件),其监听器必须调用 next() 才能委托下去; agent/turn-stopping 是 serial 事件,没有 next() 。 输入通过同一个 inbox 到达驱动器。有些消息会立即唤醒它;注入的上下文会留在 inbox 中,直到另一条消息将其唤醒。 agent/pre-step 决定模型看到什么。监听器可以改写已领取的消息,也可以直接拒绝它们;首次领取被拒绝或被改写为空时,仍会关闭一个不含步骤的持久轮次,因此日志会记录这次尝试。enter 决策还可以设置 startsRequestSeries 来开启独立的模型消息序列:loop 会随之记录一个新的 request/header (原因为 series ,或在封装同时变化时为携带 startsSeries: true 的 change )。重建下游 enter 决策的监听器必须展开它( { ...decision, messages } ),该声明才能存活。每个步骤读取插件注册的提示词片段和工具 schema。 详情见 时序图 、 工具流水线 和 取消与错误恢复 。 会话日志 会话日志是模型所见上下文的来源。 deriveMessages() 从中投影出模型历史,原始 assistant/chunk 事件则保证回放和 UI 保真。fork、恢复、transcript(文本记录)、遥测和持久化都派生自该事件流。 模型可见即已记录。 抵达模型请求的一切都必须能从日志重建,并由一项运行时不变量断言这一点。因此,新增一项模型可见输入就需要新增一个会话事件:扩展 SessionEventMap 并从日志渲染。 投影 seam。 dsh-session-projection 提供 ctx.sessionProjections :已注册单元增量折叠已提交事件,host 消费方通过 stateOf() 读取单个类型化状态,载体通过 snapshot() 批量取得裁剪后的客户端视图。host 读取方要么在激活时要求该服务,要么在注册表或必需 key 缺席时明确失败。贡献方可以保留 ctx.inject(['sessionProjections'], ...) 注册,但不能为缺失的 host 值静默提供默认值。agent loop 为读取方注册共享的 turnBoundary 状态( 决策 )。 能力 seam 一个 seam 是一项可替换能力,包含三种角色:声明接口的 Service Definition 、实现它的 Service Provider ,以及使用它的 Consumer (通常是面向模型的工具)。一个包可以合并承担多个角色,但单一角色本身不是 seam;添加一项能力意味着把三者一并设计( 能力图 )。 seam 正是替换一个提供方就能改变整个产品的原因。文件系统与进程提供方共享同一个执行世界,因此把它们指向远程沙箱,也就把 Bash、PTY 和 LSP 一并搬了过去,无需提供方专用 fork。 subagent 提供方 在同一个接口之后同样千差万别,从新建一个子 agent,到把一个轮次委派给另一个产品。 实验性 Agent Teams 是 ctx.agentTeams 上的私有显式启用协作 seam,在可继续 subagent 之上提供持久 roster、任务板和 mailbox。 新行为的归属位置 新行为附加到已有文档记录的扩展点。改动循环本身时,本映射随之更新。 目标 机制 添加模型提供方 在 ctx.llm 上注册其适配器 添加面向模型的能力 在 ctx.tools 上注册;其 schema 加入提示词组装 让某个会话拥有不同的能力集合 组装一个 agent preset;其中的服务行需要 isolate realm 添加 shell 执行 注册 ctx.shell 后端;本地后端通过 ctx.subprocess spawn 进程 添加持久化终端执行 注册 ctx.terminals 后端和 dsh-tool-terminal 添加用户命令 在 ctx.commands 上注册;它无需模型轮次即可分派 添加后台工作 在 ctx.jobs 上注册; job_* 工具负责收集或停止 从外部 webhook 启动 Session 在 ctx.webhookRuntime 上注册可信规则,并挂载提供方适配器 添加文件系统访问或策略 注册 ctx.fs 提供方,或监听 fs/* 事件 限制所启动的进程 使用 ctx.sandbox 后端;消费方在启动进程前包装 argv 拦截请求、工具或轮次 使用相应的 agent/* 或 tools/* 事件; agent/turn-stopping 会停止轮次 添加模型可见上下文 调用 agent.inject() ;它会落到下一次获准的请求中 添加 UI 或编辑器集成 驱动 ctx.agents 并从 session/event 渲染 添加 Web Client Chat 节点 注册 ConversationNodeDefinition + keyed renderer 添加持久会话状态 扩展 SessionEventMap ;从日志渲染和回放 生成会话标题 注册唯一的 ctx.sessionTitle 提供方 管理同会话目标 使用 ctx.goals ;通过 agent/* 续跑 fork 活跃会话 ctx.sessions.fork(source, boundary?, childSessionId?) 将注册项限定到单个 agent 使用该 agent 的 agent.ctx 扩展实操手册 将功能映射到能力,并索引 包 、 工具 、 LLM(大语言模型)适配器 和 设置卡片 的分步指南。 Conversation 子系统 负责 Chat node 组装。 插件配置目录 English | 中文 每个 config: 块均可由 cordis.yml 条目设置:针对每个可加载的 harness 包,原样列出其 apply 函数或服务构造函数接收的配置声明(包括 JSDoc),并附上所有引用类型——包内类型直接粘贴,其他类型则提供链接。粘贴的内容是插件声明的完整配置类型——运行时 schema 有意排除的字段是仅供运行时使用的 seam(其自身的 JSDoc 会如此说明),不能通过 cordis.yml 设置。这是以 部署 为轴的参考文档——插件作者所依据的连接方式请参阅各 子系统页面 中的生成 cordis-surface 区域,面向模型的工具 schema 请参阅 工具目录 ,而 subsystems/ 则记录了这些声明所引用的类型。 英文源文件由源代码( scripts/gen-config-catalog.ts )生成,并通过 pnpm run verify-config-catalog ( doc-sync 的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。声明块使用 ts config-catalog 围栏(doc-typecheck 会跳过它,因为单独引用导入项的声明无法独立编译)。英文生成器还会将运行时 schemastery schema 与粘贴的声明进行交叉核对——每个经 schema 验证的键(包括嵌套键)都必须能在声明的配置类型中找到——因此,粘贴内容无法隐藏加载器接受的字段。 Requires: 行列出插件通过 inject 注入的服务键:其 cordis.yml 树还必须加载这些服务的提供者。范围限定为 harness 层级( packages/ );配置树还可能加载的 vendored cordis 插件( hmr 、控制台日志记录器等)固定为上游源代码(参见 vendoring policy ),未收录于此目录。 @deepseek-ai/dsh-acp 需要: agents · llm · sessionPersistence · sessions /** Plugin config: the provider/model selection used for each ACP-created agent. */ export interface AcpConfig { /** Provider route for created agents. */ provider?: string /** Model name for created agents. */ model?: string /** Maximum summaries returned by one session/list page. */ sessionListPageSize?: number /** Runtime-only transport override; production uses stdio. */ stream?: Stream } 依赖: Stream ( @agentclientprotocol/sdk ) 来源: packages/acp/acp/src/index.ts:75 @deepseek-ai/dsh-agent-default-model /** Composition entry for the default model selection. */ export interface Config { /** Registered provider route. */ provider: string /** Provider-owned model id. */ model: string } 来源: packages/core/agent-default-model/src/index.ts:41 @deepseek-ai/dsh-agent-instructions 需要: sessionProjections /** User-facing workspace instruction loader configuration. */ export interface Config { /** Harness home containing the fixed user-global `AGENTS.md`; defaults to `$DSH_HOME` or `~/.dsh`. */ dshHome?: string /** Directory entries that identify the project root while walking upward from the session cwd. */ projectRootMarkers?: string[] /** UTF-8 byte cap for one rendered baseline or dynamic batch; non-positive or non-finite disables loading. */ maxBytes: number /** Maximum UTF-8 bytes read from one instruction file; larger files are ignored. */ maxSourceBytes?: number /** * Ordered same-directory project candidates; every existing file loads, with * per-directory trimmed-content duplicates collapsed to the earliest candidate. */ instructionFileCandidates?: string[] /** * Ordered same-directory local-overlay candidates loaded after the base files * under the same per-directory trimmed-content dedup; empty disables the overlay. */ localInstructionFileCandidates?: string[] } 来源: packages/context/agent-instructions/src/config.ts:18 @deepseek-ai/dsh-agent-loop 需要: agents · sessions · llm · tools · systemPrompt · sessionProjections /** Agent-loop plugin configuration. */ export interface Config { /** * Maximum parallel-safe calls in flight per agent step. `1` is serial; * omission defaults to {@link DEFAULT_MAX_PARALLEL_TOOL_CALLS}. */ maxParallelToolCalls?: number /** Agents created or resumed at plugin startup. */ agents: (AgentOptions & { /** Stable config label used in logs and as the fresh combined-id prefix. */ id: string /** Optional stable identity; remounts resume its materialized history, while first use creates it fresh. */ sessionId?: SessionId /** Optional workspace for a fresh session. */ cwd?: string /** Persisted session to resume instead of creating a fresh session. */ resumeSessionId?: SessionId })[] } 依赖: AgentOptions · SessionId 来源: packages/core/agent-loop/src/index.ts:311 @deepseek-ai/dsh-agent-presets 需要: loader · sessionProjections /** Plugin config: which preset is the default, and where presets live. */ export interface Config { /** Preset id mounted when a caller names none. Missing at mount time fails loud. */ default: string /** Scanned roots in precedence order; an earlier root wins a duplicate id. */ roots: PresetRoot[] /** * Prepend this package's bundled shipped presets as a `system` root, before * every configured root, so the shipped set always mounts and wins a * duplicate id. The default survives a whole-`config` patch replacement; * only an explicit `false` — a deployment supplying purely its own presets, * or an embedder using the roster as bare machinery — drops the set. */ includeShippedRoot: boolean /** * Append the harness home's `USER_PRESET_DIR` as a `user` root, after every * configured root. False mounts a roster without the derived writable root. */ includeUserRoot: boolean } /** One directory scanned for preset subdirectories. */ export interface PresetRoot { /** Directory holding one subdirectory per preset; a leading `~` expands. */ path: string /** Trust recorded on every preset discovered under this root. */ trust: PresetTrust } /** * Where a preset's composition came from. A `system` preset ships with the * deployment; a `user` preset was authored locally, by a person or by an * agent, and therefore carries the same trust as shell access. */ export type PresetTrust = 'system' | 'user' 来源: packages/preset/agent-presets/src/preset.ts:52 @deepseek-ai/dsh-agent-tool-presentation 需要: tools /** Plugin config. */ export interface Config { /** * The form this agent's model sees. `native` sends every visible schema, * `ptc` sends only `run_code` plus a generated SDK, `both` sends both. * Required rather than defaulted: the deployment default is what a preset * without this row already gets, so an omitted value would mean the row was * composed for nothing. */ mode: ToolPresentationMode } 依赖: ToolPresentationMode 来源: packages/core/agent-tool-presentation/src/index.ts:38 @deepseek-ai/dsh-api-gateway 需要: typert /** Gateway transport configuration. */ export interface Config { /** WebSocket Ping interval from 1 through 2,147,483,647 milliseconds. @default 2000 */ readonly websocketHeartbeatIntervalMs?: number } 来源: packages/api/gateway/src/index.ts:119 @deepseek-ai/dsh-api-session-controller 需要: agentDefaultModel · agents · attachments · llm · sessions · sessionProjections · sessionQuery · typert · workspaceRegistry /** Session Controller deployment policy. */ export interface Config { /** Maximum cold Session artifact size eligible for one full projection observation. */ readonly coldBlankProbeMaxBytes?: number /** Override platform desktop-opener detection. */ readonly nativeOpen?: boolean } 来源: packages/api/session-controller/src/index.ts:68 @deepseek-ai/dsh-api-settings-controller /** Native document-opening policy. */ export interface Config { /** Override platform desktop-opener detection. */ readonly nativeOpen?: boolean } 来源: packages/api/settings-controller/src/index.ts:36 @deepseek-ai/dsh-attachment-local /** Local attachment backend configuration. */ export interface Config { /** Explicit harness home; omitted follows `DSH_HOME`, then `~/.dsh`. */ dshHome?: string /** Maximum encoded bytes accepted for one submitted image. Default: 20 MiB. */ maxImageBytes?: number /** Maximum image count accepted in one submitted message. Default: 20. */ maxImagesPerMessage?: number /** Maximum aggregate encoded image bytes accepted in one submitted message. Default: 200 MiB. */ maxMessageImageBytes?: number /** Maximum intrinsic width multiplied by height accepted for one submitted image. Default: 64,000,000. */ maxImagePixels?: number /** Maximum intrinsic width and maximum intrinsic height accepted for one submitted image. Default: 8192px. */ maxImageDimension?: number /** Total-pixel budget of the stored provider-independent normalized image. */ normalizedImageMaxPixels?: number /** Long-edge pixel cap of the stored provider-independent normalized image, applied after the total-pixel budget. */ normalizedImageMaxDimension?: number /** * Encoded-byte target of the stored provider-independent normalized image; * the smallest quality-ladder output is kept when no quality fits. */ normalizedImageMaxBytes?: number /** Maximum simultaneous normalization or request-image transformations in this service instance. */ imageCompressionConcurrency?: number } 来源: packages/attachment/attachment-local/src/index.ts:55 @deepseek-ai/dsh-bash-local 需要: subprocess /** Plugin config (all optional — `static Config` supplies the defaults). */ export interface Config { /** Default working directory for commands (default: process.cwd()). */ cwd?: string /** Default foreground timeout in milliseconds. */ timeoutMs?: number /** Upper bound for per-call timeout overrides. */ maxTimeoutMs?: number /** Per-stream in-memory output cap; overflow spills to a temp file. */ maxOutputBytes?: number /** Per-stream spill-file cap; larger streams retain only their in-memory tail. */ maxSpillBytes?: number /** Grace period for kill escalation and inherited pipes; at most `MAX_TIMER_DELAY_MS`. */ graceMs?: number } 来源: packages/shell/bash-local/src/index.ts:41 @deepseek-ai/dsh-bash-sandbox 需要: subprocess · sandbox · sandboxPolicy /** * Plugin config: the local executor's knobs, verbatim. The sandbox policy — * the default mode and fallback `workspace-write` root — is NOT here: it lives * on `ctx.sandboxPolicy` (`@deepseek-ai/dsh-sandbox-policy`), which resolves * each calling session's mode and cwd for every enforcing capability. The runner * choice is likewise the `ctx.sandbox` provider's config, not this executor's. */ export type Config = LocalConfig 依赖: LocalConfig 来源: packages/shell/bash-sandbox/src/index.ts:35 @deepseek-ai/dsh-client-connection 需要: webServer · credentials /** Plugin config: the deployment's non-loopback serving authorities. */ export interface ConnectionConfig { /** * Authorities this deployment serves beyond loopback: exact `host:port`, or * port-less `host` matching any port. The /api trust fence refuses any * request whose Host is neither loopback nor listed here, so a * non-loopback (`0.0.0.0`) deployment must declare the names it is reached * by; the Web runtime derives LAN IP literals from an active all-interface * bind. An entry that is not a bare, canonical authority fails plugin load. */ trustedHosts?: string[] /** Absolute browser-session lifetime in days. Default: 30. */ cookieMaxAgeDays?: number /** Maximum buffered JSON body for every `/api` request. Default: 300 MiB. */ maxRequestBodyBytes?: number } 来源: packages/client/connection/src/index.ts:55 @deepseek-ai/dsh-client-hmr 需要: clientModules · webServer /** Plugin config, validated by the same-named schemastery schema. */ export interface Config { /** Bundle stat-poll interval in milliseconds (default 500, the build-side watcher's polling default). */ pollIntervalMs?: number } 来源: packages/client/hmr/src/index.ts:31 @deepseek-ai/dsh-code-runtime-worker-thread /** Plugin config: every execution cap, changeable from `cordis.yml` (no hardcoded tunables). */ export interface Config { /** * Busy-time budget in milliseconds: the run fails with kind `'timeout'` * once the worker's MEASURED event-loop active time * (`worker.performance.eventLoopUtilization()`) exceeds this. Metering * measured busy time — not wall time, not host-side pending-call * bookkeeping — is what makes the budget both fair (a program awaiting a * slow tool accrues nothing) and ungameable (a hot loop accrues whether * or not a decoy dispatch is in flight). */ computeMs?: number /** * Wall-clock ceiling in milliseconds; never pauses for anything. The * backstop for what busy-time cannot see (a program awaiting a promise * nobody will resolve). At most `2_147_483_647` (Node's maximum * `setTimeout` delay, about 24.9 days): a longer value is rejected at load * because `setTimeout` would clamp it to 1 ms. */ maxWallMs?: number /** * Hard cap for serialized log-array, completion-value, and failure-message payloads; * fixed result-envelope syntax is excluded. */ maxOutputBytes?: number /** The worker's max old-generation heap in MiB (`resourceLimits`); overflow kills the worker, surfacing as kind `'worker-exit'`. */ maxOldGenerationSizeMb?: number } 来源: packages/code-runtime/code-runtime-worker-thread/src/index.ts:25 @deepseek-ai/dsh-compaction-basic 需要: llm · tokenMeter · sessions /** Basic compaction configuration with an optional exact-target policy table. */ export interface BasicCompactionConfig extends CompactionPolicyConfig { /** Exact provider/model overrides; duplicate targets fail plugin load. */ modelPolicies?: ModelCompactPolicyConfig[] /** Enable automatic step-boundary pressure and overflow-recovery listeners. Defaults to `true`. */ auto?: boolean } /** Policy fields shared by the default policy and exact model overrides. */ export interface CompactionPolicyConfig { /** Compact at this fraction of the model's context window. Defaults to `0.8`. */ thresholdRatio?: number /** Recent context retained as a fraction of the model's window. Defaults to `0.16`. */ retainRatio?: number /** Absolute recent-context budget; mutually exclusive with `retainRatio`. */ retainTokens?: number /** Summary provider; set together with `summarizationModel`, or inherit the conversation target. */ summarizationProvider?: string /** Summary model; set together with `summarizationProvider`, or inherit the conversation target. */ summarizationModel?: string /** Provider generation cap for summarization. Defaults to `8192`. */ maxTokens?: number /** Extra attempts after the first compaction when pressure remains above threshold. Defaults to `1`. */ compactionRetries?: number /** Maximum retries after canonical context overflow; `0` disables recovery. Defaults to `1`. */ maxOverflowRetries?: number } /** Exact provider/model override merged over the default compaction policy. */ export interface ModelCompactPolicyConfig extends CompactionPolicyConfig { /** Registered provider route to match. */ provider: string /** Exact routed model id to match within `provider`. */ model: string } 来源: packages/compaction/compaction-basic/src/types.ts:38 @deepseek-ai/dsh-compaction-tool-result-pruner 需要: tokenMeter /** Character-budget policy for deterministic tool-result pruning. */ export interface ToolResultPruneConfig { /** Prune when total text exceeds this many Unicode code points. Defaults to `8192`. */ thresholdChars?: number /** Maximum leading Unicode code points retained. Defaults to `4096`. */ headChars?: number /** Maximum trailing Unicode code points retained. Defaults to `1024`. */ tailChars?: number } 来源: packages/compaction/compaction-tool-result-pruner/src/types.ts:5 @deepseek-ai/dsh-cordis-host-runner 需要: tools /** Runner configuration. */ export interface Config { /** Maximum synchronous VM evaluation time in milliseconds. */ vmTimeoutMs?: number } 来源: packages/extensions/cordis-host-runner/src/index.ts:88 @deepseek-ai/dsh-credentials-local /** Plugin config: file location and hot-reload behavior. */ export interface Config { /** Credentials document path; defaults to `.credentials.yaml` under the harness home. */ path?: string /** Harness home used when `path` is omitted; defaults to `$DSH_HOME` or `~/.dsh`. */ dshHome?: string /** Watch the document and hot-publish external edits; defaults to true. */ watch?: boolean /** Watcher write-settle window in milliseconds; defaults to 100. */ debounceMs?: number } 来源: packages/credentials/credentials-local/src/index.ts:64 @deepseek-ai/dsh-e2b /** Configuration for the shared E2B sandbox owner. */ export interface Config { /** API key; omission reads `E2B_API_KEY`. It is never forwarded into the sandbox. */ apiKey?: string /** Shared remote working directory, created before adapters receive the sandbox. */ cwd?: string /** E2B sandbox lifetime in milliseconds; expiry always deletes the sandbox. */ timeoutMs?: number } 来源: packages/e2b/e2b/src/index.ts:43 @deepseek-ai/dsh-experimental-agent-team 需要: agents · sessions · sessionPersistence · sessionProjections · subagents /** Team-service deployment limits. */ export interface Config { /** Maximum immutable teammate names retained by one Team. */ readonly maxMembers?: number /** Maximum non-deleted tasks retained by one Team. */ readonly maxTasks?: number /** Maximum queued-minus-delivered messages for one target member. */ readonly maxPendingMessagesPerMember?: number /** Maximum UTF-8 bytes in one complete sender-framed delivery. */ readonly maxMessageBytes?: number /** Maximum milliseconds allowed for Team-owned runtime disposal. */ readonly disposalTimeoutMs?: number } 来源: packages/experimental/agent-team/src/types.ts:125 @deepseek-ai/dsh-experimental-code-runtime-python /** Plugin config: every cap, changeable from `cordis.yml` (no hardcoded tunables). */ export interface Config { /** * RLIMIT_CPU in whole seconds (a positive integer — `setrlimit` in the child * rejects a float). The child sets the soft limit to `cpuSeconds` and the * hard limit to `cpuSeconds + 1`: the kernel delivers SIGXCPU at the soft * limit, which the host classifies as a `timeout`; the +1s hard limit is a * SIGKILL backstop for a program that traps SIGXCPU. Granularity is seconds — * a coarser counterpart to the worker backend's millisecond `computeMs`. */ cpuSeconds?: number /** Wall-clock ceiling in milliseconds; backstops CPU time for programs awaiting a promise nobody resolves. */ maxWallMs?: number /** * RLIMIT_AS in mebibytes; caps address space so a runaway allocation fails * cleanly. Not applied on Darwin, where the dyld shared cache mapped into * every process at exec exceeds any practical cap and the kernel rejects * the call; `cpuSeconds` and `maxWallMs` still bound the run there. Bounds * `maxLogBytes`/`maxValueBytes` at load on EVERY platform (this static check * runs on Darwin too, where only the runtime `setrlimit` is skipped): each * budget times a worst-case Unicode expansion must fit this byte count minus a * fixed interpreter baseline, so a near-budget output cannot breach the address * space during the child's build-and-encode. */ addressSpaceMb?: number /** * Shared byte budget for captured log text (host-side ledger). Bounded at load * against `addressSpaceMb`: the child builds and encodes a near-budget entry * under RLIMIT_AS with several copies live at once, so this cap times the * worst-case Unicode expansion must fit the address space left after the * interpreter baseline (see `addressSpaceMb`) — a load-time rejection, not a * runtime clamp. Also bounded at load by the host's configured heap like * `maxValueBytes` (see its JSDoc): the effective frame cap minus the frame * envelope. */ maxLogBytes?: number /** * Byte cap for the completion value. Bounded at load against `addressSpaceMb` * the same way `maxLogBytes` is: the child builds and encodes a near-budget * value under RLIMIT_AS with several copies live at once, so this cap times the * worst-case Unicode expansion must fit the address space left after the * interpreter baseline. Both budgets are ALSO bounded at load by the host's * configured heap: the effective frame cap (the protocol cap, or a lower * heap-derived ceiling when the host heap cannot safely parse a near-cap * frame — see `hostFrameParseCeiling`) minus the frame envelope, so a budget * whose honest frame could OOM the host's own JSON.parse is rejected up * front. */ maxValueBytes?: number /** SIGTERM→SIGKILL grace period on kill, matching bash-local's default. */ graceMs?: number /** * Absolute path, relative path, or basename of a CPython 3.10+ interpreter. * Resolved and validated once at plugin load under a five-second force-kill * deadline; a basename searches `PATH`. */ pythonBin?: string } 来源: packages/experimental/code-runtime-python/src/index.ts:42 @deepseek-ai/dsh-experimental-inspector 需要: webServer /** Host plugin configuration. Fetch capture is enabled by default. */ export interface Config extends Omit { /** Browser origins allowed to open the Client ingest WebSocket. */ clientOrigins?: string[] } /** User-facing Host options; every memory and lifecycle bound is configurable. */ export interface InspectorOptions { /** Loopback address used by the Worker HTTP and WebSocket endpoint. */ readonly host?: '127.0.0.1' /** First port to bind; occupied ports advance until one is available. */ readonly port?: number /** Additional exact browser origins admitted to the Client ingest socket. */ readonly clientOrigins?: readonly string[] /** Whether to observe calls made through the current global fetch function. */ readonly captureFetch?: boolean /** Maximum request-body prefix retained for one fetch. */ readonly maxRequestBodyBytes?: number /** Maximum response-body prefix retained for one fetch. */ readonly maxResponseBodyBytes?: number /** Maximum raw bytes encoded into one body observation. */ readonly maxBodyChunkBytes?: number /** Maximum total request and response body bytes retained by the Worker. */ readonly maxJournalBytes?: number /** Maximum active and completed fetch requests retained by the Worker. */ readonly maxRetainedRequests?: number /** Maximum encoded bytes accepted in one source transport frame. */ readonly maxSourceFrameBytes?: number /** Maximum observation records accepted in one source batch. */ readonly maxSourceRecordsPerFrame?: number /** Maximum records waiting in one producer queue. */ readonly maxQueuedRecords?: number /** Maximum encoded bytes waiting in one producer queue. */ readonly maxQueuedBytes?: number /** Maximum time allowed for the Worker to become ready. */ readonly startupTimeoutMs?: number /** Grace period before a stopping Worker is terminated. */ readonly stopTimeoutMs?: number /** Initial upper bound for randomized Client reconnect delay. */ readonly clientReconnectBaseMs?: number /** Maximum upper bound for randomized Client reconnect delay. */ readonly clientReconnectMaxMs?: number /** Deadline for one Worker-to-Client Runtime or Sources request. */ readonly clientRuntimeTimeoutMs?: number /** Deadline for one non-CDP semantic query. */ readonly queryTimeoutMs?: number /** Maximum live object handles retained per Client Runtime session. */ readonly maxClientRuntimeObjects?: number /** Maximum descriptors returned by one Client property request. */ readonly maxClientRuntimeProperties?: number /** Maximum encoded bytes read for one Client script or source map. */ readonly maxClientSourceBytes?: number /** Maximum Context and Fiber nodes retained in one realm snapshot. */ readonly maxCordisNodes?: number /** Disconnected Cordis snapshots retained after their live realm closes. */ readonly maxDisconnectedCordisTrees?: number } 来源: packages/experimental/inspector/src/index.ts:66 @deepseek-ai/dsh-experimental-tool-agent-team 需要: agents · agentTeams · tools · systemPrompt /** Tool routing configuration. */ export interface Config { /** Continuable-subagent provider used for fresh teammates. */ readonly freshProvider?: string /** Continuable-subagent provider used for completed-prefix fork teammates. */ readonly forkProvider?: string } 来源: packages/experimental/tool-agent-team/src/index.ts:17 @deepseek-ai/dsh-file-reference-local 需要: agents · sessionProjections /** Local file-reference discovery configuration. */ export interface Config { /** Maximum ranked candidates returned for one query. */ maxResults?: number /** Maximum indexed files and directories per agent workspace. */ maxEntries?: number /** Directory basenames never traversed or offered. */ excludedDirectories?: string[] } 来源: packages/context/file-reference-local/src/index.ts:34 @deepseek-ai/dsh-fs-local /** Configuration for the local filesystem backend. */ export interface Config { /** Base directory for relative paths. Defaults to `process.cwd()`. */ cwd?: string /** * Exclusive UTF-8 byte limit on each overwrite-diff side, capped by the * runtime's safe allocation/decode maximum. Defaults to 10 MiB. */ diffBasisMaxBytes?: number } 来源: packages/fs/fs-local/src/index.ts:41 @deepseek-ai/dsh-fs-sandbox 需要: sandboxPolicy /** * Plugin config: the local backend's knobs verbatim (`cwd` resolution default * and `diffBasisMaxBytes` overwrite-presentation bound). The sandbox default * (mode + `workspace-write` fallback root) is NOT here — `ctx.sandboxPolicy` * resolves each calling session for every enforcing capability. */ export type Config = LocalConfig 依赖: LocalConfig 来源: packages/fs/fs-sandbox/src/index.ts:45 @deepseek-ai/dsh-goal 需要: agents · sessionProjections /** Deployment defaults for goal creation. */ export interface Config { /** Total rounds used when a create request omits its own cap. */ defaultMaxGoalRounds?: number } 来源: packages/goal/goal/src/index.ts:172 @deepseek-ai/dsh-headless 需要: agentDefaultModel · agents · sessions /** Plugin config: the task resolved from this app's injected provider service. */ export interface Config { /** The prompt text for the single run. */ task: string } 来源: packages/bundle/headless/src/index.ts:33 @deepseek-ai/dsh-hooks-claude-code 需要: shell · sessionProjections /** Plugin config: where the CC hook config lives + substitution roots. */ export interface Config { /** * Path to a `hooks.json` or a settings file whose `hooks` key holds the config. * Process-level: read once at load, a relative path resolves against the process * launch cwd, so one config applies to the whole process. * TODO(per-session-hook-config): per-session discovery of a project-local * `hooks.json` from each `session/new.cwd`. */ configPath: string /** * Replaces `${CLAUDE_PLUGIN_ROOT}` in command strings (the plugin's root dir). */ pluginRoot?: string /** * Replaces `${CLAUDE_PROJECT_DIR}` in command strings AND is exported as the * `CLAUDE_PROJECT_DIR` env var for hook processes. When omitted, the env var * defaults per-run to the agent's session workspace (`session.header.cwd`, the * same dir the hook runs in) — Claude Code always exports this var, and common * unmodified hooks reference `$CLAUDE_PROJECT_DIR` for project-relative paths. */ projectDir?: string /** Default per-hook timeout in ms when a hook sets none (CC default: 600000). */ defaultTimeoutMs?: number /** Character cap for the `hook/result` event's persisted stderr summary. */ stderrSummaryMaxChars?: number } 来源: packages/hooks/hooks-claude-code/src/index.ts:46 @deepseek-ai/dsh-hooks-codex 需要: shell · sessionProjections /** Plugin config: where the Codex hooks.json lives + the model name for payloads. */ export interface Config { /** * Path to a Codex `hooks.json`. Process-level: read once at load, a relative * path resolves against the process launch cwd. * TODO(per-session-hook-config): per-session project-local discovery from each * `session/new.cwd`. */ configPath: string /** The model name stamped on every payload (Codex includes `model` on each event). */ model?: string /** Default per-hook timeout in ms when a hook sets none (Codex default: 600000). */ defaultTimeoutMs?: number /** Character cap for the `hook/result` event's persisted stderr summary. */ stderrSummaryMaxChars?: number } 来源: packages/hooks/hooks-codex/src/index.ts:45 @deepseek-ai/dsh-host-directory-picker-browse /** Validated plugin configuration. */ export interface Config { /** Complete-result bound of one listing level; see {@link BrowseDirectoryPicker.Config}. */ maxEntries: number } 来源: packages/host/directory-picker-browse/src/index.ts:181 @deepseek-ai/dsh-host-frontend-static 需要: webServer · connection /** Plugin config: the dist anchor. */ export interface Config { /** Absolute path of index.html inside the dist root. */ distIndex: string } 来源: packages/host/frontend-static/src/index.ts:30 @deepseek-ai/dsh-host-webserver /** Web server listen and response-compression config. */ export interface Config { /** Listen host; the two supported values are loopback and all-interfaces. */ host: '127.0.0.1' | '0.0.0.0' /** Listen port; zero requests an OS-assigned port. */ port: number /** Response compression for socket-backed HTTP requests. @default 'none' */ compression?: 'none' | 'gzip' /** Gzip DEFLATE level from 0 through 9. @default 1 */ compressionLevel?: number /** Minimum known response length eligible for gzip; unknown-length streams are eligible. @default 1024 */ compressionThresholdBytes?: number } 来源: packages/host/webserver/src/index.ts:59 @deepseek-ai/dsh-invariants /** Runtime invariant selection configured on the service plugin. */ export interface Config { /** Global switch; defaults to `true`. */ readonly enabled?: boolean /** Case-sensitive JavaScript regex sources that admit package names; empty admits all. */ readonly package_allowlist?: string[] /** Case-sensitive JavaScript regex sources that exclude package names after allowlist matching. */ readonly package_blocklist?: string[] } 来源: packages/runtime-diagnostics/invariants/src/index.ts:15 @deepseek-ai/dsh-jobs-local /** Configuration for the process-local job registry. */ export interface Config { /** * Maximum `running` plus `stopping` jobs per exact owner or in the shared unowned bucket; * omission defaults to 10. */ maxConcurrentJobsPerOwner?: number } 来源: packages/jobs/jobs-local/src/index.ts:31 @deepseek-ai/dsh-llm-deepseek 需要: llm /** * Plugin config, validated by the same-named schemastery schema and doubling * as the `llm-deepseek` settings-section shape. Every field is optional in * yml: a missing API key resolves through {@link Config.apiKeyEnv} at each * request (a request without any key fails with `MISSING_CREDENTIAL`, not at * plugin load), omitted thinking mode uses the provider default, and omitted * reasoning effort resolves to `high`. */ export interface Config { /** Credential reference (environment-variable name) resolved per request; defaults to `DEEPSEEK_API_KEY`. */ apiKeyEnv?: string /** Endpoint base; falls back to $DEEPSEEK_BASE_URL from a trusted environment layer, then the public API. */ baseURL?: string /** Deployment thinking policy; `disabled` limits every conversation request to `off`. */ thinking?: 'enabled' | 'disabled' /** Default thinking effort (default `high`); `off` disables thinking per request. */ reasoningEffort?: 'off' | 'low' | 'high' | 'max' /** Default per-request output cap (default 256,000); a model's own cap and explicit request values win. */ maxTokens?: number /** Positive context capacity used when the selected model has no exact value (default 1,000,000). */ defaultContextWindow?: number /** Advisory models shown by discovery consumers; defaults to V4 Flash, V4 Pro, and V4 Flash Vision Exp. */ models?: DeepSeekCatalogModel[] /** Maximum provider idle time while one stream read is outstanding (default five minutes). */ streamIdleTimeoutMs?: number /** Maximum accumulated file-referenced image bytes per chat request (default 128 MiB). */ maxRequestFilesBytes?: number /** Maximum accumulated base64 image payload after Files API fallback (default 20 MiB). */ maxInlineRequestImageBytes?: number /** Maximum number of represented images per chat request (default 600). */ maxImagesPerRequest?: number /** Raw-byte removal step after the request exceeds its file bound (default 64 MiB). */ imageOffloadByteQuantum?: number /** Base64-byte removal step after inline fallback exceeds its bound (default 10 MiB). */ inlineImageOffloadByteQuantum?: number /** Image-count removal step after the request exceeds its count bound (default 20). */ imageOffloadCountQuantum?: number /** Maximum duration of one request-image Files API resolution (default one minute). */ filesApiTimeoutMs?: number /** Explicit lifetime assigned to each uploaded image (default seven days). */ fileExpiresAfterSeconds?: number /** Remaining lifetime below which an indexed file is replaced (default one hour). */ fileRefreshMarginSeconds?: number /** Oldest harness-owned files deleted before one quota-recovery upload retry (default 100). */ fileQuotaCleanupBatch?: number /** Provider-owned model-request retry policy; omission uses normal mode with five retries. */ retryPolicy?: RetryPolicyConfig } /** One optional model entry advertised by the direct-fetch adapter. */ export interface DeepSeekCatalogModel { /** Wire model id accepted by the configured endpoint. */ id: string /** Selector label; defaults to {@link id}. */ name?: string /** Optional selector detail for deployments with similar model variants. */ description?: string /** Known combined request/response context capacity; omitted when deployment metadata is unavailable. */ contextWindow?: number /** Per-request output cap for this model; omission falls back to the profile's {@link DeepSeekConnectionOptions.maxTokens}. */ maxTokens?: number /** Accepted request modalities; omission is text-only. */ inputModalities?: ModelModality[] /** Total-pixel budget for one deterministic request preview, or the 512-by-512 `low` preset. */ imagePixelBudget?: number | 'low' /** Encoded-byte target for one deterministic request preview; the smallest quality-ladder output is used when no quality fits. */ imageMaxBytes?: number } 依赖: ModelModality · RetryPolicyConfig 来源: packages/llm/llm-deepseek/src/index.ts:125 @deepseek-ai/dsh-llm-pi-ai 需要: llm /** Plugin configuration: the provider routes this instance owns. */ export interface Config { /** * pi-ai provider routes, keyed by provider. An empty (or omitted) dict is * the dormant settings-driven posture: the adapter mounts with no routes * and registers them the moment a settings section supplies profiles. */ providers?: Record } /** Configuration for one pi-ai provider route; the `providers` dict key IS the route. */ export interface PiAiProviderProfile { /** Credential reference (environment-variable name) resolved per request through `ctx.credentials`. */ apiKeyEnv?: string /** Name shown by configuration surfaces; defaults to the route key. */ displayName?: string /** * Wire protocol every model on this route speaks. Omission keeps each * installed catalog model's own protocol, which is why a catalog route needs * no protocol at all; a route the catalog does not ship must name one. */ api?: string /** Endpoint for this route's models; defaults to the installed catalog's endpoint. */ baseURL?: string /** * This route's model catalog. Omission serves the installed catalog for the * route unchanged; an explicit list replaces it, each entry defaulting its * unset fields from the installed model of the same id. */ models?: PiAiModelProfile[] /** * Installed-catalog customizations by model id: each entry reshapes that * one model with the same fields a {@link models} entry takes, while the * rest of the catalog keeps serving untouched. Only meaningful on a catalog * route with no `models` list — `models` already replaces the catalog, so * an override beside it, on a route the catalog does not ship, or naming a * model the catalog does not describe is refused rather than skipped. */ modelOverrides?: Record /** * pi-ai wire-compatibility switches defaulting every model on this route * whose protocol declares them; each model's own `compat` overrides per * field. What neither sets keeps the installed catalog entry's value, then * pi-ai's own detection. A switch no model on the route could read is * refused rather than left looking applied. */ compat?: PiAiCompatProfile /** * Context capacity for a model this route lists that neither the entry nor * the installed catalog sizes (default 262,144). A guess by construction, so * a deployment whose gateway serves smaller models corrects it here. */ defaultContextWindow?: number /** * Output capability for a model this route lists that neither the entry nor * the installed catalog sizes (default 32,768). This sizes the model; it * never becomes a per-request cap on its own. */ defaultMaxTokens?: number /** * Request modalities for a model this route lists that neither its entry's * {@link PiAiModelProfile.input} nor the installed catalog declares (default * `[text]`). A fallback like the capacities above, not an override: a * catalog model keeps the modalities the catalog records for it, and this * value never narrows one. A gateway serving vision models the catalog does * not describe declares `[text, image]` once here instead of on every entry. * Unlike an entry's list, this one may not be empty — nothing sits below it * to answer instead. */ defaultInput?: PiAiModality[] /** Provider request headers, validated against Fetch when the profile resolves; Harness attribution wins reserved names. */ headers?: Record /** Provider-neutral pi-ai reasoning level. */ reasoning?: ModelThinkingLevel /** Token budgets used by reasoning providers that support them. */ thinkingBudgets?: ThinkingBudgets /** Prompt-cache retention preference. */ cacheRetention?: CacheRetention /** Streaming transport preference. */ transport?: Transport /** HTTP/provider SDK timeout in milliseconds. */ timeoutMs?: number /** WebSocket connection timeout in milliseconds. */ websocketConnectTimeoutMs?: number /** Maximum provider idle time while one stream read is outstanding. */ streamIdleTimeoutMs?: number /** * Maximum base64-encoded image payload per request. When a request's * accumulated images exceed it, the oldest images are replaced by text * placeholders until the request fits, so a long session keeps completing * requests instead of being rejected by a request-size cap. */ maxRequestImageBytes?: number /** Total-pixel budget for each deterministic inline request version. */ requestImagePixelBudget?: number /** * Raw encoded-byte target for each deterministic inline request version; * the smallest quality-ladder output is used when no quality fits. */ requestImageMaxBytes?: number /** Provider-owned model-request retry policy; omission uses normal mode with five retries. */ retryPolicy?: RetryPolicyConfig } /** One configured model entry: an id plus the catalog fields it overrides. */ export interface PiAiModelProfile { /** Model id sent to the provider and accepted by {@link GenerateOptions.model}. */ id: string /** Display name for selectors; defaults to the catalog name, then the id. */ name?: string /** Maximum combined request and response context in tokens. */ contextWindow?: number /** * Maximum output tokens. Configuring one also makes it this model's * per-request default; a value inherited from the installed catalog, or the * route's fallback, is the model's capability and never becomes a request * default on its own. */ maxTokens?: number /** * Request modalities this model accepts. Absent — or empty, which describes * a model that accepts nothing and so states no answer either — keeps the * installed catalog entry's modalities, then the route's `defaultInput`. * Declaring images is what makes a hand-declared vision model usable, and * declaring text alone corrects a catalog model whose gateway does not serve * what the catalog records. This is a claim about the endpoint, not a check * of it: nothing interrogates a gateway for what it accepts, so a model * claiming images its endpoint refuses is refused by the provider instead, * mid-turn. */ input?: PiAiModality[] /** * Selectable reasoning efforts. Absent inherits the installed catalog * entry's capability (a hand-declared model has none and does not reason); * `false` declares a non-reasoning model, which is how a profile strips * reasoning from a catalog model its gateway cannot serve; a non-empty dict * declares the offered levels and their wire spellings. */ reasoningEfforts?: false | PiAiReasoningEfforts /** pi-ai wire-compatibility switches for this model, winning over the route's per field; one its protocol does not declare is refused. */ compat?: PiAiCompatProfile } /** * Customization of one installed catalog model, keyed by its id in the * route's `modelOverrides` dict — the same fields a `models` entry may set, * with the id living in the key. Unlike a `models` list, overrides leave the * rest of the catalog serving untouched, which is what makes "correct one * model, keep the other thirty-seven" a three-line edit. */ export type PiAiModelOverride = Omit /** * pi-ai wire-compatibility switches, set on the route (its models' default) or * per model (winning over the route, field by field). * * pi-ai decides each of these from the provider id and baseURL when no layer * sets it, and a private gateway's URL says nothing: for an endpoint it does * not recognize the detection answers as though it were OpenAI itself, which * is wrong for most OpenAI-compatible gateways. So every field here is one a * deployment must be able to state because nothing can infer it, while the * fields pi-ai's catalog sets for a named vendor stay withheld. * * A field belongs to the protocols whose upstream compat type declares it: a * model-level switch its protocol does not take fails resolution, and a * route-level one skips past models it cannot fit. "The three Responses * protocols" below means `openai-responses`, `azure-openai-responses`, and * `openai-codex-responses`, which pi-ai gives one shared compat type, so a * switch settable on one is settable on all three. */ export interface PiAiCompatProfile { /** Whether the endpoint accepts `store`; `openai-completions`. */ supportsStore?: boolean /** * Whether the endpoint accepts the `developer` role for the system prompt, * which pi-ai sends only to a reasoning model; `false` keeps `system`. * `openai-completions` and the three Responses protocols. */ supportsDeveloperRole?: boolean /** Whether the endpoint accepts `reasoning_effort`; `openai-completions`. */ supportsReasoningEffort?: boolean /** Whether the endpoint accepts `stream_options: {include_usage: true}`; `openai-completions`. */ supportsUsageInStreaming?: boolean /** * Whether streams include `finish_reason`; `false` lets pi-ai infer the * terminal reason when the stream ends; `openai-completions`. */ supportsFinishReason?: boolean /** Which output-cap field the endpoint reads; `openai-completions`. */ maxTokensField?: NonNullable /** Whether tool results must carry `name`; `openai-completions`. */ requiresToolResultName?: boolean /** Whether a user message after tool results needs an assistant message between; `openai-completions`. */ requiresAssistantAfterToolResult?: boolean /** Whether thinking blocks must travel as text in `` delimiters; `openai-completions`. */ requiresThinkingAsText?: boolean /** Whether replayed assistant messages need an empty `reasoning_content` while reasoning is on; `openai-completions`. */ requiresReasoningContentOnAssistantMessages?: boolean /** Reasoning parameter format the endpoint expects; `openai-completions`. */ thinkingFormat?: PiAiThinkingFormat /** * Kwargs sent as `chat_template_kwargs`, which pi-ai reads only under the * two `chat-template` thinking formats; `openai-completions`. Nothing checks * that pairing: the format in force may come from the installed catalog * entry or from pi-ai's own baseURL detection, neither of which resolution * can read, so kwargs set beside another format are sent nowhere. */ chatTemplateKwargs?: NonNullable /** Arguments sent as `chat_template_args` under the `baseten` thinking format; `openai-completions`. */ chatTemplateArgs?: NonNullable /** Whether the endpoint accepts `thinking_token_budget` to cap vLLM reasoning; `openai-completions`. */ supportsThinkingTokenBudget?: boolean /** * Whether the endpoint accepts `strict` in tool definitions; * `openai-completions`, the three Responses protocols, `bedrock-converse-stream`. */ supportsStrictMode?: boolean /** Prompt-cache marker convention; `openai-completions`. */ cacheControlFormat?: NonNullable /** * Whether the endpoint accepts long prompt-cache retention; * `openai-completions`, the three Responses protocols, `anthropic-messages`. */ supportsLongCacheRetention?: boolean /** Whether the endpoint accepts per-tool `eager_input_streaming`; `anthropic-messages`. */ supportsEagerToolInputStreaming?: boolean /** Whether the endpoint accepts `cache_control` on tool definitions; `anthropic-messages`. */ supportsCacheControlOnTools?: boolean /** Whether the endpoint accepts the `temperature` request field; `anthropic-messages`. */ supportsTemperature?: boolean /** Whether to force adaptive thinking regardless of model id; `anthropic-messages`. */ forceAdaptiveThinking?: boolean /** Whether to replay an empty thinking signature instead of converting thinking to text; `anthropic-messages`. */ allowEmptySignature?: boolean /** Whether the endpoint accepts Anthropic strict tool schemas; `anthropic-messages`. */ supportsStrictTools?: boolean } /** One request modality a pi-ai model may accept. */ export type PiAiModality = Model['input'][number] /** * Selectable reasoning efforts for one model: each key is a level the model * offers (and selectors show), and its value is the wire spelling dispatch * sends for it. `off` alone may leave its value empty — "supported, send * nothing" — because for most providers not thinking is the parameter's * absence; every other declared level must name a wire value. A level absent * from the dict is not offered. */ export type PiAiReasoningEfforts = Partial> /** One reasoning-dispatch wire format a profile may name. */ export type PiAiThinkingFormat = NonNullable 依赖: Api ( @earendil-works/pi-ai )· CacheRetention ( @earendil-works/pi-ai )· Model ( @earendil-works/pi-ai )· ModelThinkingLevel ( @earendil-works/pi-ai )· OpenAICompletionsCompat ( @earendil-works/pi-ai )· RetryPolicyConfig · ThinkingBudgets ( @earendil-works/pi-ai )· Transport ( @earendil-works/pi-ai ) 来源: packages/llm/llm-pi-ai/src/config.ts:213 @deepseek-ai/dsh-llm-replay 需要: llm /** Plugin config: the {@link ReplayConfig} inputs, each defaulting to its `DSH_SNAPSHOT_*` env var in `apply`. */ export interface Config { /** Override the fixture path; defaults to `$DSH_SNAPSHOT_FILE`. */ file?: string /** Override the sidecar path; defaults to `$DSH_SNAPSHOT_OVERRIDE`. */ overrideFile?: string /** * Override the child-log paths; defaults to `$DSH_SNAPSHOT_CHILD_FILES` (a * path-separator-delimited list). Each is a recorded subagent session log for * a nested-agent scenario; absent/empty for a single-session scenario. */ childFiles?: string[] /** Optional replay-only provider catalog; absent or empty selects catch-all waterfall replay. */ providers?: ReplayProviderConfig[] /** Optional per-chunk pacing delay in ms (see {@link ReplayConfig.paceMs}); absent keeps burst yield. */ paceMs?: number } /** One provider route exposed by the replay adapter. */ export interface ReplayProviderConfig { /** Provider route used for replay requests. */ id: string /** Selector label; defaults to {@link id}. */ name?: string /** Advisory models exposed to replay scenarios that exercise discovery. */ models?: ReplayModelConfig[] /** Optional provider-owned retry policy used by assembled recovery snapshots. */ retryPolicy?: RetryPolicyConfig } /** One model exposed by a replay-only provider catalog. */ export interface ReplayModelConfig { /** Model id used for replay requests. */ id: string /** Selector label; defaults to {@link id}. */ name?: string /** Optional selector description. */ description?: string /** Optional positive integer context capacity published by the replay adapter. */ contextWindow?: number /** Optional declared input modalities, so a scenario can exercise capability gates (e.g. image-capable `read_image`). */ inputModalities?: readonly ModelModality[] /** * Optional per-request output cap the replay route materializes when callers * omit one, so replay reconstructs the request header a live catalog produced. */ defaultMaxTokens?: number /** * Optional flat visual-token price the replay route declares for every * retained request image, so keyless scenarios exercise route-priced * request pressure; each occurrence is priced at this value plus its * request-preview handle text. Requires {@link inputModalities} to include * `image` — a text-only route never sends visual tokens. Absent declares * no image pricing. */ imageRequestTokens?: number /** Optional reasoning-effort ids the replay route accepts, in display order. */ reasoningEfforts?: string[] /** * Optional effort materialized when callers omit one; must appear in * {@link reasoningEfforts} or call resolution rejects the route. */ defaultReasoningEffort?: string } 依赖: ModelModality · RetryPolicyConfig 来源: packages/test-support/llm-replay/src/index.ts:924 @deepseek-ai/dsh-llm-retry 需要: agents · sessionProjections /** This policy executor has no config; providers own `retryPolicy`. */ export type Config = Readonly> 来源: packages/llm/llm-retry/src/index.ts:25 @deepseek-ai/dsh-lsp-stdio 需要: fs · lsp · subprocess /** Plugin configuration: provider id → local language-server configuration. */ export interface Config { /** Non-empty table of stable provider ids to independent local server configurations. */ servers: Record } /** One configured local language server and its host bounds. */ export interface LspLocalServerConfig { /** Executable to spawn (absolute, or resolved on PATH at load). */ command: string /** Lowercase leading-dot extension → LSP language id (e.g. `{ '.ts': 'typescript' }`). */ extensionToLanguage: Record /** Arguments passed to the executable (no shell). Default `[]`. */ args?: string[] /** Extra env vars merged on top of the scrubbed ambient env. Default `{}`. */ env?: Record /** Static `initialize` options forwarded to the server. Default `null`. */ initializationOptions?: unknown /** Static answer to every `workspace/configuration` item. Default `null`. */ configuration?: unknown /** Largest single framed message accepted from the server (bytes). Default 16000000. */ maxMessageBytes?: number /** Largest stderr tail retained for diagnostics (bytes). Default 1000000. */ maxStderrBytes?: number /** Largest source file this host will open (bytes). Default 4000000. */ maxDocumentBytes?: number /** Graceful `shutdown`/`exit` budget before escalation (ms). Default 5000. */ shutdownTimeoutMs?: number /** Request-cancel and SIGTERM→SIGKILL grace (ms). Default 2000. */ killGraceMs?: number } 来源: packages/lsp/lsp-stdio/src/index.ts:82 @deepseek-ai/dsh-mcp-client 需要: tools /** Configuration for one stdio or Streamable HTTP MCP server. */ export type Config = StdioConfig | StreamableHttpConfig /** Config for connecting to an MCP server via a spawned child process over stdio. */ export interface StdioConfig { /** Selects child-process stdio transport. */ transport: 'stdio' /** * Stable local namespace for this server's model-facing tool names * (`mcp____`). Must match `[A-Za-z0-9_-]{1,32}` and be * unique across live mcp-client instances. */ serverName: string /** Executable used to start the server. */ command: string /** Arguments passed directly, without shell interpolation. */ args: string[] /** Extra env vars merged on top of scrubbed ambient env. */ env: Record /** Working directory for the child process. */ cwd: string /** Per-tool-call timeout in milliseconds. */ toolCallTimeoutMs: number /** Fail plugin activation when the initial connection or tool synchronization fails. */ failOnStartupError: boolean /** Automatic reconnect policy after a lost connection; omission uses the defaults. */ reconnect?: ReconnectConfig } /** Config for connecting to an MCP server over Streamable HTTP (SSE). */ export interface StreamableHttpConfig { /** Selects Streamable HTTP transport. */ transport: 'streamable-http' /** * Stable local namespace for this server's model-facing tool names * (`mcp____`). Must match `[A-Za-z0-9_-]{1,32}` and be * unique across live mcp-client instances. */ serverName: string /** MCP endpoint URL. */ url: string /** Additional headers attached to MCP requests. */ headers: Record /** Per-tool-call timeout in milliseconds. */ toolCallTimeoutMs: number /** Fail plugin activation when the initial connection or tool synchronization fails. */ failOnStartupError: boolean /** Automatic reconnect policy after a lost connection; omission uses the defaults. */ reconnect?: ReconnectConfig } /** Automatic reconnect policy for one MCP server connection. */ export interface ReconnectConfig { /** Reconnect automatically after a lost connection (default true). */ enabled?: boolean /** First reconnect delay in milliseconds; doubles per consecutive failed attempt (default 500). */ initialDelayMs?: number /** Backoff ceiling in milliseconds; also the uptime after which the attempt budget resets (default 30000). */ maxDelayMs?: number /** Consecutive failed attempts per outage before giving up for good (default 10). */ maxAttempts?: number } 来源: packages/mcp/mcp-client/src/index.ts:98 @deepseek-ai/dsh-message-feedback 需要: storageDomain · sessionPersistence · sessions /** Required deployment policy for optional notes. */ export interface Config { /** Maximum UTF-8 byte length accepted for one note. */ readonly maxNoteBytes: number } 来源: packages/feedback/message-feedback/src/index.ts:50 @deepseek-ai/dsh-permission-presets 需要: shell · approval · sessions · sessionProjections /** The {@link PermissionPresetService} config: preset table and composition default. */ export interface Config { /** * The preset table: name → knob bundle. Defaults to `workspace-write` * (workspace-write + ask) and `danger-full-access` (danger-full-access + * never). The name `custom` is reserved for the derived not-a-preset state. */ presets?: Record /** * Default for new sessions. When omitted, the preset matching the composed * sandbox and approval defaults is used. */ defaultPreset?: string } /** One preset's sandbox/approval bundle and optional client presentation. */ export interface PresetSpec { /** The `sandbox/mode` value the preset writes through. */ sandbox: SandboxMode /** The `approval/policy` value the preset writes through. */ approval: ApprovalPolicy /** The display label a client shows for this preset; the raw table key when omitted. */ name?: string /** One user-facing sentence on what the preset means; omitted when not configured. */ description?: string } 依赖: ApprovalPolicy · SandboxMode 来源: packages/interaction/permission-presets/src/index.ts:143 @deepseek-ai/dsh-persona 需要: systemPrompt /** Plugin config: the persona text this composition contributes. */ export interface Config { /** * Persona prose rendered as the `deployment:persona` section. A template: * complete `{{…}}` groups interpolate strictly against registered prompt * variables. Empty text drops the section at render, matching the registry. */ text: string /** Make this persona the complete system prompt, suppressing every other section. */ complete?: boolean /** Suppress dynamic runtime-context snapshots for this persona's agent scope. */ includeRuntimeContext?: boolean } 来源: packages/preset/persona/src/index.ts:30 @deepseek-ai/dsh-plan-mode 需要: tools · systemPrompt · sessionProjections /** Deployment-owned plan guidance. */ export interface PlanModeConfig { /** Guidance rendered as the `plan:policy` prompt section while plan mode is active. */ section: string } 来源: packages/plan/plan-mode/src/index.ts:63 @deepseek-ai/dsh-plugin-package-inventory-deepseek 需要: agents · deepseekLlmApiExtensions · loader /** Plugin-package request contribution configuration. */ export interface Config { /** Contribute `dsh_plugin_packages` to official DeepSeek requests. Defaults to `true`. */ enabled?: boolean } 来源: packages/llm/plugin-package-inventory-deepseek/src/index.ts:31 @deepseek-ai/dsh-pwsh-local 需要: subprocess /** Plugin config (all optional — `static Config` supplies the defaults). */ export interface Config { /** Default working directory for commands (default: process.cwd()). */ cwd?: string /** Default foreground timeout in milliseconds. */ timeoutMs?: number /** Upper bound for per-call timeout overrides. */ maxTimeoutMs?: number /** Per-stream in-memory output cap; overflow spills to a temp file. */ maxOutputBytes?: number /** Per-stream spill-file cap; larger streams retain only their in-memory tail. */ maxSpillBytes?: number /** Grace period for kill escalation and inherited pipes; at most `MAX_TIMER_DELAY_MS`. */ graceMs?: number /** * Explicit pwsh executable. When omitted, well-known Windows install * locations and PATH entries are probed in order (PowerShell 7 install, * PATH entries such as the Microsoft Store install, then Windows * PowerShell 5.1), falling back to a bare `pwsh` resolved through PATH. */ pwshPath?: string } 来源: packages/shell/pwsh-local/src/index.ts:58 @deepseek-ai/dsh-pwsh-sandbox 需要: subprocess · sandbox · sandboxPolicy /** * Plugin config: the local executor's knobs, verbatim. The sandbox policy — * the default mode and fallback `workspace-write` root — is NOT here: it lives * on `ctx.sandboxPolicy` (`@deepseek-ai/dsh-sandbox-policy`), which resolves * each calling session's mode and cwd for every enforcing capability. The * runner choice is likewise the `ctx.sandbox` provider's config, not this * executor's. */ export type Config = LocalConfig 依赖: LocalConfig 来源: packages/shell/pwsh-sandbox/src/index.ts:40 @deepseek-ai/dsh-repeat-tool-reminder /** * Plugin config, validated by the same-named schemastery schema plus the * load-time checks in `apply` (misconfiguration fails loud: an empty * `thresholds` list, a non-integer, a value below 2, or a duplicate throws at * plugin load, never a silent fall-back). `include`/`exclude` entries are * `*`-wildcard predicates over tool names at call time, not references to * registry entries — a pattern matching no currently registered tool is valid * (`exclude: [mcp_*]` must stay legal in a deployment that loads no MCP tools). */ export interface Config { /** Consecutive-repeat counts that trigger a reminder (default `[3, 5, 8]`). */ thresholds?: number[] /** Tool-name patterns to track; empty means every tool is tracked. */ include?: string[] /** Tool-name patterns transparent to the chain (neither count nor reset). */ exclude?: string[] /** * Maximum characters of canonical arguments quoted in the DETAILED reminder * (default 500). Large payloads (a `write` body, a long command) would * otherwise ride into the next request unbounded — precisely in a loop * scenario; the cap bounds the reminder, never the detection (the chain key * always compares the FULL canonical string). */ argumentsPreviewChars?: number } 来源: packages/guard/repeat-tool-reminder/src/index.ts:28 @deepseek-ai/dsh-sandbox-local /** Plugin config. All optional — `static Config` supplies the defaults. */ export interface Config { /** * Override the runner argv; bwrap-compatible profile arguments are appended. A * non-empty override asserts full enforcement and skips built-in selection and * probing. A runner that starts but refuses its profile must be identifiable by * {@link runnerFailureSignatures}. Consumers classify a spawn rejection only after * confirming the workdir is usable. `ENOENT` or `EACCES` identifies the runner when * `error.path` equals argv[0] and `error.syscall` is `spawn` or `spawn `, or * when `error.path` is absent and `error.syscall` is exactly `spawn `. */ runnerCommand?: string[] /** * Case-insensitive stderr substrings emitted when a configured * {@link runnerCommand} refuses its profile before executing the wrapped * command. Required and non-empty with `runnerCommand`; rejected without * it. Each entry is a non-empty, single-line, case-insensitive substring * covering the executable runner's own failure dialect. */ runnerFailureSignatures?: string[] /** Positive timeout for each functional probe; zero would mean unbounded to Node. */ probeTimeoutMs?: number } 来源: packages/sandbox/sandbox-local/src/index.ts:44 @deepseek-ai/dsh-sandbox-policy 需要: sessionProjections /** * Plugin config: the deployment's sandbox default. All optional — `Config` * supplies the defaults (`mode: 'read-only'` is the fail-safe default; a * deployment that wants a workspace-writable agent opts in explicitly). The * runner choice is NOT here (it is the `ctx.sandbox` provider's config), nor * is any per-family knob: this is the one shared policy home. */ export interface Config { /** File-sandbox mode a session starts from (default: `read-only`). */ mode?: SandboxMode /** * Fallback root for agentless calls and sessions without a cwd (default: * `process.cwd()`). Normal agent calls use their session cwd instead. */ workspaceRoot?: string } 依赖: SandboxMode 来源: packages/sandbox/sandbox-policy/src/index.ts:70 @deepseek-ai/dsh-sdk-app 需要: cmdlineArgs /** SDK stdio startup configuration. */ export interface Config { /** Profile name rendered in help and diagnostics (default `sdk`). */ profile?: string } 来源: packages/bundle/sdk-app/src/index.ts:23 @deepseek-ai/dsh-sdk-jsonrpc-server 需要: agents /** JSON-RPC deployment config plus runtime-only test hooks. */ export interface JsonRpcConfig { /** Report max-token turn/subagent termination as a successful SDK result. */ maxTokensAsSuccess?: boolean /** Transport input override; production uses `process.stdin`. */ input?: Readable /** Transport output override; production uses `process.stdout`. */ output?: Writable /** Process-exit override; production uses `process.exit`. */ exit?: (code: number) => void } 依赖: Readable ( node:stream )· Writable ( node:stream ) 来源: packages/sdk/server/src/index.ts:25 @deepseek-ai/dsh-session-log-deepseek 需要: deepseekLlmApiExtensions · sessions /** Session-log request contribution configuration. */ export interface Config { /** Contribute `dsh_session_log` to official DeepSeek requests. Defaults to `false`. */ enabled?: boolean } 来源: packages/session/session-log-deepseek/src/index.ts:36 @deepseek-ai/dsh-session-log-export 需要: commands · connection /** Session-log archive policy. */ export interface Config { /** DEFLATE level for each ZIP entry. @default 6 */ readonly compressionLevel?: SessionLogCompressionLevel } /** Valid fflate DEFLATE levels accepted by session-log export. */ export type SessionLogCompressionLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 来源: packages/session-query/session-log-export/src/index.ts:42 @deepseek-ai/dsh-session-persistence-jsonl 需要: sessions · sessionProjections /** Plugin config: where the JSONL backend keeps its session logs, and the packed-row write switch. */ export interface Config { /** * Root directory for all session files. Required (no default): a default of * `process.cwd()` would scatter session files as the process's cwd changes * (bash calls, subprocesses). Sessions group under human-readable project * directories, then per-session directories. An existing root must be a * readable directory; an absent root is created on first materialization. */ root: string /** * Write runs of consecutive `assistant/chunk` delta events as packed * `text-chunks`/`reasoning-chunks`/`tool-call-chunks` rows (lossless, * ~60% smaller logs measured on a real session). Defaults to true; false * keeps one `SessionEvent` per line for diagnostics. Reading packed rows is * unconditional: a log's layout never depends on this switch. */ packChunks?: boolean /** Physical encoding; defaults to checksummed Zstandard frames. */ compression?: JsonlCompression /** Maximum cold Session preparations retained for history-to-resume reuse. */ preparedSessionCacheSize?: number /** Fixed live-event coalescing window; not a backend completion deadline. */ writeBatchMaxDelayMs?: number } /** Physical encoding selected for JSONL session artifacts. */ export type JsonlCompression = 'zstd' | 'none' 来源: packages/session/session-persistence-jsonl/src/index.ts:70 @deepseek-ai/dsh-session-projection-cache 需要: storageDomain · sessionProjections · sessions /** * Plugin config. Both throttle triggers are deployment choices with no * universally correct value, so the composition states them explicitly * (cordis.yml); the three mandatory write points (session creation, * `turn/end`, and session disposal) are policy, not tunables, and always * fire. */ export interface Config { /** Committed events per session that force a durable checkpoint write between mandatory points. */ writeEveryEvents: number /** Longest time (milliseconds) a dirty checkpoint may stay unwritten between mandatory points. */ writeIntervalMs: number } 来源: packages/session/session-projection-cache/src/index.ts:55 @deepseek-ai/dsh-session-query-sqlite 需要: sessions /** Combined session-query configuration backed by SQLite full-text search. */ export interface Config extends SessionQueryConfig { /** * Dedicated derived-index path; `:memory:` is supported for ephemeral * indexes. Missing directories and database files are created owner-only on * POSIX filesystems; existing modes are preserved. */ path: string /** * Open the SQLite module and handle at service activation or the first * search, or `never` to disable full-text search: the inherited exact * reads, filters, and traces stay available, while `searchSessions` and * `searchEvents` fail with `SESSION_QUERY_SEARCH_DISABLED` and SQLite is * never imported or opened. Defaults to `startup`. */ openAt?: OpenAt /** SQLite journal mode. Defaults to `wal`. */ journalMode?: JournalMode /** Page size when a request omits `limit`. At most `Number.MAX_SAFE_INTEGER - 1`; defaults to 20. */ defaultLimit?: number /** Largest accepted page size. At most `Number.MAX_SAFE_INTEGER - 1`; defaults to 100. */ maxLimit?: number /** Maximum snippet length in Unicode code points. Defaults to 240. */ snippetChars?: number /** Maximum concurrent persisted-log inspections in one inherited batch read. Defaults to 4. */ persistedInspectConcurrency?: number } /** SQLite module/handle opening phase; `never` disables full-text search entirely. */ export type OpenAt = 'startup' | 'first-search' | 'never' /** Supported SQLite journal modes. */ export type JournalMode = 'wal' | 'delete' | 'truncate' | 'persist' 依赖: SessionQueryConfig 来源: packages/session-query/session-query-sqlite/src/index.ts:96 @deepseek-ai/dsh-session-reference 需要: sessionQuery /** Session-reference service configuration. */ export interface Config { /** Maximum distinct source sessions referenced by one message, from one to three. */ maxReferences?: number /** Default host candidate-list limit. */ candidateLimit?: number /** Maximum rendered UTF-8 bytes for one source snapshot. */ maxReferenceBytes?: number } 来源: packages/context/session-reference/src/config.ts:11 @deepseek-ai/dsh-session-telemetry-otel 需要: sessions /** * Plugin configuration: one sharing policy, two verbatim SDK option objects, * and one DSH-owned shutdown bound. Uploading modes validate their endpoint * and shutdown deadline at plugin load; `DISABLED` reads neither. */ export interface Config { /** Sharing policy; defaults to local-only `DISABLED` behavior. */ mode?: SessionTelemetryMode /** * Passed verbatim to the SDK's OTLP/HTTP log exporter — the complete * `OTLPExporterNodeConfigBase` shape (`headers`, `timeoutMillis`, * `compression`, `keepAlive`, …), owned and documented by the SDK. `url` * is the one field this package requires and validates itself. */ exporter?: OTLPExporterNodeConfigBase & { /** Full logs endpoint (e.g. `https://collector.example.com/v1/logs`). Required outside `DISABLED`; validated at load. */ url?: string } /** * Passed verbatim to `BatchLogRecordProcessor` (minus the exporter slot, * which this plugin fills); the SDK owns and documents these knobs. */ processor?: Omit /** Maximum time spent awaiting the SDK provider's complete shutdown path. */ shutdownTimeoutMillis?: number } /** Session-sharing policy selected by {@link Config.mode}. */ export enum SessionTelemetryMode { FULL = 'FULL', FEEDBACK_ONLY = 'FEEDBACK_ONLY', DISABLED = 'DISABLED', } 依赖: BatchLogRecordProcessorOptions ( @opentelemetry/sdk-logs )· OTLPExporterNodeConfigBase ( @opentelemetry/otlp-exporter-base ) 来源: packages/session/session-telemetry-otel/src/index.ts:91 @deepseek-ai/dsh-session-title 需要: sessions /** Required deterministic fallback and accepted-title limits. */ export interface Config { /** Maximum whitespace-delimited words in the built-in fallback. */ readonly fallbackMaxWords: number /** Maximum UTF-8 bytes in the built-in fallback. */ readonly fallbackMaxBytes: number /** Maximum UTF-8 bytes in any accepted title. */ readonly maxTitleBytes: number } 来源: packages/session/session-title/src/index.ts:56 @deepseek-ai/dsh-session-title-all-prompts-llm 需要: sessionTitle · llm · sessions /** Required LLM policy; this plugin adds no defaults. */ export type Config = SessionTitleLlmConfig 依赖: SessionTitleLlmConfig 来源: packages/session/session-title-all-prompts-llm/src/index.ts:15 @deepseek-ai/dsh-session-title-first-prompt-llm 需要: sessionTitle · llm · sessions /** Required LLM policy; this plugin adds no defaults. */ export type Config = SessionTitleLlmConfig 依赖: SessionTitleLlmConfig 来源: packages/session/session-title-first-prompt-llm/src/index.ts:15 @deepseek-ai/dsh-settings-file /** Plugin config: file location and hot-reload behavior. */ export interface Config { /** Settings document path; defaults to `settings.yaml` under the harness home. */ path?: string /** Harness home used when `path` is omitted; defaults to `$DSH_HOME` or `~/.dsh`. */ dshHome?: string /** Watch the document and hot-publish external edits; defaults to true. */ watch?: boolean /** Watcher write-settle window in milliseconds; defaults to 100. */ debounceMs?: number } 来源: packages/settings/settings-file/src/index.ts:22 @deepseek-ai/dsh-shell-env /** Plugin config (all optional — the built-in facts resolve without defaults). */ export interface Config { /** DeepSeek Harness home directory exposed as `DSH_HOME`; defaults to `$DSH_HOME` or `~/.dsh`. */ dshHome?: string } 来源: packages/shell/shell-env/src/index.ts:29 @deepseek-ai/dsh-skill /** Skill registry configuration. */ export interface Config { /** Maximum number of completed cwd/provider catalogs kept in memory. */ readonly collectCacheMaxEntries?: number } 来源: packages/skill/skill/src/index.ts:280 @deepseek-ai/dsh-skill-filesystem 需要: skills /** Local filesystem skill provider configuration. */ export interface Config { /** Unique provider name. Defaults to `filesystem`. */ providerName?: string /** Whether project and user roots are included around custom roots. */ includeDefaultRoots?: boolean /** DeepSeek Harness config root. Defaults to `$DSH_HOME` or `~/.dsh`. */ dshHome?: string /** Shared agent config root. Defaults to `$DSH_AGENTS_HOME` or `~/.agents`. */ agentsHome?: string /** Additional skill roots scanned after project roots and before user roots. */ customSkillDirs?: string[] /** Whether host-local skill roots are watched for catalog changes. */ watch?: boolean /** Whether Chokidar uses polling instead of native filesystem events. */ watchUsePolling?: boolean /** Milliseconds a changed skill entry must remain stable before it is observed. */ watchStabilityThresholdMs?: number /** Milliseconds between Chokidar stability or polling probes. */ watchPollIntervalMs?: number /** Maximum distinct project roots whose skill directories remain watched. */ watchMaxProjects?: number /** Whether watched symbolic links follow their target files. */ watchFollowSymlinks?: boolean /** Bundled skill root; defaults to `$DSH_BUNDLED_SKILL_DIR` when default roots are included, otherwise mounts none. */ bundledSkillDir?: string } 来源: packages/skill/skill-filesystem/src/index.ts:49 @deepseek-ai/dsh-spill-local /** Plugin config (all optional — `static Config` supplies the defaults). */ export interface Config { /** * Root directory for spill files. Omitted uses a lazily-created private * (0700) per-process directory under the OS temp dir — the safe default for * a local deployment. Set it to keep spill files under a known location. */ root?: string /** * Age in days after which a spill file is eligible for the one-shot startup * cleanup sweep. Defaults to `30`; `0` disables cleanup entirely. Files whose * `mtime` is strictly older than the cutoff are deleted and emptied * directories are pruned; fresh files, symlinks, and unrelated entries are * left untouched. On POSIX, cleanup skips roots and session directories that * another local user could modify or replace. Retention is deliberate — a * resumed or forked session may still reference an older locator until it * ages out. */ cleanupPeriodDays?: number } 来源: packages/spill/spill-local/src/index.ts:31 @deepseek-ai/dsh-spill-policy 需要: tools · sessionProjections /** Plugin config. */ export interface Config { /** * The model-facing context cap for a plain-text tool result, in UTF-8 bytes. * Omitted disables the policy entirely (no-op). When set, a result larger than * this is spilled and replaced with a preview derived from this same budget. */ maxInlineBytes?: number } 来源: packages/spill/spill-policy/src/index.ts:60 @deepseek-ai/dsh-storage-domain 需要: storage /** * Plugin config. Which backend serves which domain is decided here, not * globally on the hub: `backend` is the default route and `routes` overrides * it per domain name. A route naming an unregistered backend fails loud at * `open` with `backend-not-found`. */ export interface Config { /** Default backend name for every domain without an explicit route. Required: there is no universally correct medium. */ backend: string /** Per-domain overrides: domain name → backend name. */ routes?: Record } 来源: packages/storage/storage-domain/src/index.ts:52 @deepseek-ai/dsh-storage-json 需要: storage /** * Plugin configuration. * `root` has NO default on purpose: a `process.cwd()` fallback would scatter * unit files wherever the process happens to start; assemblies state the * location explicitly. */ export interface Config { /** Directory holding one `.json` file (or `/` tree) per unit. */ root: string } 来源: packages/storage/storage-json/src/index.ts:28 @deepseek-ai/dsh-storage-sqlite 需要: storage /** Plugin configuration. */ export interface Config { /** * Filesystem path to the SQLite database file. The special value `:memory:` * opens an in-process database (tests). On filesystems with POSIX modes, * missing directories and databases are created owner-only; existing path * modes are preserved. Filesystem setup errors other than an existing * database fail the open. The backend does not protect confidentiality or * integrity when another principal can replace the database entry in its * parent directory. */ path: string /** * SQLite `journal_mode` pragma. `wal` (the default) suits local disks; pick * a rollback-journal mode (`delete`/`truncate`/`persist`) on filesystems * where WAL's shared-memory files do not work (network mounts). See * {@link JournalMode}. */ journalMode?: JournalMode } /** * Journal modes the backend will run under. `wal` is the default; the * rollback-journal modes (`delete`/`truncate`/`persist`) exist for * filesystems where WAL's shared-memory files do not work (network mounts). * `memory`/`off` are excluded: dropping journal durability silently * contradicts the durability clause of the KV backend contract. */ export type JournalMode = 'wal' | 'delete' | 'truncate' | 'persist' 来源: packages/storage/storage-sqlite/src/index.ts:24 @deepseek-ai/dsh-subagent-acp 需要: subagents · subprocess /** Config: how to spawn and drive the child ACP agent process. */ export interface Config { /** Provider name on `ctx.subagents` (default `acp`). */ providerName: string /** The executable to spawn for each run (the child ACP agent). */ command: string /** Arguments passed to {@link command}. */ args: string[] /** * Working directory override for the child process and its ACP session. * Must be non-empty; a relative path resolves against the harness launch * directory at load, and the result must be an existing directory. When * omitted, each child inherits its delegating parent session's cwd — and * starting one from a parent session that has no cwd fails. */ cwd?: string /** * How to auto-answer the child's `session/request_permission` prompts: * `reject` (default — decline every prompt) or `allow` (approve via the first * `allow_once` or `allow_always` option). No prompt is surfaced to a human. */ permission: PermissionPolicy /** * Extra environment variables for the child process — e.g. the child * harness's own `DEEPSEEK_API_KEY`. Forwarded on top of a credential-scrubbed * copy of the parent env, so an explicit key here reaches the child while * ambient secrets do not leak implicitly. */ env: Record /** * Grace period (ms) for the child's EOF-driven quiesce on dispose — its * window to flush persistence and tear down its own nested subprocesses * before the parent escalates to a signal. Must not exceed * `MAX_TIMER_DELAY_MS`. */ disposeEofGraceMs?: number /** Failure-observation and termination-escalation grace (ms); must not exceed `MAX_TIMER_DELAY_MS`. */ disposeGraceMs?: number } /** Fixed response to child permission requests: reject by default, or select the first allow option. */ export type PermissionPolicy = 'allow' | 'reject' 来源: packages/subagent/subagent-acp/src/index.ts:27 @deepseek-ai/dsh-subagent-claude-code 需要: subagents · subprocess /** Deployment-owned model, permission, environment, and process-release settings. */ export interface Config { /** Provider name on `ctx.subagents` (default `claude-code`). */ providerName?: string /** Native Claude model fixed for this instance; omitted to inherit Claude settings. */ model?: string /** * Explicit environment entries layered over the subprocess seam's * credential-scrubbed parent environment. */ env?: Record /** * Native non-interactive mode fixed for this Provider instance. Defaults to * `dontAsk`; `acceptEdits` accepts edits, `auto` uses the native classifier, * `plan` returns a plan without approving execution, and * `bypassPermissions` explicitly skips permission checks. */ permissionMode?: ClaudeCodePermissionMode /** Grace in milliseconds for Claude Code process-tree termination. */ disposeGraceMs?: number } /** Profile-selectable non-interactive Claude Code permission mode. */ export type ClaudeCodePermissionMode = typeof CLAUDE_CODE_PERMISSION_MODES[number] 来源: packages/subagent/subagent-claude-code/src/index.ts:38 @deepseek-ai/dsh-subagent-codex 需要: subagents · subprocess /** Deployment-owned model, permission, environment, and process-release settings. */ export interface Config { /** Provider name on `ctx.subagents` (default `codex`). */ providerName?: string /** Native Codex model fixed for this instance; omitted to inherit Codex settings. */ model?: string /** * Explicit environment entries layered over the subprocess seam's * credential-scrubbed parent environment. */ env?: Record /** Native non-interactive permission mode fixed for this Provider instance. */ permissionMode?: CodexPermissionMode /** Grace in milliseconds for app-server process-tree termination. */ disposeGraceMs?: number } /** Profile-selectable non-interactive Codex permission mode. */ export type CodexPermissionMode = | 'never' | 'approve-for-me' | 'dangerously-bypass-approvals-and-sandbox' 来源: packages/subagent/subagent-codex/src/index.ts:36 @deepseek-ai/dsh-subagent-dsh-sdk 需要: subagents /** Config: how to spawn and drive the child SDK runtime process. */ export interface Config { /** Provider name on `ctx.subagents` (default `dsh-sdk`). */ providerName: string /** Explicit dsh CLI module, resolved and checked at plugin load; omission uses the SDK dependency. */ dshBin?: string /** Named child profile (default `sdk`). */ profile: string /** Ordered per-launch profile patch files, resolved and checked at plugin load. */ patches: string[] /** Absolute isolated Harness home for every nested child process. */ dshHome: string /** * Working directory override for the child process and its SDK session * workspace. Must be non-empty; a relative path resolves against the * harness launch directory at load, and the result must be an existing * directory. When omitted, each child inherits its delegating parent * session's cwd — and starting one from a parent session that has no cwd * fails. */ cwd?: string /** Provider route the child runtime initializes with (default `deepseek-official`). */ provider: string /** Model the child runtime initializes with (default `deepseek-v4-flash`). */ model: string /** Optional per-request output-token cap for the child runtime. */ maxTokens?: number /** * Extra environment variables for the child process — e.g. the child * runtime's own `DEEPSEEK_API_KEY`. Forwarded on top of a credential-scrubbed copy of the parent * env, so an explicit key here reaches the child while ambient secrets do * not leak implicitly. */ env: Record /** Bound (ms) on the protocol `shutdown` exchange during dispose. */ shutdownTimeoutMs?: number /** * Grace period (ms) for the child's EOF-driven quiesce on dispose — its * window to flush persistence and tear down its own nested subprocesses * before the parent escalates to a signal. */ disposeEofGraceMs?: number /** Termination confirmation window (ms), including forced exit on every platform. */ disposeGraceMs?: number } 来源: packages/subagent/subagent-dsh-sdk/src/index.ts:34 @deepseek-ai/dsh-subagent-fork-in-process 需要: subagents /** Config: the registry name to register the provider under. */ export interface Config { /** Provider name on `ctx.subagents` (default `fork`). */ providerName: string } 来源: packages/subagent/subagent-fork-in-process/src/index.ts:31 @deepseek-ai/dsh-subagent-spawn-in-process 需要: subagents /** Config: the registry name to register the provider under. */ export interface Config { /** Provider name on `ctx.subagents` (default `spawn`). */ providerName: string } 来源: packages/subagent/subagent-spawn-in-process/src/index.ts:25 @deepseek-ai/dsh-subprocess-e2b 需要: e2b /** Configuration for the E2B subprocess adapter. */ export interface Config { /** Remote status/liveness poll cadence in milliseconds; each tick is one control-plane request. */ pollMs?: number } 来源: packages/e2b/subprocess-e2b/src/index.ts:25 @deepseek-ai/dsh-system-prompt /** Plugin config: the deployment-authored fragment of the system prompt (see {@link Config.persona} for its contract). */ export interface Config { /** Include the fixed DeepSeek Harness identity before the deployment persona (default true). */ includeHarnessIdentity?: boolean /** Include dynamic runtime-context snapshots in model history (default true). */ includeRuntimeContext?: boolean /** * Deployment-wide order-0 persona template. A scoped section named * `deployment:persona` shadows it; `{{variable}}` references are strict. */ persona?: string /** * Model-facing tool names in order, with {@link TOOL_ORDER_REST} exactly once. * Invalid fields fail at load and unknown names fail at assembly; known names * hidden in one scope may be absent there. Omitted means lexicographic order. */ toolOrder?: string[] } 来源: packages/core/system-prompt/src/index.ts:237 @deepseek-ai/dsh-terminal-bash 需要: terminals · sandboxPolicy · sessionProjections · subprocess /** Public plugin configuration. */ export interface Config { /** Backend registry type (default: `shell`). */ backendType?: string /** Interactive shell dialect (default: `bash`); selects the argv/env/startup defaults. */ shellDialect?: ShellDialect /** Interactive shell executable (default per dialect: `/bin/bash`, or the resolved pwsh). */ shellPath?: string /** Shell arguments (default per dialect: bash `--noprofile --norc -i`, pwsh `-NoLogo -NoProfile`). */ shellArgs?: string[] /** Terminal rows. */ rows?: number /** Terminal columns. */ cols?: number /** Maximum retained logical lines. */ scrollbackLines?: number /** Maximum retained UTF-8 bytes. */ scrollbackMaxBytes?: number /** Maximum bytes returned by one read or settled viewport. */ maxReadBytes?: number /** Readiness polling interval. */ pollIntervalMs?: number /** Delay before Linux exact syscall probes. */ exactProbeAfterMs?: number /** Silence duration that yields `inferred_idle`. */ idleSilenceMs?: number /** * Extra wait beyond `idleSilenceMs`, once a prompt marker was seen, for the shell to * regain the foreground before `inferred_idle` settles; at least one `pollIntervalMs`. */ handoffGraceMs?: number /** Absolute bound for one send and the complete pwsh startup sequence. */ timeoutMs?: number /** Grace before teardown escalates to `SIGKILL`. */ disposeGraceMs?: number } /** One supported interactive shell dialect. */ export type ShellDialect = 'bash' | 'pwsh' 来源: packages/terminal/terminal-bash/src/config.ts:10 @deepseek-ai/dsh-time-context 需要: agents · sessionProjections /** Request-preparation clock formatting and append scheduling. Invalid values fail plugin load. */ export interface Config { /** Fallback display zone when the open turn has no unique browser zone. Omit to use the process zone. */ timeZone?: string /** Minimum milliseconds between durable injections in one session. Omit or set to 0 to inject at every eligible step. */ refreshIntervalMs?: number } 来源: packages/context/time-context/src/index.ts:48 @deepseek-ai/dsh-tmux-context 需要: agents · sessionProjections /** Per-turn tmux-location scheduling. Invalid values fail plugin load. */ export interface Config { /** Minimum milliseconds between durable injections in one session. Omit or set to 0 to inject on every eligible change. */ refreshIntervalMs?: number } 来源: packages/context/tmux-context/src/index.ts:36 @deepseek-ai/dsh-token-meter 需要: sessionProjections /** Token-meter plugin configuration; the fixed estimator has no settings. */ export type TokenMeterConfig = Record 来源: packages/llm/token-meter/src/types.ts:13 @deepseek-ai/dsh-tool-bash 需要: tools · shell · systemPrompt · shellEnv /** Configuration for the bash tool. */ export interface Config { /** Expose `run_in_background` (default true); disabled calls are also rejected. */ enableRunInBackground?: boolean } 来源: packages/shell/tool-bash/src/index.ts:33 @deepseek-ai/dsh-tool-bash-persistent 需要: tools · terminals /** Configuration for the persistent Bash tool. */ export interface Config { /** PTY backend used for each owner-isolated persistent shell (default `shell`). */ backendType?: string /** Wall-clock limit for one command (default 300000). */ timeoutMs?: number /** Maximum returned command-output characters before clipping (default 16000). */ maxOutputChars?: number /** Model-facing tool description; deployments may describe their environment. */ description?: string } 来源: packages/shell/tool-bash-persistent/src/index.ts:432 @deepseek-ai/dsh-tool-fs 需要: tools · fs · systemPrompt /** Plugin config (all optional — `Config` supplies the defaults). */ export interface Config { /** Default and maximum number of lines returned by one `read` call. */ readLimit?: number /** Maximum characters returned for a single line before truncation. */ readMaxLineLength?: number /** Maximum bytes returned for the selected lines of one `read` call. */ readMaxBytes?: number /** Files at or above this size stream instead of loading whole into memory. */ readStreamMinSize?: number } 来源: packages/fs/tool-fs/src/index.ts:25 @deepseek-ai/dsh-tool-fs-search 需要: tools · systemPrompt · subprocess /** Plugin config; over-cap glob sampling is an explicit deployment choice and the remaining fields have defaults. */ export interface Config { /** Whether an over-cap `glob` page is sampled across top-level entries instead of taking the modification-time head. */ sampleOverCapGlobResults: boolean /** Max paths one `glob` call retains inline; later paths go to the formatted spill file. */ globMaxResults?: number /** Max flat matches one `grep` call retains inline; later matches go to the formatted spill file. */ grepMaxMatches?: number /** Max bytes retained for one matched-line preview (the cut preserves UTF-8 boundaries). */ grepMaxLineBytes?: number /** Max bytes of one search's serialized `presentationMeta`; trailing groups/paths drop past it so the persisted card stays bounded. */ searchMetaMaxBytes?: number /** Max complete raw `rg` stdout bytes a search will parse; larger raw output fails with `SEARCH_RAW_OUTPUT_OVERFLOW`. */ rawOutputMaxBytes?: number /** Terminate-escalation grace (ms), handed to the subprocess seam and bounded by `MAX_TIMER_DELAY_MS`. */ graceMs?: number /** Max bytes retained for one search's stderr tail; the excerpt is embedded in `SEARCH_*` error messages, never shown on success. */ stderrMaxBytes?: number /** * Cooperative tool-call timeout budget (ms) on both tools, enforced by * `@deepseek-ai/dsh-tool-call-timeout-policy` through `exec.signal`. */ timeoutMs?: number } 来源: packages/fs/tool-fs-search/src/index.ts:73 @deepseek-ai/dsh-tool-goal 需要: agents · goals · tools · systemPrompt · sessionProjections /** Model policy and hard lower bounds for goal-state updates. */ export interface Config { /** Minimum admitted goal rounds before the model may self-report `blocked`. */ blockedAfterConsecutiveRounds?: number } 来源: packages/goal/tool-goal/src/index.ts:25 @deepseek-ai/dsh-tool-jobs 需要: tools · jobs · systemPrompt /** Configures bounded `job_output` waits and completion-notice delivery. */ export interface Config { /** Wait duration applied when `job_output` sets `wait` without `timeout_ms` (default 30s). */ waitTimeoutMs?: number /** Hard cap on any single wait; a larger model-supplied `timeout_ms` is clamped down to it (default 10min). */ maxWaitTimeoutMs?: number /** Whether a completion opens a turn on an idle owner (default `wakeup`). */ completionDelivery?: CompletionDelivery /** * Turns one owner may have opened by completion wakes before the next * notice degrades to injection, reset by any user-authored input (default 3). * Bounds the self-exciting chain where a woken turn starts the job whose * completion wakes it again. */ maxConsecutiveWakes?: number } /** * How an unreported completion reaches an owner that is already idle: `wakeup` * opens a turn for it, `quiet` leaves it pending until something else wakes the * owner. A busy owner is injected either way. */ export type CompletionDelivery = 'quiet' | 'wakeup' 来源: packages/jobs/tool-jobs/src/index.ts:31 @deepseek-ai/dsh-tool-lsp 需要: tools · lsp · systemPrompt /** Plugin configuration: result caps and the timeout budget. */ export interface Config { /** Largest number of rendered locations before an omission marker (default 100). */ maxLocations?: number /** Largest complete rendered result in characters, including truncation metadata (default 16000). */ maxResultChars?: number /** Tool-call timeout budget in ms (default 60000). */ timeoutMs?: number } 来源: packages/lsp/tool-lsp/src/index.ts:57 @deepseek-ai/dsh-tool-pwsh 需要: tools · shell · systemPrompt · shellEnv /** Configuration for the pwsh tool. */ export interface Config { /** Expose `run_in_background` (default true); disabled calls are also rejected. */ enableRunInBackground?: boolean } 来源: packages/shell/tool-pwsh/src/index.ts:51 @deepseek-ai/dsh-tool-pwsh-persistent 需要: tools · terminals /** Configuration for the persistent pwsh tool. */ export interface Config { /** PTY backend used for each owner-isolated persistent shell (default `shell`). */ backendType?: string /** Wall-clock limit for one command (default 300000). */ timeoutMs?: number /** Maximum returned command-output characters before clipping (default 16000). */ maxOutputChars?: number /** Model-facing tool description; deployments may describe their environment. */ description?: string } 来源: packages/shell/tool-pwsh-persistent/src/index.ts:472 @deepseek-ai/dsh-tool-ralph 需要: tools · workflowEngine · subagents · systemPrompt /** Deployment policy for the fixed Ralph workflow. */ export interface Config { /** Fresh structured-output provider used for every round (default `spawn`). */ subagentProvider?: string /** Default and deployment ceiling for one call's round count (default 256). */ maxRounds?: number /** Maximum serialized characters in one structured handoff (default 16384). */ maxHandoffChars?: number /** Maximum characters in a successful parent-facing terminal text (default 16384). */ maxResultChars?: number } 来源: packages/workflow/tool-ralph/src/index.ts:21 @deepseek-ai/dsh-tool-session-query 需要: tools · systemPrompt · sessionQuery · sessionProjections /** Deployment-owned search count and timeout bounds. */ export interface Config { /** Maximum authorized hits returned by one search call. Defaults to 100. */ maxSearchResults?: number /** Cooperative full-text search deadline in milliseconds. Defaults to 30000. */ searchTimeoutMs?: number } 来源: packages/session-query/tool-session-query/src/index.ts:28 @deepseek-ai/dsh-tool-skill 需要: agents · tools · skills /** Model-facing skill catalog configuration. */ export interface Config { /** Maximum normalized description length rendered in the session catalog; minimum 3. */ catalogDescriptionMaxLength?: number } 来源: packages/skill/tool-skill/src/index.ts:61 @deepseek-ai/dsh-tool-str-replace-editor 需要: tools · fs /** Configuration for the string-replacement editor tool. */ export interface Config { /** Maximum returned view characters before clipping (default 16000). */ maxOutputChars?: number /** Model-facing tool description. */ description?: string } 来源: packages/fs/tool-str-replace-editor/src/index.ts:505 @deepseek-ai/dsh-tool-subagent 需要: tools · subagents · systemPrompt · sessionProjections /** Config: which registered provider this tool delegates to, plus child defaults. */ export interface Config { /** The `ctx.subagents` provider name to start runs on (e.g. `spawn`, `acp`). */ provider: string /** * Model-facing tool name (default `subagent`). Each loaded instance must use * a distinct name. */ toolName?: string /** * Sample the Host `subagent-model-selection` user setting for each new * top-level session and inherit that decision in its child sessions. */ modelSelectionSettings?: boolean /** * Expose `run_in_background` (default true). Disabled instances omit the * parameter and reject forced background calls. */ enableRunInBackground?: boolean /** * Background execution policy (default `one-shot`). `one-shot` defaults calls * to foreground; `continuable` defaults them to background, requires a provider * with the `prepareContinuable` capability, and returns the durable child id. * Follow-up adapters remain independently optional. */ backgroundMode?: 'one-shot' | 'continuable' /** * Agent options applied to every child; omitted fields use child-loop defaults. */ agentOptions?: AgentOptions /** * Per-child persona that shadows `deployment:persona`. Requires the * provider's `persona` capability; omission preserves the deployment persona. */ persona?: string /** * Tool filter applied to every child. Filtered tools disappear from its * prompt and reject execution. Requires the provider's `toolFilter` * capability; unknown names fail startup. */ toolFilter?: { /** Global tool names the child keeps; everything else is removed. */ allow?: string[] /** Global tool names removed from the child. */ deny?: string[] } /** * Maximum child depth: a non-negative safe integer (default `3`; `0` forbids * delegation entirely), or `'provider-managed'` to send no cap. A numeric cap * requires the provider's `depthLimit` capability (mount fails loud * otherwise). The provider checks the calling agent's current depth at every * start; the tool remains model-visible so runtime policy owns rejection. * `'provider-managed'` is for an out-of-process provider whose recursion * budget belongs to the child runtime or its own deployment. */ maxDepth?: number | 'provider-managed' } 依赖: AgentOptions 来源: packages/subagent/tool-subagent/src/index.ts:48 @deepseek-ai/dsh-tool-terminal 需要: terminals · tools · systemPrompt /** Model-facing terminal tool configuration. */ export interface Config { /** Expose `run_in_background` and accept background sends (default true). */ enableRunInBackground?: boolean /** Maximum UTF-8 bytes in one complete terminal or task-output result. */ maxResultBytes?: number } 来源: packages/terminal/tool-terminal/src/index.ts:35 @deepseek-ai/dsh-tool-todo 需要: tools /** Model-facing todo tool configuration. */ export interface Config { /** * Required deployment choice for whether several todos may be `in_progress` at once. True suits * agents that run work concurrently — subagents, background commands, workflow fan-out — and the * description then instructs the model to mark every actively worked task. False restores the * single-active discipline: the description asks for exactly one, and a call marking more is * rejected. */ allowParallelInProgress: boolean } 来源: packages/todo/tool-todo/src/index.ts:29 @deepseek-ai/dsh-tool-web 需要: tools · web · systemPrompt /** Plugin config: which web tools to register, search bounds, per-tool budgets, and the fetch output cap. */ export interface Config { /** Register `web_search`. Defaults to true. */ search?: boolean /** Register `web_fetch`. Defaults to true. */ fetch?: boolean /** Upper bound on sources returned by one `web_search` call. */ searchMaxResults?: number /** Upper bound on queries accepted by one `web_search` call. */ searchMaxQueries?: number /** Cooperative timeout budget (ms) for `web_fetch`. Defaults to 30000. */ fetchTimeoutMs?: number /** Cooperative timeout budget (ms) for `web_search`. Defaults to 30000. */ searchTimeoutMs?: number /** Cap on source characters converted and complete `web_fetch` output characters. Defaults to 200000. */ fetchMaxOutputChars?: number } 来源: packages/web/tool-web/src/index.ts:37 @deepseek-ai/dsh-tool-workflow 需要: tools · workflowEngine · systemPrompt /** Config: the model-facing tool name plus result rendering caps. */ export interface Config { /** The model-facing tool name to register (default `workflow`). */ toolName?: string /** Rendered-result ceiling, in characters: a longer JSON value is truncated with a notice (default 50000). */ maxResultChars?: number } 来源: packages/workflow/tool-workflow/src/index.ts:32 @deepseek-ai/dsh-tools 需要: systemPrompt /** Plugin config: how the registered tools are presented to the model. */ export interface Config { /** * Model presentation. `native` (default) sends every visible schema; `ptc` * sends only `run_code` plus a generated SDK prompt and collapses the * executor to the same surface (a model-direct call may only name * `run_code`; `run_code` SDK sub-dispatches keep every visible tool); `both` * sends both forms. PTC mode requires a `ctx.codeRuntime` whose `language` * has a registered SDK renderer (TypeScript or Python) and fail prompt * assembly when it is absent or has no renderer. Under `ptc`, native names * in `toolOrder` are invalid. */ mode?: ToolPresentationMode /** * Concurrency cap for a `run_code` program's overlapping sub-calls * (default 10, the loop scheduler's own default). Sub-calls follow the * native scheduling contract — only calls whose tools classify * concurrency-safe overlap; exclusive calls form barriers — so `1` * restores strictly serial dispatch. Must be a positive integer. */ maxParallelSubCalls?: number } /** How the registry presents its tools to the model (see {@link Config.mode}). */ export type ToolPresentationMode = 'native' | 'ptc' | 'both' 来源: packages/core/tools/src/index.ts:647 @deepseek-ai/dsh-typert-loader 需要: typert · loader /** Additional package artifacts whose owning plugins are nested behind another Loader entry. */ export interface Config { /** Exact npm package names that must resolve and export `./typert`. */ packages?: string[] } 来源: packages/typert/loader/src/index.ts:47 @deepseek-ai/dsh-user-approval /** Plugin config. All optional — `static Config` supplies the defaults. */ export interface Config { /** * The deployment's default {@link ApprovalPolicy} for sessions without an * `approval/policy` override — `'ask'` delegates to the composed answerers * (fail-closed with none); `'never'` auto-rejects every ask without * prompting (the deterministic CI/unattended stance). */ readonly policy?: ApprovalPolicy } /** * A session's approval policy — what happens to an {@link ApprovalService} * ask BEFORE any interactive answerer sees it: * * - `'ask'` (the default) — delegate to the composed answerers; with none * composed the chain falls through to the fail-closed `'unavailable'`. * - `'never'` — never prompt anyone: every ask resolves `'rejected'` * deterministically. The strict headless stance (CI, unattended runs) and * the policy whose outcome is knowable without asking. */ export type ApprovalPolicy = 'ask' | 'never' 来源: packages/interaction/user-approval/src/index.ts:126 @deepseek-ai/dsh-web /** * Config for the web seam. `searchProvider` / `fetchProvider` pin which provider * wins for each capability; both are optional (a single registered usable * provider auto-selects). Operational overrides such as environment variables * must feed these same fields rather than introduce a hidden priority chain. */ export interface WebRuntimeConfig { /** Explicit search provider id. Omitted = auto-select when exactly one usable. */ readonly searchProvider?: string /** Explicit fetch provider id. Omitted = auto-select when exactly one usable. */ readonly fetchProvider?: string } 来源: packages/web/web/src/index.ts:55 @deepseek-ai/dsh-web-app 需要: webServer /** Plugin config: composed deployment settings plus per-invocation command-line values. */ export interface Config { /** Permit default-browser handoff after the Loader tree settles; an SSH launch suppresses it. */ openBrowser: boolean /** Print the URL line on activation; a non-interactive layer can turn it off. */ printUrl: boolean /** * Register the model-visible surface context (the `app:web-surface` prompt * section and the `DSH_WEB_URL` bash variable). A one-shot non-interactive * layer can turn it off when its user is not in the GUI, so the * orientation text would be false. */ surfaceContext: boolean /** Explicit `--trusted-host` authorities from this invocation. */ trustedHosts: string[] } 来源: packages/bundle/web-app/src/index.ts:44 @deepseek-ai/dsh-web-fetch-http 需要: web /** Plugin config: the provider's transport and size limits plus its `User-Agent` (all defaulted). */ export interface Config { /** Maximum response body size in bytes. */ maxResponseBytes?: number /** Maximum decoded body length in characters. */ maxBodyChars?: number /** Default fetch timeout in milliseconds, within Node's timer range. */ timeoutMs?: number /** Maximum number of same-origin redirect hops to follow. */ maxRedirects?: number /** `User-Agent` header sent on every request. */ userAgent?: string } 来源: packages/web/web-fetch-http/src/index.ts:32 @deepseek-ai/dsh-web-search-deepseek 需要: web /** Plugin config (all optional — `apply` fills env-var and constant defaults). */ export interface Config { /** Literal DeepSeek API key; prefer {@link apiKeyEnv} so no secret enters configuration files. */ apiKey?: string /** Credential reference resolved for each search; defaults to `DEEPSEEK_API_KEY`. */ apiKeyEnv?: string /** Anthropic-compatible endpoint base; `/messages` is appended. */ baseURL?: string /** Anthropic-format model name. Defaults to `deepseek-v4-flash`. */ model?: string /** `anthropic-version` header value. Defaults to `2023-06-01`. */ apiVersion?: string /** Upper bound on generated tokens for the Messages request. Defaults to 4096. */ maxTokens?: number /** Maximum `web_search` server-tool uses per request. Defaults to 5. */ maxUses?: number } 来源: packages/web/web-search-deepseek/src/index.ts:46 @deepseek-ai/dsh-web-search-exa 需要: web /** Plugin config (all optional — `apply` fills env-var and constant defaults). */ export interface Config { /** Exa API key. Falls back to `$EXA_API_KEY`. Empty → provider unavailable. */ apiKey?: string /** Endpoint base; `/search` is appended. Defaults to the public API. */ baseURL?: string /** Retrieval mode sent as Exa's `type`. Defaults to `auto`. */ searchType?: 'auto' | 'keyword' | 'neural' /** Default result count when a request carries no `maxResults`. Omitted = none. */ numResults?: number /** Highlight sentences requested per result. Defaults to 1. */ highlightsPerResult?: number } 来源: packages/web/web-search-exa/src/index.ts:35 @deepseek-ai/dsh-web-search-perplexity 需要: web /** Plugin config (all optional — `apply` fills env-var and constant defaults). */ export interface Config { /** Perplexity API key. Falls back to `$PERPLEXITY_API_KEY`. Empty → unavailable. */ apiKey?: string /** Endpoint base; `/chat/completions` is appended. Defaults to the public API. */ baseURL?: string /** Search model name. Defaults to `sonar`. */ model?: string /** Upper bound on generated answer tokens. Defaults to 1024. */ maxTokens?: number /** Recency window sent as `search_recency_filter`. Omitted = no filter. */ searchRecency?: 'day' | 'week' | 'month' | 'year' } 来源: packages/web/web-search-perplexity/src/index.ts:30 @deepseek-ai/dsh-webhook-github 需要: webServer · webhookRuntime · credentials /** Required GitHub ingress configuration. */ export interface Config { /** Adapter instance name carried to rules. */ readonly source: string /** Exact absolute route path. */ readonly path: string /** Credential reference containing the shared webhook secret. */ readonly secretEnv: string /** Positive raw body ceiling in bytes. */ readonly maxBodyBytes: number } 来源: packages/webhook/webhook-github/src/index.ts:17 @deepseek-ai/dsh-workflow-worker-thread 需要: subagents /** Plugin config (all optional — `static Config` supplies the defaults). */ export interface Config { /** The `ctx.subagents` provider children run on (default `spawn`). */ provider?: string /** Concurrent `agent()` ceiling; `0` (the default) auto-resolves to `min(16, max(1, cores - 2))`. */ maxConcurrentAgents?: number /** Total `agent()` calls one run may start — the runaway-loop backstop (default 1000). */ maxTotalAgents?: number /** Items accepted by a single `parallel()`/`pipeline()` call (default 4096). */ maxItemsPerCall?: number /** vm timeout for the script's initial synchronous slice, inside the worker (default 5000 ms). */ syncTimeoutMs?: number /** * How long after a cancellation an unsettled script may keep running before * the run force-settles `cancelled` and its worker is TERMINATED (default * 5000 ms); also bounds `dispose()`. */ disposeGraceMs?: number } 来源: packages/workflow/workflow-worker-thread/src/index.ts:32 无配置的可加载插件 这些插件通过 cordis.yml 中不含 config: 块的条目加载;它们未声明任何配置接口。 @deepseek-ai/dsh-acp-app — 需要 cmdlineArgs ( packages/bundle/acp-app/src/index.ts ) @deepseek-ai/dsh-agent ( packages/core/agent/src/index.ts ) @deepseek-ai/dsh-api-remotes — 需要 typertGateway ( packages/api/remotes/src/index.ts ) @deepseek-ai/dsh-api-workspace-controller — 需要 typert · workspaceRegistry ( packages/api/workspace-controller/src/index.ts ) @deepseek-ai/dsh-authorization — 需要 credentials ( packages/credentials/authorization/src/index.ts ) @deepseek-ai/dsh-client-locale ( packages/client/locale/src/index.ts ) @deepseek-ai/dsh-client-modules — 需要 webServer · loader ( packages/client/modules/src/index.ts ) @deepseek-ai/dsh-client-ui-agent-preset ( packages/client/ui-agent-preset/src/index.ts ) @deepseek-ai/dsh-client-ui-approval ( packages/client/ui-approval/src/index.ts ) @deepseek-ai/dsh-client-ui-attachment ( packages/client/ui-attachment/src/index.ts ) @deepseek-ai/dsh-client-ui-brand-official ( packages/client/ui-brand-official/src/index.ts ) @deepseek-ai/dsh-client-ui-chat ( packages/client/ui-chat/src/index.ts ) @deepseek-ai/dsh-client-ui-commands ( packages/client/ui-commands/src/index.ts ) @deepseek-ai/dsh-client-ui-conversation ( packages/client/ui-conversation/src/index.ts ) @deepseek-ai/dsh-client-ui-cordis ( packages/extensions/ui-cordis/src/index.ts ) @deepseek-ai/dsh-client-ui-deliverables — 需要 systemPrompt ( packages/client/ui-deliverables/src/index.ts ) @deepseek-ai/dsh-client-ui-directory-picker-browse ( packages/client/ui-directory-picker-browse/src/index.ts ) @deepseek-ai/dsh-client-ui-directory-picker-native ( packages/client/ui-directory-picker-native/src/index.ts ) @deepseek-ai/dsh-client-ui-goal ( packages/client/ui-goal/src/index.ts ) @deepseek-ai/dsh-client-ui-input-trigger ( packages/client/ui-input-trigger/src/index.ts ) @deepseek-ai/dsh-client-ui-jobs ( packages/client/ui-jobs/src/index.ts ) @deepseek-ai/dsh-client-ui-layout ( packages/client/ui-layout/src/index.ts ) @deepseek-ai/dsh-client-ui-message-feedback ( packages/client/ui-message-feedback/src/index.ts ) @deepseek-ai/dsh-client-ui-model-selection ( packages/client/ui-model-selection/src/index.ts ) @deepseek-ai/dsh-client-ui-permission-presets ( packages/client/ui-permission-presets/src/index.ts ) @deepseek-ai/dsh-client-ui-plan ( packages/client/ui-plan/src/index.ts ) @deepseek-ai/dsh-client-ui-reference ( packages/client/ui-reference/src/index.ts ) @deepseek-ai/dsh-client-ui-renderer ( packages/client/ui-renderer/src/index.ts ) @deepseek-ai/dsh-client-ui-schedule ( packages/client/ui-schedule/src/index.ts ) @deepseek-ai/dsh-client-ui-session ( packages/client/ui-session/src/index.ts ) @deepseek-ai/dsh-client-ui-settings ( packages/client/ui-settings/src/index.ts ) @deepseek-ai/dsh-client-ui-settings-general ( packages/client/ui-settings-general/src/index.ts ) @deepseek-ai/dsh-client-ui-settings-models ( packages/client/ui-settings-models/src/index.ts ) @deepseek-ai/dsh-client-ui-settings-plugin-inventory ( packages/client/ui-settings-plugin-inventory/src/index.ts ) @deepseek-ai/dsh-client-ui-settings-plugins ( packages/client/ui-settings-plugins/src/index.ts ) @deepseek-ai/dsh-client-ui-sidebar ( packages/client/ui-sidebar/src/index.ts ) @deepseek-ai/dsh-client-ui-skill ( packages/client/ui-skill/src/index.ts ) @deepseek-ai/dsh-client-ui-subagent ( packages/client/ui-subagent/src/index.ts ) @deepseek-ai/dsh-client-ui-theme ( packages/client/ui-theme/src/index.ts ) @deepseek-ai/dsh-client-ui-tool ( packages/client/ui-tool/src/index.ts ) @deepseek-ai/dsh-client-ui-trajectory ( packages/client/ui-trajectory/src/index.ts ) @deepseek-ai/dsh-client-ui-user-questions ( packages/client/ui-user-questions/src/index.ts ) @deepseek-ai/dsh-client-ui-workflow-run ( packages/client/ui-workflow-run/src/index.ts ) @deepseek-ai/dsh-client-ui-workspace ( packages/client/ui-workspace/src/index.ts ) @deepseek-ai/dsh-command-compact — 需要 commands · compact ( packages/compaction/command-compact/src/index.ts ) @deepseek-ai/dsh-command-feedback — 需要 commands ( packages/feedback/command-feedback/src/index.ts ) @deepseek-ai/dsh-command-goal — 需要 commands · goals ( packages/goal/command-goal/src/index.ts ) @deepseek-ai/dsh-commands ( packages/interaction/commands/src/index.ts ) @deepseek-ai/dsh-cordis-client-runner ( packages/extensions/cordis-client-runner/src/index.ts ) @deepseek-ai/dsh-deepseek-llm-api-extensions ( packages/llm/deepseek-llm-api-extensions/src/index.ts ) @deepseek-ai/dsh-experimental-client-ui-agent-team ( packages/experimental/client-ui-agent-team/src/index.ts ) @deepseek-ai/dsh-fs-e2b — 需要 e2b ( packages/e2b/fs-e2b/src/index.ts ) @deepseek-ai/dsh-fs-observation-policy ( packages/fs/fs-observation-policy/src/index.ts ) @deepseek-ai/dsh-goal-round-driver — 需要 agents · goals · sessions ( packages/goal/goal-round-driver/src/index.ts ) @deepseek-ai/dsh-host-directory-picker-auto — 需要 webServer · loader ( packages/host/directory-picker-auto/src/index.ts ) @deepseek-ai/dsh-host-directory-picker-native ( packages/host/directory-picker-native/src/index.ts ) @deepseek-ai/dsh-host-plugin-inventory — 需要 loader ( packages/host/plugin-inventory/src/index.ts ) @deepseek-ai/dsh-llm ( packages/llm/llm/src/index.ts ) @deepseek-ai/dsh-lsp ( packages/lsp/lsp/src/index.ts ) @deepseek-ai/dsh-schedule — 需要 agents · sessions · tools · sessionPersistence ( packages/schedule/schedule/src/index.ts ) @deepseek-ai/dsh-session ( packages/core/session/src/index.ts ) @deepseek-ai/dsh-session-checkpoint-policy — 需要 llm · sessionPersistence · sessions · tools ( packages/session/session-checkpoint-policy/src/index.ts ) @deepseek-ai/dsh-session-projection ( packages/session/session-projection/src/index.ts ) @deepseek-ai/dsh-session-stats — 需要 sessionProjections ( packages/session/session-stats/src/index.ts ) @deepseek-ai/dsh-session-turn-outline — 需要 sessionProjections ( packages/session/session-turn-outline/src/index.ts ) @deepseek-ai/dsh-skill-badge — 需要 skills ( packages/skill/skill-badge/src/index.ts ) @deepseek-ai/dsh-storage ( packages/storage/storage/src/index.ts ) @deepseek-ai/dsh-subagent ( packages/subagent/subagent/src/index.ts ) @deepseek-ai/dsh-subprocess-local ( packages/subprocess/subprocess-local/src/index.ts ) @deepseek-ai/dsh-terminal ( packages/terminal/terminal/src/index.ts ) @deepseek-ai/dsh-tool-ask-user — 需要 tools · userInteraction ( packages/interaction/tool-ask-user/src/index.ts ) @deepseek-ai/dsh-tool-call-timeout-policy — 需要 tools ( packages/guard/timeout-policy/src/index.ts ) @deepseek-ai/dsh-tool-cordis — 需要 tools · systemPrompt · dynamicCordisRunner · cordisInspect ( packages/extensions/tool-cordis/src/index.ts ) @deepseek-ai/dsh-tool-subagent-control — 需要 tools · subagents ( packages/subagent/tool-subagent-control/src/index.ts ) @deepseek-ai/dsh-user-questions ( packages/interaction/user-questions/src/index.ts ) @deepseek-ai/dsh-webhook — 需要 agents · agentDefaultModel · agentPresets · permissionPresets · sessionTitle · workspaceRegistry ( packages/webhook/webhook/src/index.ts ) @deepseek-ai/dsh-workspace — 需要 storageDomain · sessionPersistence ( packages/workspace/workspace/src/index.ts ) Seam 包(不可直接加载) 抽象服务类——部署时应改为加载具体的实现包(参见 能力 seam )。 @deepseek-ai/dsh-attachment — 抽象 AttachmentStore ( packages/attachment/attachment/src/index.ts ) @deepseek-ai/dsh-code-runtime — 抽象 CodeRuntime ( packages/code-runtime/code-runtime/src/index.ts ) @deepseek-ai/dsh-compaction — 抽象 CompactionEngine ( packages/compaction/compaction/src/index.ts ) @deepseek-ai/dsh-credentials — 抽象 Credentials ( packages/credentials/credentials/src/index.ts ) @deepseek-ai/dsh-file-reference — 抽象 FileReferenceService ( packages/context/file-reference/src/index.ts ) @deepseek-ai/dsh-fs — 抽象 FileSystem ( packages/fs/fs/src/index.ts ) @deepseek-ai/dsh-host-directory-picker — 抽象 DirectoryPicker ( packages/host/directory-picker/src/index.ts ) @deepseek-ai/dsh-jobs — 抽象 JobRegistry ( packages/jobs/jobs/src/index.ts ) @deepseek-ai/dsh-sandbox — 抽象 SandboxProvider ( packages/sandbox/sandbox/src/index.ts ) @deepseek-ai/dsh-session-persistence — 抽象 SessionPersistence ( packages/session/session-persistence/src/index.ts ) @deepseek-ai/dsh-session-query — 抽象 SessionQueryEngine ( packages/session-query/session-query/src/index.ts ) @deepseek-ai/dsh-settings — 抽象 Settings ( packages/settings/settings/src/index.ts ) @deepseek-ai/dsh-shell — 抽象 ShellExecutor ( packages/shell/shell/src/index.ts ) @deepseek-ai/dsh-spill — 抽象 SpillStore ( packages/spill/spill/src/index.ts ) @deepseek-ai/dsh-subprocess — 抽象 SubprocessRuntime ( packages/subprocess/subprocess/src/index.ts ) @deepseek-ai/dsh-workflow — 抽象 WorkflowEngine ( packages/workflow/workflow/src/index.ts ) 库包(无插件入口) 由其他包作为库导入; cordis.yml 无法加载它们。 @deepseek-ai/dsh-agent-loop-testkit ( packages/test-support/agent-loop-testkit/src/index.ts ) @deepseek-ai/dsh-anonymous-user-id ( packages/identity/anonymous-user-id/src/index.ts ) @deepseek-ai/dsh-app-boot ( packages/boot/app-boot/src/index.ts ) @deepseek-ai/dsh-atomic-write ( packages/util/atomic-write/src/index.ts ) @deepseek-ai/dsh-base ( packages/bundle/base/src/index.ts ) @deepseek-ai/dsh-brand ( packages/util/brand/src/index.ts ) @deepseek-ai/dsh-client-store ( packages/client/store/src/index.ts ) @deepseek-ai/dsh-client-test-runtime ( packages/test-support/client-runtime/src/index.ts ) @deepseek-ai/dsh-client-ui-primitives ( packages/client/ui-primitives/src/index.ts ) @deepseek-ai/dsh-client-ui-slots ( packages/client/ui-slots/src/index.ts ) @deepseek-ai/dsh-client-web ( packages/client/web/src/index.ts ) @deepseek-ai/dsh-cmdline ( packages/boot/cmdline/src/index.ts ) @deepseek-ai/dsh-deque ( packages/util/deque/src/index.ts ) @deepseek-ai/dsh-experimental-agent-team-profile ( packages/experimental/agent-team-profile/src/index.ts ) @deepseek-ai/dsh-experimental-agent-team-web-profile ( packages/experimental/agent-team-web-profile/src/index.ts ) @deepseek-ai/dsh-experimental-webworker-packer ( packages/experimental/webworker-packer/src/index.ts ) @deepseek-ai/dsh-experimental-webworker-runtime ( packages/experimental/webworker-runtime/src/index.ts ) @deepseek-ai/dsh-home-paths ( packages/util/home-paths/src/index.ts ) @deepseek-ai/dsh-hook-protocol ( packages/hooks/hook-protocol/src/index.ts ) @deepseek-ai/dsh-launch-environment ( packages/util/launch-environment/src/index.ts ) @deepseek-ai/dsh-llm-mock-server ( packages/test-support/llm-mock-server/src/index.ts ) @deepseek-ai/dsh-loader-smoke ( packages/test-support/loader-smoke/src/index.ts ) @deepseek-ai/dsh-native-command ( packages/util/native-command/src/index.ts ) @deepseek-ai/dsh-output-retention ( packages/util/output-retention/src/index.ts ) @deepseek-ai/dsh-sandbox-windows-acl ( packages/sandbox/sandbox-windows-acl/src/index.ts ) @deepseek-ai/dsh-scope ( packages/core/scope/src/index.ts ) @deepseek-ai/dsh-sdk-client ( packages/sdk/client/src/index.ts ) @deepseek-ai/dsh-sdk-minimal ( packages/bundle/sdk-minimal/src/index.ts ) @deepseek-ai/dsh-sdk-protocol ( packages/sdk/protocol/src/index.ts ) @deepseek-ai/dsh-session-snapshot ( packages/test-support/session-snapshot/src/index.ts ) @deepseek-ai/dsh-session-telemetry ( packages/session/session-telemetry/src/index.ts ) @deepseek-ai/dsh-session-title-llm ( packages/session/session-title-llm/src/index.ts ) @deepseek-ai/dsh-subagent-in-process-driver ( packages/subagent/subagent-in-process-driver/src/index.ts ) @deepseek-ai/dsh-timeout ( packages/util/timeout/src/index.ts ) @deepseek-ai/dsh-typert-generator ( packages/typert/generator/src/index.ts ) @deepseek-ai/dsh-typert-protocol ( packages/typert/protocol/src/index.ts ) @deepseek-ai/dsh-typert-registry ( packages/typert/registry/src/index.ts ) @deepseek-ai/dsh-util-crypto ( packages/util/crypto/src/index.ts ) @deepseek-ai/dsh-util-time ( packages/util/time/src/index.ts ) @deepseek-ai/dsh-util-values ( packages/util/values/src/index.ts ) @deepseek-ai/dsh-util-workspace-path ( packages/util/workspace-path/src/index.ts ) @deepseek-ai/dsh-win32-process ( packages/subprocess/win32-process/src/index.ts ) 开发指南 English | 中文 搭建教程引导新贡献者从准备前置条件开始,直到检出目录通过检查。后面的贡献者参考介绍仓库布局、日常工作流和 CI 组织方式。设计依据与实现细节属于链接的 Agent Note 和脚本。 搭建教程 前置条件 Node.js 支持 22.19+ 与 24+。CI 覆盖 22.19、24 和 26;见 Node 引擎下限 Agent Note 。 启用了 Corepack 的 pnpm。仓库在 package.json 中固定使用 pnpm@11.7.0 ;如果 pnpm --version 无法通过 Corepack 解析,请先运行 corepack enable 。 Git 2.26 或更高版本;钩子设置会启用 Git 的 worktree 专属配置扩展。 可选:一个 DeepSeek API key,用于 Web、headless 和 ACP(Agent Client Protocol)自动化 agent(智能体)演示以及真实 API 的 e2e 测试。 首次搭建 在仓库根目录安装依赖: pnpm install 安装过程还会通过 scripts/install-lefthook.mjs 配置 worktree 本地的 Lefthook 钩子和 dsh-translation-pairing Git 合并驱动。 worktree 本地钩子 Agent Note 负责钩子路径的安全约定; 自动配对合并 Agent Note 负责合并驱动。 如果依赖是从缓存恢复或 postinstall 被跳过而导致任一集成缺失,请手动安装: node scripts/install-lefthook.mjs 如果包装脚本拒绝现有 Git 配置或报告陈旧锁,请遵循其诊断和所链接的 Agent Note,不要凭猜测编辑 worktree 元数据。移动检出目录后,请重新运行包装脚本以重新生成自有路径。 新克隆后请先运行一次类型检查: pnpm run typecheck pnpm run typecheck 成功退出即表示搭建完成。 贡献者参考 TypeScript 项目布局 仓库使用相互隔离的 Host 与 Client aggregate。普通包只登记进其中一个 aggregate;Host 包进入 tsconfig.host.json ,Client 包进入 tsconfig.client.json ; host/webserver 、 compaction/compaction 与 typert/registry 三个包被两个 aggregate 同时引用,作为共享 leaf,让两侧对同一份源码做类型检查。 文件 角色 是否构成 program? tsconfig.json solution 根: extends base、 files: [] 、引用两个 aggregate。它是 tsserver 发现入口,也是显式执行整张 Project Reference 图时的入口;经继承的 paths 充当 tsx 运行 scripts/ 时的解析配置。 否 tsconfig.host.json Host aggregate:Host 包、示例、测试、脚本和 website,以及 api/remotes 的 Host 特例 project。 是 tsconfig.client.json Client aggregate: packages/client/* 包及其测试、 apps/web ,以及 api/remotes 的 Client 特例 project。 是 tsconfig.base.json 共享 compilerOptions 与源码 paths 映射。同时是各 vitest 配置让 vite-tsconfig-paths 指向的解析门面:它没有 include ,因此其 paths 适用于任何 importer。 否 tsconfig.base.client.json 浏览器编译设置( jsx 、DOM lib、 types: [] ),由 Client aggregate 和每个 packages/client/* 包 extends。 否 Host 与 Client 保持两个 aggregate program,是因为两侧在相同键下以不同服务对 cordis Context 接口做声明合并;单一 program 同时看到两份合并会报冲突。这种冲突只存在于 ts.Program 内部——模块解析永远不会触发它——所以 solution 可以同时引用两个 aggregate,一个 paths 门面也可以横跨两侧。由此推出三条纪律: tsconfig.base.json 永不添加 include 或 files :它们会泄漏进每个 extends 它的包项目,并收窄门面的全匹配范围。 构造全仓 ts.Program 的脚本显式以 tsconfig.host.json 或 tsconfig.client.json 为种子——根 solution 永不作为种子,因为把两个 aggregate 展平进一个 program 会撞上 Context 合并冲突。 新包只登记进一个 aggregate;只有上述拆分包同时携带两个 leaf 配置,共享 leaf 因两侧需要对同一份源码做类型检查而登记进两个 aggregate。包同时具有 Node loader 入口和 browser 入口并不构成拆分理由;普通 Client 插件的两份运行时产物都在 Client 构建阶段生成。 拆分 Host/Client tsconfig 的包有六个: api/remotes 、 api/gateway 、 api/session-controller 、 api/workspace-controller 、 client/connection 与 session-query/session-log-export 。 api/remotes 的 Host 入口进入 Host Typert 图,而 Client 入口导入生成的 /remote 声明; session-log-export 则让 Node archive 生产代码不进入浏览器 controller。每个拆分包根 tsconfig.json 因此只作为 solution,两个 aggregate 和直接消费方分别引用 tsconfig.host.json 或 tsconfig.client.json 。workspace constraints 门禁遍历可达的 Project Reference 图,并按各引用 project 自身的 compiler face 检查:只有单一配置的目标可由任一 face 引用,拆分配置的目标则必须引用匹配的 leaf,不得引用 solution 根或另一侧 leaf;该门禁按「两个 leaf 配置同时存在」自动发现拆分包,所以新拆分的包会自动纳入管辖。 api-remotes README 与 session-log-export README 分别说明其拆分。 根构建按生成依赖排序: tsc -b tsconfig.host.json tsdown --env.DSH_BUILD_FACE host tsc -b tsconfig.client.json tsdown --env.DSH_BUILD_FACE client pnpm run build:web 两次 tsdown 都使用同一组完整 workspace 匹配,不扫描构建产物来发现 Client 包,也不维护 Host/Client 包过滤表。包内 tsdown 配置根据 DSH_BUILD_FACE 决定当前阶段的入口:普通 Client 插件在 Client 阶段同时生成 Node loader 与 browser bundle; api-remotes 通过 hostPhase: true 提前生成 Host 入口,再在 Client 阶段只生成 browser bundle。tsdown 只消费 lib/types 中由前置 tsc 发射的 JavaScript。 Typert 只在 Host tsdown 中以 tsconfig.host.json 为种子运行。它分析 Host 类型并生成 Host 反射产物及 Host-for-Client Remote 投影;Client tsdown 不启动 Typert。 pnpm run typecheck 因此先执行完整 Host lib 阶段,再运行 Client tsc; pnpm run build 继续执行 Client tsdown 和 Web 构建。该顺序的决策记录见 API Remotes 生成约定构建 Note 。 pnpm run build 会内联根包版本、七位源码 commit,并在 Git 报告本地变化时内联 dirty 标记;调用方提供的其他 DSH_CLIENT_* 值也会被继承。 pnpm run build:official 是与 CI 和 release 产物构建等价的跨平台本地命令,并省略本地 dirty 标记。每次完整构建成功后都会写入一份被 gitignore 的记录,把精确公开值与 Vite 输出及动态 client bundle 绑定;release 打包和 built Web 测试会拒绝缺少记录或被后续局部构建改动的产物。 pnpm run dev:web 仍需要先执行完整构建来准备产物树,但会在启动时读取一次当前版本和 Git 状态,并在本次会话的所有 watcher stage 之间共享该环境;它不会校验完整构建记录,因为 watcher stage 会重写记录覆盖的产物。 静态分析和测试通过 base 的 paths 映射把工作区 import 解析到 src ,且必须在干净树上通过;消费构建产物 lib/ 的门禁显式声明该依赖。生成的 Host-for-Client Remote 声明是有意设置的例外:公共 typecheck 、 lint 和 doc-typecheck 命令会先生成这些声明,而内部 *:contracts-ready 脚本假定调用它的公共命令或调度器门禁已经依赖 Typert 约定生成阶段或完整构建。两个 aggregate 的设置见 solution-root Note ,tsc-first 发射职责见 ts-build-config Note ,门禁准备约定见 Typert Remote Agent Note 。 业务服务在 Host 使用 @Remote 或 @RemoteScope 声明可调用方法;Host 构建生成 Host-for-Client 类型与运行时贡献,Client 的 api-remotes 组合加载这些贡献并挂到 ctx.remote 与作用域 agentCtx.remote namespace。两侧的生成产物、装配关系、SRC 开发回退和 Web 构建顺序见 API Gateway 。 如果相关的本地检查需要使用构建后的包产物,请先构建一次: pnpm run build pnpm run hygiene 包含 publint (用构建出的 lib/*.js 文件校验包入口点)和 verify-node-next-types (用一个临时的 NodeNext 消费方校验构建出的声明文件)。新 worktree 在 pnpm run build 运行之前没有打包的 JS 和声明文件;普通提交和推送无需构建,除非所选检查会使用这些产物。 环境变量 真实的 DeepSeek 适配器和需要密钥的 agent 演示从环境变量或仓库根目录一个被 gitignore 的 .env 文件读取凭证: DEEPSEEK_API_KEY=sk-... DEEPSEEK_BASE_URL=https://... # optional DEEPSEEK_BASE_URL 可选,默认为公开 API。请勿提交真实凭证。未设置 DEEPSEEK_API_KEY 时,真实 API 的 e2e 套件会自动跳过。 Git 集成 当两种语言的文件都使用 Git 默认文本策略且能干净合并时,配对合并驱动会根据已确认的祖先、当前和另一侧的配对文档 blob,推导出发生冲突的 .i18n.yaml 记录。配对文档发生冲突、存在非文本合并配置或记录无效时,它会拒绝处理并保留冲突;如果合并已经因冲突而停止,请运行 pnpm run resolve-translation-pairing-conflicts ,该命令会暂存每份可安全生成的配对记录;如果其他配对冲突仍需手工处理,则以非零状态退出。 双语文档约定 列出该驱动接受的确切文件和状态。 安装脚本在发布 worktree 配置前,会探测确切的 Node/tsx 驱动入口点。如果该运行时之后变得不可用,不依赖 Node 的启动器会写入 Git 的普通文本合并结果、让伴随文件保持未解决状态,并打印恢复路径;请恢复依赖后运行 pnpm run resolve-translation-pairing-conflicts ,或运行 git merge --abort 。如果 pre-merge-commit 拒绝原本能干净完成的合并,Git 会把完整结果留在暂存区但不创建提交;请修复失败后运行 git commit ,或中止合并。确切的索引与 MERGE_HEAD 状态由 自动配对合并 Agent Note 负责记录。 lefthook 在 lefthook.yml 中配置,作为快速的本地检查点: pre-commit 对照暂存的配对文档 blob 校验暂存的配对记录,使用不加载项目的 .oxlintrc.staged.json 配置验证暂存文件,并通过一次有界重试应用 Oxlint 修复,在暂存文件属于 THIRD_PARTY_NOTICES.md 的输入时重新生成该文件,然后检查暂存 diff 中的空白错误,并运行 vendor manifest(元数据清单)守卫; pre-merge-commit 在 Git 创建自动合并提交前执行同样以索引为准的配对检查; pre-push 运行 pnpm run typecheck ;该命令会先完成包含 Typert 约定生成的完整 Host lib 阶段,再运行 Client TypeScript 检查。 vendor manifest 守卫检查 vendor/*/src 下的改动是否连同对应的 vendor/README.md manifest 更新一起暂存。请在编辑 vendor 代码前先阅读 vendor/README.md 。 除限定范围的暂存记录校验外,这些钩子有意不运行测试、快照、文档检查、构建或 hygiene 。贡献者只运行一次 与改动行为相关的检查 ;CI 负责全量覆盖率门禁、构建产物冒烟测试,以及 Node 22.19、24 和 26 兼容性矩阵。 贡献者可以选择运行 pnpm run check:all ,执行全面的本地门禁集。该命令独立于 Git 钩子,也不是对 agent 的指令。 CI 门禁 keyless CI 工作流 将独立门禁分组到若干宽粒度 lane,并在受支持的 Node 版本上运行一组较小的兼容性检查。产物消费方在各自 lane 内等待一次 build。单独的真实 API 工作流按其配置的 worker 上限运行 pnpm run test:e2e 。当前门禁和 job 清单以 scripts/run-gates.ts 和工作流文件为准。 日常命令 根目录的 贡献者说明 概述常用命令, package.json 与 scripts/run-gates.ts 则负责当前脚本和门禁清单。请选择覆盖变更表面的最小检查集。文档变更使用 pnpm run doc-sync ;包公开行为变更还需更新所属 README 或 JSDoc,而基于构建产物的检查需要先运行 pnpm run build 。 Profile 运行 从源码 checkout 运行这些演示前,请单独执行仓库构建: pnpm run build 单次运行的 Headless coding agent 需要环境变量或仓库根目录 .env 中的 DEEPSEEK_API_KEY : pnpm dsh --profile headless "summarize this workspace" PTC mode 演示启用代码式工具展示,并运行同一个 headless profile: pnpm run demo:ptc -- "summarize this workspace" TODO 标记 请使用以下三种注释标签之一标记代码中的已知问题,按紧急程度排序: FIXME :应当阻塞新版本发布的问题。除非评审者明确同意该更改可以合并,否则发布版本不应包含未解决的 FIXME ; TODO :应当尽快修复的问题,等资源到位即可处理; XXX :也许某天会修复的问题,优先级最低,不作承诺。 请选择与紧急程度匹配的标签,让浏览代码的人一眼分清「发布阻塞」和「有空再说」。 逐字记录类型定义( ts type-equiv ) 子系统 页面会把与源码等价的声明及其原始 JSDoc 一并粘贴,让读者看到确切类型定义和源码约定。为防止粘贴内容在源码变化时漂移,请将其围栏为 ```ts type-equiv (而不是 ```ts ),并在 scripts/type-equiv.manifest.json 中登记它镜像的源文件和符号: { "doc": "docs/subsystems/session.md", "symbol": "SessionEvent", "source": "packages/core/session/src/types.ts" } pnpm run verify-type-equiv ( doc-sync 的一环)随后通过 TypeScript 解析器从源码提取该符号的声明及其附带的 JSDoc,并断言代码块同时匹配两者。对于不应把实现体写进目录的类,请使用 ```ts public-api 并设置 "projection": "public-api" ;门禁检查的投影会保留公共字段、构造函数、访问器、方法以及类和成员的原始 JSDoc,同时省略实现体和私有或受保护成员。比对会忽略空白和非 JSDoc 注释,但要求保留每条原始 JSDoc(包括成员文档),让读者同时看到源码约定和确切类型定义。该门禁按文档、符号和投影,在主块与 manifest 条目之间强制 1:1 对应;只有当配对 .zh.md 块的完整受跟踪围栏序列与其无后缀兄弟文件按字节一致且顺序相同时,才会复用后者的条目。 doc-typecheck 对可编译围栏应用同一派生规则,同时跳过两种源码等价围栏的编译,并将其排除在 opt-out 比例的计算之外。当你改动一个已记录的类型声明或其 JSDoc 时,门禁会失败直到你更新粘贴内容;当你增删一个主块时,请在同一个变更里更新 manifest。 API Gateway English | 中文 本文是 Typert API Gateway 的当前状态参考。它描述业务服务如何声明一元 Remote 方法、构建如何生成 Host 与 Client 约定,以及调用如何复用 Connection 的 RPC 与 /api 路由。会话事件、增量数据和其他流协议不属于本文范围;它们可以使用同一个 Connection,但不使用 Remote 方法描述符。 编程模型 业务服务通过 @Remote 或 @RemoteScope 选择对 Client 开放的方法。未标记的方法不会进入生成的 Client 类型或运行时贡献,也不能通过 ctx.remote 调用。 @Remote 表示调用根 Host Context 中注册的 Cordis 服务。复杂的 Host 对象不能直接跨 wire 传输;业务包必须通过 TypertLookupMap 声明它与 wire identity 的关联,并在运行时向 ctx.typert.lookups 注册默认解析提供方。例如 Agent 参数在 Host 签名中名为 agent ,生成的 wire 字段为 agentId ,Gateway 在调用业务方法前将 id 解析为 Host 对象。Host 组合可以用 ctx.typert.lookups.configure() 覆盖某个 lookup key 的解析策略,而不改变业务包拥有的参数名、wire 字段或规范类型 symbol。 @RemoteScope(key) 表示先通过 ctx.typert.contexts 把 identity 解析为一个作用域 Context,再从该 Context 取得服务并调用方法。它适用于方法本身依赖作用域组合、而不需要显式接收 Agent 等对象的情形。 服务通常继承 TypertRemoteService ,让 Cordis 服务 key 与默认 Remote namespace 在构造器中显式绑定。已有其他基类的服务可以改为声明 readonly typertRemote = bindTypertRemote(this, serviceKey) ;两种方式都会留下可检查的公开 binding,不依赖编译器向构造函数注入 symbol。 import type { Agent } from '@deepseek-ai/dsh-agent' import { TypertRemoteService, Remote, RemoteScope } from '@deepseek-ai/dsh-typert-protocol' import type { Context } from '@deepseek-ai/cordis' export interface CreateGoalRequest { objective: string } export interface CreateGoalResult { accepted: boolean } export class GoalService extends TypertRemoteService { constructor(ctx: Context) { super(ctx, 'goals') } @Remote('create') createForClient( agent: Agent, request: CreateGoalRequest, signal: AbortSignal, ): CreateGoalResult { signal.throwIfAborted() return this.create(agent, request) } @RemoteScope('agent', 'current') currentForClient(): CreateGoalResult { return { accepted: true } } private create(_agent: Agent, request: CreateGoalRequest): CreateGoalResult { return { accepted: request.objective.length > 0 } } } Remote 方法可以同步返回或返回 Promise。若需要协作式取消,Host 签名的最后一个参数必须是全局类型的 signal: AbortSignal ;它记录在描述符中而不是进入 args ,Client 生成的方法则接受最后一个可选的 AbortSignal 。 Client 使用普通对象上的具体函数,不使用 JavaScript Proxy。直接调用与作用域调用分别出现在 ctx.remote. 和 agentCtx.remote. 。每个 namespace 都是注册为 remote. 的可追踪 Cordis 子服务;Client assembly 通过 ctx.remote.$mount() 挂载贡献,最后一个方法撤回后该 namespace 随即卸载。依赖声明归实际调用方所有:只有读取 ctx.remote. 或 agentCtx.remote. 的业务包才在自己的 inject 中同时声明 remote 与 remote. ;只负责挂载 contribution 的 assembly,以及不调用该 namespace 的上层运行时,不代业务包声明 namespace 依赖。当一个 @Remote 方法恰好有一个 lookup 参数、且同名 TypertContextMap 使用相同 wire identity 时,生成的作用域签名会省略该 identity 参数。 @RemoteScope 只生成作用域调用接口。 import type { SessionId } from '@deepseek-ai/dsh-session/types' import type { AgentContext } from '@deepseek-ai/dsh-api-session-controller/client' import type { Context } from '@deepseek-ai/cordis' import type {} from '@deepseek-ai/dsh-api-remotes/client' export const inject = ['remote', 'remote.goals'] declare const ctx: Context declare const agentCtx: AgentContext declare const agentId: SessionId await ctx.remote.goals.create(agentId, { objective: 'ship it' }) await agentCtx.remote.goals.create({ objective: 'ship it' }) Client 应用只装配 @deepseek-ai/dsh-api-remotes 。该包以运行时值导入被选业务包的 /remote 子路径,通过 ctx.remote.$mount() 挂载贡献,同时重新导出相同文件中的声明合并。增加一个 Host Remote 包是 Client 组合所有者的显式选择;业务组件不需要分别加载 Typert Gateway 或业务包的 Remote JS。 api-remotes 装配与 ctx.remote 约定不依赖 React;任何 Client 装配能看到的 Host 方法都只限于生成时选择的 Remote 方法。 组件职责 位置 包或入口 职责 共享 @deepseek-ai/dsh-typert-protocol 声明 decorator、Gateway binding、可合并协议映射、调用描述符及提供方类型;不启动 TypeScript 分析,也不注册 Cordis 服务 构建 @deepseek-ai/dsh-typert-generator 从 Host ts.Program 严格分析 Remote 签名、类型图、lookup、Context 与源码位置,并生成 Host 和 Host-for-Client 产物 Host @deepseek-ai/dsh-typert-registry 与 Loader 把生成的 Host 描述符、schema 及业务包注册项放入 ctx.typert ,并持有 lookup 与 Context 提供方 Host @deepseek-ai/dsh-api-session-controller 负责应用的 Agent/Session 身份策略,并配置对应的 Typert lookup Host @deepseek-ai/dsh-api-gateway 提供 ctx.typertGateway ,认领 Remote endpoint,解析对象或 Context,调用实时 Cordis 服务,并校验请求值和返回值 Client @deepseek-ai/dsh-api-gateway/client 提供 ctx.remote 与 remote. 子服务,把生成的描述符挂成具体方法,并通过 Connection 发起、校验和取消调用 Client @deepseek-ai/dsh-api-remotes/client 显式选择并挂载本应用允许使用的 /remote 贡献,向业务代码带入对应的声明合并 双侧 @deepseek-ai/dsh-client-connection 提供 RPC carrier、请求关联、信任边界、取消、响应 envelope 与 /api HTTP bridge API Gateway 包同时拥有 Host dispatcher 与 Client Remote endpoint 两个对等入口,但两侧构建不会进入同一个 ts.Program 。Host 入口不导入 Client 的 Cordis Context 合并,Client 入口也不导入 Host Gateway 服务。 严格生成流水线 根构建依次执行 build:lib:host 、 build:lib:client 与 build:web 。Host lib 阶段先运行 tsc -b tsconfig.host.json ,再运行 tsdown --env.DSH_BUILD_FACE host ;Typert generator 由正常 Host Project Reference 图编译,并在这次 tsdown 中以 Host aggregate 为唯一 ts.Program 种子运行。Client lib 阶段随后运行 tsc -b tsconfig.client.json 与 tsdown --env.DSH_BUILD_FACE client ,使用刚生成的 Remote Client 声明和运行时贡献,但不再次启动 Typert。 两次 tsdown 都接收完整 workspace,且都只打包 lib/types 中由对应 tsc 阶段发射的 JavaScript。根配置不扫描 Client 产物、不按包名分类,也不向 tsdown 传维护式 filter;各包的本地配置根据 DSH_BUILD_FACE 返回当前阶段的入口。普通 Client 插件在 Client 阶段一起生成 Node loader 入口与 browser bundle。 api/remotes 、 api/gateway 、 api/session-controller 与 api/workspace-controller (外加 client/connection )都拆分 TypeScript face。 api/remotes 的 Client project 依赖业务包在 Host tsdown 中生成的 /remote 声明;根 aggregate 与直接消费方必须分别引用各拆分包自己的 tsconfig.host.json 或 tsconfig.client.json 。 api-remotes 的 clientBundle(..., { hostPhase: true }) 让 Host 入口在 Host tsdown 中生成,让 Client tsdown 只生成 browser 入口。Agent/Session lookup 策略位于 @deepseek-ai/dsh-api-session-controller ,而非 api-remotes 。 每个贡献业务包把生成文件写入自己的 lib/ ,而不是源码目录: 文件 消费方 内容 typert.host.js Host Loader Host face 的运行时反射、严格调用描述符和 schema 注册值 typert.host.d.ts Host 类型系统 Host face 的生成声明 typert.remote-client.js api-remotes 可挂载的 TypertRemoteContribution ,包含严格描述符与运行时 codec typert.remote-client.d.ts Client 类型系统 TypertRemoteNamespaceMap 与 TypertRemoteScopeMap 的声明合并及 Client-safe 类型引用 typert.remote-client.d.ts.map 编辑器 将生成的方法属性映射回 Host 包中的 Remote 方法声明 业务包通过 ./typert 暴露 Host Loader 入口,通过 ./remote 暴露 Host-for-Client 入口。生成器同时校验这些包 export 及发布文件清单;只有具备相应入口的显式贡献包才会生成产物。 Remote Client 声明中的参数名来自 wire 字段,参数和返回类型则引用原业务包导出的 Client-safe 类型。声明 map 把 ctx.remote.goals.create 最终解析到的生成属性映射到带 @Remote 的 Host 源方法,因此支持 declaration-map 的编辑器可以从 Client 调用跳到真实实现,而不是停在生成的 .d.ts 。 严格分析要求 Remote 是公开、非静态、有具体实现的实例方法。方法不能是泛型;参数必须是具名且必填的简单标识符,不能使用解构、默认值、rest 或可选参数。可 JSON 表示的普通类型由 Typert 生成严格 schema;工作区 class 等复杂对象必须具有唯一的 TypertLookupMap 声明。lookup 与 Context 包同时负责静态声明合并和运行时提供方注册;缺少任一侧都会导致构建失败,或者首次调用需要该提供方时失败。 运行时调用 Remote 调用使用 Connection 的 /api 路由。Client Remote 调用 connection.rpc.call('/api', '/', { args }, signal) ;HTTP carrier 对应 POST /api// ,payload 只包含一个具名 args 对象。 Connection 在 HTTP bridge 之前执行 /api 的统一信任检查,再在共享 FetchHandler 内分发。Typert Gateway 只认领存在严格描述符或活跃 SRC marker 的两段式 endpoint;功能自有的精确 Fetch 路由处理非 JSON 响应,其他请求返回 404。Connection 拥有传输、RPC id、响应 envelope 和请求取消,Gateway 只拥有 Remote 数据协议和业务分发。替换 Connection carrier 不要求改变 Remote 描述符或 Client 编程接口。 Gateway 每次调用都从当前注册表解析描述符和实时服务,不缓存业务对象。它要求 args 的字段集合与描述符完全一致,先用 codec 校验 wire 值,再通过注册的 lookup 或 Context 提供方解析对象或接收者,最后调用 binding 指向的服务方法并校验返回值。缺少提供方、identity 未命中、binding 不一致、参数缺失或多余、schema 失败和方法不存在都会在进入业务代码前或离开业务代码后失败。 lookup 提供方的 register() 同时提供稳定声明和默认 resolver; configure() 提供由 Host 组合拥有、可异步执行且受 effect 生命周期约束的 resolver。配置可以先于提供方挂载;没有提供方时调用仍以 gateway/lookup-unavailable 失败,配置卸载后则恢复提供方默认策略。Session Controller 负责 agent 与 session 的标准 resolver 语义:复用 live Agent,自动恢复普通冷会话,对并发恢复去重,并拒绝由 subagent routing 拥有的 identity; session lookup 返回该 Agent 的 Session。恢复失败与 ownership fence 抛出携带自有码的 RemoteError ( session/not-found 或 session/agent-busy ),Gateway 原样编码上 wire;只有未归类的 throw 才折成 gateway/internal 。 Client 卸载一个贡献时会一起移除描述符和具体方法,中止其进行中的调用,并使外部仍持有的陈旧方法句柄拒绝继续调用。Host 上已经注册过的严格 endpoint 被撤回后也不会降级到 SRC 推断,以免热卸载悄然降低校验强度。 SRC 开发回退 Host 通过 node --import tsx/esm 从源码启动时不会执行 Typert 编译插件。标准 decorator 初始化器仍会把方法名和调用模式记录到 Service 原型上的带版本描述符中, TypertRemoteService 或 bindTypertRemote() 则提供显式服务 binding;Gateway 因而可以在不启动 ts.Program 的情况下构造一个较弱的临时描述符。描述符使用稳定的字符串属性名,因此 remoteMethods() 能读取协议包另一个已安装副本写入的标记。 SRC 回退从运行中函数解析简单参数名。参数名与某个已注册 lookup 的 parameter 相同,例如 agent 或 session ,就使用其 agentId 或 sessionId wire 字段并在 Host 解析对象;其他参数只检查值是否为无循环、无特殊 prototype 的 JSON-safe 数据。 @RemoteScope 直接使用已注册 Host Context 提供方的 wire 字段。SRC 不读取 TypeScript 类型,不生成 Zod schema,不推断可选参数,也不支持解构、默认值、rest 或重复参数名。 SRC 只解决 Host 源码进程的分发问题。Client 不会从运行中的 Host 发现 decorator,Client Remote 也拒绝挂载缺少严格 codec 的 SRC 描述符;其类型、codec 和 Remote 注册值始终来自最近一次生成的 lib/typert.remote-client.* 。 开发模式 Web 开发先使用 pnpm run build 准备当前 Host、Client 与 Web 产物,然后在两个终端中分别运行源码 Host 和 Client plugin watcher: pnpm dsh web pnpm run dev:web dsh 通过 tsx 启动 Host 源码,所以 Host 可以使用 SRC 回退; dev:web 只监听带 dsh.client 声明的 Client 插件并重写其 lib/client.js ,它不会分析 Host decorator,也不会生成 Remote Client DTS。 只修改 Remote 方法实现体而不改变约定时,无需重新生成 Typert 文件。新增或删除 decorator、修改导出名、namespace、参数、返回值、lookup、Context 或取消签名时,重新执行有序 lib 构建,让 Host 先生成严格约定,再让 Client 编译并打包新的贡献: pnpm run build:lib 运行中的 Client watcher 会在重新打包时消费这些生成文件。若已单独运行 pnpm run build:lib:host 刷新 Host 约定,也可再运行 pnpm run build:lib:client 完成 Client 侧;干净工作树不能跳过 Host 阶段。仅重新编译前端源码不能从 Host decorator 推导新类型。 pnpm run typecheck 会执行 Host lib 阶段后再运行 Client tsc,CI 与发布构建也使用同一顺序。 边界 Remote 只处理有单个请求与单个结果的一元方法调用。会话事件流、分页、增量 reduce、projection 和实体子流需要独立的数据协议与注册模型;即使它们复用 Connection,也不应伪装成 Remote 方法或放入调用描述符。 API 各层按 remotes → gateway → connection → webserver 组织。BFF 与 Typert RPC 层位于 packages/api ;Connection 与 WebServer 位于 packages/client/connection 和 packages/host/webserver 。需要流式或浏览器原生响应的功能注册精确的 Connection Fetch 路由,而不定义 Remote 方法。 lookup 策略按 key 配置,因此所有 agent 或 session 参数共享冷恢复行为。只接受 live 对象需要显式的逐参数或逐 endpoint 策略,而这种策略并不存在;不能通过业务方法内部猜测对象是否来自恢复。 DeepSeek 官方 LLM API 协议扩展 English | 中文 本参考文档定义 @deepseek-ai/dsh-llm-deepseek 在 deepseek-official 聊天补全请求中发送的全部 DeepSeek Harness 特有 HTTP 标头和附加 JSON 字段。本文不重复定义 DeepSeek 上游 API 持有的字段。提供方无关的 LLM(大语言模型)接口与 llm-pi-ai 均不实现这些扩展。 适配器将这些扩展发送至已解析的 baseURL ,包括已配置的网关。扩展位于 messages 、系统提示词和工具 schema 之外,因此不会增加模型输入 token,也不会改变模型可见前缀。 协议命名空间与版本 位置 命名方式 示例 HTTP 字段名 小写 kebab-case;HTTP 匹配仍不区分大小写 user-agent , x-deepseek-harness-session-id DeepSeek 请求正文扩展字段 使用保留 dsh_ 前缀的 snake case dsh_plugin_packages , dsh_session_log DSH 持有的嵌套 JSON 成员 Camel case afterSeq , throughSeq , sessionId 带标签的值 使用 kebab-case 字符串;持久事件采用 domain/action session-log-deepseek/delivery-accepted 每个正文扩展独立持有自身的 version 。版本仅适用于包含该字段的对象;不同字段的版本之间不存在兼容或排序关系。JSON 成员顺序不属于协议。 DeepSeekLlmApiExtensionRegistry 为每个顶层扩展名保留一个提供方。空名称、两端带空白的名称、重复注册以及与 DeepSeek 基础请求冲突的名称都会在 HTTP 分派前失败。 请求标头 标头 出现条件 值 user-agent 每个提供方 HTTP 请求,包括 Files API 操作 采用 product/version (+url) 形式的应用身份;默认产品为 deepseek-harness x-deepseek-harness-user-id 每个已授权的聊天补全请求 已解析 Harness home 的稳定匿名 UUID x-deepseek-harness-session-id 携带会话 id 的聊天补全请求 确切的请求 sessionId 字符串 x-deepseek-harness-compact 用途为 compaction 的聊天补全请求 字面字符串 1 凭据失败发生在解析匿名用户 id 之前,因此未授权请求既不会发送这些标头,也不会创建身份文件。没有会话的直接请求会省略 x-deepseek-harness-session-id 。会话标题请求没有额外的用途标头;请求携带 sessionId 时,仍然适用普通的会话 id 规则。 正文扩展事务 适配器先序列化包括确切 messages 在内的完整基础正文,再让已注册提供方准备字段。提供方会收到该不可变正文、请求取消信号,以及可选的 sessionId 和辅助调用 purpose 。提供方返回 undefined 时,本次请求会省略其字段。 系统将已准备的 JSON 值与提供方持有的状态分离,再将其作为基础字段的顶层同级成员合并,并序列化到同一个 HTTP 正文中。准备失败或冲突会阻止请求。组合未挂载注册表时,适配器发送未经扩展的基础正文。 已配置端点返回 HTTP 2xx 后,适配器会在读取 SSE 正文之前运行已准备的 accept() 事务。传输失败和非 2xx 响应不会接受任何贡献。即使端点返回 2xx,接受失败仍会使模型请求失败。接受仅记录端点级 HTTP 成功,不表示 SSE 流已完整结束,也不表示端点已持久化扩展。 dsh_plugin_packages @deepseek-ai/dsh-plugin-package-inventory-deepseek 贡献完整存活的 Loader-backed 插件包清单。该字段默认启用。 { "dsh_plugin_packages": { "version": 1, "packages": [ { "name": "@deepseek-ai/dsh-example", "version": "0.1.1-rc.2" } ] } } 成员 类型 含义 version 1 dsh_plugin_packages 的 schema 版本 packages 数组 本次请求的完整存活集合 packages[].name 字符串 来自所属 manifest(元数据清单)的确切非空 npm 包名 packages[].version 字符串 来自同一 manifest 的确切非空包版本 每个请求都会重新读取宿主树中的存活非分组 Loader 配置项;请求会话存在 standing agent-preset 树时,也会读取该树。相对与绝对模块使用距离自身最近的所属 manifest;裸包配置项使用激活自身的 Loader 解析基准。具名 manifest 未提供非空版本时,请求准备会失败。 发送方会对确切 (name, version) 组合去重,并使用与 locale 无关的文本比较,先按 name 、再按 version 排序。同一包的多个同时存活版本会保留为独立配置项。接收方不得按包名折叠该数组,也不得根据数组顺序推断包的激活关系。 该清单不包含已禁用、pending、failed、unloading、disposed 和结构性 Loader 配置项。普通依赖、没有具名所属包的松散模块、以编程方式挂载的子 fiber,以及内存动态插件也不在其中,因为它们没有权威的 Loader 包来源信息。 清单已启用但没有符合条件的配置项时,系统发送 packages: [] ;禁用贡献插件时,系统省略整个 dsh_plugin_packages 字段。包身份属于提供方元数据,绝不进入模型输入。 dsh_session_log @deepseek-ai/dsh-session-log-deepseek 贡献权威会话日志的一段连续后缀。该字段默认禁用。启用后,它适用于携带存活会话且至少存在一个事件的请求;直接请求、陈旧会话 id 或空日志会省略该字段。 { "dsh_session_log": { "version": 1, "session": { "version": 0, "id": "session-id", "createdAt": 1780000000000 }, "afterSeq": -1, "throughSeq": 0, "events": [ { "type": "turn/start", "seq": 0, "time": 1780000000001, "data": { "turn": 1 } } ] } } 成员 类型 含义 version 1 dsh_session_log 的 schema 版本 session 对象 不可变的权威 SessionHeader afterSeq 整数 本次请求前记录为已接受的最大序号,或 -1 throughSeq 非负整数 本次请求所表示的最大序号 events 数组 从 afterSeq + 1 到 throughSeq 的连续事件 首次上传使用 afterSeq: -1 ,并携带当前的完整日志。此后每次上传都从同一会话 id 的最大已接受水位(watermark)之后开始。发送方为每次请求仅快照一次事件数组;快照后的追加内容属于后续请求。 会话头 session 成员是确切的 Session.header ,不是完整的运行时会话。外层 dsh_session_log.version 选择本扩展 schema, session.version 则选择权威磁盘会话格式;两个版本值相互独立演进。 成员 出现条件 含义 version 必需 权威会话格式版本;当前为 0 id 必需 确切的会话 id createdAt 必需 非负安全整数 Unix epoch 毫秒数 cwd 可选 创建会话时记录的绝对工作目录 parentSession 可选 fork 的父会话 id seedLength 可选 通过 seed 继承的前导事件数量 origin 可选 subagent 子项使用的字面值 subagent delegationDepth 可选 持久化的非负 subagent 委派深度 agentPreset 可选 用于组合该会话的 agent preset id 权威事件信封 每个 events 元素都是完整的权威 SessionEvent ,不依赖任何其他请求字段。事件始终携带 type 、 seq 、 time 与 data ;它可以携带 ignorable: true ,展示事件还可携带 sourceEventSeqs 与 surfaceOp 。发送方会复制每个已有成员,不执行投影、脱敏或重建。 接受水位与至少一次交付 端点返回 HTTP 2xx 后,该贡献会向同一会话追加以下权威事件: { "type": "session-log-deepseek/delivery-accepted", "seq": 8, "time": 1780000000002, "data": { "sessionId": "session-id", "throughSeq": 7 } } delivery-accepted 表示已配置端点为包含该字段的 LLM 请求返回 HTTP 2xx。它不表示 SSE 已完整结束,也不表示远端已经持久化。该事件的 throughSeq 必须标识一项更早的事件, sessionId 则标识已发送后缀所属的会话。 发送方会折叠最大的匹配 throughSeq ,因此并发已接受请求无法使游标倒退。恢复后的进程会从持久日志重建游标。fork 会忽略命名其父会话的继承水位,因此先发送自身完整的继承前缀,再以子会话 id 推进。水位事件自身属于下一段未发送后缀。 传输失败和非 2xx 响应不会追加水位。端点接受后、本地持久化前发生崩溃时,系统可能重新发送已接受范围;不确定性只会产生重复,绝不会产生序号缺口。系统没有独立上传存储、大小上限或截断路径。 暴露内容与接收方要求 请求标头会暴露 Harness 应用版本、一个匿名 Harness-home 身份和可选的会话身份。 dsh_plugin_packages 会暴露存活 npm 包的名称与版本。启用后, dsh_session_log 可能暴露会话工作目录、系统提示词快照、用户与 assistant 内容、原始 assistant 分片、工具参数与结果、压缩摘要、反馈和插件持有的事件。适配器 API key 不是会话事件,因此不会进入该字段。通过 baseURL 选择的网关会收到与官方端点相同的值。 接收方按名称定位扩展字段,按各字段自己的 version 分派,保留不同的包版本,并忽略 JSON 成员顺序。会话日志接收方必须先校验连续序号范围,再解释事件类型。遇到不带 ignorable: true 的未知权威事件时,接收方无法进行无损重建。即使缺少注册表或某项贡献,基础请求仍然可用;字段缺失表示该项贡献不适用于本次请求。 会话持久化事件目录 English | 中文 会话持久事件日志中可能出现的所有事件类型:完整持久化的 SessionEvent 信封,以及可通过合并扩展的 SessionEventMap 中的每个成员,包括 @deepseek-ai/dsh-session 所属的词汇和本仓库中每个插件对 @deepseek-ai/dsh-session/types 的声明合并,并附有源 JSDoc、完整 payload 声明、surface 标记和声明位置。本文档是 session.md (surface 排序与 deriveMessages() 投影)、 persistence.md (如何让日志持久化)和 session.md 中生成区域(实时总线接线;日志事件 不是 cordis 事件,它通过唯一的 session/event emit 到达监听器)的补充。 英文源文件根据源码生成( scripts/gen-persistence-catalog.ts ),并由 pnpm run verify-persistence-catalog ( doc-sync (文档同步门禁)的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。声明块保留源码声明和嵌套属性的 JSDoc,只移除其所在接口/模块带来的缩进,并使用 ts persistence-catalog 围栏(doc-typecheck 会跳过这些围栏,因为声明引用了其所属模块中的类型)。payload 中的类型名称会链接到记录该类型的页面。参见 persistence-log-catalog Agent Note 。 以下信封声明组合了每个事件的 type 、单调递增的 seq 、以 epoch 毫秒表示的 time 、 data 、可选的未知类型跳过标记 ignorable ,以及条件字段 surfaceOp / sourceEventSeqs 。 surface 表示 SurfaceEventType 成员:它会生成一条 LLM(大语言模型)消息,并声明该事件如何加入 surface 列表。 log-only 表示其他所有事件:这类记录可持久化、可回放,但不参与派生历史。每个 payload 均可进行 JSON 序列化(在 Session.append 处强制执行),整个格式固定为 SESSION_FORMAT_VERSION = 0 :这是预发布格式,不暗示任何兼容性(参见 版本立场 )。范围仅限本仓库中的包;下游插件可以继续合并其他事件类型,而这些类型按设计不属于本目录。 事件信封 /** The appendable event-type keys of {@link SessionEventMap}, plugin-merged extensions included. */ export type SessionEventType = keyof SessionEventMap /** * The subset of {@link SessionEventType} values whose events produce LLM * messages and are eligible to appear on the ordered surface. Only these * event types may carry {@link SurfaceOp} and {@link SessionEvent.sourceEventSeqs}. */ export type SurfaceEventType = | 'user/message' | 'assistant/message' | 'tool/result' /** * How a session event entered the ordered surface. Only valid on * {@link SurfaceEventType} events. * * - `'append'`: added to the tail — normal path for user/assistant/tool * messages. * - `{ op: 'replace', start, end }`: replaces surface nodes from `start` * (inclusive) through `end` (inclusive) with this node. Both must exist as * surface nodes in the current surface. `start === end` replaces a single * node. The node's {@link SessionEvent.sourceEventSeqs} must include every * shadowed surface node. Used by compaction; any surface-replacing producer * may use it. */ export type SurfaceOp = | 'append' | { op: 'replace'; start: SessionSeq; end: SessionSeq } /** * One immutable entry in the session log. * * A proper discriminated union over `type` (not independent `type`/`data` * unions), so `switch (event.type)` narrows `event.data` without casts. * * The {@link sourceEventSeqs} and {@link surfaceOp} fields are conditional: * they only exist on {@link SurfaceEventType} variants (`user/message`, * `assistant/message`, `tool/result`). * Non-surface events (boundary markers, chunks, usage, errors) never carry * surface metadata — the compiler enforces this at `Session.append()` * call sites. */ export type SessionEvent = { [K in SessionEventType]: { type: K /** Monotonic sequence number within the session. */ seq: SessionSeq /** Unix epoch milliseconds. */ time: number data: SessionEventMap[K] /** * Marks an event a reader may safely skip when it does not recognize * `type`. Absent means required: a reader meeting an unrecognized type * without this marker MUST refuse to reconstruct the session instead of * silently dropping the event, because an unrecognized required event may * change how the rest of the log is interpreted. A writer sets `true` only * on purely informational records whose loss cannot affect reconstruction; * defaulting to required means a forgotten marker over-refuses (an * inconvenience) rather than silently resuming a gutted session. */ ignorable?: true } & (K extends SurfaceEventType ? { /** * Seq numbers of earlier events that this event cites as sources * (e.g. the `assistant/chunk` seqs that built an `assistant/message`, * or the surface nodes shadowed by a compaction replace node). An * `assistant/message` may carry a present empty array for a known empty * provider stream; when the field is absent, the event does not record which * earlier events produced the message. */ sourceEventSeqs?: SessionSeq[] /** How this event entered the surface; absent for non-surface events. */ surfaceOp?: SurfaceOp } : object) }[T] 来源: packages/core/session/src/types.ts:366 · packages/core/session/src/types.ts:373 · packages/core/session/src/types.ts:402 · packages/core/session/src/types.ts:434 事件 agent/* agent/inbox/spliced — log-only /** * One normalized mutation of an agent's durable pending-message lists. * Live dispatch precedes projection mutation, so synchronous observers may * read the pre-splice inbox to recover the removed messages. */ 'agent/inbox/spliced': { target: InboxTarget start: number removedCount?: number inserted: UserMessage[] outcome?: 'canceled' } 来源: packages/core/agent/src/types.ts:58 agent-preset/* agent-preset/selected — log-only /** * The session's agent preset was chosen after creation, while the session * was still blank. Log-only: it records the composition later turns ran * under, so a resumed or forked session rebuilds the same one instead of * the header's creation-time value. */ 'agent-preset/selected': { agentPreset: string } 来源: packages/preset/agent-presets/src/session.ts:28 approval/* approval/asked — log-only /** * An approval question was put to the answerer chain — log-only audit * (like `hook/*`; NOT a surface event, carries no `surfaceOp`). `id` pairs * it with the `approval/decided` that always follows; `toolName` is the * tool the question is about, `callId` the exact tool call when the asker * had one, `reason` the asker's human-readable explanation (e.g. a hook's * permission-decision reason). */ 'approval/asked': { id: ApprovalRequestId toolName: string callId?: ToolCallId reason?: string } 类型: ToolCallId 来源: packages/interaction/user-approval/src/types.ts:44 approval/decided — log-only /** * The outcome of a prior `approval/asked` (same `id`) — log-only audit. * Exactly one per ask, appended when the outcome is known: a decision, a * cancellation, or the fail-closed `'unavailable'`. */ 'approval/decided': { id: ApprovalRequestId outcome: ApprovalOutcome } 来源: packages/interaction/user-approval/src/types.ts:55 approval/policy — log-only /** * The session's approval policy was switched — log-only, durable, * replayable, never in the model transcript (the model learns the policy * from the runtime-context snapshot and live switch notices). The LAST * such event is the session's override. * `source: 'delegation'` marks an override seeded into a child; an absent * source is a runtime switch. */ 'approval/policy': { policy: ApprovalPolicy /** Marks an override seeded into a child at delegation. */ source?: 'delegation' } 来源: packages/interaction/user-approval/src/index.ts:32 assistant/* assistant/chunk — log-only /** Raw stream chunk — token-level replay fidelity. */ 'assistant/chunk': { turn: number; step: number; chunk: StreamChunk } 类型: StreamChunk 来源: packages/core/session/src/types.ts:289 assistant/message — surface /** * Assembled assistant message for one step (derived history uses this). * Carries the step's `usage` when the adapter reported token accounting, so * the model output and its accounting travel together (there is no separate * usage record). `usage` is absent when the adapter reported none. A turn * cancelled mid-stream finalizes its delivered text/reasoning prefix as this * event with `interrupted: true`; undispatched tool calls are absent. The * marker distinguishes that prefix without re-deriving interruption from turn * boundaries. An aborted turn with no such event streamed no visible content. */ 'assistant/message': { turn: number; step: number; message: AssistantMessage; usage?: TokenUsage; interrupted?: true } 类型: TokenUsage 来源: packages/core/session/src/types.ts:300 command/* command/done — log-only /** * The paired command settled. `kind`/`text` carry the handler's verbatim * outcome (a thrown/aborted handler settles as `kind: 'error'` with the * rendered failure). A successful command may identify the earlier * authoritative domain event for a richer client-computed presentation. */ 'command/done': { commandId: CommandId kind: 'success' | 'error' text?: string sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq } 来源: packages/interaction/commands/src/types.ts:104 command/run — log-only /** * A resolved slash command entered its handler. Log-only (never model * surface); paired with `command/done` by `commandId`, mirroring the * `tool/call`↔`tool/result` pairing. The payload is structured — `name` * and `args` are `parseCommand`'s own split (name and verbatim rawInput, * separator whitespace included), so a consumer (a projection unit * folding its own command records, a rich command card) never re-parses * a line. `args` is absent when the definition sets `recordInput: false` * because an authoritative domain event owns the input payload. */ 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource } 来源: packages/interaction/commands/src/types.ts:97 compaction/* compaction/end — log-only /** * Marks the end of a compaction — log-only, releases the lock. Its owner * matches `compaction/start`; `error` records an unsuccessful attempt. */ 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string } 来源: packages/compaction/compaction/src/types.ts:72 compaction/prune — log-only /** * Shadow price of one model-free prune replacement — log-only, no * surfaceOp. The shared shadow-price protocol: a surface `replace` event * is priced by the metering event immediately before it (`compaction/summary` * for a summarizing compaction, this event for a prune), which states the * heuristic token price of the exact replaced range so a pure consumer * can subtract it without retaining per-node prices. The replacement MUST * be appended synchronously right after this event. */ 'compaction/prune': { /** The replaced range's first and last surface-node seqs (a surface-position span, like {@link CompactionResult.shadowedRange}). */ shadowedRange: { start: SessionSeq; end: SessionSeq } /** The seqs of all shadowed surface nodes, in surface order. */ shadowedSeqs: SessionSeq[] /** Heuristic price of the shadowed content under the token-meter's fixed estimator. */ shadowedTokenCount: number } 来源: packages/compaction/compaction/src/types.ts:82 compaction/start — log-only /** * Marks the start of a compaction — log-only, holds the lock until * `compaction/end`. A numbered owner is strictly enclosed by that open turn; * `null` identifies a standalone manual transaction between turns. */ 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null } 来源: packages/compaction/compaction/src/types.ts:24 compaction/summary — log-only /** * Completed summary, its inputs, and its model call facts — log-only, no surfaceOp. * The summary content is in `data.summary`; the actual surface replacement * is performed by the immediately following `user/message` event that * shadows the compacted range. That adjacency is contractual — the * shadowed pricing fields are the replacement's shadow price, so a * consumer may pair a replacement with the metering event directly * before it (`compaction/prune` documents the shared protocol). */ 'compaction/summary': { compactionId: CompactionId sourceCommandId?: CommandId summary: ContentBlock[] shadowedRange: { start: SessionSeq; end: SessionSeq } shadowedSeqs: SessionSeq[] shadowedTokenCount: number /** The provider route that wrote the summary. */ provider: string /** * The model that wrote the summary — the summarize call's envelope, * reported by the backend that made the call, logged so the one-shot * request is reconstructable from log + code and "which model wrote * this summary" has a durable answer (the reconstructability Agent Note). */ model: string /** The generation cap the summarize call sent, when one applied. */ maxTokens?: number /** Provider-reported token usage for the summarization request, when emitted. */ usage?: TokenUsage } & ( | { /** Complete provider output before the backend's safe summary projection. */ rawOutput: ContentBlock[] /** Identifies exactly one call through this context's `ctx.llm.stream()`. */ llmStreamCall: true } | { /** Optional complete output from an unmarked template, remote, or other summarizer. */ rawOutput?: ContentBlock[] /** An unmarked summary does not identify a call through this context's LLM seam. */ llmStreamCall?: never } ) 类型: ContentBlock · TokenUsage 来源: packages/compaction/compaction/src/types.ts:34 feedback/* feedback/record — log-only /** * One recorded human remark about this session. Log-only and independent * of its trigger; it never enters model context or derived history. */ 'feedback/record': { text: string } 来源: packages/feedback/command-feedback/src/index.ts:62 goal/* goal/change — log-only /** * Complete post-mutation goal state or clear tombstone. */ 'goal/change': GoalChangeMeta 来源: packages/goal/goal/src/domain.ts:66 hook/* hook/invoked — log-only /** * A hook command was invoked at a hook point — a log-only record (like * `compaction/*`; NOT a {@link SurfaceEventType}, carries no `surfaceOp`). * `dialect` is the bridge that ran it (`claude`/`codex`), `point` * the hook point (`PreToolUse`, `Stop`, …), `matcher` the matcher-group * pattern that selected it (absent for match-all), `handlerId` a stable id * for the command (so an invoked/result pair correlates). `turn` is the open * turn the invocation lives inside. */ 'hook/invoked': { turn: number point: string dialect: HookDialect matcher?: string handlerId: string } 来源: packages/hooks/hook-protocol/src/types.ts:19 hook/result — log-only /** * Log-only outcome paired to `hook/invoked` by `handlerId`. Decision is the * parsed permission result, `stop` for `continue:false`, or `pass`; exit code * may be absent, stderr is bounded, and duration is wall-clock runtime. */ 'hook/result': { turn: number point: string handlerId: string decision: string exitCode?: number stderrSummary?: string durationMs: number } 来源: packages/hooks/hook-protocol/src/types.ts:31 llm/* llm/retry — log-only /** Durable, non-surface record of one provider-routed retry scheduled after a failed request attempt. */ 'llm/retry': LlmRetryEventData 来源: packages/llm/llm-retry/src/types.ts:9 llm/retry-started — log-only /** Durable transition written after a retry wait succeeds and before the next request attempt starts. */ 'llm/retry-started': LlmRetryStartedEventData 来源: packages/llm/llm-retry/src/types.ts:11 model/* model/selection — log-only /** * Complete validated model selection requested for subsequent prompt * assembly. Log-only: it never enters derived model history. */ 'model/selection': ModelSelection 来源: packages/api/session-controller/src/types.ts:41 permission/* permission/preset — log-only /** * Records the selected preset as durable, log-only user intent. The knob * events follow in the same turn and control execution; this event stays * out of the model transcript and lets the permission projection unit * preserve a selection when bundles match. */ 'permission/preset': { preset: string } 来源: packages/interaction/permission-presets/src/index.ts:53 plan/* plan/mode — log-only /** * Whether plan mode is in force from this point on: log-only, non-surface, * whole-value replace. The last `plan/mode` wins; a log with none folds to * inactive through the projection unit's fold. */ 'plan/mode': { active: boolean } 来源: packages/plan/plan-mode/src/index.ts:46 request/* request/context — log-only /** * Route metadata for the next request, logged only when the route or capacity * changes. It does not participate in request reconstruction or header equality. */ 'request/context': RequestContext 来源: packages/core/session/src/types.ts:339 request/header — log-only /** * Full header for the next request, appended inside its step before dispatch. * It is log-only; the latest snapshot reconstructs the request header. */ 'request/header': { header: EpochHeader reason: RequestHeaderReason /** A changed header also begins a distinct model-message series. */ startsSeries?: true } 来源: packages/core/session/src/types.ts:329 sandbox/* sandbox/mode — log-only /** * The session's sandbox mode was switched — log-only (like `approval/*`; * NOT a surface event, carries no `surfaceOp`): durable and replayable, * never in the model transcript. The LAST such event is the session's * override (folded by the sandboxMode projection unit). `source: 'delegation'` marks * an override seeded into a child; an absent source is a runtime switch. */ 'sandbox/mode': { mode: SandboxMode /** Marks an override seeded into a child at delegation. */ source?: 'delegation' } 来源: packages/sandbox/sandbox-policy/src/session-mode.ts:33 schedule/* schedule/change — log-only /** * Versioned Schedule mutation. The owning package validates the complete * session-local transition stream before accepting a candidate event. */ 'schedule/change': ScheduleChange 类型: ScheduleChange 来源: packages/schedule/schedule/src/types.ts:219 session/* session/end-seed — log-only /** * Marks the end of a constructor seed. Events before it have smaller seq * values and came from the seed (resume, fork, or replay); this lifecycle * produced none of them. This log-only event is the durable projection of * {@link Session.firstLiveSeq}. Its payload is empty — position and `time` * carry the meaning. * * Locate the LAST one in stored history. A seed already ending in one is not * re-marked, so reopening an untouched session does not grow its log per * pickup and the event need not be at the current `firstLiveSeq`. * * `Session`'s constructor is the only legitimate writer. The invariant * companion deliberately constrains nothing here, so a plugin appending one * would silently classify every live bracket before it as seed history. * * An owner of a standalone open/close bracket (`compaction/start` … * `compaction/end`) reads it because seed history and live work are otherwise * byte-identical: an unmatched opening marker before this event belongs to * an ended lifecycle, whatever ended it. NOT a liveness signal about other * writers — a concurrently live session holds its own boundary elsewhere, * so tolerating concurrent writers needs a signal beyond the log. */ 'session/end-seed': Record 来源: packages/core/session/src/types.ts:362 session/title — log-only /** * Latest-wins session title snapshot. Log-only: it never enters the model * surface or derived history. */ 'session/title': SessionTitleEventData 类型: SessionTitleEventData 来源: packages/session/session-title/src/index.ts:77 session/title-llm-request — log-only /** Log-only pre-dispatch record of one session-title model request. */ 'session/title-llm-request': SessionTitleLlmRequestEventData 类型: SessionTitleLlmRequestEventData 来源: packages/session/session-title-llm/src/index.ts:45 session-log-deepseek/* session-log-deepseek/delivery-accepted — log-only /** Records that the configured endpoint accepted one delivery through `throughSeq`. */ 'session-log-deepseek/delivery-accepted': { /** Session identity the accepted delivery carried; inherited fork markers retain the parent's id. */ sessionId: import('@deepseek-ai/dsh-session/types').SessionId /** Last canonical event included in the accepted request. */ throughSeq: import('@deepseek-ai/dsh-session/types').SessionSeq } 来源: packages/session/session-log-deepseek/src/types.ts:57 step/* step/end — log-only /** Closes step `step` of turn `turn`. */ 'step/end': { turn: number; step: number } 来源: packages/core/session/src/types.ts:279 step/start — log-only /** Opens step `step` of turn `turn` — one model call plus the tool executions it requested. */ 'step/start': { turn: number; step: number } 来源: packages/core/session/src/types.ts:277 subagent/* subagent/descriptor — log-only /** * Durable identity and lifecycle mode of a session-backed subagent child, * appended once by the establishing provider inside the child's initial * turn, before its first request. Continuable records also carry their * resumable composition. Log-only: it carries no `surfaceOp`, never enters * model history, and survives compaction. */ 'subagent/descriptor': SubagentDescriptorData 来源: packages/subagent/subagent/src/descriptor.ts:38 subagent/model-selection-policy — 仅日志 /** * Records that this session's delegation tool exposes child provider, * model, and reasoning-effort selection. Appended before the first model * request; absence means the fixed-route definition. Log-only: it carries * no `surfaceOp` and never enters model history. */ 'subagent/model-selection-policy': { /** Exact routes this Session may select explicitly for a child. */ allowedModels: AllowedModelRoute[] } 来源: packages/subagent/tool-subagent/src/model-selection-state.ts:17 team/* team/member — log-only /** Whole teammate lifecycle value, stored only in the Team Lead Session. */ 'team/member': { version: 1; teamId: TeamId; member: TeamMemberSnapshot } 类型: TeamId · TeamMemberSnapshot 来源: packages/experimental/agent-team/src/types.ts:206 team/message/delivered — log-only /** Durable acknowledgement that the target Session recorded the message. */ 'team/message/delivered': { version: 1 teamId: TeamId messageId: TeamMessageId targetId: SessionId } 类型: TeamId · TeamMessageId 来源: packages/experimental/agent-team/src/types.ts:212 team/message/queued — log-only /** Durable mailbox enqueue, stored before delivery is attempted. */ 'team/message/queued': { version: 1; teamId: TeamId; message: TeamMessageSnapshot } 类型: TeamId · TeamMessageSnapshot 来源: packages/experimental/agent-team/src/types.ts:210 team/task — log-only /** Whole shared-task value, stored only in the Team Lead Session. */ 'team/task': { version: 1; teamId: TeamId; task: TeamTaskSnapshot } 类型: TeamId · TeamTaskSnapshot 来源: packages/experimental/agent-team/src/types.ts:208 todo/* todo/write — log-only /** Whole-list snapshot; latest write wins on replay. Log-only UI state; never derived history. */ 'todo/write': { todos: TodoItem[] } 类型: TodoItem 来源: packages/todo/tool-todo/src/types.ts:31 tool/* tool/call — log-only /** * The model requested one tool invocation: `name` with the raw `arguments` * JSON string exactly as the model produced it (unparsed). `callId` pairs the * call with its `tool/result`. */ 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string } 类型: ToolCallId 来源: packages/core/session/src/types.ts:306 tool/code-dispatch — log-only /** * One bridged sub-dispatch SETTLING: the pairing ids (matching the * `tool/code-dispatch-start` with the same `subCallId`), the tool `name` * with the same JSON-normalized `arguments`, and the sub-call's complete * model-facing outcome in `tool/result`'s own vocabulary * (`content` + `isError`), so UIs render a sub-call through the exact * code path that renders a native call. Every started sub-call settles * with exactly one of these (abort included: the aborted pipeline result * is an `isError` outcome). * Log-only: `deriveMessages()` ignores it, so sub-calls never re-enter * model context; persistence and UIs get every call. Appended inside the * parent `run_code`'s execution (the bridge drains in-flight dispatches * before returning), so its execution-enclosure relation holds by * construction. */ 'tool/code-dispatch': PtcDispatchEventData 来源: packages/core/tools/src/types.ts:56 tool/code-dispatch-start — log-only /** * One sub-dispatch STARTING inside a `run_code` program: the parent * `run_code` call id, the deterministic sub-call id (`:code:`, * numbered in submission order), and the tool `name` with its * JSON-normalized `arguments` — the exact value dispatched, normalized * BEFORE dispatch, so this append can never fail on payload shape. * Appended when the scheduler actually starts the call (not at * submission), so a start means the tool body pipeline was entered; a * call abandoned in the queue logs nothing. Log-only: `deriveMessages()` * ignores it; UIs use it for live per-sub-call running state and pair it * with `tool/code-dispatch` by `subCallId` (timing = the two events' * `time` fields). */ 'tool/code-dispatch-start': PtcDispatchStartEventData 来源: packages/core/tools/src/types.ts:40 tool/result — surface /** * A completed tool call's model-facing result, optional internal failure * identity, and optional tool-private `meta` presentation payload. `meta` is * opaque to the core (the producing tool owns its shape and reads it back in * `presentResult`) but MUST be JSON-serializable: `Session.append` * runtime-validates all event data with `isJsonValue`, so a non-serializable * `meta` is rejected at the source, and the durable log reproduces the * identical card on replay. Absent * unless the tool attaches one (e.g. `dsh-tool-fs` carries its result-time * contextual diff here). */ 'tool/result': { turn: number step: number message: ToolResultMessage error?: { name: string; code: string } meta?: JsonValue } 来源: packages/core/session/src/types.ts:318 tool-workflow/* tool-workflow/agent-end — log-only /** * Records one member settlement. * @param data - run identity, paired member sequence, and outcome. */ 'tool-workflow/agent-end': ToolWorkflowAgentEndData 来源: packages/workflow/tool-workflow/src/types.ts:57 tool-workflow/agent-start — log-only /** * Records one published workflow member. * @param data - run identity, member sequence, display identity, and child Session. */ 'tool-workflow/agent-start': ToolWorkflowAgentStartData 来源: packages/workflow/tool-workflow/src/types.ts:52 tool-workflow/run-end — log-only /** * Closes one workflow record after cleanup. * @param data - stable run identity and terminal reason. */ 'tool-workflow/run-end': ToolWorkflowRunEndData 来源: packages/workflow/tool-workflow/src/types.ts:62 tool-workflow/run-start — log-only /** * Opens one top-level workflow record. * @param data - stable run identity and display name. */ 'tool-workflow/run-start': ToolWorkflowRunStartData 来源: packages/workflow/tool-workflow/src/types.ts:47 turn/* turn/end — log-only /** * Closes turn `turn` with the {@link TurnEndReason} that ended it. A turn * with no entered step has no `step/start` or `step/end`. The loop does not await a * flush at turn boundaries: `dsh-session-checkpoint-policy` owns the * per-request durability checkpoint, and consumers that read storage after * `whenIdle()` flush themselves. Success commits the turn; rejection is * reported live and does not prevent later work. */ 'turn/end': { turn: number; reason: TurnEndReason } 类型: TurnEndReason 来源: packages/core/session/src/types.ts:275 turn/start — log-only /** * Opens turn `turn` before the loop claims queued input or runs pre-step. * Rejection, empty input, cancellation, or failure may close it with no * step; otherwise the following identified `user/message` event or batch * records the messages entering the step. */ 'turn/start': { turn: number } 来源: packages/core/session/src/types.ts:266 user/* user/message — surface /** * A user-role message on the model-visible surface: a direct human prompt * (the queued message claimed for this turn), a synthetic `agent.inject()` * context (file-change notices, subdir AGENTS.md, skill content, cron * notifications, …), or an entered goal continuation round. All three * project their `content` verbatim; `source` tells them apart. */ 'user/message': UserMessage 来源: packages/core/session/src/types.ts:287 web/* web/deepseek-search-llm-request — log-only /** Secret-free auxiliary DeepSeek search request recorded before dispatch. */ 'web/deepseek-search-llm-request': DeepSeekSearchLlmRequest 来源: packages/web/web-search-deepseek/src/provider.ts:83 Vendored 包改名 English | 中文 Cordis 框架及其基础库以源码形式 vendored 在 vendor/ 下,并以 @deepseek-ai scope 发布:每个 harness 包都把框架声明为 peer dependency,发布 harness 就会连带发布这一层,用上游名发布等于在 registry 上占用别人的名字。本页是名字映射表;决策与影响见 改名 Agent Note ,上游 commit 见 vendor/README.md 。 名字映射 目录 上游名 发布名 上游版本 角色 vendor/cordis/ cordis @deepseek-ai/cordis 4.0.0-rc.7 框架核心: Context 、 Service 、 Fiber 、事件 vendor/cosmokit/ cosmokit @deepseek-ai/cosmokit 1.8.1 框架与 Schemastery 共用的基础工具 vendor/schemastery/ schemastery @deepseek-ai/schemastery 3.18.0 配置 schema( Schema ),每个插件的 Config 都基于它 vendor/loader/ @cordisjs/plugin-loader @deepseek-ai/cordis-plugin-loader 1.0.0-rc.5 cordis.yml 装载、插件解析、repository 缓存 vendor/include/ @cordisjs/plugin-include @deepseek-ai/cordis-plugin-include 1.0.4 配置包含与 patch 叠加 vendor/group/ @cordisjs/plugin-group @deepseek-ai/cordis-plugin-group 1.0.0 嵌套插件分组 vendor/timer/ @cordisjs/plugin-timer @deepseek-ai/cordis-plugin-timer 1.1.2 ctx 上随 disposal 回收的定时器 vendor/hmr/ @cordisjs/plugin-hmr @deepseek-ai/cordis-plugin-hmr 1.0.15 插件与配置的热替换 vendor/logger-console/ @cordisjs/plugin-logger-console @deepseek-ai/cordis-plugin-logger-console 1.0.0 控制台日志导出 子路径导出保持原路径: @cordisjs/plugin-loader/repository 变成 @deepseek-ai/cordis-plugin-loader/repository 。 改名不碰什么 目录名与上游源码版本。 vendor/hmr/ 仍是 vendor/hmr/ ,清单表记录的是所钉住源码快照的上游版本,因此清单读作一份上游快照;而每个 vendored 包 package.json 自身的 version 字段是 harness 发布的清单版本, pnpm run release:vendor 会提升它,重新 sync 时会恢复成上游版本。 依赖 range。 依赖条目只换键、不换范围: "cordis": "^4.0.0-rc.7" 变成 "@deepseek-ai/cordis": "^4.0.0-rc.7" ; linkWorkspacePackages 靠这些保留下来的范围把它们解析到固定的 workspace。 Loader 的 cordis: 内建前缀。 cordis:include 、 cordis:group 是协议前缀,不是包名。 cordis.yml 配置文件家族 ,包括 *.cordis.yml 、 *.cordis.snapshot.yml 、 cordis.patch.yml 。 名字里带这个词的 harness 包 ,例如 @deepseek-ai/dsh-tool-cordis 。 上游运行时标识符 ,例如 Schemastery 的 Symbol.for('schemastery') 及其 vendor: 元数据字段。 docs/ 之外的散文。 vendor/*/README.md 、各包 README 与 Agent Note 保留写作当时的名字;那里的裸 cordis 也可能是 Python SDK 的选项名或某个 agent-preset 的 id。 docs/ 之内,散文与所有 Markdown 围栏都跟着改。 你的代码要改什么 位置 改前 改后 模块 import import { Context } from 'cordis' import { Context } from '@deepseek-ai/cordis' 类型事件声明合并 declare module 'cordis' declare module '@deepseek-ai/cordis' package.json 依赖键 "@cordisjs/plugin-hmr": "^1.0.15" "@deepseek-ai/cordis-plugin-hmr": "^1.0.15" cordis.yml 插件条目 name: '@cordisjs/plugin-include' name: '@deepseek-ai/cordis-plugin-include' 施加、核验与回退 上面这份映射由 scripts/rescope-vendor.ts 承载并执行改名,任何引用都不靠手改: pnpm run rescope-vendor # report what would change pnpm run rescope-vendor --apply # rewrite every reference pnpm run rescope-vendor:check # assert the post-state; runs in the hygiene gate pnpm run rescope-vendor --apply --reverse # return to the upstream names 上游 sync 之后重跑它( 流程 ),并接上它打印的重生成: pnpm install 重生成 lockfile、 pnpm run gen-third-party-notices 、以及对它触及的双语对跑 pnpm run verify-translation-pairing --write 。 防御性模式 English | 中文 来之不易的缺陷类别规则:下面每条模式都是本项目实际发布或差点发布的一类缺陷,以防止其复发的规则形式陈述。在编写生命周期、并发、子进程或清理代码之前请先阅读本文。测试层面的对应规则(真实入口路径、验证实际结果、资源归属)见 testing.md 。 正交结果独立上报 一个结果可以同时具有多种性质:进程可能已经超时,却仍以退出码 0 结束,因为它捕获了终止信号。每个独立事实( timedOut 、 signal 、 exitCode )都应单独上报;切勿把一个标志的上报嵌套在另一个标志的分支中,否则调用方可能把提前终止的运行误判为正常成功。 公共约定两侧都要遵守 当一个实现收到同一结果的多种表示时,应在通过公共 API 返回前将其规范化。 LlmAdapter.stream() 的实现可以抛出异常或发出 finish {kind:'error'|'aborted'} ,但 LlmRuntime.stream() 只会通过终止型 finish 分片暴露模型请求失败;middleware 缺陷与消费方缺陷仍会以异常形式抛出。这使消费方不必猜测捕获的异常究竟来自提供方、包装层、分片日志记录还是自身组装逻辑。请在类型定义处记录规范化后的约定;通过真实消费方覆盖每种来源形式。 异步状态不是同步状态 agent.followup() 没有逐消息的完成状态或结果;后台任务的完成与轮次边界存在竞争; reader.close() 在 EOF 和 dispose(资源释放)两种情况下都会触发。切勿把 agent/status 或 whenIdle() 当作某次 followup() 的结果:多条已排队的后续消息、steering(中途引导)和注入工作可能共用同一个 running 区间,而取消或资源释放可能丢弃尚未启动的项。真正拥有一次运行的自动化调用方必须显式定义其区间——例如从消息的持久 inbox 回执到整个 agent(智能体)下一次进入 idle ——并将选取的任何输出描述为整个区间的输出,而不是把因果关系归于该消息。这条守则是双向的:如果等待的转换永远不会发生,等待就会挂起,因此应显式处理「无需等待」的分支。 dispose 必须达到完全停稳,而不仅仅是请求停止 如果清理流程只发出终止或中止信号便返回,而不等待工作真正停止,就会留下孤儿进程。清理逻辑应采用异步流程,并等待子进程退出(发出终止信号后等待 done );还应在终止进程前关闭监听器注册表和通知注册表,使迟到的完成事件保持静默。 在分发器中隔离回调异常 用户提供的监听器如果抛出异常,不得导致它所在的 promise 被 reject,也不得饿死排在它后面的监听器。请用 try/catch 包裹分发循环并记录日志;一个行为不当的订阅者绝不能破坏核心生命周期。 绝不将环境变量或可预测路径暴露给不可信输出 启动的命令应使用经过清理的环境变量,移除名称匹配 *KEY* 、 *SECRET* 、 *TOKEN* 或 *PASSWORD* 的项,防止 harness 凭证通过命令输出、 env 或 spill 文件泄漏。临时文件和 spill 文件应放在权限为 0700 的私有目录中,使用随机文件名,并以独占且仅所有者可访问的方式打开( 'wx' 、 0o600 );可预测且全局可读的路径会引发符号链接竞态和信息泄露。 用 unlink 删除链接形态的路径 可能是符号链接或 Windows junction 的路径,应先用 lstatSync().isSymbolicLink() 判断,再用 unlinkSync 删除:unlink 只删除链接本身并拒绝真实目录,因此绝不会跟随链接进入其目标。Windows 上对 junction 调用 rmSync(link) 会抛 ERR_FS_EISDIR ;递归删除可能穿过 junction 进入其目标。真实目录才使用带 recursive 的 rmSync 。 测试策略 English | 中文 本文说明本仓库的分层测试方式,以及保持绿色测试套件有意义的规则。命令见根目录 AGENTS.md ;相关 Agent Note 承载设计动机。 层级 单元测试 ( pnpm run test ):vitest 运行包和示例各自的 tests/** 目录下的测试,以及匹配 scripts/**/*.spec.ts 的仓库脚本测试;测试文件与其所覆盖的代码区域放在一起。每个注册表都有一个 HMR(热模块替换)安全测试(对向该注册表贡献内容的 fiber 执行 dispose(资源释放),并断言清理完成)。优先覆盖边界情况、错误路径、事件顺序、并发竞态,以及针对约定回归的永久测试(见 packages/core/agent-loop/tests/contract-regressions.spec.ts )。 覆盖率门禁 ( pnpm run test:coverage ):门禁级运行,对 packages/*/*/src 按文件 100% 覆盖。未覆盖的行往往是门禁正确标记出的死代码(应删除),而非需要补写的测试。行覆盖率是必要条件,但永远不是充分条件:它证明行被执行过,不证明功能按交付预期工作。 packages/shell/pwsh-local/src 的按文件 100% 覆盖需要真实的 pwsh :缺少它时其执行器套件会自动跳过, vitest.config.ts 会豁免该文件以使无 pwsh 的主机保持绿色,而 CI runner 自带 pwsh,仍按完整标准执行门禁。 真实 API e2e ( pnpm run test:e2e ):带密钥测试调用真实提供方 API,包括 DeepSeek 模型以及各提供方特有的冒烟测试;这些测试各自由自己的密钥控制( EXA_API_KEY 、 PERPLEXITY_API_KEY 等),缺少密钥时套件会自动跳过,使 keyless CI 保持绿色( 真实 API e2e Agent Note )。 所属位置的预期输出 ( pnpm run test:expected ):无录制会话往返的无密钥组装 CLI/进程预期。驱动使用 *.expected.e2e.ts ,并与 tests/expected/ 同属一处;CI 针对构建产物运行。包/脚本预期使用 test ,浏览器预期使用 test:web 。 快照 ( pnpm run test:snapshot ):顶层场景的录制 session.jsonl 同时提供用户输入和模型回放,并作为持久化结果的预期值。进程级场景都通过 dsh 启动:headless 负责一次性行为,SDK 负责持久控制,ACP 负责自动化协议行为,Web 在同一会话旁保留浏览器与 ARIA 证据。 snapshot.yml 声明 profile、组合与请求头类别、录制策略、例外回放或输入元数据以及工作区事实。带类型的 token 保留父子身份关系;只有请求头 pin 拥有提示词/schema sidecar。变更工作区的场景会独立比较完整的 workspace.expected/ 目录,record 与 refresh 绝不改写该目录。当模型 transcript(文本记录)变化时使用 test:snapshot:record ,回放输入仍有效时使用 test:snapshot:refresh ;请审查所有结果差异。 Web 浏览器快照 ( pnpm run test:web ;必需的 Linux PR(Pull Request)门禁):Chromium 比较 snapshots/web/ 下由会话驱动的输出,以及 apps/web/tests/expected/ 下仅含 UI 的输出。CI 强制只读的 DSH_SNAPSHOT=replay ,绝不写入预期输出;record/refresh 留在本地,每处 diff 都须评审( web e2e 车道 、 CI 门禁决策 )。 test:web 会 先构建 以交付插件 CSS。 会话 fixture 保留 header 与 payload,但省略正文序号/时间 envelope。回放会合成这些字段;运行时持久化不变。fixture 使用规范打包行; 迁移器 会改写旧布局。 spec 如何被执行 fork 出的 worker 会同时运行多个 spec 文件,coverage gate 会拆成并发的 partition,与同一个 job 中的其它 gate 并排运行,而自托管 runner 共用同一台宿主机和同一个卷。被隔离的只有进程:端口、可预测路径、外部命名空间和继承而来的子进程都不隔离。为每个占用的资源负责到它的 teardown,并把「只有单独运行时才通过」的 spec 读作该 spec 的缺陷,而不是 runner 不稳定。 dsh-ci-test-reliability 负责资源分配、状态恢复、同步、超时预算、平台差异与 teardown 规则;它的 flake 诊断流程 用于归类已经存在的概率性失败。 带密钥策略:推理(inference)在这里很便宜 我们是 DeepSeek,不要吝惜真实 API 测试。无密钥测试只能证明底层通路;只有带密钥运行才能证明 agent(智能体)能对接真实模型正常工作。覆盖文件写入提示词、包含多个轮次的对话、工具使用和流中取消。价值最高的是 冒烟测试 :启动已交付的 dsh profile、发送一条提示词,并检查外部世界;它们能捕获「单元测试全绿、产品却坏了」这一类 mock 无法发现的问题( 事故复盘 0001 )。自动跳过让无密钥 CI 和无密钥贡献者不受阻塞;它不是成本信号。Profile 级集成测试位于 apps/cli/tests/profiles/ ;包专属组合留在对应包的测试目录中。 优先使用真实实现而非 mock 只 mock 开销高或不确定的边界(LLM(大语言模型)适配器、网络、时钟);下游一切保持真实。手写替身只能证明桥接层在搬运字节,不能证明交付的工具行为符合断言。桥接工具调用测试把真实的工具注册表与执行管线保留在脚本化 mock 模型下游: makeBridgeHarness() (packages/acp/acp/tests/harness.ts)挂载 agent loop、会话存储、工具注册表与 JSONL 持久化,唯一 mock 是脚本化 MockAdapter 。 恢复测试按步骤区分分片前与分片后的失败,并证明失败分片不会派生出消息或工具副作用。覆盖耗尽、取消、策略组合、持久化、状态、协议计数、会关闭传输的空闲超时,以及交付的 Loader 组合。 验证外部世界,而非自我报告 e2e 断言应重新运行命令或从外部重新读取文件;对 agent 自身输出做关键词探测会让作弊的 agent 通过。断言未修改的文件逐字节一致。e2e 测试自行管理资源:在测试中创建 harness,在 afterEach 中 dispose(即使失败/重试/超时也要释放);共享 fixture 放在普通的 tests/harness.ts 中,绝不放在另一个 *.e2e.ts 中(导入一个 spec 会重新注册其 describe ,导致真实 API 调用重复执行)。 测试真实入口路径 产品可见的插件必须有一个非单元的真实组合测试。手动构建的 ctx.plugin(...) 套件不够:通过 Loader 和 app/process 启动仅用于测试的 cordis.yml ,只 mock 外部服务或非确定性输入,断言模型可见的请求/日志、持久状态或用户可见输出。不要把 opt-in 选项混入交付默认值。 一个守卫只有在回归能让它失败时才有效。对于没有 inject 的插件(bundle/组合插件),Loader 冒烟测试在默认导出替换必需的具名导出时仍然绿着——需要添加显式的 expect('default' in mod).toBe(false) 加 unwrapExports 往返断言,并证明它有效:引入回归、观察变红、回退。 「真实入口路径」指已发布的产物:包的 bin 所运行的是构建后的 lib/bin.js ,并由普通 node 执行,从而暴露 tsx 会掩盖的失败(结算竞态、模块解析、被吞掉的加载失败)。同样的规则适用于非 index 运行时入口(worker-thread 的同级文件 lib/worker.cjs ),也适用于多个 bundle 共享的单例模块( packages/sdk/server/tests/built-scope-carrier.e2e.ts )。保持构建产物冒烟测试绿色( packages/examples/*/tests/built-bin.e2e.ts 、 packages/code-runtime/code-runtime-worker-thread/tests/built-lib.e2e.ts ),并断言真正缺失的配置以非零状态退出。 测试解析:仅限源码 每个 vitest 配置都将 vite-tsconfig-paths 指向 tsconfig.base.json ;工作区包的裸导入解析到 src ( 布局 ),绝不会经由包的 exports 解析到构建后的 lib/ ,因为其中的陈旧产物会加载第二份模块单例。构建产物只在显式指定时使用:以 lib 模式运行的子进程,以及下文的构建产物冒烟测试。 测试子进程启动模式 CI 与已有构建产物的测试通道通过共享双模式启动器,从构建后的 lib/ 运行每个 profile 或 Cordis 配置子进程。不要为这些子进程手写 --import tsx 。 不加载 Cordis 的协议与操作系统 fixture 直接通过 Node 运行使用可擦除语法的 .ts 文件,不经过 tsx 或根路径映射。 只有测试对象本身是源码路径解析时,才可以选择 src ;在测试中写明这一约定。 何时需要快照测试 每项非平凡的模型可见、协议可见或人类可见变更,都在同一 PR 中添加或更新无密钥录制会话场景;包级、e2e、仅 mock 和 PR 理由证据不能取代组装后的 transcript。Headless、SDK、ACP 和 Web 录制分别位于 snapshots/session/ 、 snapshots/sdk/ 、 snapshots/acp/ 和 snapshots/web/ ;Web 渲染可以显式借用另一个场景的规范会话。不由录制会话驱动的预期输出保留在所属应用、包或脚本的 tests/expected/ 下,并且不使用 *.snapshot.ts 后缀。 dsh-session-snapshot 拥有共享存储规则和 profile 适配器。Agent loop、会话生命周期和 SessionEventMap 变更应更新两个 SDK 投影: snapshots/sdk/ 拥有 TypeScript,必需的 Python 运行时 CI 拥有 scripts/snapshots/python-sdk-single-exe/ 。新增 capability seam、生命周期或 transcript 变体应在计划阶段列出每个必需层级。 Web UI 样式参考 English | 中文 本文规定浏览器客户端包的样式职责归属与组件规则。当前 token 值位于 packages/client/ui-theme/src/styles/ ;本文不重复这份由源码生成的清单。 职责归属 ui-theme 负责 --dsw-* 静态色阶、语义别名、排版、动效、渐变、阴影、滚动条样式以及明暗主题偏好。 ui-layout 将解析后的主题快照应用到文档。功能包使用语义别名,不得另行定义全局主题。 全局样式表归 ui-theme/src/styles/ 所有。组件样式以 CSS Modules 形式放在组件旁。当某个值属于该组件的布局或呈现约定时,组件可以定义局部自定义属性;共享颜色、排版、层级和动效属于主题包。 组件规则 使用 CSS Modules 和 clsx ;不得添加组件库或 Tailwind。 功能组件使用 --dsw-alias-* 语义 token。不得复制静态色板值或在其中写入颜色字面量。 功能组件 CSS 不得包含主题选择器。明暗主题覆盖属于主题所有方。 字体大小必须与行高配对;已有角色匹配时使用主题排版变量。 当组件约定要求保留列结构时,源码文本、终端输出和 diff 行不得换行;使用共享滚动条样式,不得定义组件专用滚动条选择器。 呈现规则写在 CSS 中。React 内联样式可以传递组件局部自定义属性值,但不得编码主题分支。 添加过渡动画或仅悬停可见的控件时,保留清晰可见的键盘焦点和减少动态效果行为。 支持的引擎上,圆角继承 ui-theme corner-shape.css 的全局超级椭圆平滑。每个正圆 border-radius ( 50% 、 100% 或胶囊半径)必须配对 corner-shape: round ,使圆形与胶囊保持圆弧;ui-theme 的 corner-shape spec 强制这一配对。 高层级表面(菜单、浮层、对话框、面板、悬浮按钮、输入框)设 border: 0 并使用 box-shadow: var(--dsw-elevation-panel) 、 var(--dsw-elevation-prominent) 或输入框专用的 var(--dsw-elevation-soft) (更大模糊、更低透明度):0.5px 发丝描边是第一层投影, --dsw-elevation-stroke-color 可按表面或状态重绑或抑制描边。不得将 --dsw-alias-border-* border 与 lv/elevation 投影配对——ui-theme 的 elevation spec 会拒绝;状态色 border(warn 面板)保持真 border。 使用中性 --dsw-alias-border-* token 的平面边框与分割线一律 0.5px ——按钮、输入框、卡片、行分割线,以及以填充盒绘制的分隔线(菜单分隔、对话标题栏接缝、markdown hr 、竖向轨道线)共用发丝线粗细,Chromium 将其绘制为一个设备像素。dashed 记号与状态色 border 保持 1px;spinner 圆环经 spec 的显式豁免保留原宽度。更宽的中性 solid border 会被 ui-theme elevation spec 拒绝。 变更系统 在所属 ui-theme 样式表中添加或修改共享 token,然后在功能包中使用其语义别名。公共样式约定发生变化时,更新所属包的参考文档。视觉行为遵循 测试策略 ; 样式系统 Agent Note 记录框架依据。 术语表 English | 中文 DeepSeek Harness 的领域词汇为每个概念规定一个规范术语。各术语通过标准 Markdown 锚点链接到相应条目;实现细节留在各包的 README 与 Agent Note 中。 capability-seam seam :一种包含三种角色的 可替换能力 : Service Definition (拥有自身 ctx. 和词汇类型的 Cordis Service ——可以是 ShellExecutor 这样的抽象类,也可以是 WebRuntime 这样的具体注册表,绝不是 TypeScript interface )、一个或多个 Service Provider ,以及一个或多个注入该服务的 Consumer 。 packages/shell 是规范范例: dsh-shell (Service Definition)、 dsh-bash-local / dsh-bash-sandbox (提供方),以及 dsh-tool-bash (Consumer)。角色需要独立演进时通常位于不同包,但属于同一关注点时,一个包也可以承担多个角色( dsh-user-approval 在同一个包中承担 approval seam 的 Service Definition 与其具体实现)。seam 是完整能力,绝不是其中一个角色;该术语仅保留此义,能力成员应按其角色、类、服务、约定或扩展点命名。 agent-scope scope :按 agent(智能体)划分的注册单位。一项贡献(工具、提示词段、变量、限制、监听器)要么是 全局的 (对所有 agent 可见),要么是 带作用域的 (归属于恰好一个 scope key )。只有两层,采用扁平结构:带作用域的注册不会向下继承给 subagent;子树行为通过 lineage 数据表达,从不通过 scope 结构。 scope key :scope 的不透明标识,按对象同一性比较。harness 约定:一个活跃的 agent 就是其自身 scope 的 key。 agent 上下文( agent.ctx ) :agent 的带作用域上下文;通过它进行的注册既具有 scope 可见性,其生命周期也绑定到该 scope(同一事实决定两者),其上的监听器参与该 agent 的 scope 过滤分发。注册表主体事件可以根据各自的事件约定有意保持不过滤。 scope carrier :scope 过滤分发所携带的 thisArg (由 scopeTarget 构建);其过滤器放行无标签监听器加上主体自身的监听器。 无主体 的 carrier(没有 key)只放行无标签监听器。 scoped dispatch :规则是:关于某个 agent 的活动的事件以该 agent 的 carrier 进行分发。关于注册表本身的事件(如「一个工具被添加了」)属于 注册表主体 事件,保持不过滤。 shadowing :最具体者胜出的名称解析:一个带作用域的工具/片段/变量仅在该 scope 内替换同名的全局对应项。这是按 agent 定制 persona 和按 agent 定制工具变体的机制。 restriction / scope-local 注册 :restriction( tools.restrict )为单个 scope 过滤全局工具集合(多个 restriction 取交集组合);scope-local 注册在过滤之后合并。被过滤掉的全局工具既不出现在提示词中,也拒绝执行,与不存在的工具无法区分。 setup window :创建者组装 agent 作用域环境的创建时隙( CreateAgentOptions.setup ):此时 scope 和 agent 对象已存在,但 agent 或会话尚未发布, agent/session-start 尚未触发,首次提示词尚未组装。setup 只做注册,从不驱动 agent。 lineage :以数据形式携带的父子关系事实( parentSession 、持久的 delegationDepth 、运行时 subagentDepth );从不影响可见性。 目标 目标 :附着在现有会话上的单个持久完成目标,带有按修订号演进的 active / paused / blocked / complete 阶段和 Goal Round 上限; blocked 保留策略代码与说明。目标是一种状态,不是调度器,也不是一段独立对话;会话日志仍是其真源。 Goal Round :为当前目标接纳的一次续行周期。同会话驱动器将 Goal Round 具体化为一个由目标触发的 轮次 ,其中可包含零个或多个步骤;同一会话中无关的人类轮次不消耗 Goal Round 上限。 目标激活 :续行消费方接纳下一个 Goal Round 的进程本地权限。激活态为 armed 或 disarmed ;它有意不参与持久回放,因此在恢复或 fork 后,只有随后通过 /goal 或模型工具执行一次经人类授权的恢复变更,自动工作才能开始。 人类命令 人类命令 :以斜杠开头的指令,由面向人类的适配器通过 ctx.commands 解释并执行,不会成为模型消息。它既不同于面向模型的工具,也不同于通过 ctx.shell 执行 shell 命令。 命令平面 :由 UI 适配器和命令插件负责的发现、解析、分发、取消与结果渲染机制。除非处理器另行改变持久领域,否则命令输出属于 UI 状态。 目标命令 : /goal 是由 dsh-command-goal 提供的人类命令;它直接观察或更改当前目标,而目标领域拥有每条持久且模型可见的记录。 循环层级 轮次 :会话中一次对已接纳输入的排空过程,在模型及其工具停止工作或终止策略介入后结束。 步骤 :一次模型请求,以及由模型响应引发的工具执行;一个轮次包含零个或多个步骤。 Round :承载一个轮次的外层策略迭代,例如一个 Goal Round 或一次使用全新 agent 的 Ralph 尝试。Round 计数器归该策略所有,并不统计会话中的每个轮次。 Ralph Ralph 循环 :一次面向不可变目标的前台全新 agent 工作流运行。它是由工作流和 subagent 原语组合而成的面向模型的工具策略,不是同会话目标、agent loop(智能体循环)模式、调度器或通用工作流脚本功能。 Ralph Round : Ralph 循环 中的一个全新子会话。子会话不接收父会话或此前子会话的对话种子;共享工作区和一份有界的 Ralph 交接 承载跨 Round 的状态。 Ralph 交接 :从一个仍需继续的 Ralph Round 传给下一个 Ralph Round 的规范化、有界结构化报告,包含状态、摘要、证据、后续步骤和阻塞说明。它补充共享工作区,而不取代工作区的权威地位。 文档图索引 English | 中文 这些图展示生成目录未包含的关系。可以用它们查找包之间的关系、能力 seam、事件流、面向模型的工具、应用组合和运行时生命周期路径。精确签名和类型定义仍以 子系统页面 (类型和生成的 cordis-surface 区域)及 工具目录 为准。 本索引背后的流程决策记录在 文档图 Agent Note 中。 图 模式 模块依赖图 generated 工具 schema 目录与包映射 generated 能力 seam 与核心服务 hybrid generated dsh 共享基础组合 hybrid generated 事件生产方/消费方矩阵 hybrid generated agent(智能体)轮次与步骤生命周期 curated 工具执行流水线 curated 运行 pnpm run gen-doc-graphs 可重新生成英文源文件;运行 pnpm run verify-doc-graphs 可验证英文源的新鲜度,中文对侧则通过双语配对维护。 英文源文件的维护模式为混合。每个链接页面都会声明其英文源模式为生成、混合或人工编写;本中文文件是通过双语配对维护的经评审对侧。 共享实例依赖关系图 English | 中文 @deepseek-ai/dsh-* harness 包之间的 peer 依赖关系。peer 表示消费端需要提供共享实例,不包括普通运行时 dependency 或仅开发期关系。该图按 packages// 层级分组;边 a --> b 表示包 a peer 依赖包 b 。名称中的 @deepseek-ai/dsh- 前缀已移除。 flowchart TD subgraph group_util["packages/util"] pkg_atomic_write["atomic-write"] pkg_brand["brand"] pkg_deque["deque"] pkg_home_paths["home-paths"] pkg_launch_environment["launch-environment"] pkg_native_command["native-command"] pkg_output_retention["output-retention"] pkg_timeout["timeout"] pkg_util_crypto["util-crypto"] pkg_util_time["util-time"] pkg_util_values["util-values"] pkg_util_workspace_path["util-workspace-path"] end subgraph group_llm["packages/llm"] pkg_deepseek_llm_api_extensions["deepseek-llm-api-extensions"] pkg_llm["llm"] pkg_llm_deepseek["llm-deepseek"] pkg_llm_pi_ai["llm-pi-ai"] pkg_llm_retry["llm-retry"] pkg_plugin_package_inventory_deepseek["plugin-package-inventory-deepseek"] pkg_token_meter["token-meter"] end subgraph group_core["packages/core"] pkg_agent["agent"] pkg_agent_default_model["agent-default-model"] pkg_agent_loop["agent-loop"] pkg_agent_tool_presentation["agent-tool-presentation"] pkg_scope["scope"] pkg_session["session"] pkg_system_prompt["system-prompt"] pkg_tools["tools"] end subgraph group_goal["packages/goal"] pkg_command_goal["command-goal"] pkg_goal["goal"] pkg_goal_round_driver["goal-round-driver"] pkg_tool_goal["tool-goal"] end subgraph group_fs["packages/fs"] pkg_fs["fs"] pkg_fs_local["fs-local"] pkg_fs_observation_policy["fs-observation-policy"] pkg_fs_sandbox["fs-sandbox"] pkg_tool_fs["tool-fs"] pkg_tool_fs_search["tool-fs-search"] pkg_tool_str_replace_editor["tool-str-replace-editor"] end subgraph group_skill["packages/skill"] pkg_skill["skill"] pkg_skill_badge["skill-badge"] pkg_skill_filesystem["skill-filesystem"] pkg_tool_skill["tool-skill"] end subgraph group_subagent["packages/subagent"] pkg_subagent["subagent"] pkg_subagent_acp["subagent-acp"] pkg_subagent_claude_code["subagent-claude-code"] pkg_subagent_codex["subagent-codex"] pkg_subagent_dsh_sdk["subagent-dsh-sdk"] pkg_subagent_fork_in_process["subagent-fork-in-process"] pkg_subagent_in_process_driver["subagent-in-process-driver"] pkg_subagent_spawn_in_process["subagent-spawn-in-process"] pkg_tool_subagent["tool-subagent"] pkg_tool_subagent_control["tool-subagent-control"] end subgraph group_web["packages/web"] pkg_tool_web["tool-web"] pkg_web["web"] pkg_web_fetch_http["web-fetch-http"] pkg_web_search_deepseek["web-search-deepseek"] pkg_web_search_exa["web-search-exa"] pkg_web_search_perplexity["web-search-perplexity"] end subgraph group_spill["packages/spill"] pkg_spill["spill"] pkg_spill_local["spill-local"] pkg_spill_policy["spill-policy"] end subgraph group_todo["packages/todo"] pkg_tool_todo["tool-todo"] end subgraph group_plan["packages/plan"] pkg_plan_mode["plan-mode"] end subgraph group_hooks["packages/hooks"] pkg_hook_protocol["hook-protocol"] pkg_hooks_claude_code["hooks-claude-code"] pkg_hooks_codex["hooks-codex"] end subgraph group_session_query["packages/session-query"] pkg_session_log_export["session-log-export"] pkg_session_query["session-query"] pkg_session_query_sqlite["session-query-sqlite"] pkg_tool_session_query["tool-session-query"] end subgraph group_acp["packages/acp"] pkg_acp["acp"] end subgraph group_api["packages/api"] pkg_api_gateway["api-gateway"] pkg_api_remotes["api-remotes"] pkg_api_session_controller["api-session-controller"] pkg_api_settings_controller["api-settings-controller"] pkg_api_workspace_controller["api-workspace-controller"] end subgraph group_attachment["packages/attachment"] pkg_attachment["attachment"] pkg_attachment_local["attachment-local"] end subgraph group_boot["packages/boot"] pkg_app_boot["app-boot"] pkg_cmdline["cmdline"] end subgraph group_bundle["packages/bundle"] pkg_acp_app["acp-app"] pkg_base["base"] pkg_headless["headless"] pkg_sdk_app["sdk-app"] pkg_sdk_minimal["sdk-minimal"] pkg_web_app["web-app"] end subgraph group_client["packages/client"] pkg_client_connection["client-connection"] pkg_client_hmr["client-hmr"] pkg_client_locale["client-locale"] pkg_client_modules["client-modules"] pkg_client_store["client-store"] pkg_client_ui_agent_preset["client-ui-agent-preset"] pkg_client_ui_approval["client-ui-approval"] pkg_client_ui_attachment["client-ui-attachment"] pkg_client_ui_brand_official["client-ui-brand-official"] pkg_client_ui_chat["client-ui-chat"] pkg_client_ui_commands["client-ui-commands"] pkg_client_ui_conversation["client-ui-conversation"] pkg_client_ui_deliverables["client-ui-deliverables"] pkg_client_ui_directory_picker_browse["client-ui-directory-picker-browse"] pkg_client_ui_directory_picker_native["client-ui-directory-picker-native"] pkg_client_ui_goal["client-ui-goal"] pkg_client_ui_input_trigger["client-ui-input-trigger"] pkg_client_ui_jobs["client-ui-jobs"] pkg_client_ui_layout["client-ui-layout"] pkg_client_ui_message_feedback["client-ui-message-feedback"] pkg_client_ui_model_selection["client-ui-model-selection"] pkg_client_ui_permission_presets["client-ui-permission-presets"] pkg_client_ui_plan["client-ui-plan"] pkg_client_ui_primitives["client-ui-primitives"] pkg_client_ui_reference["client-ui-reference"] pkg_client_ui_renderer["client-ui-renderer"] pkg_client_ui_schedule["client-ui-schedule"] pkg_client_ui_session["client-ui-session"] pkg_client_ui_settings["client-ui-settings"] pkg_client_ui_settings_general["client-ui-settings-general"] pkg_client_ui_settings_models["client-ui-settings-models"] pkg_client_ui_settings_plugin_inventory["client-ui-settings-plugin-inventory"] pkg_client_ui_settings_plugins["client-ui-settings-plugins"] pkg_client_ui_sidebar["client-ui-sidebar"] pkg_client_ui_skill["client-ui-skill"] pkg_client_ui_slots["client-ui-slots"] pkg_client_ui_subagent["client-ui-subagent"] pkg_client_ui_theme["client-ui-theme"] pkg_client_ui_tool["client-ui-tool"] pkg_client_ui_trajectory["client-ui-trajectory"] pkg_client_ui_user_questions["client-ui-user-questions"] pkg_client_ui_workflow_run["client-ui-workflow-run"] pkg_client_ui_workspace["client-ui-workspace"] pkg_client_web["client-web"] end subgraph group_code_runtime["packages/code-runtime"] pkg_code_runtime["code-runtime"] pkg_code_runtime_worker_thread["code-runtime-worker-thread"] end subgraph group_compaction["packages/compaction"] pkg_command_compact["command-compact"] pkg_compaction["compaction"] pkg_compaction_basic["compaction-basic"] pkg_compaction_tool_result_pruner["compaction-tool-result-pruner"] end subgraph group_context["packages/context"] pkg_agent_instructions["agent-instructions"] pkg_file_reference["file-reference"] pkg_file_reference_local["file-reference-local"] pkg_session_reference["session-reference"] pkg_time_context["time-context"] pkg_tmux_context["tmux-context"] end subgraph group_credentials["packages/credentials"] pkg_authorization["authorization"] pkg_credentials["credentials"] pkg_credentials_local["credentials-local"] end subgraph group_e2b["packages/e2b"] pkg_e2b["e2b"] pkg_fs_e2b["fs-e2b"] pkg_subprocess_e2b["subprocess-e2b"] end subgraph group_experimental["packages/experimental"] pkg_experimental_agent_team["experimental-agent-team"] pkg_experimental_agent_team_profile["experimental-agent-team-profile"] pkg_experimental_agent_team_web_profile["experimental-agent-team-web-profile"] pkg_experimental_client_ui_agent_team["experimental-client-ui-agent-team"] pkg_experimental_code_runtime_python["experimental-code-runtime-python"] pkg_experimental_inspector["experimental-inspector"] pkg_experimental_tool_agent_team["experimental-tool-agent-team"] pkg_experimental_webworker_packer["experimental-webworker-packer"] pkg_experimental_webworker_runtime["experimental-webworker-runtime"] end subgraph group_extensions["packages/extensions"] pkg_client_ui_cordis["client-ui-cordis"] pkg_cordis_client_runner["cordis-client-runner"] pkg_cordis_host_runner["cordis-host-runner"] pkg_tool_cordis["tool-cordis"] end subgraph group_feedback["packages/feedback"] pkg_command_feedback["command-feedback"] pkg_message_feedback["message-feedback"] end subgraph group_guard["packages/guard"] pkg_repeat_tool_reminder["repeat-tool-reminder"] pkg_tool_call_timeout_policy["tool-call-timeout-policy"] end subgraph group_host["packages/host"] pkg_host_directory_picker["host-directory-picker"] pkg_host_directory_picker_auto["host-directory-picker-auto"] pkg_host_directory_picker_browse["host-directory-picker-browse"] pkg_host_directory_picker_native["host-directory-picker-native"] pkg_host_frontend_static["host-frontend-static"] pkg_host_plugin_inventory["host-plugin-inventory"] pkg_host_webserver["host-webserver"] end subgraph group_identity["packages/identity"] pkg_anonymous_user_id["anonymous-user-id"] end subgraph group_interaction["packages/interaction"] pkg_commands["commands"] pkg_permission_presets["permission-presets"] pkg_tool_ask_user["tool-ask-user"] pkg_user_approval["user-approval"] pkg_user_questions["user-questions"] end subgraph group_jobs["packages/jobs"] pkg_jobs["jobs"] pkg_jobs_local["jobs-local"] pkg_tool_jobs["tool-jobs"] end subgraph group_lsp["packages/lsp"] pkg_lsp["lsp"] pkg_lsp_stdio["lsp-stdio"] pkg_tool_lsp["tool-lsp"] end subgraph group_mcp["packages/mcp"] pkg_mcp_client["mcp-client"] end subgraph group_preset["packages/preset"] pkg_agent_presets["agent-presets"] pkg_persona["persona"] end subgraph group_runtime_diagnostics["packages/runtime-diagnostics"] pkg_invariants["invariants"] end subgraph group_sandbox["packages/sandbox"] pkg_sandbox["sandbox"] pkg_sandbox_local["sandbox-local"] pkg_sandbox_policy["sandbox-policy"] pkg_sandbox_windows_acl["sandbox-windows-acl"] end subgraph group_schedule["packages/schedule"] pkg_schedule["schedule"] end subgraph group_sdk["packages/sdk"] pkg_sdk_client["sdk-client"] pkg_sdk_jsonrpc_server["sdk-jsonrpc-server"] pkg_sdk_protocol["sdk-protocol"] end subgraph group_session["packages/session"] pkg_session_checkpoint_policy["session-checkpoint-policy"] pkg_session_log_deepseek["session-log-deepseek"] pkg_session_persistence["session-persistence"] pkg_session_persistence_jsonl["session-persistence-jsonl"] pkg_session_projection["session-projection"] pkg_session_projection_cache["session-projection-cache"] pkg_session_stats["session-stats"] pkg_session_telemetry["session-telemetry"] pkg_session_telemetry_otel["session-telemetry-otel"] pkg_session_title["session-title"] pkg_session_title_all_prompts_llm["session-title-all-prompts-llm"] pkg_session_title_first_prompt_llm["session-title-first-prompt-llm"] pkg_session_title_llm["session-title-llm"] pkg_session_turn_outline["session-turn-outline"] end subgraph group_settings["packages/settings"] pkg_settings["settings"] pkg_settings_file["settings-file"] end subgraph group_shell["packages/shell"] pkg_bash_local["bash-local"] pkg_bash_sandbox["bash-sandbox"] pkg_pwsh_local["pwsh-local"] pkg_pwsh_sandbox["pwsh-sandbox"] pkg_shell["shell"] pkg_shell_env["shell-env"] pkg_tool_bash["tool-bash"] pkg_tool_bash_persistent["tool-bash-persistent"] pkg_tool_pwsh["tool-pwsh"] pkg_tool_pwsh_persistent["tool-pwsh-persistent"] end subgraph group_storage["packages/storage"] pkg_storage["storage"] pkg_storage_domain["storage-domain"] pkg_storage_json["storage-json"] pkg_storage_sqlite["storage-sqlite"] end subgraph group_subprocess["packages/subprocess"] pkg_subprocess["subprocess"] pkg_subprocess_local["subprocess-local"] pkg_win32_process["win32-process"] end subgraph group_terminal["packages/terminal"] pkg_terminal["terminal"] pkg_terminal_bash["terminal-bash"] pkg_tool_terminal["tool-terminal"] end subgraph group_test_support["packages/test-support"] pkg_agent_loop_testkit["agent-loop-testkit"] pkg_client_test_runtime["client-test-runtime"] pkg_llm_mock_server["llm-mock-server"] pkg_llm_replay["llm-replay"] pkg_loader_smoke["loader-smoke"] pkg_session_snapshot["session-snapshot"] end subgraph group_typert["packages/typert"] pkg_typert_generator["typert-generator"] pkg_typert_loader["typert-loader"] pkg_typert_protocol["typert-protocol"] pkg_typert_registry["typert-registry"] end subgraph group_webhook["packages/webhook"] pkg_webhook["webhook"] pkg_webhook_github["webhook-github"] end subgraph group_workflow["packages/workflow"] pkg_tool_ralph["tool-ralph"] pkg_tool_workflow["tool-workflow"] pkg_workflow["workflow"] pkg_workflow_worker_thread["workflow-worker-thread"] end subgraph group_workspace["packages/workspace"] pkg_workspace["workspace"] end pkg_scope --> pkg_invariants pkg_web --> pkg_llm pkg_attachment --> pkg_brand pkg_credentials --> pkg_invariants pkg_subprocess_e2b --> pkg_e2b pkg_subprocess_e2b --> pkg_subprocess pkg_subprocess_e2b --> pkg_timeout pkg_experimental_code_runtime_python --> pkg_code_runtime pkg_experimental_code_runtime_python --> pkg_timeout pkg_experimental_code_runtime_python --> pkg_util_values pkg_experimental_inspector --> pkg_client_modules pkg_experimental_inspector --> pkg_host_webserver pkg_experimental_webworker_runtime --> pkg_client_connection pkg_experimental_webworker_runtime --> pkg_client_modules pkg_experimental_webworker_runtime --> pkg_host_webserver pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_browse pkg_host_directory_picker_auto --> pkg_client_ui_directory_picker_native pkg_host_directory_picker_auto --> pkg_host_directory_picker_browse pkg_host_directory_picker_auto --> pkg_host_directory_picker_native pkg_host_directory_picker_auto --> pkg_host_webserver pkg_host_frontend_static --> pkg_client_connection pkg_host_frontend_static --> pkg_host_webserver pkg_anonymous_user_id --> pkg_brand pkg_anonymous_user_id --> pkg_home_paths pkg_lsp --> pkg_brand pkg_lsp --> pkg_llm pkg_storage_domain --> pkg_invariants pkg_storage_domain --> pkg_storage pkg_storage_json --> pkg_storage pkg_storage_sqlite --> pkg_storage pkg_subprocess_local --> pkg_subprocess pkg_subprocess_local --> pkg_timeout pkg_typert_loader --> pkg_typert_registry pkg_session --> pkg_scope pkg_system_prompt --> pkg_invariants pkg_system_prompt --> pkg_llm pkg_system_prompt --> pkg_scope pkg_skill --> pkg_llm pkg_skill --> pkg_scope pkg_web_fetch_http --> pkg_timeout pkg_web_fetch_http --> pkg_web pkg_web_search_exa --> pkg_launch_environment pkg_web_search_exa --> pkg_web pkg_web_search_perplexity --> pkg_launch_environment pkg_web_search_perplexity --> pkg_web pkg_api_remotes --> pkg_scope pkg_attachment_local --> pkg_attachment pkg_attachment_local --> pkg_home_paths pkg_authorization --> pkg_credentials pkg_authorization --> pkg_invariants pkg_authorization --> pkg_llm pkg_credentials_local --> pkg_atomic_write pkg_credentials_local --> pkg_credentials pkg_credentials_local --> pkg_home_paths pkg_credentials_local --> pkg_launch_environment pkg_skill_badge --> pkg_skill pkg_spill --> pkg_brand pkg_spill --> pkg_llm pkg_spill --> pkg_session pkg_app_boot --> pkg_home_paths pkg_app_boot --> pkg_launch_environment pkg_app_boot --> pkg_system_prompt pkg_code_runtime_worker_thread --> pkg_code_runtime pkg_code_runtime_worker_thread --> pkg_session pkg_code_runtime_worker_thread --> pkg_timeout pkg_persona --> pkg_system_prompt pkg_sandbox --> pkg_llm pkg_sandbox --> pkg_session pkg_session_log_deepseek --> pkg_deepseek_llm_api_extensions pkg_session_log_deepseek --> pkg_invariants pkg_session_log_deepseek --> pkg_session pkg_session_persistence --> pkg_brand pkg_session_persistence --> pkg_session pkg_session_persistence --> pkg_timeout pkg_session_projection --> pkg_session pkg_settings --> pkg_brand pkg_settings --> pkg_invariants pkg_settings --> pkg_session pkg_session_snapshot --> pkg_session pkg_agent --> pkg_invariants pkg_agent --> pkg_llm pkg_agent --> pkg_scope pkg_agent --> pkg_session pkg_agent --> pkg_session_projection pkg_agent --> pkg_system_prompt pkg_agent --> pkg_typert_protocol pkg_fs --> pkg_brand pkg_fs --> pkg_invariants pkg_fs --> pkg_llm pkg_fs --> pkg_sandbox pkg_spill_local --> pkg_spill pkg_message_feedback --> pkg_brand pkg_message_feedback --> pkg_llm pkg_message_feedback --> pkg_session pkg_message_feedback --> pkg_session_persistence pkg_message_feedback --> pkg_storage_domain pkg_message_feedback --> pkg_typert_protocol pkg_sandbox_local --> pkg_llm pkg_sandbox_local --> pkg_sandbox pkg_sandbox_local --> pkg_session pkg_session_persistence_jsonl --> pkg_session pkg_session_persistence_jsonl --> pkg_session_persistence pkg_session_projection_cache --> pkg_session pkg_session_projection_cache --> pkg_session_projection pkg_session_projection_cache --> pkg_storage_domain pkg_session_stats --> pkg_llm pkg_session_stats --> pkg_session pkg_session_stats --> pkg_session_projection pkg_session_turn_outline --> pkg_llm pkg_session_turn_outline --> pkg_session pkg_session_turn_outline --> pkg_session_projection pkg_settings_file --> pkg_atomic_write pkg_settings_file --> pkg_home_paths pkg_settings_file --> pkg_settings pkg_shell --> pkg_sandbox pkg_shell --> pkg_settings pkg_shell --> pkg_subprocess pkg_workspace --> pkg_invariants pkg_workspace --> pkg_session pkg_workspace --> pkg_session_persistence pkg_workspace --> pkg_storage pkg_workspace --> pkg_storage_domain pkg_workspace --> pkg_typert_protocol pkg_llm_deepseek --> pkg_anonymous_user_id pkg_llm_deepseek --> pkg_atomic_write pkg_llm_deepseek --> pkg_attachment pkg_llm_deepseek --> pkg_credentials pkg_llm_deepseek --> pkg_deepseek_llm_api_extensions pkg_llm_deepseek --> pkg_fs pkg_llm_deepseek --> pkg_home_paths pkg_llm_deepseek --> pkg_launch_environment pkg_llm_deepseek --> pkg_llm pkg_llm_deepseek --> pkg_settings pkg_llm_deepseek --> pkg_timeout pkg_llm_pi_ai --> pkg_attachment pkg_llm_pi_ai --> pkg_authorization pkg_llm_pi_ai --> pkg_credentials pkg_llm_pi_ai --> pkg_fs pkg_llm_pi_ai --> pkg_launch_environment pkg_llm_pi_ai --> pkg_llm pkg_llm_pi_ai --> pkg_settings pkg_llm_pi_ai --> pkg_timeout pkg_llm_retry --> pkg_agent pkg_llm_retry --> pkg_brand pkg_llm_retry --> pkg_invariants pkg_llm_retry --> pkg_llm pkg_llm_retry --> pkg_session pkg_llm_retry --> pkg_session_projection pkg_llm_retry --> pkg_timeout pkg_agent_default_model --> pkg_agent pkg_agent_default_model --> pkg_llm pkg_agent_default_model --> pkg_settings pkg_goal --> pkg_agent pkg_goal --> pkg_brand pkg_goal --> pkg_invariants pkg_goal --> pkg_llm pkg_goal --> pkg_scope pkg_goal --> pkg_session pkg_goal --> pkg_session_projection pkg_goal --> pkg_typert_protocol pkg_fs_local --> pkg_fs pkg_fs_observation_policy --> pkg_fs pkg_skill_filesystem --> pkg_fs pkg_skill_filesystem --> pkg_home_paths pkg_skill_filesystem --> pkg_skill pkg_web_search_deepseek --> pkg_agent pkg_web_search_deepseek --> pkg_credentials pkg_web_search_deepseek --> pkg_launch_environment pkg_web_search_deepseek --> pkg_session pkg_web_search_deepseek --> pkg_settings pkg_web_search_deepseek --> pkg_web pkg_hook_protocol --> pkg_invariants pkg_hook_protocol --> pkg_session pkg_hook_protocol --> pkg_shell pkg_api_workspace_controller --> pkg_api_gateway pkg_api_workspace_controller --> pkg_client_connection pkg_api_workspace_controller --> pkg_host_directory_picker pkg_api_workspace_controller --> pkg_session pkg_api_workspace_controller --> pkg_storage_domain pkg_api_workspace_controller --> pkg_typert_protocol pkg_api_workspace_controller --> pkg_workspace pkg_file_reference --> pkg_agent pkg_time_context --> pkg_agent pkg_time_context --> pkg_invariants pkg_time_context --> pkg_llm pkg_time_context --> pkg_session pkg_time_context --> pkg_session_projection pkg_tmux_context --> pkg_agent pkg_tmux_context --> pkg_session pkg_tmux_context --> pkg_session_projection pkg_tmux_context --> pkg_shell pkg_fs_e2b --> pkg_e2b pkg_fs_e2b --> pkg_fs pkg_commands --> pkg_agent pkg_commands --> pkg_attachment pkg_commands --> pkg_brand pkg_commands --> pkg_invariants pkg_commands --> pkg_llm pkg_commands --> pkg_scope pkg_commands --> pkg_session pkg_commands --> pkg_typert_protocol pkg_user_approval --> pkg_agent pkg_user_approval --> pkg_brand pkg_user_approval --> pkg_invariants pkg_user_approval --> pkg_llm pkg_user_approval --> pkg_scope pkg_user_approval --> pkg_session pkg_user_approval --> pkg_system_prompt pkg_user_questions --> pkg_agent pkg_user_questions --> pkg_llm pkg_user_questions --> pkg_scope pkg_jobs --> pkg_agent pkg_jobs --> pkg_brand pkg_jobs --> pkg_invariants pkg_jobs --> pkg_session pkg_lsp_stdio --> pkg_brand pkg_lsp_stdio --> pkg_fs pkg_lsp_stdio --> pkg_llm pkg_lsp_stdio --> pkg_lsp pkg_lsp_stdio --> pkg_subprocess pkg_lsp_stdio --> pkg_timeout pkg_sandbox_policy --> pkg_agent pkg_sandbox_policy --> pkg_invariants pkg_sandbox_policy --> pkg_sandbox pkg_sandbox_policy --> pkg_session pkg_sandbox_policy --> pkg_session_projection pkg_sandbox_policy --> pkg_system_prompt pkg_session_telemetry --> pkg_agent pkg_session_telemetry --> pkg_session pkg_session_title --> pkg_agent pkg_session_title --> pkg_brand pkg_session_title --> pkg_invariants pkg_session_title --> pkg_llm pkg_session_title --> pkg_session pkg_session_title --> pkg_session_projection pkg_bash_local --> pkg_settings pkg_bash_local --> pkg_shell pkg_bash_local --> pkg_subprocess pkg_bash_local --> pkg_timeout pkg_pwsh_local --> pkg_settings pkg_pwsh_local --> pkg_shell pkg_pwsh_local --> pkg_subprocess pkg_pwsh_local --> pkg_timeout pkg_terminal --> pkg_agent pkg_terminal --> pkg_brand pkg_loader_smoke --> pkg_agent pkg_loader_smoke --> pkg_llm pkg_loader_smoke --> pkg_session pkg_workflow --> pkg_agent pkg_workflow --> pkg_brand pkg_workflow --> pkg_invariants pkg_workflow --> pkg_llm pkg_workflow --> pkg_session pkg_tools --> pkg_agent pkg_tools --> pkg_code_runtime pkg_tools --> pkg_invariants pkg_tools --> pkg_llm pkg_tools --> pkg_scope pkg_tools --> pkg_session pkg_tools --> pkg_system_prompt pkg_tools --> pkg_user_approval pkg_command_goal --> pkg_commands pkg_command_goal --> pkg_goal pkg_command_goal --> pkg_llm pkg_goal_round_driver --> pkg_agent pkg_goal_round_driver --> pkg_goal pkg_goal_round_driver --> pkg_invariants pkg_goal_round_driver --> pkg_llm pkg_goal_round_driver --> pkg_session pkg_fs_sandbox --> pkg_fs pkg_fs_sandbox --> pkg_fs_local pkg_fs_sandbox --> pkg_sandbox pkg_fs_sandbox --> pkg_sandbox_policy pkg_headless --> pkg_agent pkg_headless --> pkg_agent_default_model pkg_headless --> pkg_llm pkg_headless --> pkg_session pkg_compaction --> pkg_brand pkg_compaction --> pkg_commands pkg_compaction --> pkg_invariants pkg_compaction --> pkg_llm pkg_compaction --> pkg_session pkg_command_feedback --> pkg_anonymous_user_id pkg_command_feedback --> pkg_commands pkg_command_feedback --> pkg_session pkg_command_feedback --> pkg_session_telemetry pkg_permission_presets --> pkg_commands pkg_permission_presets --> pkg_invariants pkg_permission_presets --> pkg_sandbox pkg_permission_presets --> pkg_sandbox_policy pkg_permission_presets --> pkg_session pkg_permission_presets --> pkg_session_projection pkg_permission_presets --> pkg_settings pkg_permission_presets --> pkg_shell pkg_permission_presets --> pkg_user_approval pkg_jobs_local --> pkg_agent pkg_jobs_local --> pkg_jobs pkg_jobs_local --> pkg_scope pkg_jobs_local --> pkg_timeout pkg_session_title_llm --> pkg_llm pkg_session_title_llm --> pkg_session pkg_session_title_llm --> pkg_session_title pkg_session_title_llm --> pkg_timeout pkg_bash_sandbox --> pkg_bash_local pkg_bash_sandbox --> pkg_sandbox pkg_bash_sandbox --> pkg_sandbox_policy pkg_bash_sandbox --> pkg_shell pkg_pwsh_sandbox --> pkg_pwsh_local pkg_pwsh_sandbox --> pkg_sandbox pkg_pwsh_sandbox --> pkg_sandbox_policy pkg_pwsh_sandbox --> pkg_shell pkg_terminal_bash --> pkg_agent pkg_terminal_bash --> pkg_sandbox pkg_terminal_bash --> pkg_sandbox_policy pkg_terminal_bash --> pkg_session pkg_terminal_bash --> pkg_session_projection pkg_terminal_bash --> pkg_subprocess pkg_terminal_bash --> pkg_terminal pkg_token_meter --> pkg_compaction pkg_token_meter --> pkg_llm pkg_token_meter --> pkg_llm_retry pkg_token_meter --> pkg_session pkg_token_meter --> pkg_session_projection pkg_agent_loop --> pkg_agent pkg_agent_loop --> pkg_invariants pkg_agent_loop --> pkg_llm pkg_agent_loop --> pkg_scope pkg_agent_loop --> pkg_session pkg_agent_loop --> pkg_session_persistence pkg_agent_loop --> pkg_session_projection pkg_agent_loop --> pkg_settings pkg_agent_loop --> pkg_system_prompt pkg_agent_loop --> pkg_tools pkg_agent_tool_presentation --> pkg_tools pkg_tool_goal --> pkg_agent pkg_tool_goal --> pkg_goal pkg_tool_goal --> pkg_llm pkg_tool_goal --> pkg_session pkg_tool_goal --> pkg_session_projection pkg_tool_goal --> pkg_system_prompt pkg_tool_goal --> pkg_tools pkg_tool_fs --> pkg_attachment pkg_tool_fs --> pkg_fs pkg_tool_fs --> pkg_llm pkg_tool_fs --> pkg_sandbox pkg_tool_fs --> pkg_sandbox_policy pkg_tool_fs --> pkg_session pkg_tool_fs --> pkg_system_prompt pkg_tool_fs --> pkg_tools pkg_tool_fs --> pkg_user_approval pkg_tool_fs_search --> pkg_llm pkg_tool_fs_search --> pkg_output_retention pkg_tool_fs_search --> pkg_session pkg_tool_fs_search --> pkg_spill pkg_tool_fs_search --> pkg_subprocess pkg_tool_fs_search --> pkg_system_prompt pkg_tool_fs_search --> pkg_timeout pkg_tool_fs_search --> pkg_tools pkg_tool_str_replace_editor --> pkg_fs pkg_tool_str_replace_editor --> pkg_sandbox pkg_tool_str_replace_editor --> pkg_sandbox_policy pkg_tool_str_replace_editor --> pkg_tools pkg_tool_skill --> pkg_agent pkg_tool_skill --> pkg_llm pkg_tool_skill --> pkg_skill pkg_tool_skill --> pkg_tools pkg_tool_web --> pkg_llm pkg_tool_web --> pkg_system_prompt pkg_tool_web --> pkg_tools pkg_tool_web --> pkg_web pkg_spill_policy --> pkg_llm pkg_spill_policy --> pkg_output_retention pkg_spill_policy --> pkg_session pkg_spill_policy --> pkg_spill pkg_spill_policy --> pkg_tools pkg_tool_todo --> pkg_agent pkg_tool_todo --> pkg_invariants pkg_tool_todo --> pkg_session pkg_tool_todo --> pkg_session_projection pkg_tool_todo --> pkg_tools pkg_plan_mode --> pkg_agent pkg_plan_mode --> pkg_commands pkg_plan_mode --> pkg_invariants pkg_plan_mode --> pkg_llm pkg_plan_mode --> pkg_session pkg_plan_mode --> pkg_session_projection pkg_plan_mode --> pkg_system_prompt pkg_plan_mode --> pkg_tools pkg_plan_mode --> pkg_user_questions pkg_hooks_codex --> pkg_agent pkg_hooks_codex --> pkg_hook_protocol pkg_hooks_codex --> pkg_llm pkg_hooks_codex --> pkg_session pkg_hooks_codex --> pkg_session_persistence pkg_hooks_codex --> pkg_session_projection pkg_hooks_codex --> pkg_tools pkg_command_compact --> pkg_commands pkg_command_compact --> pkg_compaction pkg_agent_instructions --> pkg_agent pkg_agent_instructions --> pkg_fs pkg_agent_instructions --> pkg_home_paths pkg_agent_instructions --> pkg_llm pkg_agent_instructions --> pkg_session pkg_agent_instructions --> pkg_session_projection pkg_agent_instructions --> pkg_tools pkg_file_reference_local --> pkg_agent pkg_file_reference_local --> pkg_file_reference pkg_file_reference_local --> pkg_system_prompt pkg_file_reference_local --> pkg_tools pkg_cordis_host_runner --> pkg_agent pkg_cordis_host_runner --> pkg_brand pkg_cordis_host_runner --> pkg_llm pkg_cordis_host_runner --> pkg_scope pkg_cordis_host_runner --> pkg_session pkg_cordis_host_runner --> pkg_tools pkg_cordis_host_runner --> pkg_typert_protocol pkg_repeat_tool_reminder --> pkg_agent pkg_repeat_tool_reminder --> pkg_tools pkg_tool_call_timeout_policy --> pkg_llm pkg_tool_call_timeout_policy --> pkg_timeout pkg_tool_call_timeout_policy --> pkg_tools pkg_tool_ask_user --> pkg_agent pkg_tool_ask_user --> pkg_tools pkg_tool_ask_user --> pkg_user_questions pkg_tool_jobs --> pkg_agent pkg_tool_jobs --> pkg_jobs pkg_tool_jobs --> pkg_llm pkg_tool_jobs --> pkg_output_retention pkg_tool_jobs --> pkg_system_prompt pkg_tool_jobs --> pkg_tools pkg_tool_lsp --> pkg_llm pkg_tool_lsp --> pkg_lsp pkg_tool_lsp --> pkg_system_prompt pkg_tool_lsp --> pkg_timeout pkg_tool_lsp --> pkg_tools pkg_mcp_client --> pkg_attachment pkg_mcp_client --> pkg_llm pkg_mcp_client --> pkg_scope pkg_mcp_client --> pkg_subprocess pkg_mcp_client --> pkg_timeout pkg_mcp_client --> pkg_tools pkg_agent_presets --> pkg_agent pkg_agent_presets --> pkg_atomic_write pkg_agent_presets --> pkg_home_paths pkg_agent_presets --> pkg_invariants pkg_agent_presets --> pkg_scope pkg_agent_presets --> pkg_session pkg_agent_presets --> pkg_session_projection pkg_agent_presets --> pkg_settings pkg_agent_presets --> pkg_system_prompt pkg_agent_presets --> pkg_tools pkg_agent_presets --> pkg_typert_protocol pkg_schedule --> pkg_agent pkg_schedule --> pkg_brand pkg_schedule --> pkg_invariants pkg_schedule --> pkg_llm pkg_schedule --> pkg_session pkg_schedule --> pkg_session_persistence pkg_schedule --> pkg_session_projection pkg_schedule --> pkg_tools pkg_session_checkpoint_policy --> pkg_agent pkg_session_checkpoint_policy --> pkg_llm pkg_session_checkpoint_policy --> pkg_session pkg_session_checkpoint_policy --> pkg_session_persistence pkg_session_checkpoint_policy --> pkg_tools pkg_session_telemetry_otel --> pkg_anonymous_user_id pkg_session_telemetry_otel --> pkg_command_feedback pkg_session_telemetry_otel --> pkg_llm pkg_session_telemetry_otel --> pkg_session pkg_session_telemetry_otel --> pkg_session_telemetry pkg_session_title_all_prompts_llm --> pkg_llm pkg_session_title_all_prompts_llm --> pkg_session pkg_session_title_all_prompts_llm --> pkg_session_title pkg_session_title_all_prompts_llm --> pkg_session_title_llm pkg_session_title_first_prompt_llm --> pkg_llm pkg_session_title_first_prompt_llm --> pkg_session pkg_session_title_first_prompt_llm --> pkg_session_title pkg_session_title_first_prompt_llm --> pkg_session_title_llm pkg_shell_env --> pkg_home_paths pkg_shell_env --> pkg_session_persistence pkg_shell_env --> pkg_shell pkg_shell_env --> pkg_tools pkg_tool_bash_persistent --> pkg_agent pkg_tool_bash_persistent --> pkg_terminal pkg_tool_bash_persistent --> pkg_timeout pkg_tool_bash_persistent --> pkg_tools pkg_tool_pwsh_persistent --> pkg_agent pkg_tool_pwsh_persistent --> pkg_terminal pkg_tool_pwsh_persistent --> pkg_timeout pkg_tool_pwsh_persistent --> pkg_tools pkg_tool_terminal --> pkg_agent pkg_tool_terminal --> pkg_jobs pkg_tool_terminal --> pkg_llm pkg_tool_terminal --> pkg_output_retention pkg_tool_terminal --> pkg_system_prompt pkg_tool_terminal --> pkg_terminal pkg_tool_terminal --> pkg_tools pkg_agent_loop_testkit --> pkg_agent pkg_agent_loop_testkit --> pkg_llm pkg_agent_loop_testkit --> pkg_session pkg_agent_loop_testkit --> pkg_system_prompt pkg_agent_loop_testkit --> pkg_tools pkg_llm_replay --> pkg_compaction pkg_llm_replay --> pkg_deepseek_llm_api_extensions pkg_llm_replay --> pkg_llm pkg_llm_replay --> pkg_session pkg_tool_workflow --> pkg_agent pkg_tool_workflow --> pkg_invariants pkg_tool_workflow --> pkg_llm pkg_tool_workflow --> pkg_session pkg_tool_workflow --> pkg_system_prompt pkg_tool_workflow --> pkg_tools pkg_tool_workflow --> pkg_workflow pkg_plugin_package_inventory_deepseek --> pkg_agent pkg_plugin_package_inventory_deepseek --> pkg_agent_presets pkg_plugin_package_inventory_deepseek --> pkg_deepseek_llm_api_extensions pkg_plugin_package_inventory_deepseek --> pkg_session pkg_session_query --> pkg_brand pkg_session_query --> pkg_llm pkg_session_query --> pkg_session pkg_session_query --> pkg_session_persistence pkg_session_query --> pkg_session_projection pkg_session_query --> pkg_session_projection_cache pkg_session_query --> pkg_session_title pkg_session_query --> pkg_tool_todo pkg_acp --> pkg_agent pkg_acp --> pkg_attachment pkg_acp --> pkg_llm pkg_acp --> pkg_mcp_client pkg_acp --> pkg_session pkg_acp --> pkg_session_persistence pkg_acp --> pkg_token_meter pkg_acp --> pkg_user_approval pkg_api_settings_controller --> pkg_agent_presets pkg_api_settings_controller --> pkg_credentials pkg_api_settings_controller --> pkg_native_command pkg_api_settings_controller --> pkg_session pkg_api_settings_controller --> pkg_settings pkg_api_settings_controller --> pkg_typert_protocol pkg_web_app --> pkg_shell_env pkg_web_app --> pkg_system_prompt pkg_compaction_tool_result_pruner --> pkg_compaction pkg_compaction_tool_result_pruner --> pkg_llm pkg_compaction_tool_result_pruner --> pkg_session pkg_compaction_tool_result_pruner --> pkg_token_meter pkg_tool_cordis --> pkg_agent pkg_tool_cordis --> pkg_cordis_host_runner pkg_tool_cordis --> pkg_llm pkg_tool_cordis --> pkg_scope pkg_tool_cordis --> pkg_session pkg_tool_cordis --> pkg_system_prompt pkg_tool_cordis --> pkg_tools pkg_host_plugin_inventory --> pkg_agent_presets pkg_host_plugin_inventory --> pkg_brand pkg_host_plugin_inventory --> pkg_typert_protocol pkg_tool_bash --> pkg_agent pkg_tool_bash --> pkg_jobs pkg_tool_bash --> pkg_llm pkg_tool_bash --> pkg_sandbox pkg_tool_bash --> pkg_sandbox_policy pkg_tool_bash --> pkg_shell pkg_tool_bash --> pkg_shell_env pkg_tool_bash --> pkg_system_prompt pkg_tool_bash --> pkg_tools pkg_tool_bash --> pkg_user_approval pkg_tool_pwsh --> pkg_agent pkg_tool_pwsh --> pkg_jobs pkg_tool_pwsh --> pkg_llm pkg_tool_pwsh --> pkg_sandbox pkg_tool_pwsh --> pkg_sandbox_policy pkg_tool_pwsh --> pkg_shell pkg_tool_pwsh --> pkg_shell_env pkg_tool_pwsh --> pkg_system_prompt pkg_tool_pwsh --> pkg_tools pkg_tool_pwsh --> pkg_user_approval pkg_webhook --> pkg_agent pkg_webhook --> pkg_agent_default_model pkg_webhook --> pkg_agent_presets pkg_webhook --> pkg_invariants pkg_webhook --> pkg_llm pkg_webhook --> pkg_permission_presets pkg_webhook --> pkg_session pkg_webhook --> pkg_session_title pkg_webhook --> pkg_workspace pkg_subagent --> pkg_agent pkg_subagent --> pkg_agent_presets pkg_subagent --> pkg_attachment pkg_subagent --> pkg_invariants pkg_subagent --> pkg_jobs pkg_subagent --> pkg_llm pkg_subagent --> pkg_sandbox pkg_subagent --> pkg_sandbox_policy pkg_subagent --> pkg_scope pkg_subagent --> pkg_session pkg_subagent --> pkg_session_persistence pkg_subagent --> pkg_session_projection pkg_subagent --> pkg_session_projection_cache pkg_subagent --> pkg_session_query pkg_subagent --> pkg_system_prompt pkg_subagent --> pkg_tools pkg_subagent --> pkg_typert_protocol pkg_subagent --> pkg_user_approval pkg_subagent --> pkg_util_time pkg_session_query_sqlite --> pkg_session pkg_session_query_sqlite --> pkg_session_persistence pkg_session_query_sqlite --> pkg_session_query pkg_tool_session_query --> pkg_agent pkg_tool_session_query --> pkg_llm pkg_tool_session_query --> pkg_session pkg_tool_session_query --> pkg_session_projection pkg_tool_session_query --> pkg_session_query pkg_tool_session_query --> pkg_system_prompt pkg_tool_session_query --> pkg_timeout pkg_tool_session_query --> pkg_tools pkg_compaction_basic --> pkg_agent pkg_compaction_basic --> pkg_commands pkg_compaction_basic --> pkg_compaction pkg_compaction_basic --> pkg_compaction_tool_result_pruner pkg_compaction_basic --> pkg_llm pkg_compaction_basic --> pkg_session pkg_compaction_basic --> pkg_token_meter pkg_session_reference --> pkg_agent pkg_session_reference --> pkg_compaction pkg_session_reference --> pkg_llm pkg_session_reference --> pkg_output_retention pkg_session_reference --> pkg_session pkg_session_reference --> pkg_session_projection pkg_session_reference --> pkg_session_projection_cache pkg_session_reference --> pkg_session_query pkg_session_reference --> pkg_session_title pkg_session_reference --> pkg_typert_protocol pkg_webhook_github --> pkg_credentials pkg_webhook_github --> pkg_host_webserver pkg_webhook_github --> pkg_session pkg_webhook_github --> pkg_webhook pkg_subagent_acp --> pkg_agent pkg_subagent_acp --> pkg_llm pkg_subagent_acp --> pkg_session pkg_subagent_acp --> pkg_subagent pkg_subagent_acp --> pkg_subprocess pkg_subagent_acp --> pkg_timeout pkg_subagent_claude_code --> pkg_llm pkg_subagent_claude_code --> pkg_session pkg_subagent_claude_code --> pkg_subagent pkg_subagent_claude_code --> pkg_subprocess pkg_subagent_claude_code --> pkg_timeout pkg_subagent_codex --> pkg_llm pkg_subagent_codex --> pkg_session pkg_subagent_codex --> pkg_subagent pkg_subagent_codex --> pkg_subprocess pkg_subagent_codex --> pkg_timeout pkg_subagent_in_process_driver --> pkg_agent pkg_subagent_in_process_driver --> pkg_llm pkg_subagent_in_process_driver --> pkg_session pkg_subagent_in_process_driver --> pkg_subagent pkg_subagent_in_process_driver --> pkg_system_prompt pkg_subagent_in_process_driver --> pkg_tools pkg_tool_subagent --> pkg_agent pkg_tool_subagent --> pkg_invariants pkg_tool_subagent --> pkg_jobs pkg_tool_subagent --> pkg_llm pkg_tool_subagent --> pkg_scope pkg_tool_subagent --> pkg_session pkg_tool_subagent --> pkg_session_projection pkg_tool_subagent --> pkg_settings pkg_tool_subagent --> pkg_subagent pkg_tool_subagent --> pkg_system_prompt pkg_tool_subagent --> pkg_tools pkg_tool_subagent_control --> pkg_llm pkg_tool_subagent_control --> pkg_session pkg_tool_subagent_control --> pkg_subagent pkg_tool_subagent_control --> pkg_tools pkg_hooks_claude_code --> pkg_agent pkg_hooks_claude_code --> pkg_hook_protocol pkg_hooks_claude_code --> pkg_llm pkg_hooks_claude_code --> pkg_session pkg_hooks_claude_code --> pkg_session_persistence pkg_hooks_claude_code --> pkg_session_projection pkg_hooks_claude_code --> pkg_subagent pkg_hooks_claude_code --> pkg_tools pkg_api_session_controller --> pkg_agent pkg_api_session_controller --> pkg_agent_default_model pkg_api_session_controller --> pkg_agent_presets pkg_api_session_controller --> pkg_api_gateway pkg_api_session_controller --> pkg_attachment pkg_api_session_controller --> pkg_client_connection pkg_api_session_controller --> pkg_file_reference pkg_api_session_controller --> pkg_jobs pkg_api_session_controller --> pkg_llm pkg_api_session_controller --> pkg_native_command pkg_api_session_controller --> pkg_scope pkg_api_session_controller --> pkg_session pkg_api_session_controller --> pkg_session_persistence pkg_api_session_controller --> pkg_session_projection pkg_api_session_controller --> pkg_session_projection_cache pkg_api_session_controller --> pkg_session_query pkg_api_session_controller --> pkg_session_title pkg_api_session_controller --> pkg_skill pkg_api_session_controller --> pkg_subagent pkg_api_session_controller --> pkg_typert_protocol pkg_api_session_controller --> pkg_typert_registry pkg_api_session_controller --> pkg_util_time pkg_api_session_controller --> pkg_util_workspace_path pkg_api_session_controller --> pkg_workspace pkg_experimental_agent_team --> pkg_agent pkg_experimental_agent_team --> pkg_invariants pkg_experimental_agent_team --> pkg_llm pkg_experimental_agent_team --> pkg_session pkg_experimental_agent_team --> pkg_session_persistence pkg_experimental_agent_team --> pkg_session_projection pkg_experimental_agent_team --> pkg_subagent pkg_experimental_agent_team --> pkg_typert_protocol pkg_sdk_protocol --> pkg_llm pkg_sdk_protocol --> pkg_session pkg_sdk_protocol --> pkg_subagent pkg_tool_ralph --> pkg_agent pkg_tool_ralph --> pkg_llm pkg_tool_ralph --> pkg_subagent pkg_tool_ralph --> pkg_system_prompt pkg_tool_ralph --> pkg_tools pkg_tool_ralph --> pkg_workflow pkg_workflow_worker_thread --> pkg_agent pkg_workflow_worker_thread --> pkg_llm pkg_workflow_worker_thread --> pkg_session pkg_workflow_worker_thread --> pkg_subagent pkg_workflow_worker_thread --> pkg_tools pkg_workflow_worker_thread --> pkg_workflow pkg_subagent_fork_in_process --> pkg_agent pkg_subagent_fork_in_process --> pkg_session pkg_subagent_fork_in_process --> pkg_subagent pkg_subagent_fork_in_process --> pkg_subagent_in_process_driver pkg_subagent_spawn_in_process --> pkg_subagent pkg_subagent_spawn_in_process --> pkg_subagent_in_process_driver pkg_experimental_client_ui_agent_team --> pkg_api_remotes pkg_experimental_client_ui_agent_team --> pkg_api_session_controller pkg_experimental_client_ui_agent_team --> pkg_client_locale pkg_experimental_client_ui_agent_team --> pkg_client_ui_conversation pkg_experimental_client_ui_agent_team --> pkg_client_ui_primitives pkg_experimental_client_ui_agent_team --> pkg_client_ui_renderer pkg_experimental_client_ui_agent_team --> pkg_client_ui_session pkg_experimental_client_ui_agent_team --> pkg_client_ui_slots pkg_experimental_client_ui_agent_team --> pkg_experimental_agent_team pkg_experimental_client_ui_agent_team --> pkg_session pkg_experimental_client_ui_agent_team --> pkg_typert_protocol pkg_experimental_tool_agent_team --> pkg_agent pkg_experimental_tool_agent_team --> pkg_experimental_agent_team pkg_experimental_tool_agent_team --> pkg_session pkg_experimental_tool_agent_team --> pkg_system_prompt pkg_experimental_tool_agent_team --> pkg_tools pkg_sdk_client --> pkg_llm pkg_sdk_client --> pkg_sdk_protocol pkg_sdk_client --> pkg_session pkg_sdk_jsonrpc_server --> pkg_agent pkg_sdk_jsonrpc_server --> pkg_attachment pkg_sdk_jsonrpc_server --> pkg_llm pkg_sdk_jsonrpc_server --> pkg_llm_deepseek pkg_sdk_jsonrpc_server --> pkg_scope pkg_sdk_jsonrpc_server --> pkg_sdk_protocol pkg_sdk_jsonrpc_server --> pkg_session pkg_sdk_jsonrpc_server --> pkg_subagent pkg_client_test_runtime --> pkg_api_session_controller pkg_client_test_runtime --> pkg_api_workspace_controller pkg_client_test_runtime --> pkg_attachment pkg_client_test_runtime --> pkg_client_connection pkg_client_test_runtime --> pkg_client_store pkg_client_test_runtime --> pkg_client_ui_chat pkg_client_test_runtime --> pkg_client_ui_conversation pkg_client_test_runtime --> pkg_client_ui_renderer pkg_client_test_runtime --> pkg_client_ui_session pkg_client_test_runtime --> pkg_client_ui_settings pkg_client_test_runtime --> pkg_client_ui_slots pkg_client_test_runtime --> pkg_session pkg_client_test_runtime --> pkg_subagent pkg_client_test_runtime --> pkg_typert_protocol pkg_subagent_dsh_sdk --> pkg_agent pkg_subagent_dsh_sdk --> pkg_llm pkg_subagent_dsh_sdk --> pkg_sdk_client pkg_subagent_dsh_sdk --> pkg_session pkg_subagent_dsh_sdk --> pkg_subagent pkg_subagent_dsh_sdk --> pkg_subprocess 包 分组 Peer 依赖 atomic-write util — brand util — deque util — home-paths util — launch-environment util — native-command util — output-retention util — timeout util — util-crypto util — util-time util — util-values util — util-workspace-path util — deepseek-llm-api-extensions llm — llm llm — session-log-export session-query — api-gateway api — cmdline boot — acp-app bundle — base bundle — sdk-app bundle — sdk-minimal bundle — client-connection client — client-hmr client — client-locale client — client-modules client — client-store client — client-ui-agent-preset client — client-ui-approval client — client-ui-attachment client — client-ui-brand-official client — client-ui-chat client — client-ui-commands client — client-ui-conversation client — client-ui-deliverables client — client-ui-directory-picker-browse client — client-ui-directory-picker-native client — client-ui-goal client — client-ui-input-trigger client — client-ui-jobs client — client-ui-layout client — client-ui-message-feedback client — client-ui-model-selection client — client-ui-permission-presets client — client-ui-plan client — client-ui-primitives client — client-ui-reference client — client-ui-renderer client — client-ui-schedule client — client-ui-session client — client-ui-settings client — client-ui-settings-general client — client-ui-settings-models client — client-ui-settings-plugin-inventory client — client-ui-settings-plugins client — client-ui-sidebar client — client-ui-skill client — client-ui-slots client — client-ui-subagent client — client-ui-theme client — client-ui-tool client — client-ui-trajectory client — client-ui-user-questions client — client-ui-workflow-run client — client-ui-workspace client — client-web client — code-runtime code-runtime — e2b e2b — experimental-agent-team-profile experimental — experimental-agent-team-web-profile experimental — experimental-webworker-packer experimental — client-ui-cordis extensions — cordis-client-runner extensions — host-directory-picker host — host-directory-picker-browse host — host-directory-picker-native host — host-webserver host — invariants runtime-diagnostics — sandbox-windows-acl sandbox — storage storage — subprocess subprocess — win32-process subprocess — llm-mock-server test-support — typert-generator typert — typert-protocol typert — typert-registry typert — scope core invariants web web llm attachment attachment brand credentials credentials invariants subprocess-e2b e2b e2b , subprocess , timeout experimental-code-runtime-python experimental code-runtime , timeout , util-values experimental-inspector experimental client-modules , host-webserver experimental-webworker-runtime experimental client-connection , client-modules , host-webserver host-directory-picker-auto host client-ui-directory-picker-browse , client-ui-directory-picker-native , host-directory-picker-browse , host-directory-picker-native , host-webserver host-frontend-static host client-connection , host-webserver anonymous-user-id identity brand , home-paths lsp lsp brand , llm storage-domain storage invariants , storage storage-json storage storage storage-sqlite storage storage subprocess-local subprocess subprocess , timeout typert-loader typert typert-registry session core scope system-prompt core invariants , llm , scope skill skill llm , scope web-fetch-http web timeout , web web-search-exa web launch-environment , web web-search-perplexity web launch-environment , web api-remotes api scope attachment-local attachment attachment , home-paths authorization credentials credentials , invariants , llm credentials-local credentials atomic-write , credentials , home-paths , launch-environment skill-badge skill skill spill spill brand , llm , session app-boot boot home-paths , launch-environment , system-prompt code-runtime-worker-thread code-runtime code-runtime , session , timeout persona preset system-prompt sandbox sandbox llm , session session-log-deepseek session deepseek-llm-api-extensions , invariants , session session-persistence session brand , session , timeout session-projection session session settings settings brand , invariants , session session-snapshot test-support session agent core invariants , llm , scope , session , session-projection , system-prompt , typert-protocol fs fs brand , invariants , llm , sandbox spill-local spill spill message-feedback feedback brand , llm , session , session-persistence , storage-domain , typert-protocol sandbox-local sandbox llm , sandbox , session session-persistence-jsonl session session , session-persistence session-projection-cache session session , session-projection , storage-domain session-stats session llm , session , session-projection session-turn-outline session llm , session , session-projection settings-file settings atomic-write , home-paths , settings shell shell sandbox , settings , subprocess workspace workspace invariants , session , session-persistence , storage , storage-domain , typert-protocol llm-deepseek llm anonymous-user-id , atomic-write , attachment , credentials , deepseek-llm-api-extensions , fs , home-paths , launch-environment , llm , settings , timeout llm-pi-ai llm attachment , authorization , credentials , fs , launch-environment , llm , settings , timeout llm-retry llm agent , brand , invariants , llm , session , session-projection , timeout agent-default-model core agent , llm , settings goal goal agent , brand , invariants , llm , scope , session , session-projection , typert-protocol fs-local fs fs fs-observation-policy fs fs skill-filesystem skill fs , home-paths , skill web-search-deepseek web agent , credentials , launch-environment , session , settings , web hook-protocol hooks invariants , session , shell api-workspace-controller api api-gateway , client-connection , host-directory-picker , session , storage-domain , typert-protocol , workspace file-reference context agent time-context context agent , invariants , llm , session , session-projection tmux-context context agent , session , session-projection , shell fs-e2b e2b e2b , fs commands interaction agent , attachment , brand , invariants , llm , scope , session , typert-protocol user-approval interaction agent , brand , invariants , llm , scope , session , system-prompt user-questions interaction agent , llm , scope jobs jobs agent , brand , invariants , session lsp-stdio lsp brand , fs , llm , lsp , subprocess , timeout sandbox-policy sandbox agent , invariants , sandbox , session , session-projection , system-prompt session-telemetry session agent , session session-title session agent , brand , invariants , llm , session , session-projection bash-local shell settings , shell , subprocess , timeout pwsh-local shell settings , shell , subprocess , timeout terminal terminal agent , brand loader-smoke test-support agent , llm , session workflow workflow agent , brand , invariants , llm , session tools core agent , code-runtime , invariants , llm , scope , session , system-prompt , user-approval command-goal goal commands , goal , llm goal-round-driver goal agent , goal , invariants , llm , session fs-sandbox fs fs , fs-local , sandbox , sandbox-policy headless bundle agent , agent-default-model , llm , session compaction compaction brand , commands , invariants , llm , session command-feedback feedback anonymous-user-id , commands , session , session-telemetry permission-presets interaction commands , invariants , sandbox , sandbox-policy , session , session-projection , settings , shell , user-approval jobs-local jobs agent , jobs , scope , timeout session-title-llm session llm , session , session-title , timeout bash-sandbox shell bash-local , sandbox , sandbox-policy , shell pwsh-sandbox shell pwsh-local , sandbox , sandbox-policy , shell terminal-bash terminal agent , sandbox , sandbox-policy , session , session-projection , subprocess , terminal token-meter llm compaction , llm , llm-retry , session , session-projection agent-loop core agent , invariants , llm , scope , session , session-persistence , session-projection , settings , system-prompt , tools agent-tool-presentation core tools tool-goal goal agent , goal , llm , session , session-projection , system-prompt , tools tool-fs fs attachment , fs , llm , sandbox , sandbox-policy , session , system-prompt , tools , user-approval tool-fs-search fs llm , output-retention , session , spill , subprocess , system-prompt , timeout , tools tool-str-replace-editor fs fs , sandbox , sandbox-policy , tools tool-skill skill agent , llm , skill , tools tool-web web llm , system-prompt , tools , web spill-policy spill llm , output-retention , session , spill , tools tool-todo todo agent , invariants , session , session-projection , tools plan-mode plan agent , commands , invariants , llm , session , session-projection , system-prompt , tools , user-questions hooks-codex hooks agent , hook-protocol , llm , session , session-persistence , session-projection , tools command-compact compaction commands , compaction agent-instructions context agent , fs , home-paths , llm , session , session-projection , tools file-reference-local context agent , file-reference , system-prompt , tools cordis-host-runner extensions agent , brand , llm , scope , session , tools , typert-protocol repeat-tool-reminder guard agent , tools tool-call-timeout-policy guard llm , timeout , tools tool-ask-user interaction agent , tools , user-questions tool-jobs jobs agent , jobs , llm , output-retention , system-prompt , tools tool-lsp lsp llm , lsp , system-prompt , timeout , tools mcp-client mcp attachment , llm , scope , subprocess , timeout , tools agent-presets preset agent , atomic-write , home-paths , invariants , scope , session , session-projection , settings , system-prompt , tools , typert-protocol schedule schedule agent , brand , invariants , llm , session , session-persistence , session-projection , tools session-checkpoint-policy session agent , llm , session , session-persistence , tools session-telemetry-otel session anonymous-user-id , command-feedback , llm , session , session-telemetry session-title-all-prompts-llm session llm , session , session-title , session-title-llm session-title-first-prompt-llm session llm , session , session-title , session-title-llm shell-env shell home-paths , session-persistence , shell , tools tool-bash-persistent shell agent , terminal , timeout , tools tool-pwsh-persistent shell agent , terminal , timeout , tools tool-terminal terminal agent , jobs , llm , output-retention , system-prompt , terminal , tools agent-loop-testkit test-support agent , llm , session , system-prompt , tools llm-replay test-support compaction , deepseek-llm-api-extensions , llm , session tool-workflow workflow agent , invariants , llm , session , system-prompt , tools , workflow plugin-package-inventory-deepseek llm agent , agent-presets , deepseek-llm-api-extensions , session session-query session-query brand , llm , session , session-persistence , session-projection , session-projection-cache , session-title , tool-todo acp acp agent , attachment , llm , mcp-client , session , session-persistence , token-meter , user-approval api-settings-controller api agent-presets , credentials , native-command , session , settings , typert-protocol web-app bundle shell-env , system-prompt compaction-tool-result-pruner compaction compaction , llm , session , token-meter tool-cordis extensions agent , cordis-host-runner , llm , scope , session , system-prompt , tools host-plugin-inventory host agent-presets , brand , typert-protocol tool-bash shell agent , jobs , llm , sandbox , sandbox-policy , shell , shell-env , system-prompt , tools , user-approval tool-pwsh shell agent , jobs , llm , sandbox , sandbox-policy , shell , shell-env , system-prompt , tools , user-approval webhook webhook agent , agent-default-model , agent-presets , invariants , llm , permission-presets , session , session-title , workspace subagent subagent agent , agent-presets , attachment , invariants , jobs , llm , sandbox , sandbox-policy , scope , session , session-persistence , session-projection , session-projection-cache , session-query , system-prompt , tools , typert-protocol , user-approval , util-time session-query-sqlite session-query session , session-persistence , session-query tool-session-query session-query agent , llm , session , session-projection , session-query , system-prompt , timeout , tools compaction-basic compaction agent , commands , compaction , compaction-tool-result-pruner , llm , session , token-meter session-reference context agent , compaction , llm , output-retention , session , session-projection , session-projection-cache , session-query , session-title , typert-protocol webhook-github webhook credentials , host-webserver , session , webhook subagent-acp subagent agent , llm , session , subagent , subprocess , timeout subagent-claude-code subagent llm , session , subagent , subprocess , timeout subagent-codex subagent llm , session , subagent , subprocess , timeout subagent-in-process-driver subagent agent , llm , session , subagent , system-prompt , tools tool-subagent subagent agent , invariants , jobs , llm , scope , session , session-projection , settings , subagent , system-prompt , tools tool-subagent-control subagent llm , session , subagent , tools hooks-claude-code hooks agent , hook-protocol , llm , session , session-persistence , session-projection , subagent , tools api-session-controller api agent , agent-default-model , agent-presets , api-gateway , attachment , client-connection , file-reference , jobs , llm , native-command , scope , session , session-persistence , session-projection , session-projection-cache , session-query , session-title , skill , subagent , typert-protocol , typert-registry , util-time , util-workspace-path , workspace experimental-agent-team experimental agent , invariants , llm , session , session-persistence , session-projection , subagent , typert-protocol sdk-protocol sdk llm , session , subagent tool-ralph workflow agent , llm , subagent , system-prompt , tools , workflow workflow-worker-thread workflow agent , llm , session , subagent , tools , workflow subagent-fork-in-process subagent agent , session , subagent , subagent-in-process-driver subagent-spawn-in-process subagent subagent , subagent-in-process-driver experimental-client-ui-agent-team experimental api-remotes , api-session-controller , client-locale , client-ui-conversation , client-ui-primitives , client-ui-renderer , client-ui-session , client-ui-slots , experimental-agent-team , session , typert-protocol experimental-tool-agent-team experimental agent , experimental-agent-team , session , system-prompt , tools sdk-client sdk llm , sdk-protocol , session sdk-jsonrpc-server sdk agent , attachment , llm , llm-deepseek , scope , sdk-protocol , session , subagent client-test-runtime test-support api-session-controller , api-workspace-controller , attachment , client-connection , client-store , client-ui-chat , client-ui-conversation , client-ui-renderer , client-ui-session , client-ui-settings , client-ui-slots , session , subagent , typert-protocol subagent-dsh-sdk subagent agent , llm , sdk-client , session , subagent , subprocess 工具 Schema 目录 English | 中文 已发布插件向 ctx.tools 提供的所有面向模型的工具:模型通过系统提示词组装获得的 name 、 description 和 JSON Schema parameters 。本目录是 子系统页面 (类型及每页生成的 cordis-surface 接线区域)的补充;本页列出的是向 agent(智能体)提供的 工具 。 英文源文件由系统 生成 ,并通过 pnpm run verify-tool-catalog ( doc-sync (文档同步门禁)的一部分)验证新鲜度;本中文文件作为经评审对侧通过双语配对维护。与 Cordis 目录(纯源码 AST 处理)不同,英文生成器会在真实上下文中 启动 每个工具插件并读取 ctx.tools.schemas() ,因为工具 schema 无法通过静态分析完全确定,例如运行时展开的枚举、拼接的描述、由配置决定的名称以及使用原始 JSON Schema 的 MCP 工具。完整性守卫会 glob 匹配 packages/*/tool-* ;如果生成器的启动 manifest(元数据清单)遗漏任何包,检查就会失败,因此新工具不会在无人察觉的情况下缺少文档。参见 工具 schema 目录 Agent Note 。 范围: packages/*/tool-* 下已发布的产品工具,每个工具均使用其 默认 配置启动;但如果某个 Config 字段是 必填项 且没有默认值,生成器就必须作出选择,对应包的说明会记录本页展示的是哪个分支。注册的工具 名称 可以是加载时配置,例如 tool-subagent 的 toolName ,因此部署可能以不同名称或额外名称提供某个包;如果存在随产品发布的别名,对应包的说明会予以记录。 examples/ 中的演示工具(例如 echo )不在范围内,这与 Cordis 目录仅涵盖包的范围一致。 工具包映射 下表将模型可见的工具名称与其背后的插件包和服务 seam 对应起来。各包章节随后给出确切的 JSON Schema。 工具包 模型可见名称 依赖 写入/影响 随产品发布的别名 部署说明 @deepseek-ai/dsh-tool-ask-user ask_user_question ctx.tools 、 ctx.userQuestions tool/call 、 tool/result after a UI/provider answers the question - ask_user_question 会暂停工具调用,直到当前 UI 提供方返回人类答案。 @deepseek-ai/dsh-tools run_code ctx.tools 、 ctx.codeRuntime (execution time) 、 ctx.systemPrompt tool/call 、 one tool/code-dispatch-start + tool/code-dispatch pair per bridged sub-call 、 tool/result - 在 mode: ptc / mode: both 下,它由工具注册表所有,作为可过滤能力层之外的保留传输机制(参见 PTC mode Agent Note)。在 ptc 下,它是注册表对协议格式(wire format)的唯一贡献;其他可见能力在使用已加载运行时语言生成的 SDK 章节中声明。程序通过 binding 调用这些能力,调用按照原生并发约定调度:启动顺序和策略遵循提交顺序,并发安全的函数体最多重叠执行 maxParallelSubCalls 个。调用会重新进入完整且受守卫保护的工具流水线,并将每个嵌套执行关联到此外层结果。 @deepseek-ai/dsh-plan-mode exit_plan_mode ctx.tools 、 ctx.systemPrompt 、 ctx.userQuestions (execution time, opportunistic) tool/call 、 plan/mode inactive on an approved review 、 tool/result - 规划未激活时,exit_plan_mode 仍保留在面向模型的 schema 中,这样状态转换不会在规划策略变更之外额外造成工具目录变动。其执行路径会拒绝规划模式之外的调用;在规划模式下,它通过用户交互 seam 提交计划(批准/根据反馈继续规划),批准后会在步骤边界记录规划模式已停用。 @deepseek-ai/dsh-tool-bash bash ctx.tools 、 ctx.shell 、 ctx.systemPrompt 、 ctx.shellEnv 、 ctx.jobs at call time for run_in_background tool/call 、 tool/result - bash 工具是 bash 执行器 seam 面向模型的消费方。使用 run_in_background 的运行会注册到通用 ctx.jobs 运行时,并通过 job_* 工具(来自 @deepseek-ai/dsh-tool-jobs )收集/停止;禁用 enableRunInBackground 配置(默认为 true)后,该参数会被完全移除。 @deepseek-ai/dsh-tool-pwsh pwsh ctx.tools 、 ctx.shell 、 ctx.systemPrompt 、 ctx.shellEnv 、 ctx.jobs at call time for run_in_background tool/call 、 tool/result - pwsh 工具是 Windows 组合中 bash 执行器 seam 的 PowerShell 方言消费方(由 @deepseek-ai/dsh-pwsh-local 等 PowerShell 执行器为 ctx.shell 提供后端);除沙箱接口外,它逐项对应 bash 工具调用。使用 run_in_background 的运行会注册到通用 ctx.jobs 运行时,并通过 job_* 工具收集/停止;托管的 DSH_* 环境来自 @deepseek-ai/dsh-shell-env 。每次调用都在新进程中运行,不使用持久 PTY 会话。路径采用原生 C:\... 形式,变量采用 $env:NAME 。 @deepseek-ai/dsh-tool-cordis cordis_define 、 cordis_inspect_list 、 cordis_inspect_query 、 cordis_inspect_self 、 cordis_run 、 cordis_stop 、 cordis_undefine ctx.tools 、 ctx.dynamicCordisRunner tool/call 、 tool/result 、 process-local dynamic package lifecycle - 不在任何随产品发布的树中,需要显式选择启用;动态 Package 代码可以访问真实运行时,见 .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md。该工具集注入 @deepseek-ai/dsh-cordis-host-runner 提供的 ctx.dynamicCordisRunner ,后者拥有定义注册表和 vm 沙箱;组合缺少它时这些工具不会激活。运行中的 Package 在停止、undefine 或 DSH 重启前可以注册 额外的 模型可见工具;发生这类工具集变化时,系统会记录完整且有变动的请求头。 @deepseek-ai/dsh-tool-bash-persistent bash ctx.tools 、 ctx.terminals 、 an owning Agent at execution time tool/call 、 PTY shell state 、 tool/result - 一个按所有者隔离的持久 bash 工具;部署组合提供 PTY 后端,并可覆盖面向模型的环境描述。 @deepseek-ai/dsh-tool-pwsh-persistent pwsh ctx.tools 、 ctx.terminals 、 an owning Agent at execution time tool/call 、 PTY shell state 、 tool/result - 一个按所有者隔离的持久 pwsh 工具,持久 bash 工具的 Windows 对应物;部署组合提供 pwsh 方言的 PTY 后端,并可覆盖面向模型的环境描述。 @deepseek-ai/dsh-tool-str-replace-editor str_replace_editor ctx.tools 、 ctx.fs tool/call 、 fs/observed after view presence/absence, edit absence, or successful mutation 、 tool/result - 基于文件系统 seam 的独立查看/创建/唯一字面量替换/按行插入工具;可与任何 shell 或终端接口组合。 @deepseek-ai/dsh-tool-fs edit 、 read 、 read_image 、 write ctx.tools 、 ctx.fs 、 ctx.systemPrompt 、 ctx.attachments (image-tool registration) 、 ctx.llm + an image-capable route (image-tool execution) tool/call 、 fs/write-intent or fs/edit-intent for mutations 、 fs/observed after read presence/absence or successful file operation 、 durable attachment (read_image) 、 tool/result - 先读后写/编辑策略由 @deepseek-ai/dsh-fs-observation-policy 添加;它是一个 fs/* 事件门禁插件,不会改变 schema。加载这些工具的部署按预期也应加载该插件。没有 ctx.attachments 时图片工具不会注册;其 schema 与路由无关,执行时除非确切路由的模型声明图片输入,否则拒绝。 @deepseek-ai/dsh-tool-fs-search glob 、 grep ctx.tools 、 ctx.subprocess 、 ctx.systemPrompt tool/call 、 tool/result - glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn 随包提供的 ripgrep 二进制文件( @vscode/ripgrep ),并作为普通前台调用运行,绝不作为后台任务;无需在宿主机安装 rg ,也不经过 shell 层。本目录使用 sampleOverCapGlobResults: true ;部署必须显式选择该行为。结果超过上限时,会通过可选的 ctx.spillStore 后端保存完整的格式化列表;在共置部署中,如果后端公开本地路径,返回的定位信息可供后续读取/搜索。 @deepseek-ai/dsh-tool-terminal terminal_close 、 terminal_list 、 terminal_open 、 terminal_read 、 terminal_send 、 terminal_signal ctx.tools 、 ctx.terminals 、 ctx.systemPrompt 、 ctx.jobs at call time for run_in_background tool/call 、 tool/result - 这 6 个终端工具需要选择启用,用于补充一次性 bash/文件系统工具。 terminal_send(run_in_background: true) 会注册到 ctx.jobs ;schema 不包含 TUI、具名按键序列、BEL、调整尺寸、自动启动和跨 agent 共享。 @deepseek-ai/dsh-tool-goal create_goal 、 get_goal 、 update_goal ctx.tools 、 ctx.agents 、 ctx.goals 、 ctx.systemPrompt 、 a calling Agent in an authorized open turn tool/call 、 goal/change for mutations 、 tool/result - create、edit、pause 和 resume 要求直接来自人类的根权限;complete 和 blocked 也接受确切的当前 Goal Round。blocked 的默认下限是 3 个获准的 Round。 @deepseek-ai/dsh-schedule schedule_create 、 schedule_delete 、 schedule_list ctx.tools 、 ctx.sessions 、Session 持久化、未来创建的 live 根 Agent tool/call 、 schedule/change create or delete 、 tool/result - 仅在选择启用的 Schedule 插件加载后创建的 live 根 Agent scope 内注册。版本 1 接受 after_seconds、显式绝对 at 和有界固定速率 every_seconds,并披露 session-local 交付;管理读取与变更必须通过共享的 Session 持久化 barrier。 @deepseek-ai/dsh-tool-lsp lsp ctx.tools 、 ctx.lsp 、 ctx.systemPrompt tool/call 、 tool/result - lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,因此其模型可见 schema 在更换提供方时保持稳定。运行时要求已注册提供方,例如 @deepseek-ai/dsh-lsp-stdio ;如果没有提供方,查询会返回结构化 LSP_UNAVAILABLE 错误,而不会改变 schema。 @deepseek-ai/dsh-tool-ralph ralph ctx.tools 、 ctx.workflowEngine 、 ctx.subagents 、 ctx.systemPrompt 、 a calling Agent (exec.agent parents every fresh round) tool/call 、 tool/result 、 workflow and child session events during execution - 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 @deepseek-ai/dsh-tool-skill skill ctx.tools 、 ctx.agents 、 ctx.skills tool/call 、 tool/result 、 user/message replacement catalogs via agent.inject() - - @deepseek-ai/dsh-tool-session-query session_event_read 、 session_event_search 、 session_event_trace 、 session_search 、 session_trace ctx.tools 、 ctx.systemPrompt 、 ctx.sessionQuery 、 a calling Agent for workspace authority tool/call 、 tool/result - 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 @deepseek-ai/dsh-tool-subagent list_subagent_models 、 subagent ctx.tools 、 ctx.subagents 、 ctx.systemPrompt 、 用于模型发现和所选路由校验的 ctx.llm tool/call 、 tool/result 、 child session events through the chosen provider subagent 、 subagent_fork 注册的委派工具名称取决于加载时 toolName 配置(默认为 subagent );上述默认 schema 关闭模型选择,而发现 schema 则展示为已启用 Session 中可用的固定配套工具。Web preset 会在每个新顶层 Session 创建时读取插件页偏好,并为其子 Session 保留该决定; subagent_fork 始终使用固定路由。每个实例通过 modelSelectionSettings 、 backgroundMode 与 enableRunInBackground 独立控制是否读取模型选择设置及其后台行为。 @deepseek-ai/dsh-tool-subagent-control interrupt_agent 、 list_agents 、 send_message ctx.tools 、 ctx.subagents 、 ctx.agents and ctx.sessionProjections (list_agents only) tool/call 、 tool/result 、 child session events through ctx.subagents - 这些是控制可继续后台 subagent 的全局命名工具:绑定提供方的 tool-subagent 实例注册不同的委派工具;本包注册一次 send_message 和 interrupt_agent ,另由 list_agents 通过单独加载的 /list-agents 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。 @deepseek-ai/dsh-tool-jobs job_kill 、 job_list 、 job_output ctx.tools 、 ctx.jobs 、 ctx.systemPrompt tool/call 、 tool/result 、 user/message via agent.inject() for background completion notices - 与任务种类无关的后台任务控制器:后台 bash 命令、PTY 发送和 subagent 都通过相同的 3 个工具读取、列出和终止。加载该插件会挂接控制器,从而启用生产方的 ctx.jobs.start() 。 @deepseek-ai/dsh-experimental-tool-agent-team followup_task 、 interrupt_agent 、 list_agents 、 send_message 、 spawn_teammate 、 team_task_create 、 team_task_get 、 team_task_list 、 team_task_update 、 wait_agent ctx.tools 、 ctx.systemPrompt 、 ctx.agentTeams 、 an exact live Team member Agent tool/call 、 team/member 、 team/message/queued 、 team/message/delivered 、 team/task 、 tool/result - 这 10 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 @deepseek-ai/dsh-tool-todo todo_write ctx.tools 、 owning Agent session tool/call 、 todo/write 、 tool/result - todo_write 是会话所有的状态;UI 将最新的 todo/write 事件渲染为检查清单。 allowParallelInProgress 是没有默认值的必填项,因此本目录明确选择 true ,对应描述允许同时存在多个 in_progress 项。选择 false 的部署会获得同一工具,但描述会要求只能有 1 个活动任务。 @deepseek-ai/dsh-tool-workflow workflow ctx.tools 、 ctx.workflowEngine 、 ctx.systemPrompt 、 a calling Agent (exec.agent parents the script children) tool/call 、 tool/result - - @deepseek-ai/dsh-tool-web web_fetch 、 web_search ctx.tools 、 ctx.web 、 ctx.systemPrompt tool/call 、 tool/result - web_search 和 web_fetch 将提供方选择置于 ctx.web 之后,使模型可见 schema 在更换后端时保持稳定。 @deepseek-ai/dsh-tool-ask-user ask_user_question 继续操作前,如果需要确认、选择或缺失的信息,请向用户提出简明问题。发送一个或多个问题,每个问题都带一个稳定 id,该 id 会在答案中原样返回。 { "type": "object", "properties": { "questions": { "type": "array", "description": "Questions to ask the user before continuing.", "items": { "type": "object", "additionalProperties": true, "properties": { "id": { "type": "string", "description": "Stable id for this question; echoed in the answer." }, "question": { "type": "string", "description": "The specific question to ask the user." }, "header": { "type": "string", "description": "Optional short heading for the question, such as \"Confirm\" or \"Choose Mode\"." }, "options": { "type": "array", "description": "Optional choices to show the user. If you recommend one, put it first and append \"(Recommended)\" to that label.", "items": { "type": "object", "additionalProperties": true, "properties": { "label": { "type": "string", "description": "Short user-facing option label." }, "description": { "type": "string", "description": "One sentence explaining the tradeoff or impact." } }, "required": [ "label" ] } }, "multi_select": { "type": "boolean", "description": "Whether the user may select more than one option. Defaults to false." } }, "required": [ "id", "question" ] } } }, "required": [ "questions" ] } 来源: packages/interaction/tool-ask-user/src/index.ts ask_user_question 会暂停工具调用,直到当前 UI 提供方返回人类答案。 @deepseek-ai/dsh-tools run_code 针对可用工具执行 TypeScript 程序。接受两个必填参数: code ,即异步函数的 函数体 (仅使用可擦除语法;支持顶层 await 和 return );以及 description ,简要说明该程序做什么。请根据系统提示词中的声明,以 await tools.name(args) 形式调用工具。只有打印或返回的内容属于程序输出,请谨慎筛选。含图片的子工具结果会在运行结束后附加。 { "type": "object", "properties": { "code": { "type": "string", "description": "The program: the body of an async TypeScript function." }, "description": { "type": "string", "description": "Clear, concise description of what this program does in active voice, 5-10 words (shown in the UI). Examples: \"Count TODO markers across packages\"; \"Read failing test and its fixture\"; \"Rename config key in every cordis.yml\"." } }, "required": [ "code", "description" ] } 来源: packages/core/tools/src/ptc.ts 在 mode: ptc / mode: both 下,它由工具注册表所有,作为可过滤能力层之外的保留传输机制(参见 PTC mode Agent Note)。在 ptc 下,它是注册表对协议格式的唯一贡献;其他可见能力在使用已加载运行时语言生成的 SDK 章节中声明。程序通过 binding 调用这些能力,调用按照原生并发约定调度:启动顺序和策略遵循提交顺序,并发安全的函数体最多重叠执行 maxParallelSubCalls 个。调用会重新进入完整且受守卫保护的工具流水线,并将每个嵌套执行关联到此外层结果。 @deepseek-ai/dsh-plan-mode exit_plan_mode 仅在规划模式下使用。提交计划供用户评审,并在获批后退出规划模式。发送 完整的 Markdown 计划,以一个为计划命名的 # 标题开头。用户可以批准(从你的下一步骤起执行计划),也可以要求继续规划;其反馈会通过工具结果返回,请修改后再次提交。 { "type": "object", "properties": { "plan": { "type": "string", "description": "The complete plan, as markdown, starting with a # heading that names it." } }, "required": [ "plan" ] } 来源: packages/plan/plan-mode/src/index.ts 规划未激活时,exit_plan_mode 仍保留在面向模型的 schema 中,这样状态转换不会在规划策略变更之外额外造成工具目录变动。其执行路径会拒绝规划模式之外的调用;在规划模式下,它通过用户交互 seam 提交计划(批准/根据反馈继续规划),批准后会在步骤边界记录规划模式已停用。 @deepseek-ai/dsh-tool-bash bash 执行 bash 命令( bash -c )并返回 stdout/stderr。每次调用都在新 shell 中运行:调用之间不保留任何状态(cwd、变量、函数),请传入 workdir ,不要使用 cd 。非零退出会报告为 [exit code: N] 。当前 harness 环境信息通过托管的 $DSH_* 变量公开,需要时请检查这些变量。命令可能在文件沙箱中运行;被阻止的文件操作报告为 [sandbox: file access denied under mode] ,这是策略拒绝,而不是命令缺陷,请勿换一种方式重试。较长的输出会截断,只保留尾部;如可用,完整输出会保存到文件并报告其路径。对于长时间运行的命令,请设置 run_in_background: true :调用会立即返回 job id;使用 job_output 读取输出,使用 job_kill 停止任务。 { "type": "object", "properties": { "command": { "type": "string", "description": "The bash command to execute." }, "description": { "type": "string", "description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"." }, "timeoutMs": { "type": "number", "description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry." }, "workdir": { "type": "string", "description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it." }, "run_in_background": { "type": "boolean", "description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies." } }, "required": [ "command", "description" ] } 来源: packages/shell/tool-bash/src/index.ts bash 工具是 bash 执行器 seam 面向模型的消费方。使用 run_in_background 的运行会注册到通用 ctx.jobs 运行时,并通过 job_* 工具(来自 @deepseek-ai/dsh-tool-jobs )收集/停止;禁用 enableRunInBackground 配置(默认为 true)后,该参数会被完全移除。 @deepseek-ai/dsh-tool-pwsh pwsh 执行 PowerShell 命令( pwsh -Command )并返回 stdout/stderr。每次调用都在新的 pwsh 进程中运行:调用之间不保留任何状态(cwd、变量、函数),请传入 workdir ,不要使用 cd 。路径采用 Windows 原生形式( C:\... );使用 $env:NAME 读取环境变量。非零退出会报告为 [exit code: N] 。当前 harness 环境信息通过托管的 $env:DSH_* 变量公开,需要时请检查这些变量。命令可能在文件沙箱中运行;被阻止的文件操作报告为 [sandbox: file access denied under mode] ,这是策略拒绝,而不是命令缺陷,请勿换一种方式重试。较长的输出会截断,只保留尾部;如可用,完整输出会保存到文件并报告其路径。在 Windows 上,被强制终止的命令会以 [exit code: 1] 结算且不带信号标记,请将其视为中断,而不是命令失败。对于长时间运行的命令,请设置 run_in_background: true :调用会立即返回 job id;使用 job_output 读取输出,使用 job_kill 停止任务。 { "type": "object", "properties": { "command": { "type": "string", "description": "The PowerShell command to execute." }, "description": { "type": "string", "description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"Get-Process\" → \"List running processes\"." }, "timeoutMs": { "type": "number", "description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry." }, "workdir": { "type": "string", "description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it." }, "run_in_background": { "type": "boolean", "description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies." } }, "required": [ "command", "description" ] } 来源: packages/shell/tool-pwsh/src/index.ts pwsh 工具是 Windows 组合中 bash 执行器 seam 的 PowerShell 方言消费方(由 @deepseek-ai/dsh-pwsh-local 等 PowerShell 执行器为 ctx.shell 提供后端);除沙箱接口外,它逐项对应 bash 工具调用。使用 run_in_background 的运行会注册到通用 ctx.jobs 运行时,并通过 job_* 工具收集/停止;托管的 DSH_* 环境来自 @deepseek-ai/dsh-shell-env 。每次调用都在新进程中运行,不使用持久 PTY 会话。路径采用原生 C:\... 形式,变量采用 $env:NAME 。 @deepseek-ai/dsh-tool-cordis cordis_define 定义一个不可变的 Cordis Package。新建 Plugin 时使用 kind:"new",只提供 3 至 6 位小写英文字母组成的语义前缀;Host 返回最终 pluginId 和 packageId。修改现有 Plugin 时使用 kind:"existing" 并传入精确 pluginId,以追加 Package 而不覆盖旧版本。code.host 与 code.client 至少提供一个;每个值都是返回 Cordis Plugin 的 plain JavaScript 函数体,不经过 TypeScript、JSX 或 import 转换。依赖 Service、Event、Builtin、Slot 或 token 前先查询 Inspect。Define 只校验参数和语法并记录源码,不申请审批、不执行 apply,也不改变 currentPackageId。成功后用返回的 ID 调用 cordis_run。 { "type": "object", "properties": { "plugin": { "oneOf": [ { "type": "object", "additionalProperties": false, "properties": { "kind": { "type": "string", "const": "new" }, "idPrefix": { "type": "string", "description": "Suggested semantic prefix of 3–6 lowercase English letters; the Host adds a unique numeric suffix." } }, "required": [ "kind", "idPrefix" ] }, { "type": "object", "additionalProperties": false, "properties": { "kind": { "type": "string", "const": "existing" }, "pluginId": { "type": "string", "description": "Exact ID of an existing Plugin; the new Package is appended to that instance." } }, "required": [ "kind", "pluginId" ] } ] }, "name": { "type": "string", "description": "Short, readable Package name." }, "purpose": { "type": "string", "description": "One-sentence, user-facing description of the Package purpose." }, "code": { "type": "object", "additionalProperties": false, "properties": { "host": { "type": "string", "description": "Plain JavaScript function body that returns the Host-half Cordis Plugin." }, "client": { "type": "string", "description": "Plain JavaScript function body that returns the browser Client-half Cordis Plugin." } } } }, "required": [ "plugin", "name", "purpose", "code" ] } 来源: packages/extensions/tool-cordis/src/index.ts cordis_inspect_list 列出 Host 当前已知的全部 Cordis Inspect Provider,包括本地 Host Provider 和 Client 最近同步的 manifest。每项包含所属平台、用途、只读方法及输入/输出 schema。创建或修改 Package 前先调用本 Tool,再从结果中选择 cordis_inspect_query 的 provider 和 method。不要猜测名称,也不要把 Inspect method 当作 Plugin 代码可调用的业务 Service。 { "type": "object", "properties": {} } 来源: packages/extensions/tool-cordis/src/index.ts cordis_inspect_query 执行 Inspect Provider 显式声明的只读查询。platform、provider 和 method 必须来自 cordis_inspect_list,input 必须符合该方法的 schema。在 cordis_define 前用本 Tool 读取精确 Service 方法、Event mode、Builtin 签名、Tool schema、主题 token,或实时 Slot 树及 props。Host 查询在本地执行;Client 查询等待首个有效页面响应,在页面回答或 Tool 被取消前保持 pending。本 Tool 不能调用业务 Service 方法或修改运行时。查询 Service.listService 和 Event.listEvents 时,先不传 input 浏览紧凑签名目录,再查询精确 service 或 event 获取结构化约定和引用类型。查询 Slots.listSubTree 时,先不传 root 浏览紧凑树,再查询精确 root 获取完整注册约定和 props。 { "type": "object", "properties": { "platform": { "type": "string", "description": "Runtime platform that owns the Provider.", "enum": [ "host", "client" ] }, "provider": { "type": "string", "description": "Exact Provider ID returned by cordis_inspect_list." }, "method": { "type": "string", "description": "Exact method name declared by the Provider manifest." }, "input": { "description": "Optional query input; it must satisfy the method input schema." } }, "required": [ "platform", "provider", "method" ] } 来源: packages/extensions/tool-cordis/src/index.ts cordis_inspect_self 按逐层增加的详细程度检查当前 Session 拥有的动态 Cordis 对象。不传 ID 时只列 Plugin 摘要;只传 pluginId 时返回版本指针、最新 Run 和全部 Package 摘要;只有同时传 pluginId 与 packageId 才返回该不可变 Package 的 Host/Client 源码和运行诊断。packageId 不能单独传入。处理 @pluginId、修复异步失败或定义更新版本前,先查询精确 Package。本 Tool 只读,不执行代码,也不改变版本指针。 { "type": "object", "properties": { "pluginId": { "type": "string", "description": "Stable Plugin ID returned by cordis_define or injected by @pluginId; omit it to list every current Plugin." }, "packageId": { "type": "string", "description": "Exact immutable Package ID owned by pluginId; when specified, source and diagnostics are returned." } } } 来源: packages/extensions/tool-cordis/src/index.ts cordis_run 激活动态 Plugin 的一个精确 Package。首次激活、重启 currentPackageId 或回退使用 mode:"run";已有 current 时,即使 Plugin 当前已停止,切换到其他 Package 也使用 mode:"update"。未授权的 Client Package 创建审批请求并返回 awaiting-approval;已授权的 Package 返回 starting,并在浏览器中异步继续。两种结果都不会在 Tool 内等待最终结局。currentPackageId 只在完整成功后改变;失败时保留旧 current 和目标 next。异步成功、拒绝或技术失败通过状态与 steering 报告。技术失败后,用 cordis_inspect_self 读取诊断,修正同一 Plugin 并自主重试。用户拒绝后不要再次申请审批。 { "type": "object", "properties": { "pluginId": { "type": "string", "description": "Stable Plugin ID returned by cordis_define." }, "packageId": { "type": "string", "description": "Exact immutable Package ID to activate under that Plugin." }, "mode": { "type": "string", "description": "Use run for the first activation, restarting current, or rollback; use update to switch from current to a different Package.", "enum": [ "run", "update" ] } }, "required": [ "pluginId", "packageId", "mode" ] } 来源: packages/extensions/tool-cordis/src/index.ts cordis_stop 停止动态 Plugin 的当前 Run,并取消尚未完成的审批或激活请求。保留 Plugin、全部不可变 Package、授权、currentPackageId 和 nextPackageId,以便之后直接运行或更新。停止已处于停止状态的 Plugin 会幂等成功。临时禁用副作用使用本 Tool;永久移除使用 cordis_undefine。 { "type": "object", "properties": { "pluginId": { "type": "string", "description": "Stable dynamic Plugin ID to stop." } }, "required": [ "pluginId" ] } 来源: packages/extensions/tool-cordis/src/index.ts cordis_undefine 永久移除当前 Session 拥有的动态 Plugin。如果它正在运行或等待审批,先停止并取消请求,再删除全部 Package、授权和版本指针。返回后,其 pluginId、packageIds、@ 引用和 Package 业务视图均失效;历史卡片只保留“Plugin 已移除”记录。需要保留版本以便重启或回退时不要调用本 Tool,应改用 cordis_stop。 { "type": "object", "properties": { "pluginId": { "type": "string", "description": "Stable dynamic Plugin ID to remove permanently." } }, "required": [ "pluginId" ] } 来源: packages/extensions/tool-cordis/src/index.ts 不在任何随产品发布的树中,需要显式选择启用;动态 Package 代码可以访问真实运行时,见 .agents/notes/implemented/feature/2026-07-08-self-referential-cordis-toolset.md。该工具集注入 @deepseek-ai/dsh-cordis-host-runner 提供的 ctx.dynamicCordisRunner ,后者拥有定义注册表和 vm 沙箱;组合缺少它时这些工具不会激活。运行中的 Package 在停止、undefine 或 DSH 重启前可以注册 额外的 模型可见工具;发生这类工具集变化时,系统会记录完整且有变动的请求头。 @deepseek-ai/dsh-tool-bash-persistent bash 在持久 bash shell 中运行命令。包括当前目录和已导出环境变量在内的状态会在此 agent 的多次调用之间保留。 { "type": "object", "properties": { "command": { "type": "string", "description": "The bash command to run. Relative path is preferred in the command." } }, "required": [ "command" ] } 来源: packages/shell/tool-bash-persistent/src/index.ts 一个按所有者隔离的持久 bash 工具;部署组合提供 PTY 后端,并可覆盖面向模型的环境描述。 @deepseek-ai/dsh-tool-pwsh-persistent pwsh 在持久 PowerShell shell 中运行命令。包括当前目录和已导出环境变量在内的状态会在此 agent 的多次调用之间保留。 { "type": "object", "properties": { "command": { "type": "string", "description": "The PowerShell command to run. Relative path is preferred in the command." } }, "required": [ "command" ] } 来源: packages/shell/tool-pwsh-persistent/src/index.ts 一个按所有者隔离的持久 pwsh 工具,持久 bash 工具的 Windows 对应物;部署组合提供 pwsh 方言的 PTY 后端,并可覆盖面向模型的环境描述。 @deepseek-ai/dsh-tool-str-replace-editor str_replace_editor 用于查看、创建和编辑文件的自定义编辑工具: 状态会在命令调用以及与用户的讨论之间持久保留 如果 path 是文件, view 会显示应用 cat -n 后的结果。如果 path 是目录, view 会列出最多向下 2 层的非隐藏文件和目录 如果指定的 create 命令目标 path 已作为文件存在,则不能使用该命令 如果 command 产生较长输出,输出会被截断并标记为 当前命令不使用某个参数时,值为 null 的占位参数视为未提供。必填参数仍须提供值;删除匹配内容时应省略 str_replace.new_str ,而不是将其设为 null 使用 str_replace 命令时请注意: old_str 参数应与原文件中一行或多行连续内容 完全 匹配。请留意空白字符! 如果 old_str 参数在文件中不唯一,则不会执行替换。请确保在 old_str 中包含足够的上下文,使其唯一 new_str 参数应包含用于替换 old_str 的已编辑行 { "type": "object", "properties": { "command": { "type": "string", "description": "The commands to run. Allowed options are: `view`, `create`, `str_replace`, `insert`.", "enum": [ "view", "create", "str_replace", "insert" ] }, "path": { "type": "string", "description": "Absolute path to file or directory, e.g. `/repo/file.py` or `/repo`." }, "file_text": { "oneOf": [ { "type": "string" }, { "type": "null" } ], "description": "Required string parameter of `create` command, with the content of the file to be created. A null placeholder is treated as omitted by commands that do not use this parameter." }, "insert_line": { "oneOf": [ { "type": "integer" }, { "type": "null" } ], "description": "Required integer parameter of `insert` command. The `new_str` will be inserted AFTER the line `insert_line` of `path`. A null placeholder is treated as omitted by commands that do not use this parameter." }, "new_str": { "oneOf": [ { "type": "string" }, { "type": "null" } ], "description": "Optional string parameter of `str_replace` command containing the new string (if omitted, no string will be added). Required string parameter of `insert` command containing the string to insert. A null placeholder is accepted only by commands that do not use this parameter." }, "old_str": { "oneOf": [ { "type": "string" }, { "type": "null" } ], "description": "Required string parameter of `str_replace` command containing the string in `path` to replace. A null placeholder is treated as omitted by commands that do not use this parameter." }, "view_range": { "oneOf": [ { "type": "array", "items": { "type": "integer" } }, { "type": "null" } ], "description": "Optional parameter of `view` command when `path` points to a file. If omitted or null, the full file is shown. If provided, the file will be shown in the indicated line number range, e.g. [11, 12] will show lines 11 and 12. Indexing at 1 to start. Setting `[start_line, -1]` shows all lines from `start_line` to the end of the file." } }, "required": [ "command", "path" ] } 来源: packages/fs/tool-str-replace-editor/src/index.ts 基于文件系统 seam 的独立查看/创建/唯一字面量替换/按行插入工具;可与任何 shell 或终端接口组合。 @deepseek-ai/dsh-tool-fs edit 通过替换字面量文本来编辑现有 UTF-8 文本文件。 { "type": "object", "properties": { "file_path": { "type": "string", "description": "Path to edit, resolved by the filesystem backend." }, "old_string": { "type": "string", "description": "Literal text to replace. Must match exactly." }, "new_string": { "type": "string", "description": "Literal replacement text. Use an empty string to delete the match." }, "replace_all": { "type": "boolean", "description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once." } }, "required": [ "file_path", "old_string", "new_string" ] } 来源: packages/fs/tool-fs/src/index.ts read 读取 UTF-8 文本文件,并返回带行号的内容。 { "type": "object", "properties": { "file_path": { "type": "string", "description": "Path to read, resolved by the filesystem backend." }, "offset": { "type": "number", "description": "1-based first line to return. Defaults to 1." }, "limit": { "type": "number", "description": "Maximum number of lines to return. Defaults to 2000." } }, "required": [ "file_path" ] } 来源: packages/fs/tool-fs/src/index.ts read_image 读取 PNG/JPEG/WebP/GIF 文件并返回图像本身。无扩展名的路径同样被接受;格式按文件内容检测,因此规范化附件路径可以直接传入,无需复制或重命名。Harness 会在下一次模型请求前校验并缩小受支持的大图,因此仅为查看图片时应直接使用此工具,无需安装图片库或创建缩略图。可以用小批次并发读取彼此独立的文件。要求当前模型接受图像输入。 { "type": "object", "properties": { "file_path": { "type": "string", "description": "Path to the image file, resolved by the filesystem backend." } }, "required": [ "file_path" ] } 来源: packages/fs/tool-fs/src/index.ts write 创建或完全替换 UTF-8 文本文件。 { "type": "object", "properties": { "file_path": { "type": "string", "description": "Path to write, resolved by the filesystem backend." }, "content": { "type": "string", "description": "Full UTF-8 text content to write." } }, "required": [ "file_path", "content" ] } 来源: packages/fs/tool-fs/src/index.ts 先读后写/编辑策略由 @deepseek-ai/dsh-fs-observation-policy 添加;它是一个 fs/* 事件门禁插件,不会改变 schema。加载这些工具的部署按预期也应加载该插件。没有 ctx.attachments 时图片工具不会注册;其 schema 与路由无关,执行时除非确切路由的模型声明图片输入,否则拒绝。 @deepseek-ai/dsh-tool-fs-search glob 查找路径匹配 glob 模式的文件。只返回匹配的文件路径,绝不返回目录;包括隐藏文件和被忽略的文件,但排除 VCS 元数据目录。最多按修改时间顺序返回 100 条路径;如果结果更多,则改为返回从顶层条目中抽样的 100 条路径,说明已抽样,并报告完整排序列表的保存位置。该工具不枚举目录条目。 { "type": "object", "properties": { "pattern": { "type": "string", "description": "Glob pattern to match file paths against (e.g. \"**/*.ts\", \"src/**/*.test.js\"). A pattern with no \"/\" matches the basename at any depth, so \"*\" and \"*.ts\" both search the whole tree; include a separator to anchor the depth." }, "path": { "type": "string", "description": "Directory to search in. Defaults to the session workspace; a relative path resolves against it." } }, "required": [ "pattern" ] } 来源: packages/fs/tool-fs-search/src/index.ts grep 使用 ripgrep 正则表达式搜索文件内容。返回带行号的匹配行,并按文件分组。前 250 条匹配会直接返回;结果达到上限时会报告完整匹配列表的保存位置。如需周边上下文,请对匹配的文件使用 read。 { "type": "object", "properties": { "pattern": { "type": "string", "description": "Regular expression to search for (ripgrep syntax)." }, "path": { "type": "string", "description": "File or directory to search. Defaults to the session workspace; a relative path resolves against it." }, "include": { "type": "string", "description": "One glob filter for which files to search (e.g. \"*.ts\", \"*.{js,jsx}\"). Not a list; negation is not supported." } }, "required": [ "pattern" ] } 来源: packages/fs/tool-fs-search/src/index.ts glob 和 grep 是无条件可用的发现工具,通过 ctx.subprocess spawn 随包提供的 ripgrep 二进制文件( @vscode/ripgrep ),并作为普通前台调用运行,绝不作为后台任务;无需在宿主机安装 rg ,也不经过 shell 层。本目录使用 sampleOverCapGlobResults: true ;部署必须显式选择该行为。结果超过上限时,会通过可选的 ctx.spillStore 后端保存完整的格式化列表;在共置部署中,如果后端公开本地路径,返回的定位信息可供后续读取/搜索。 @deepseek-ai/dsh-tool-terminal terminal_close 关闭一个持久终端,并等待其捕获且所有的进程树完全退出。 { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Terminal session id." } }, "required": [ "sessionId" ] } 来源: packages/terminal/tool-terminal/src/index.ts terminal_list 列出当前 agent 所有的持久终端会话。 { "type": "object", "properties": {} } 来源: packages/terminal/tool-terminal/src/index.ts terminal_open 通过已注册的后端类型创建按所有者隔离的持久终端会话。需要在多次工具调用之间保留 shell 或 REPL 状态时,请使用此工具。 { "type": "object", "properties": { "type": { "type": "string", "description": "Registered terminal backend type, usually \"shell\"." }, "name": { "type": "string", "description": "Optional owner-local display name such as \"main\" or \"gdb\"." }, "cwd": { "type": "string", "description": "Initial working directory. Defaults to the deployment workspace root." } }, "required": [ "type" ] } 来源: packages/terminal/tool-terminal/src/index.ts terminal_read 从持久终端读取一页有界的保留输出,不发送输入。 { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Terminal session id." }, "offset": { "type": "number", "description": "Newest-relative line offset (default 0)." }, "count": { "type": "number", "description": "Requested line count (default 500; backend caps apply)." } }, "required": [ "sessionId" ] } 来源: packages/terminal/tool-terminal/src/index.ts terminal_send 向持久终端发送文本。默认会提交 Enter,并等待提示符、stdin 等待、输出静默、超时或会话退出。后台模式会返回供 job_output/job_kill 使用的 job id。 { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Terminal session id returned by terminal_open or terminal_list." }, "text": { "type": "string", "description": "UTF-8 text to write to the terminal." }, "submit": { "type": "boolean", "description": "Submit Enter after text (default true). Set false for control characters or incomplete REPL input." }, "run_in_background": { "type": "boolean", "description": "Return a job id immediately; collect with job_output or stop with job_kill." } }, "required": [ "sessionId", "text" ] } 来源: packages/terminal/tool-terminal/src/index.ts terminal_signal 向持久终端当前的前台进程组发送允许的信号。 { "type": "object", "properties": { "sessionId": { "type": "string", "description": "Terminal session id." }, "signal": { "type": "string", "description": "Signal to deliver. Shell-targeted SIGKILL is rejected; use terminal_close.", "enum": [ "SIGINT", "SIGTERM", "SIGKILL", "SIGTSTP", "SIGHUP" ] } }, "required": [ "sessionId", "signal" ] } 来源: packages/terminal/tool-terminal/src/index.ts 这 6 个终端工具需要选择启用,用于补充一次性 bash/文件系统工具。 terminal_send(run_in_background: true) 会注册到 ctx.jobs ;schema 不包含 TUI、具名按键序列、BEL、调整尺寸、自动启动和跨 agent 共享。 @deepseek-ai/dsh-tool-goal create_goal 当当前直接人类请求是需要跨自主 Goal Round 持续推进的长期目标时,创建一个持久化的同会话完成目标。即使用户没有明确说「创建目标」,你也可以推断其意图。不要用于简单的单轮工作。执行时会拒绝非人类权限和 subagent 权限。 { "type": "object", "properties": { "objective": { "type": "string", "description": "The concrete completion objective inferred from the direct human request." }, "max_goal_rounds": { "type": "number", "description": "Optional positive safe-integer limit on automatic continuation rounds." } }, "required": [ "objective" ] } 来源: packages/goal/tool-goal/src/index.ts get_goal 读取当前的同会话目标,包括确切的 id/revision、目标、阶段、已完成的延续 Round 数、Round 上限、存在时的阻塞原因,以及是否已准备下一次延续。更新目标前请先调用此工具。 { "type": "object", "properties": {} } 来源: packages/goal/tool-goal/src/index.ts update_goal 更新确切的当前目标 revision。edit、pause 和 resume 要求直接的顶层人类请求。在自动延续当前目标期间,也允许 complete 和 blocked。在达到配置的最小 Round 数之前会拒绝 blocked;模型仍须判断相同条件是否在这些 Round 中持续存在,并在 blocked_reason 中予以说明。 { "type": "object", "properties": { "goal_id": { "type": "string", "description": "Exact id returned by get_goal." }, "revision": { "type": "number", "description": "Exact positive revision returned by get_goal." }, "action": { "type": "string", "description": "edit | pause | resume | complete | blocked", "enum": [ "edit", "pause", "resume", "complete", "blocked" ] }, "objective": { "type": "string", "description": "Replacement objective; valid only with action edit." }, "max_goal_rounds": { "type": "number", "description": "Replacement cap; valid only with action edit." }, "blocked_reason": { "type": "string", "description": "Concrete blocking condition; required only with action blocked." } }, "required": [ "goal_id", "revision", "action" ] } 来源: packages/goal/tool-goal/src/index.ts create、edit、pause 和 resume 要求直接来自人类的根权限;complete 和 blocked 也接受确切的当前 Goal Round。blocked 的默认下限是 3 个获准的 Round。 @deepseek-ai/dsh-schedule schedule_create 在当前会话中创建一条提醒。请提供非空 prompt 和恰好一个 selector:正的安全整数 after_seconds 延时;作为严格带偏移日期时间或本地日期/时间对象的 at;或不小于 300 的安全整数 every_seconds。固定速率提醒始终与创建时刻对齐,会跳过错过的发生时点,并把每条逾期规则的最新一个发生时点合并到一个批次中。交付模式是 session-local:只有此会话处于 live 状态时,提醒才会准时运行;否则提醒会进入 overdue 状态,直至会话恢复。 { "type": "object", "properties": { "prompt": { "type": "string", "description": "Reminder content to present when the target becomes due." }, "after_seconds": { "type": "number", "description": "Positive safe-integer delay in seconds." }, "every_seconds": { "type": "number", "description": "Fixed-rate safe-integer interval in seconds, at least 300." }, "at": { "oneOf": [ { "type": "string" }, { "type": "object", "additionalProperties": false, "properties": { "date": { "type": "string" }, "time": { "type": "string" }, "time_zone": { "type": "string" } }, "required": [ "date", "time", "time_zone" ] } ], "description": "Absolute target as strict offset RFC 3339 or local date/time with an explicit IANA zone." } }, "required": [ "prompt" ] } 来源: packages/schedule/schedule/src/tools.ts schedule_delete 使用 schedule_create 或 schedule_list 返回的确切 id,删除当前会话中的一条活动提醒。未知或已经结束的 id 会返回 deleted false。 { "type": "object", "properties": { "id": { "type": "string", "description": "Exact session-local schedule id." } }, "required": [ "id" ] } 来源: packages/schedule/schedule/src/tools.ts schedule_list 按创建顺序列出当前会话中的所有活动提醒,包括确切 id、UTC 目标、scheduled 或 overdue 状态,以及 session-local 交付模式。 { "type": "object", "properties": {} } 来源: packages/schedule/schedule/src/tools.ts 仅在选择启用的 Schedule 插件加载后创建的 live 根 Agent scope 内注册。版本 1 接受 after_seconds、显式绝对 at 和有界固定速率 every_seconds,并披露 session-local 交付;管理读取与变更必须通过共享的 Session 持久化 barrier。 @deepseek-ai/dsh-tool-lsp lsp 查询语言服务器,以精确导航代码。operation 可取 goToDefinition、findReferences、goToImplementation 或 hover。line 和 character 是从 1 开始的 UTF-16 光标坐标。findReferences 包含声明。 { "type": "object", "properties": { "operation": { "type": "string", "description": "goToDefinition, findReferences, goToImplementation, or hover.", "enum": [ "goToDefinition", "findReferences", "goToImplementation", "hover" ] }, "file_path": { "type": "string", "description": "The source file to query, relative to the workspace or absolute." }, "line": { "type": "number", "description": "One-based line of the cursor." }, "character": { "type": "number", "description": "One-based UTF-16 column of the cursor." } }, "required": [ "operation", "file_path", "line", "character" ] } 来源: packages/lsp/tool-lsp/src/index.ts lsp 工具将提供方选择和语言服务器子进程置于 ctx.lsp 之后,因此其模型可见 schema 在更换提供方时保持稳定。运行时要求已注册提供方,例如 @deepseek-ai/dsh-lsp-stdio ;如果没有提供方,查询会返回结构化 LSP_UNAVAILABLE 错误,而不会改变 schema。 @deepseek-ai/dsh-tool-ralph ralph 围绕一个不可变目标运行使用全新 agent 的前台 Ralph 循环。仅当直接人类明确要求 Ralph 或使用全新 agent 迭代时使用。每个 Round 都会启动一个全新子级,该子级看不到父级对话或先前子会话;共享工作区充当长期记忆,Round 之间只传递有界的结构化报告。当工作进程报告完成、报告具体阻塞项或达到 Round 上限时,调用返回。普通的长期同会话工作应使用 goal 工具。 { "type": "object", "properties": { "objective": { "type": "string", "description": "The immutable completion objective for every fresh Ralph round." }, "maxRounds": { "type": "number", "description": "Optional positive safe-integer round cap, bounded by the deployment ceiling." } }, "required": [ "objective" ] } 来源: packages/workflow/tool-ralph/src/index.ts 固定的前台工作流会在每个 Round 启动一个全新的结构化子级;模型只能选择不可变目标和可选的 Round 上限。 @deepseek-ai/dsh-tool-skill skill 加载可用 skill(技能)的完整说明。在执行点名某项 skill 或与其明确匹配的任务前,请使用会话 skill 目录中的确切名称调用此工具。 { "type": "object", "properties": { "name": { "type": "string", "description": "The exact skill name from the available skills list." } }, "required": [ "name" ] } 来源: packages/skill/tool-skill/src/index.ts @deepseek-ai/dsh-tool-session-query session_event_read 从一个已获授权的会话中读取一个完整且未删节的事件,以及可选的相邻原始事件概述。 { "type": "object", "properties": { "session_id": { "type": "string", "description": "Target session id. Omit for the current session." }, "seq": { "type": "integer", "description": "Target event sequence number." }, "before": { "type": "integer", "description": "Number of preceding raw events to summarize. Omit for none." }, "after": { "type": "integer", "description": "Number of following raw events to summarize. Omit for none." } }, "required": [ "seq" ] } 来源: packages/session-query/tool-session-query/src/index.ts session_event_search 在一个已获授权的会话中搜索先前事件;如果搜索当前会话,则排除执行此次调用的步骤。 { "type": "object", "properties": { "session_id": { "type": "string", "description": "Target session id. Omit for the current session." }, "query": { "type": "string", "description": "Literal full-text query over the target session." }, "seq_from": { "type": "integer", "description": "Inclusive event sequence lower bound." }, "seq_to": { "type": "integer", "description": "Inclusive event sequence upper bound." }, "time_from": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." }, "time_to": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." }, "event_types": { "type": "array", "description": "Event types to include.", "items": { "type": "string" } }, "surfaces": { "type": "array", "description": "Event surfaces to include.", "items": { "type": "string", "enum": [ "current", "shadowed", "log-only" ] } } }, "required": [ "query" ] } 来源: packages/session-query/tool-session-query/src/index.ts session_event_trace 读取已获授权会话中某个事件的所有直接替换关系,以及该事件与其引用的来源事件之间的关系。 { "type": "object", "properties": { "session_id": { "type": "string", "description": "Target session id. Omit for the current session." }, "seq": { "type": "integer", "description": "Target event sequence number." } }, "required": [ "seq" ] } 来源: packages/session-query/tool-session-query/src/index.ts session_search 搜索调用方工作区中的先前会话,并从每个会话返回匹配度最高的事件。 { "type": "object", "properties": { "query": { "type": "string", "description": "Literal full-text query over prior session history." }, "session_ids": { "type": "array", "description": "Optional session ids to include.", "items": { "type": "string" } }, "created_at_from": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." }, "created_at_to": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." }, "parent_session_ids": { "type": "array", "description": "Optional direct parent session ids.", "items": { "type": "string" } }, "include_root_sessions": { "type": "boolean", "description": "Include sessions with no parent in the parent filter." }, "availability": { "type": "array", "description": "Require at least one selected source availability.", "items": { "type": "string", "enum": [ "live", "persisted" ] } }, "event_seq_from": { "type": "integer", "description": "Inclusive event sequence lower bound." }, "event_seq_to": { "type": "integer", "description": "Inclusive event sequence upper bound." }, "event_time_from": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." }, "event_time_to": { "type": "string", "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." }, "event_types": { "type": "array", "description": "Event types to include.", "items": { "type": "string" } }, "event_surfaces": { "type": "array", "description": "Event surfaces to include.", "items": { "type": "string", "enum": [ "current", "shadowed", "log-only" ] } } }, "required": [ "query" ] } 来源: packages/session-query/tool-session-query/src/index.ts session_trace 读取围绕一个会话的已授权会话谱系,包括完整可见的祖先和后代关系。 { "type": "object", "properties": { "session_id": { "type": "string", "description": "Target session id. Omit for the current session." } } } 来源: packages/session-query/tool-session-query/src/index.ts 这 5 个只读工具会隐藏提供方游标,并根据不可变的调用 agent 会话为每个结果授权。该包需要选择启用;需要强制截止时间或限制行内输出的组合还会挂载通用超时或 spill 策略。 @deepseek-ai/dsh-tool-subagent list_subagent_models 发现 subagent 可用的 LLM 路由,不更改当前 Agent。无参数调用会列出已注册提供方;提供 provider 时会列出其公布的模型;同时提供 provider 和 model 时会检查该精确模型及其推理强度。目录条目只提供建议:adapter 可能接受未列出的模型 id。把返回的 id 用于委派工具的 provider 、 model 与 reasoning_effort 字段。 { "type": "object", "properties": { "provider": { "type": "string", "description": "Registered LLM provider id. Omit to list providers." }, "model": { "type": "string", "description": "Exact model id to inspect. Requires provider; omit to list that provider's advertised models." } } } 来源: packages/subagent/tool-subagent/src/list-models.ts subagent 将一项自包含任务委派给 subagent(在自身上下文中工作的独立 agent),用它卸载聚焦且独立的工作,例如研究、限定范围的实现或分析,以免消耗当前对话的上下文。subagent 会返回结果,但不会返回中间步骤。请提供完整、独立的提示词,因为它看不到当前对话。此调用默认等待结果。设置 run_in_background: true 可返回 job id;使用 job_output 收集结果,使用 job_kill 停止任务。 { "type": "object", "properties": { "description": { "type": "string", "description": "A short (3-5 word) description of the delegated task, for display." }, "prompt": { "type": "string", "description": "The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs." }, "run_in_background": { "type": "boolean", "description": "Whether to run as a background job and return its id. Defaults to false; collect with job_output or stop with job_kill." } }, "required": [ "description", "prompt" ] } 来源: packages/subagent/tool-subagent/src/index.ts 注册的委派工具名称取决于加载时 toolName 配置(默认为 subagent );上述默认 schema 关闭模型选择,而发现 schema 则展示为已启用 Session 中可用的固定配套工具。Web preset 会在每个新顶层 Session 创建时读取插件页偏好,并为其子 Session 保留该决定; subagent_fork 始终使用固定路由。每个实例通过 modelSelectionSettings 、 backgroundMode 与 enableRunInBackground 独立控制是否读取模型选择设置及其后台行为。 @deepseek-ai/dsh-tool-subagent-control interrupt_agent 根据 agent id 请求取消后台 agent 的当前轮次。目标可以是你的直接子级,也可以是在你下方创建的更深层 agent。只有当前轮次会停止:已经排队发给该 agent 的消息会一直搁置到后续的 send_message;它启动的 agent 会继续运行;该 agent 本身仍可接受后续操作。停止请求被接受后,此调用立即返回,因此目标可能还会短暂运行;中断一个已经完成的 agent 是可接受的空操作。 { "type": "object", "properties": { "agent_id": { "type": "string", "description": "The agent id of the running agent to interrupt." } }, "required": [ "agent_id" ] } 来源: packages/subagent/tool-subagent-control/src/index.ts list_agents 按持久 id 和标签列出你的可继续后台 subagent。用它回忆你启动过哪些 subagent,而不是轮询完成情况——subagent 完成时你会被告知。状态来自实时注册表:running 表示 agent 此刻正在工作;idle 表示已加载但处于轮次之间,可能正在等待它启动的 agent;ready 表示它只存在于存储中——可恢复而非终态,也不表示有结果等待收集; send_message 会在运行中 child 的最近 step 边界 steer 消息,或为 idle、ready child 启动轮次,且无论处于哪种状态,直接子级都仍可作为 send_message 的目标。该快照并非投递承诺; send_message 会执行权威检查,仍可能失败。无法读取的子级会作为诊断信息报告,而不会被静默丢弃。 descendants 作用域会按稳定的前序顺序遍历你下方的整棵树,并为每个条目标注其持久的直接父会话 id 和深度。只有深度为 1 的条目可以使用 send_message ;更深的条目只能作为 interrupt_agent 的候选目标。 { "type": "object", "properties": { "scope": { "type": "string", "description": "children (default) lists direct children only; descendants walks the complete tree below you.", "enum": [ "children", "descendants" ] } } } 来源: packages/subagent/tool-subagent-control/src/list-agents.ts send_message 根据 agent id 向直接可继续 child 发送消息。如果你是驻留的可继续 child,也可以把自己的直接 parent 作为目标。如果目标仍在工作,消息会 steer 其最近的 step;如果目标处于 idle,消息会启动一个轮次。此调用不会返回该 agent 的答案,只会确认消息已投递。调用失败表示消息 未 投递。 { "type": "object", "properties": { "agent_id": { "type": "string", "description": "The agent id of your direct continuable child, or your direct parent when you are a resident continuable child." }, "message": { "type": "string", "description": "The message to deliver to the agent." } }, "required": [ "agent_id", "message" ] } 来源: packages/subagent/tool-subagent-control/src/index.ts 这些是控制可继续后台 subagent 的全局命名工具:绑定提供方的 tool-subagent 实例注册不同的委派工具;本包注册一次 send_message 和 interrupt_agent ,另由 list_agents 通过单独加载的 /list-agents 插件提供,其目录行使用 sessionProjections 和实时 Agent 注册表。 @deepseek-ai/dsh-tool-jobs job_kill 根据 job id 请求取消正在运行的后台任务。此调用立即返回;任务的工作真正停止后,会以 killed 状态结算。 { "type": "object", "properties": { "job_id": { "type": "string", "description": "Job id returned by the tool that started the background work." }, "reason": { "type": "string", "description": "Optional short reason, recorded in the log and forwarded to the job." } }, "required": [ "job_id" ] } 来源: packages/jobs/tool-jobs/src/index.ts job_list 列出你的后台任务(包括正在运行和已完成的任务)及其 id、种类和状态。 { "type": "object", "properties": {} } 来源: packages/jobs/tool-jobs/src/index.ts job_output 读取后台任务。流式任务只返回自上次读取以来的输出;最终输出任务会在结算后返回结果。每个响应都以 [status: ...] 结尾。读取默认不阻塞;设置 wait: true 后,最长等待到配置的上限。 { "type": "object", "properties": { "job_id": { "type": "string", "description": "Job id returned by the tool that started the background work." }, "wait": { "type": "boolean", "description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job alive." }, "timeout_ms": { "type": "number", "description": "Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum." } }, "required": [ "job_id" ] } 来源: packages/jobs/tool-jobs/src/index.ts 与任务种类无关的后台任务控制器:后台 bash 命令、PTY 发送和 subagent 都通过相同的 3 个工具读取、列出和终止。加载该插件会挂接控制器,从而启用生产方的 ctx.jobs.start() 。 @deepseek-ai/dsh-experimental-tool-agent-team followup_task 向另一名 Team member 发送持久 follow-up task,并在需要时启动一个 turn。 { "type": "object", "properties": { "target": { "type": "string", "description": "Team member name, or lead." }, "message": { "type": "string", "description": "Self-contained message for the target." } }, "required": [ "target", "message" ] } 来源: packages/experimental/tool-agent-team/src/index.ts interrupt_agent 中断一名 teammate 的当前 turn,同时保留其待处理 inbox。仅 Team Lead 可用。 { "type": "object", "properties": { "target": { "type": "string", "description": "Teammate name." } }, "required": [ "target" ] } 来源: packages/experimental/tool-agent-team/src/index.ts list_agents 列出 Lead 与所有持久 teammate,以及各自当前的运行时状态。 { "type": "object", "properties": {} } 来源: packages/experimental/tool-agent-team/src/index.ts send_message 向另一名 Team member 发送持久信息,但不启动 idle member。 { "type": "object", "properties": { "target": { "type": "string", "description": "Team member name, or lead." }, "message": { "type": "string", "description": "Self-contained message for the target." } }, "required": [ "target", "message" ] } 来源: packages/experimental/tool-agent-team/src/index.ts spawn_teammate 创建一名具名、持久的 teammate。只有 Team Lead 可以调用此工具。 { "type": "object", "properties": { "name": { "type": "string", "description": "Unique lower-kebab-case teammate name." }, "description": { "type": "string", "description": "Short description of the delegated responsibility." }, "prompt": { "type": "string", "description": "Complete initial task for the teammate." }, "context": { "type": "string", "description": "fresh starts without Lead history; fork inherits completed Lead turns. Defaults to fresh.", "enum": [ "fresh", "fork" ] } }, "required": [ "name", "description", "prompt" ] } 来源: packages/experimental/tool-agent-team/src/index.ts team_task_create 在共享 Team 任务板上创建一个无 owner 的 pending task。 { "type": "object", "properties": { "subject": { "type": "string", "description": "Concise task title." }, "description": { "type": "string", "description": "Complete task details and acceptance criteria." }, "blocked_by": { "type": "array", "description": "Task ids that must complete first.", "items": { "type": "string" } }, "write_scopes": { "type": "array", "description": "Advisory workspace-relative file or directory prefixes this task expects to modify.", "items": { "type": "string" } } }, "required": [ "subject", "description" ] } 来源: packages/experimental/tool-agent-team/src/index.ts team_task_get 在修改或执行共享任务前,读取其完整的最新值。 { "type": "object", "properties": { "task_id": { "type": "string", "description": "Shared task id." } }, "required": [ "task_id" ] } 来源: packages/experimental/tool-agent-team/src/index.ts team_task_list 列出共享任务,包括 readiness、owner、revision、blocker 与 write-scope warning。 { "type": "object", "properties": { "status": { "type": "string", "description": "Optional exact status filter.", "enum": [ "pending", "in_progress", "completed" ] }, "owner": { "type": "string", "description": "Optional member-name filter; use unowned for tasks without an owner." }, "ready": { "type": "boolean", "description": "Optional readiness filter." }, "cursor": { "type": "integer", "description": "Zero-based result offset. Defaults to 0." }, "limit": { "type": "integer", "description": "Number of rows, 1 through 100. Defaults to 50." } } } 来源: packages/experimental/tool-agent-team/src/index.ts team_task_update 使用 team_task_get 或 team_task_list 返回的最新 revision,对共享任务操作执行 compare-and-set。 { "type": "object", "properties": { "task_id": { "type": "string", "description": "Shared task id." }, "expected_revision": { "type": "integer", "description": "Current task revision used as the CAS precondition." }, "action": { "type": "string", "description": "Task transition to apply.", "enum": [ "claim", "release", "edit", "set_dependencies", "complete", "reopen", "reassign", "delete" ] }, "subject": { "type": "string", "description": "Replacement title for edit." }, "description": { "type": "string", "description": "Replacement details for edit." }, "blocked_by": { "type": "array", "description": "Complete blocker list for set_dependencies.", "items": { "type": "string" } }, "write_scopes": { "type": "array", "description": "Replacement advisory write scopes for edit.", "items": { "type": "string" } }, "owner": { "type": "string", "description": "Member name for Lead-only reassign; omit to unassign." } }, "required": [ "task_id", "expected_revision", "action" ] } 来源: packages/experimental/tool-agent-team/src/index.ts wait_agent 等待本次调用开始后下一次 teammate 状态、mailbox 或共享任务变更。它绝不会唤醒 inactive member;若没有其他 member 正在 running 或 provisioning,则立即返回 noProgress。唤醒或超时后应重新列出状态,而不是轮询。 { "type": "object", "properties": { "timeout_ms": { "type": "integer", "description": "Wait duration in milliseconds, from 10000 through 3600000. Defaults to 30000." } } } 来源: packages/experimental/tool-agent-team/src/index.ts 这 10 个工具限定于隐式 Team Lead 与持久 teammate 作用域。随产品发布的 dsh-base bundle 默认禁用该包;文档中的 Agent Teams profile patch 会启用它,并禁用旧 continuable child 的同名控制工具。 @deepseek-ai/dsh-tool-todo todo_write 记录并更新当前工作的结构化任务列表。每次调用都要发送 完整列表 ,它会 替换 之前的列表,不支持局部更新或逐项编辑。请用它规划多步骤工作并展示进度:开始前为每个具体步骤添加一项 todo。将当前正在处理的每项 todo 标记为 in_progress ;确实并行运行时(例如并发 subagent 或后台命令)可同时标记多项,顺序工作则标记 1 项。只要工作尚未完成,就应至少有一项任务为 in_progress 。某项 todo 完成后立即标记为 completed ,不要批量标记完成;只有全部工作完成后,才可以没有 in_progress 项。简单的单步骤任务无需使用列表。状态: pending (未开始)、 in_progress (正在处理)、 completed (已完成)。 { "type": "object", "properties": { "todos": { "type": "array", "description": "The COMPLETE task list, replacing any previous list.", "items": { "type": "object", "additionalProperties": false, "properties": { "content": { "type": "string", "description": "What the task is — a short imperative line." }, "status": { "type": "string", "description": "pending (not started) | in_progress (now) | completed (done).", "enum": [ "pending", "in_progress", "completed" ] } }, "required": [ "content", "status" ] } } }, "required": [ "todos" ] } 来源: packages/todo/tool-todo/src/index.ts todo_write 是会话所有的状态;UI 将最新的 todo/write 事件渲染为检查清单。 allowParallelInProgress 是没有默认值的必填项,因此本目录明确选择 true ,对应描述允许同时存在多个 in_progress 项。选择 false 的部署会获得同一工具,但描述会要求只能有 1 个活动任务。 @deepseek-ai/dsh-tool-workflow workflow 运行用于大规模编排 subagent 的 JavaScript 工作流脚本。当工作会分散到许多相互独立的部分时,请使用此工具,例如审查大量文件、执行迁移、开展多角度研究或对发现进行对抗式验证;此时应将编排写成脚本,而不是逐轮委派。 工作流的身份通过 meta 参数以 JSON 形式传入:必填的 name (简短 kebab-case)和 description 字符串,以及可选的 whenToUse 字符串和 phases 数组( {title, detail?, provider?, model?} )。 script 参数只能是纯 JavaScript 函数体 ,不能是 TypeScript,也不能包含 export const meta 语句;meta 是参数而非代码。脚本支持顶层 await;请以 return 结尾,该值必须可以 JSON 序列化,并作为此工具的结果。 脚本函数体提供以下钩子: agent(prompt, opts?): Promise :运行一个 subagent 直至完成。不提供 opts.schema 时,解析为子级最终文本;提供 opts.schema 时,它必须是以对象为根、且 只能 使用 type/properties/required/additionalProperties/items/enum/const/oneOf 的 JSON Schema,不支持 pattern/format/数值边界,此时解析为通过校验的对象。子级失败时解析为 null ,可使用 .filter(Boolean) 过滤。其他选项包括 label (显示名称)、 phase (进度组),以及相互独立的 provider / model LLM(大语言模型)目标覆盖项,两者可单独提供。其他任何选项( effort / isolation / agentType )都会明确报错。 pipeline(items, ...stages): Promise :让每个条目分别经过各阶段,阶段之间 没有 屏障;多阶段工作优先使用它。每个阶段接收 (prev, item, index) 。普通的阶段异常会将该 条目 变为 null ,并跳过它的剩余阶段。 parallel(thunks): Promise :并发运行零参数函数并等待 全部 完成。它会形成屏障,仅当某个阶段确实需要汇总全部先前结果时使用。抛出异常的 thunk 解析为 null 。 phase(title) :开始一个进度阶段; log(message) :说明进度; args :工具调用的 args 输入,原样提供。 如果误用钩子(参数错误、未知选项、不受支持的 schema、触发上限),抛出的错误 总会 终止脚本,绝不会退化为单个条目的 null 。 约束:并发上限和 agent 总数上限均会生效;不提供文件系统、网络、定时器或 Node.js API。具体工作由 agent 完成,脚本只负责编排。该运行在前台执行:整个脚本完成后,调用才会返回。 { "type": "object", "properties": { "script": { "type": "string", "description": "The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)." }, "meta": { "type": "object", "description": "The workflow identity block (plain JSON — never code).", "additionalProperties": true, "properties": { "name": { "type": "string", "description": "Short kebab-case workflow name." }, "description": { "type": "string", "description": "One-line description of what the workflow does." }, "whenToUse": { "type": "string", "description": "Optional guidance on when this workflow applies." }, "phases": { "type": "array", "description": "Optional phase declarations matched by phase() calls.", "items": { "type": "object", "additionalProperties": true, "properties": { "title": { "type": "string", "description": "The phase title phase() calls match by exact string." }, "detail": { "type": "string", "description": "Optional one-line description of the phase." }, "provider": { "type": "string", "description": "Optional provider override this phase is expected to use." }, "model": { "type": "string", "description": "Optional model override this phase is expected to use." } }, "required": [ "title" ] } } }, "required": [ "name", "description" ] }, "args": { "type": "object", "description": "Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).", "additionalProperties": true } }, "required": [ "script", "meta" ] } 来源: packages/workflow/tool-workflow/src/index.ts @deepseek-ai/dsh-tool-web web_fetch 获取指定 HTTP(S) URL 的内容,并将其解码为文本后返回。 { "type": "object", "properties": { "url": { "type": "string", "description": "The HTTP(S) URL to fetch." } }, "required": [ "url" ] } 来源: packages/web/tool-web/src/index.ts web_search 在 Web 上搜索最新信息。在必填的 queries 数组中提供 1–4 个查询。返回可选的摘要答案和来源 URL 列表。 { "type": "object", "properties": { "queries": { "type": "array", "description": "Required search queries; accepts 1–4 items and merges their results.", "items": { "type": "string" } } }, "required": [ "queries" ] } 来源: packages/web/tool-web/src/index.ts web_search 和 web_fetch 将提供方选择置于 ctx.web 之后,使模型可见 schema 在更换后端时保持稳定。 能力 Seams 与核心服务 English | 中文 服务可以是核心主干服务、可替换的能力 seam,也可以是组合包/组合点。下图展示了拥有服务声明的包、已知实现包,以及直接消费该服务的包。 flowchart LR pkg_attachment["attachment"] svc_attachments["ctx.attachments
Durable binary attachment storage"] pkg_attachment_local["attachment-local"] pkg_api_session_controller["api-session-controller"] pkg_tool_fs["tool-fs"] pkg_llm_pi_ai["llm-pi-ai"] pkg_llm_deepseek["llm-deepseek"] pkg_llm["llm"] svc_llm["ctx.llm
LLM adapter registry"] pkg_llm_replay["llm-replay"] pkg_agent_loop["agent-loop"] pkg_compaction_basic["compaction-basic"] pkg_deepseek_llm_api_extensions["deepseek-llm-api-extensions"] svc_deepseekLlmApiExtensions["ctx.deepseekLlmApiExtensions
Official DeepSeek request extensions"] pkg_session_log_deepseek["session-log-deepseek"] pkg_plugin_package_inventory_deepseek["plugin-package-inventory-deepseek"] pkg_token_meter["token-meter"] svc_tokenMeter["ctx.tokenMeter
Replay token measurement"] pkg_compaction_tool_result_pruner["compaction-tool-result-pruner"] svc_toolResultPruner["ctx.toolResultPruner
Model-free tool-result pruning"] pkg_session["session"] svc_sessions["ctx.sessions
In-memory session store"] pkg_agent["agent"] pkg_session_persistence["session-persistence"] pkg_session_query["session-query"] pkg_session_query_sqlite["session-query-sqlite"] pkg_subagent_in_process_driver["subagent-in-process-driver"] pkg_invariants["invariants"] pkg_message_feedback["message-feedback"] svc_sessionController["ctx.sessionController
Host Session Remote controller"] svc_sessionFileReferences["ctx.sessionFileReferences
Session-addressed file-reference Remote adapter"] svc_sessionSkillCatalog["ctx.sessionSkillCatalog
Session-addressed skill Remote adapter"] pkg_api_settings_controller["api-settings-controller"] svc_credentialsController["ctx.credentialsController
Host credential-surface Remote controller"] svc_settingsController["ctx.settingsController
Host settings-surface Remote controller"] pkg_api_workspace_controller["api-workspace-controller"] svc_workspaceController["ctx.workspaceController
Host Workspace Remote controller"] svc_directoryPickerController["ctx.directoryPickerController
Host directory-picking Remote controller"] svc_invariants["ctx.invariants
Package-owned invariant registry"] pkg_scope["scope"] pkg_typert_registry["typert-registry"] svc_typert["ctx.typert
Runtime type registry"] pkg_typert_loader["typert-loader"] pkg_api_gateway["api-gateway"] svc_typertGateway["ctx.typertGateway
Typert Host invocation gateway"] svc_sessionPersistence["ctx.sessionPersistence
Durable session persistence seam"] pkg_session_persistence_jsonl["session-persistence-jsonl"] pkg_tool_bash["tool-bash"] pkg_hooks_claude_code["hooks-claude-code"] pkg_hooks_codex["hooks-codex"] pkg_settings["settings"] svc_settings["ctx.settings
User-settings seam"] pkg_settings_file["settings-file"] pkg_tool_subagent["tool-subagent"] svc_subagentModelSelection["ctx.subagentModelSelection
Subagent model-selection preference"] pkg_credentials["credentials"] svc_credentials["ctx.credentials
Credential seam"] pkg_credentials_local["credentials-local"] pkg_authorization["authorization"] svc_authorization["ctx.authorization
Authorization flow registry"] pkg_session_telemetry["session-telemetry"] svc_sessionTelemetry["ctx.sessionTelemetry
Session telemetry seam"] pkg_session_telemetry_otel["session-telemetry-otel"] pkg_storage["storage"] svc_storage["ctx.storage
Non-session storage hub"] pkg_storage_json["storage-json"] pkg_storage_sqlite["storage-sqlite"] pkg_storage_domain["storage-domain"] svc_storageDomain["ctx.storageDomain
Domain data facility"] pkg_workspace["workspace"] svc_messageFeedback["ctx.messageFeedback
Lifecycle-bound message feedback"] svc_workspaceRegistry["ctx.workspaceRegistry
Workspace entity registry"] svc_sessionQuery["ctx.sessionQuery
Session reads, traces, filters, and search"] pkg_session_reference["session-reference"] pkg_tool_session_query["tool-session-query"] pkg_file_reference["file-reference"] svc_fileReferences["ctx.fileReferences
File reference discovery"] pkg_file_reference_local["file-reference-local"] svc_sessionReferenceResolver["ctx.sessionReferenceResolver
Cross-session snapshot preparation"] pkg_session_title["session-title"] svc_sessionTitle["ctx.sessionTitle
Log-backed session titles"] pkg_session_title_first_prompt_llm["session-title-first-prompt-llm"] pkg_session_title_all_prompts_llm["session-title-all-prompts-llm"] pkg_system_prompt["system-prompt"] svc_systemPrompt["ctx.systemPrompt
System prompt assembly registry"] pkg_tools["tools"] pkg_tool_terminal["tool-terminal"] pkg_tool_web["tool-web"] svc_tools["ctx.tools
Tool registry and guarded execution pipeline"] pkg_tool_ask_user["tool-ask-user"] pkg_tool_cordis["tool-cordis"] pkg_tool_skill["tool-skill"] pkg_tool_todo["tool-todo"] pkg_user_questions["user-questions"] svc_userQuestions["ctx.userQuestions
Human question/answer seam"] pkg_plan_mode["plan-mode"] svc_planMode["ctx.planMode
Plan collaboration state"] pkg_agent_presets["agent-presets"] svc_agentPresets["ctx.agentPresets
Per-session agent composition"] pkg_commands["commands"] svc_commands["ctx.commands
Human command registry"] pkg_session_projection["session-projection"] svc_sessionProjections["ctx.sessionProjections
Session projection units"] pkg_session_projection_cache["session-projection-cache"] svc_sessionProjectionCache["ctx.sessionProjectionCache
Persisted projection cache"] pkg_subagent["subagent"] pkg_skill["skill"] svc_skills["ctx.skills
Skill provider registry"] pkg_skill_badge["skill-badge"] pkg_skill_filesystem["skill-filesystem"] svc_agents["ctx.agents
Agent service"] pkg_acp["acp"] pkg_agent_default_model["agent-default-model"] svc_agentDefaultModel["ctx.agentDefaultModel
Default Agent model selection"] pkg_headless["headless"] svc_agentLoop["ctx.agentLoop
Concrete loop driver"] pkg_base["base"] pkg_sdk_minimal["sdk-minimal"] pkg_goal["goal"] svc_goals["ctx.goals
Same-session goal domain"] pkg_e2b["e2b"] svc_e2b["ctx.e2b
E2B sandbox lifecycle owner"] pkg_fs_e2b["fs-e2b"] pkg_subprocess_e2b["subprocess-e2b"] pkg_subprocess["subprocess"] svc_subprocess["ctx.subprocess
Subprocess seam"] pkg_subprocess_local["subprocess-local"] pkg_bash_local["bash-local"] pkg_bash_sandbox["bash-sandbox"] pkg_terminal_bash["terminal-bash"] pkg_lsp_stdio["lsp-stdio"] pkg_subagent_acp["subagent-acp"] pkg_subagent_codex["subagent-codex"] pkg_subagent_claude_code["subagent-claude-code"] pkg_shell["shell"] svc_shell["ctx.shell
Bash executor seam"] pkg_pwsh_local["pwsh-local"] pkg_tool_pwsh["tool-pwsh"] pkg_shell_env["shell-env"] svc_shellEnv["ctx.shellEnv
Managed bash environment registry"] pkg_terminal["terminal"] svc_terminals["ctx.terminals
Persistent PTY session registry"] pkg_sandbox["sandbox"] svc_sandbox["ctx.sandbox
Process-sandbox seam"] pkg_sandbox_local["sandbox-local"] pkg_sandbox_policy["sandbox-policy"] svc_sandboxPolicy["ctx.sandboxPolicy
Sandbox policy home"] pkg_fs_sandbox["fs-sandbox"] pkg_user_approval["user-approval"] svc_approval["ctx.approval
Approval seam"] pkg_permission_presets["permission-presets"] svc_permissionPresets["ctx.permissionPresets
Permission presets"] pkg_code_runtime["code-runtime"] svc_codeRuntime["ctx.codeRuntime
Code-execution seam"] pkg_code_runtime_worker_thread["code-runtime-worker-thread"] pkg_experimental_code_runtime_python["experimental-code-runtime-python"] pkg_fs["fs"] svc_fs["ctx.fs
Filesystem provider seam"] pkg_fs_local["fs-local"] pkg_fs_observation_policy["fs-observation-policy"] pkg_compaction["compaction"] svc_compaction["ctx.compaction
Compaction seam"] svc_subagents["ctx.subagents
Subagent provider and continuation service"] pkg_subagent_spawn_in_process["subagent-spawn-in-process"] pkg_subagent_fork_in_process["subagent-fork-in-process"] pkg_subagent_dsh_sdk["subagent-dsh-sdk"] pkg_tool_subagent_control["tool-subagent-control"] pkg_tool_ralph["tool-ralph"] pkg_experimental_agent_team["experimental-agent-team"] svc_agentTeams["ctx.agentTeams
Agent Teams coordination domain"] pkg_experimental_tool_agent_team["experimental-tool-agent-team"] pkg_experimental_client_ui_agent_team["experimental-client-ui-agent-team"] pkg_inspector["inspector"] svc_inspector["ctx.inspector
Cross-realm runtime inspection"] pkg_jobs["jobs"] svc_jobs["ctx.jobs
Background job registry"] pkg_jobs_local["jobs-local"] pkg_tool_jobs["tool-jobs"] pkg_web["web"] svc_web["ctx.web
Web access provider registry"] pkg_web_search_exa["web-search-exa"] pkg_web_search_perplexity["web-search-perplexity"] pkg_web_search_deepseek["web-search-deepseek"] pkg_web_fetch_http["web-fetch-http"] pkg_spill["spill"] svc_spillStore["ctx.spillStore
Spill storage seam"] pkg_spill_local["spill-local"] pkg_spill_policy["spill-policy"] pkg_host_directory_picker["host-directory-picker"] svc_directoryPicker["ctx.directoryPicker
Workspace-directory picking seam"] pkg_host_directory_picker_native["host-directory-picker-native"] pkg_host_directory_picker_browse["host-directory-picker-browse"] pkg_host_webserver["host-webserver"] svc_webServer["ctx.webServer
HTTP route registration"] pkg_client_connection["client-connection"] pkg_client_modules["client-modules"] pkg_client_hmr["client-hmr"] svc_clientModules["ctx.clientModules
Client plugin graph host"] pkg_workflow["workflow"] svc_workflowEngine["ctx.workflowEngine
Workflow script engine"] pkg_workflow_worker_thread["workflow-worker-thread"] pkg_tool_workflow["tool-workflow"] pkg_webhook["webhook"] svc_webhookRuntime["ctx.webhookRuntime
Webhook rule runtime"] pkg_webhook_github["webhook-github"] pkg_lsp["lsp"] svc_lsp["ctx.lsp
Language-server navigation seam"] pkg_tool_lsp["tool-lsp"] pkg_cordis_host_runner["cordis-host-runner"] svc_dynamicCordisRunner["ctx.dynamicCordisRunner
Dynamic Cordis package host runner"] svc_cordisInspect["ctx.cordisInspect
Dynamic Cordis inspect registry"] pkg_agent --> svc_agents pkg_agent_default_model --> svc_agentDefaultModel pkg_agent_loop --> svc_agentLoop pkg_agent_presets --> svc_agentPresets pkg_api_gateway --> svc_typertGateway pkg_api_session_controller --> svc_sessionController pkg_api_session_controller --> svc_sessionFileReferences pkg_api_session_controller --> svc_sessionSkillCatalog pkg_api_settings_controller --> svc_credentialsController pkg_api_settings_controller --> svc_settingsController pkg_api_workspace_controller --> svc_directoryPickerController pkg_api_workspace_controller --> svc_workspaceController pkg_attachment --> svc_attachments pkg_attachment_local --> svc_attachments pkg_authorization --> svc_authorization pkg_bash_local --> svc_shell pkg_bash_sandbox --> svc_shell pkg_client_modules --> svc_clientModules pkg_code_runtime --> svc_codeRuntime pkg_code_runtime_worker_thread --> svc_codeRuntime pkg_commands --> svc_commands pkg_compaction --> svc_compaction pkg_compaction_basic --> svc_compaction pkg_compaction_tool_result_pruner --> svc_toolResultPruner pkg_cordis_host_runner --> svc_cordisInspect pkg_cordis_host_runner --> svc_dynamicCordisRunner pkg_credentials --> svc_credentials pkg_credentials_local --> svc_credentials pkg_deepseek_llm_api_extensions --> svc_deepseekLlmApiExtensions pkg_e2b --> svc_e2b pkg_experimental_agent_team --> svc_agentTeams pkg_experimental_code_runtime_python --> svc_codeRuntime pkg_file_reference --> svc_fileReferences pkg_file_reference_local --> svc_fileReferences pkg_fs --> svc_fs pkg_fs_e2b --> svc_fs pkg_fs_local --> svc_fs pkg_fs_sandbox --> svc_fs pkg_goal --> svc_goals pkg_host_directory_picker --> svc_directoryPicker pkg_host_directory_picker_browse --> svc_directoryPicker pkg_host_directory_picker_native --> svc_directoryPicker pkg_host_webserver --> svc_webServer pkg_inspector --> svc_inspector pkg_invariants --> svc_invariants pkg_jobs --> svc_jobs pkg_jobs_local --> svc_jobs pkg_llm --> svc_llm pkg_llm_deepseek --> svc_llm pkg_llm_pi_ai --> svc_llm pkg_llm_replay --> svc_llm pkg_lsp --> svc_lsp pkg_lsp_stdio --> svc_lsp pkg_message_feedback --> svc_messageFeedback pkg_permission_presets --> svc_permissionPresets pkg_plan_mode --> svc_planMode pkg_plugin_package_inventory_deepseek --> svc_deepseekLlmApiExtensions pkg_pwsh_local --> svc_shell pkg_sandbox --> svc_sandbox pkg_sandbox_local --> svc_sandbox pkg_sandbox_policy --> svc_sandboxPolicy pkg_session --> svc_sessions pkg_session_log_deepseek --> svc_deepseekLlmApiExtensions pkg_session_persistence --> svc_sessionPersistence pkg_session_persistence_jsonl --> svc_sessionPersistence pkg_session_projection --> svc_sessionProjections pkg_session_projection_cache --> svc_sessionProjectionCache pkg_session_query --> svc_sessionQuery pkg_session_query_sqlite --> svc_sessionQuery pkg_session_reference --> svc_sessionReferenceResolver pkg_session_telemetry --> svc_sessionTelemetry pkg_session_telemetry_otel --> svc_sessionTelemetry pkg_session_title --> svc_sessionTitle pkg_session_title_all_prompts_llm --> svc_sessionTitle pkg_session_title_first_prompt_llm --> svc_sessionTitle pkg_settings --> svc_settings pkg_settings_file --> svc_settings pkg_shell --> svc_shell pkg_shell_env --> svc_shellEnv pkg_skill --> svc_skills pkg_skill_badge --> svc_skills pkg_skill_filesystem --> svc_skills pkg_spill --> svc_spillStore pkg_spill_local --> svc_spillStore pkg_storage --> svc_storage pkg_storage_domain --> svc_storageDomain pkg_storage_json --> svc_storage pkg_storage_sqlite --> svc_storage pkg_subagent --> svc_subagents pkg_subagent_acp --> svc_subagents pkg_subagent_claude_code --> svc_subagents pkg_subagent_codex --> svc_subagents pkg_subagent_dsh_sdk --> svc_subagents pkg_subagent_fork_in_process --> svc_subagents pkg_subagent_spawn_in_process --> svc_subagents pkg_subprocess --> svc_subprocess pkg_subprocess_e2b --> svc_subprocess pkg_subprocess_local --> svc_subprocess pkg_system_prompt --> svc_systemPrompt pkg_terminal --> svc_terminals pkg_terminal_bash --> svc_terminals pkg_token_meter --> svc_tokenMeter pkg_tool_subagent --> svc_subagentModelSelection pkg_tools --> svc_tools pkg_typert_registry --> svc_typert pkg_user_approval --> svc_approval pkg_user_questions --> svc_userQuestions pkg_web --> svc_web pkg_web_fetch_http --> svc_web pkg_web_search_deepseek --> svc_web pkg_web_search_exa --> svc_web pkg_web_search_perplexity --> svc_web pkg_webhook --> svc_webhookRuntime pkg_workflow --> svc_workflowEngine pkg_workflow_worker_thread --> svc_workflowEngine pkg_workspace --> svc_workspaceRegistry svc_agentDefaultModel --> pkg_api_session_controller svc_agentDefaultModel --> pkg_headless svc_agentLoop --> pkg_base svc_agentLoop --> pkg_sdk_minimal svc_agentTeams --> pkg_experimental_client_ui_agent_team svc_agentTeams --> pkg_experimental_tool_agent_team svc_agents --> pkg_acp svc_agents --> pkg_agent_loop svc_agents --> pkg_subagent_in_process_driver svc_approval --> pkg_acp svc_approval --> pkg_tool_bash svc_approval --> pkg_tools svc_attachments --> pkg_api_session_controller svc_attachments --> pkg_llm_deepseek svc_attachments --> pkg_llm_pi_ai svc_attachments --> pkg_tool_fs svc_authorization --> pkg_llm_pi_ai svc_clientModules --> pkg_client_hmr svc_codeRuntime --> pkg_tools svc_compaction --> pkg_compaction_basic svc_cordisInspect --> pkg_tool_cordis svc_credentials --> pkg_api_settings_controller svc_credentials --> pkg_llm_deepseek svc_credentials --> pkg_llm_pi_ai svc_deepseekLlmApiExtensions --> pkg_llm_deepseek svc_directoryPicker --> pkg_api_workspace_controller svc_dynamicCordisRunner --> pkg_tool_cordis svc_e2b --> pkg_fs_e2b svc_e2b --> pkg_subprocess_e2b svc_fileReferences --> pkg_api_session_controller svc_fs --> pkg_tool_fs svc_invariants --> pkg_agent svc_invariants --> pkg_agent_loop svc_invariants --> pkg_scope svc_invariants --> pkg_session svc_jobs --> pkg_tool_bash svc_jobs --> pkg_tool_jobs svc_jobs --> pkg_tool_subagent svc_jobs --> pkg_tool_terminal svc_llm --> pkg_agent_loop svc_llm --> pkg_compaction_basic svc_lsp --> pkg_tool_lsp svc_sandbox --> pkg_bash_sandbox svc_sandbox --> pkg_terminal_bash svc_sandboxPolicy --> pkg_bash_sandbox svc_sandboxPolicy --> pkg_fs_sandbox svc_sandboxPolicy --> pkg_terminal_bash svc_sessionPersistence --> pkg_agent_loop svc_sessionPersistence --> pkg_hooks_claude_code svc_sessionPersistence --> pkg_hooks_codex svc_sessionPersistence --> pkg_message_feedback svc_sessionPersistence --> pkg_session_query svc_sessionPersistence --> pkg_session_query_sqlite svc_sessionPersistence --> pkg_tool_bash svc_sessionProjectionCache --> pkg_api_session_controller svc_sessionProjectionCache --> pkg_session_query svc_sessionProjectionCache --> pkg_session_reference svc_sessionProjectionCache --> pkg_subagent svc_sessionProjections --> pkg_api_session_controller svc_sessionProjections --> pkg_session_title svc_sessionProjections --> pkg_tool_todo svc_sessionQuery --> pkg_session_reference svc_sessionQuery --> pkg_tool_session_query svc_sessions --> pkg_agent svc_sessions --> pkg_agent_loop svc_sessions --> pkg_invariants svc_sessions --> pkg_message_feedback svc_sessions --> pkg_session_persistence svc_sessions --> pkg_session_query svc_sessions --> pkg_session_query_sqlite svc_sessions --> pkg_subagent_in_process_driver svc_settings --> pkg_api_settings_controller svc_settings --> pkg_llm_deepseek svc_settings --> pkg_llm_pi_ai svc_shell --> pkg_hooks_claude_code svc_shell --> pkg_hooks_codex svc_shell --> pkg_tool_bash svc_shell --> pkg_tool_pwsh svc_shellEnv --> pkg_tool_bash svc_shellEnv --> pkg_tool_pwsh svc_skills --> pkg_tool_skill svc_spillStore --> pkg_spill_policy svc_storage --> pkg_storage_domain svc_storageDomain --> pkg_message_feedback svc_storageDomain --> pkg_workspace svc_subagentModelSelection --> pkg_tool_subagent svc_subagents --> pkg_tool_ralph svc_subagents --> pkg_tool_subagent svc_subagents --> pkg_tool_subagent_control svc_subprocess --> pkg_bash_local svc_subprocess --> pkg_bash_sandbox svc_subprocess --> pkg_lsp_stdio svc_subprocess --> pkg_subagent_acp svc_subprocess --> pkg_subagent_claude_code svc_subprocess --> pkg_subagent_codex svc_subprocess --> pkg_terminal_bash svc_systemPrompt --> pkg_agent_loop svc_systemPrompt --> pkg_tool_fs svc_systemPrompt --> pkg_tool_terminal svc_systemPrompt --> pkg_tool_web svc_systemPrompt --> pkg_tools svc_terminals --> pkg_tool_terminal svc_tokenMeter --> pkg_compaction_basic svc_toolResultPruner --> pkg_compaction_basic svc_tools --> pkg_agent_loop svc_tools --> pkg_tool_ask_user svc_tools --> pkg_tool_bash svc_tools --> pkg_tool_cordis svc_tools --> pkg_tool_fs svc_tools --> pkg_tool_skill svc_tools --> pkg_tool_subagent svc_tools --> pkg_tool_terminal svc_tools --> pkg_tool_todo svc_tools --> pkg_tool_web svc_typert --> pkg_api_gateway svc_typert --> pkg_typert_loader svc_userQuestions --> pkg_tool_ask_user svc_web --> pkg_tool_web svc_webServer --> pkg_client_connection svc_webServer --> pkg_client_hmr svc_webServer --> pkg_client_modules svc_webhookRuntime --> pkg_webhook_github svc_workflowEngine --> pkg_tool_ralph svc_workflowEngine --> pkg_tool_workflow svc_workspaceRegistry --> pkg_api_session_controller svc_workspaceRegistry --> pkg_api_workspace_controller svc_fs -. event gate .-> pkg_fs_observation_policy ctx 键 角色 所属包 实现 直接消费方 配套插件 说明 ctx.attachments seam attachment attachment-local api-session-controller , tool-fs , llm-pi-ai , llm-deepseek - 宿主会在会话事件之前提交已接受的图片;提供方适配器将已授权的持久引用解析为提供方原生内容。 ctx.llm seam llm llm-deepseek , llm-pi-ai , llm-replay agent-loop , compaction-basic - 适配器注册提供方实现;agent loop(智能体循环)与压缩功能调用提供方无关的流服务。 ctx.deepseekLlmApiExtensions seam deepseek-llm-api-extensions session-log-deepseek , plugin-package-inventory-deepseek llm-deepseek - 插件准备彼此独立的顶层字段;官方适配器会合并这些字段,并在 HTTP 接受后提交其交付状态。 ctx.tokenMeter core token-meter - compaction-basic - 拥有按会话隔离的回放折叠区;压力消费方共享不可变且带修订版本的测量结果。 ctx.toolResultPruner core compaction-tool-result-pruner - compaction-basic - 在摘要压缩前,通过可回放的单节点表层替换来改写过大的当前工具结果。 ctx.sessions core session - agent-loop , agent , session-persistence , session-query , session-query-sqlite , subagent-in-process-driver , invariants , message-feedback - 拥有仅追加的 Session 实例,并发出持久的会话事件流。 ctx.sessionController core api-session-controller - - - 负责 Session 命令、冷读取、持久事件跟随、实时控制状态、模型目录、workspace 打开与 Agent 激活策略。 ctx.sessionFileReferences core api-session-controller - - - 通过 Session Controller 的既有 Agent lookup 策略委托文件引用发现。 ctx.sessionSkillCatalog core api-session-controller - - - 在不激活冷 Agent 的前提下列出 Session 组合中允许用户调用的 skill。 ctx.credentialsController core api-settings-controller - - - 把凭据引用 seam 投影到生成的 Remote namespace:批量扇出、视图投影与拒绝映射都在这里,而不在 seam Definition 上。 ctx.settingsController core api-settings-controller - - - 把用户设置 seam 投影到生成的 Remote namespace:读取一律脱敏,所有拒绝在这里分类,而不在 seam Definition 上。 ctx.workspaceController core api-workspace-controller - - - 通过生成的 Remote namespace 负责 Workspace 命令和可在重连后收敛的 Workspace 状态投递。 ctx.directoryPickerController core api-workspace-controller - - - 把选目录 seam 送上线:能力门禁、取消传播,以及浏览器目录流程用于分支判断的 seam 错误码。 ctx.invariants core invariants - session , agent , scope , agent-loop - 配套子路径注册所属包本地的检查;该服务负责选择、唯一性、子 fiber,以及标明所属包的失败。 ctx.typert core typert-registry - typert-loader , api-gateway - 插件直接或通过 dsh-typert-loader 注册实时 zod 贡献;API 网关消费调用描述符和提供方,其他运行时消费方则在各自边界查询 schema 与反射元数据。 ctx.typertGateway core api-gateway - - - 将生成的 Remote 描述符与实时 Cordis 服务关联,解析已注册的身份,并通过共享的 Connection RPC 载体提供一元调用。 ctx.sessionPersistence seam session-persistence session-persistence-jsonl agent-loop , tool-bash , hooks-claude-code , hooks-codex , session-query , session-query-sqlite , message-feedback - JSONL backend 把 SessionEvent 词汇持久化为每个 Session 一份产物。 ctx.settings seam settings settings-file api-settings-controller , llm-deepseek , llm-pi-ai - 插件注册命名空间 schema 并解析分层值;提供方存储原始文档。LLM(大语言模型)适配器在用户分区下将其入口配置注册为组合基础;settings controller 提供经过脱敏的分层描述符,并写入用户层。 ctx.subagentModelSelection core tool-subagent - tool-subagent - 拥有默认关闭的设置命名空间;Agent 作用域的委派工具会在组合新顶层 Session 时读取它。 ctx.credentials seam credentials credentials-local api-settings-controller , llm-deepseek , llm-pi-ai - 配置携带对机密信息的引用;提供方拥有实际值。消费方按操作解析,因此轮换后的凭据会在紧接着的下一次请求中生效;settings controller 提供不含实际值的视图和只写存储。 ctx.authorization seam authorization - llm-pi-ai - flow 由知道如何取得某份凭据的插件注册,并以其写入的记录为键;seam 拥有这段对话与"每个键同时只跑一次尝试"的生命周期,而非协议本身。 ctx.sessionTelemetry seam session-telemetry session-telemetry-otel - - 该 seam 捕获会话记录、进行脱敏并交给一个后端;没有其他组件消费该服务,其输出会离开当前进程。 ctx.storage seam storage storage-json , storage-sqlite storage-domain - 各后端以不同名称并列注册;数据形态(领域优先)挂载到枢纽上,并将类型化操作转换为不透明的 KV 单元原语。 ctx.storageDomain core storage-domain - workspace , message-feedback - 等待所有已配置后端就绪,然后将领域形态发布为一个受生命周期约束的服务,用于类型化持久状态。 ctx.messageFeedback core message-feedback - - - 拥有本地逐 assistant 消息反馈、生命周期与目标校验、逐条目 compare-and-set 及 Host 一元 Remote 契约,且不进入 Session 历史或遥测。 ctx.workspaceRegistry core workspace - api-workspace-controller , api-session-controller - 通过领域设施拥有带 WorkspaceId 品牌类型的记录;稳定的 sessionIds 账户驱动 Host RPC 与 GUI 投影。 ctx.sessionQuery seam session-query session-query-sqlite session-reference , tool-session-query - 该接口提供精确读取、过滤和追踪;具体后端还提供全文协调、排序、摘要片段和游标世代,而模型消费方负责工作区权限与不含游标的渲染。 ctx.fileReferences seam file-reference file-reference-local api-session-controller - 该接口返回 Agent cwd 内仅含路径的补全候选;提供方负责命名空间访问与排序,但不读取文件内容。 ctx.sessionReferenceResolver core session-reference - - - 将当前表层中有界的对话快照投影为持久但不可信的消息上下文;Host 适配器负责提及语法。 ctx.sessionTitle seam session-title session-title-first-prompt-llm , session-title-all-prompts-llm - - 负责确定性回退、最新标题折叠区,以及唯一的可选异步提供方注册。 ctx.systemPrompt core system-prompt - agent-loop , tools , tool-fs , tool-terminal , tool-web - 为每个步骤收集提示词各部分和面向模型的工具 schema。 ctx.tools core tools - agent-loop , tool-ask-user , tool-bash , tool-cordis , tool-fs , tool-terminal , tool-skill , tool-subagent , tool-todo , tool-web - 注册能力,负责 PTC mode 传输,并让调用依次经过策略前处理、单调守卫、环绕分派、策略后处理和最终结果观测。 ctx.userQuestions seam user-questions - tool-ask-user - UI 前端提供当前生效的人工回答提供方;tool-ask-user 在提供方无关的 ask() promise 上暂停工具调用。 ctx.planMode core plan-mode - - - 折叠已记录的计划/模式状态,在轮次边界刷新用户选择,渲染由部署方拥有的指导信息,注册 /plan,并在状态转换期间保持计划退出 schema 稳定。 ctx.agentPresets core agent-presets - - - 在受信任根目录与用户创作根目录上发现 preset 目录,并在创建期把一份 preset cordis.yml 挂载到 agent 作用域之下,拒绝始终未激活或向根服务 realm 发布服务的行。 ctx.commands core commands - - - 插件注册直接面向人的命令,而不会把调用发送给模型。 ctx.sessionProjections core session-projection - api-session-controller , tool-todo , session-title - 各领域注册由状态驱动的折叠单元;主动驱动过程维护每个会话的水位状态,Session controller 提供 baseline 并推送发生变化的值。 ctx.sessionProjectionCache core session-projection-cache - api-session-controller , session-query , session-reference , subagent - 按会话持久保存投影单元状态的检查点(节流检查点,以及轮次/结束/分离时的必选检查点),并提供冷读取阶梯:缓存行加持久化尾部回放,因此列表读取永远不需要加载完整日志。 ctx.skills seam skill skill-badge , skill-filesystem tool-skill - 合并提供方的 skill(技能)目录;tool-skill 渲染会话前缀目录,并加载完整的 skill 正文。 ctx.agents core agent - agent-loop , acp , subagent-in-process-driver - 拥有实时 Agent 句柄、创建/恢复工厂 seam,以及进程本地的发起方传播。 ctx.agentDefaultModel core agent-default-model - api-session-controller , headless - 通过 settings 分层默认 ModelSelection ,让直接入口与 Host 支撑的 Agent 入口共享同一个状态所有者。 ctx.agentLoop bundle agent-loop - base , sdk-minimal - 唯一的具体循环插件;扩展包依赖 dsh-agent 的事件和服务,而不依赖此包。 ctx.goals core goal - - - 从会话日志折叠带修订版本的目标状态,并将实时延续激活保留在进程本地。 ctx.e2b core e2b - fs-e2b , subprocess-e2b - 拥有一个共享的 E2B SDK 句柄、远程工作目录和最终沙箱处置,使两个基础 E2B 提供方处于同一个 Linux 运行时中。 ctx.subprocess seam subprocess subprocess-local , subprocess-e2b bash-local , bash-sandbox , terminal-bash , lsp-stdio , subagent-acp , subagent-codex , subagent-claude-code - Bash 执行器、PTY shell 后端、LSP Host,以及进程外 ACP、Codex 和 Claude Code subagent 后端都通过 ctx.subprocess 执行 spawn;该服务负责进程坐标、进程树/会话生命周期、stdio 处置、终端机制和 kill 升级。 ctx.shell seam shell bash-local , bash-sandbox , pwsh-local tool-bash , tool-pwsh , hooks-claude-code , hooks-codex - 面向模型的 shell 工具和钩子桥接消费此 seam;沙箱、远程或 PowerShell 执行器可以替换 bash-local,而无需改动这些消费方。 ctx.shellEnv core shell-env - tool-bash , tool-pwsh - 插件声明限定于 effect 作用域的 DSH_* 事实;每个 shell 工具在每次执行时收集一份可信快照,其执行器据此重建命名空间。 ctx.terminals seam terminal terminal-bash tool-terminal - 注册表负责精确到 Agent 的会话身份和清理;后端负责终端机制,tool-terminal 则提供限定于所有者作用域的模型接口。 ctx.sandbox seam sandbox sandbox-local bash-sandbox , terminal-bash - 消费方交出即将执行 spawn 的确切 argv;与宿主共享文件系统和内核的后端按每次调用的策略包装该 argv,并报告强制执行情况。 ctx.sandboxPolicy core sandbox-policy - bash-sandbox , fs-sandbox , terminal-bash - 统一保存部署默认模式和工作区根目录;只有沙箱执行器和提供方读取该服务(工具层使用它同时导出的纯 sandbox/mode 折叠区)。两类强制执行组件都读取该服务,因此 bash 与 fs 不会限制到不同的根目录。 ctx.approval seam user-approval - tools , tool-bash , acp - 一次性权限决策通过 approval/request waterfall(瀑布式事件)分派;回答方是监听器(即 ACP 为自身 agent 提供的桥接),没有回答方时以 unavailable 关闭失败。 ctx.permissionPresets core permission-presets - - - 面向用户的预设表( workspace-write / danger-full-access ),将沙箱模式与审批策略选项组合在一起;一次切换会写入一个 permission/preset 事件,并贯通到两个选项事件。 ctx.codeRuntime seam code-runtime code-runtime-worker-thread , experimental-code-runtime-python tools - 使用 Host 提供的异步绑定运行一段由模型编写的程序;各后端采用不同的基础环境和语言(工具注册表在 PTC mode 下消费该服务)。 ctx.fs seam fs fs-local , fs-sandbox , fs-e2b tool-fs fs-observation-policy tool-fs 通过 ctx.fs 执行读取/写入/编辑;fs-sandbox 按共享沙箱模式限制变更;fs-observation-policy 通过 fs/* 事件门禁贡献基于观测状态的检查。 ctx.compaction seam compaction compaction-basic compaction-basic - 基础后端消费步骤后的压力事件和请求错误恢复事件;不存在面向模型的压缩工具。 ctx.subagents seam subagent subagent-spawn-in-process , subagent-fork-in-process , subagent-acp , subagent-codex , subagent-claude-code , subagent-dsh-sdk tool-subagent , tool-subagent-control , tool-ralph - 提供方实现传输;该服务还负责可选的、基于 Activation 的延续编排,tool-subagent 选择一次性或可延续委派,tool-subagent-control 传递后续消息,而 tool-ralph 要求一条全新的结构化输出路由。 ctx.agentTeams core experimental-agent-team - experimental-tool-agent-team , experimental-client-ui-agent-team - 负责隐式 Root roster、持久 peer mailbox、共享任务 DAG、continuable child 生命周期与生成式 Team Remote method;tool-agent-team 提供模型控制工具,client-ui-agent-team 挂载浏览器 contribution。 ctx.inspector core inspector - - - 负责 Worker 托管的 CDP target,以及独立于传输的 Host 和 Client observation 与 Cordis tree query API。 ctx.jobs seam jobs jobs-local tool-bash , tool-terminal , tool-subagent , tool-jobs - 生产方(后台 bash、PTY 发送和 subagent 委派)登记正在运行的工作;tool-jobs 是面向模型的控制器,用于读取、列出和终止这些工作;jobs-local 是进程本地注册表。 ctx.web seam web web-search-exa , web-search-perplexity , web-search-deepseek , web-fetch-http tool-web - 搜索和抓取提供方注册到同一个 ctx.web seam;tool-web 负责稳定的面向模型名称。 ctx.spillStore seam spill spill-local spill-policy - 后端保存过大的工具文本,并返回面向模型的定位信息和取回提示;spill-policy 是 tools/post-execute 消费方,负责决定何时 spill。 ctx.directoryPicker seam host-directory-picker host-directory-picker-native , host-directory-picker-browse api-workspace-controller - 带判别标记的交互能力:原生后端在 Host 显示设备上打开一个操作系统选择器,浏览后端为应用内浏览器提供列表与创建原语;双端后端通过其浏览器侧填充 ui-workspace 目录流程的 slot(不通过协议发布)。 ctx.webServer core host-webserver - client-connection , client-modules , client-hmr - 普通的 node:http 载体:具名路由注册表、索引转换 tap,以及静态 dist 回退;Web 传输插件注册自己的路由。 ctx.clientModules core client-modules - client-hmr - 通过增量 dsh.client 扫描组合 DSH_BOOT 入口图,提供插件组合包,并通知重建/图变更订阅方。 ctx.workflowEngine seam workflow workflow-worker-thread tool-workflow , tool-ralph - 每个上下文使用一个引擎,与 bash 相同,且没有具名提供方注册表;通用工作流与固定 Ralph 消费方启动运行,其中的 agent() 调用通过 ctx.subagents 扇出。 ctx.webhookRuntime core webhook - webhook-github - 提供方适配器分派已认证交付;可信插件注册独立的进程本地规则,runtime 把非 null 结果转换为普通的 Workspace-backed Session,不保留交付或完成状态。 ctx.lsp seam lsp lsp-stdio tool-lsp - 提供方注册与选择,加上恰好四种操作的标准化查询执行;该 seam 不提供协议逃生口,后端必须转换为标准化请求和结果。 ctx.dynamicCordisRunner core cordis-host-runner - tool-cordis - 拥有内存定义注册表、Host 半的 vm 沙箱和 request-run 往返流程;浏览器页面通过其 Remote 命名空间在线访问同一服务。 ctx.cordisInspect core cordis-host-runner - tool-cordis - 注册 Host inspect 提供方、镜像 Client 提供方 manifest,并通过动态 Cordis 传输路由 Client 查询。 维护模式:混合模式。服务从 Cordis 声明中发现;接口、实现和消费方角色在 scripts/gen-doc-graphs.ts 中分类,并设有完整性守卫。 事件生产方与消费方矩阵 English | 中文 本矩阵展示哪些包会派发各个 harness 自有事件,以及哪些包会监听这些事件。事件之间存在多对多关系,因此密集的关系数据以表格而非一张大型关系图呈现。接收方和事件名称类型还涵盖有意绕过 ctx.emit 的内含派发位置,例如 subagent 生命周期封装。 事件 模式 声明位置 派发方 监听方 agent-loop/config-start-failed emit packages/core/agent-loop/src/index.ts:239 agent-loop ( events.dispatch ) - agent-preset/selected emit packages/preset/agent-presets/src/types.ts:80 agent-presets ( emit ) remotes agent/created emit packages/core/agent/src/runtime-types.ts:166 agent ( events.dispatch ) agent-presets , file-reference-local , goal-round-driver , schedule , tool-agent-team , tool-subagent agent/disposed emit packages/core/agent/src/runtime-types.ts:175 agent ( events.dispatch ) agent-loop , file-reference-local , goal-round-driver , subagent , tool-agent-team , tool-subagent agent/error emit packages/core/agent/src/runtime-types.ts:297 agent-loop ( emit ) acp , goal-round-driver , session-controller , session-telemetry agent/inbox/claimed emit packages/core/agent/src/runtime-types.ts:204 agent-loop ( emit ) acp , goal-round-driver , subagent , tool-jobs agent/inbox/discarded emit packages/core/agent/src/runtime-types.ts:212 agent-loop ( emit ) goal-round-driver , subagent agent/inbox/inserted emit packages/core/agent/src/runtime-types.ts:193 agent-loop ( emit ) goal-round-driver agent/pre-step waterfall packages/core/agent/src/runtime-types.ts:238 agent-loop ( waterfall ) agent-instructions , compaction-basic , goal-round-driver , hooks-claude-code , hooks-codex , plan-mode , repeat-tool-reminder , session-checkpoint-policy , session-reference , subagent-in-process-driver , time-context , tmux-context , tool-cordis , tool-skill , tool-subagent agent/request waterfall packages/core/agent/src/runtime-types.ts:251 agent-loop ( waterfall ) agent , webhook agent/request-error waterfall packages/core/agent/src/runtime-types.ts:267 agent-loop ( waterfall ) compaction-basic , llm-retry agent/session-start emit packages/core/agent/src/runtime-types.ts:224 agent-loop ( emitAgentEvent ) agent-team , goal , goal-round-driver , hooks-claude-code , hooks-codex agent/status emit packages/core/agent/src/runtime-types.ts:185 agent-loop ( emit ) agent , agent-team , compaction-basic , goal-round-driver , schedule , server , session-controller agent/turn-stopping serial packages/core/agent/src/runtime-types.ts:285 agent-loop ( serial ) hooks-claude-code , hooks-codex api-session/activity emit packages/api/session-controller/src/types.ts:542 session-controller ( emit ) remotes api-session/added emit packages/api/session-controller/src/types.ts:522 session-controller ( emit ) remotes api-session/error emit packages/api/session-controller/src/types.ts:549 session-controller ( emit ) remotes api-session/removed emit packages/api/session-controller/src/types.ts:528 session-controller ( emit ) remotes api-session/status emit packages/api/session-controller/src/types.ts:535 session-controller ( emit ) remotes approval/request waterfall packages/interaction/user-approval/src/types.ts:85 user-approval ( waterfall ) acp , remotes authorization/settled emit packages/credentials/authorization/src/index.ts:57 authorization ( events.dispatch ) authorization commands/change emit packages/interaction/commands/src/types.ts:81 commands ( events.dispatch ) remotes cordis/dynamic-package emit packages/extensions/cordis-host-runner/src/types.ts:380 cordis-host-runner ( emit ) remotes cordis/dynamic-retract emit packages/extensions/cordis-host-runner/src/types.ts:386 cordis-host-runner ( emit ) remotes cordis/inspect-query emit packages/extensions/cordis-host-runner/src/types.ts:392 cordis-host-runner ( emit ) remotes cordis/inspect-query-resolved emit packages/extensions/cordis-host-runner/src/types.ts:398 cordis-host-runner ( emit ) remotes cordis/request-run emit packages/extensions/cordis-host-runner/src/types.ts:368 cordis-host-runner ( emit ) remotes cordis/request-run-resolved emit packages/extensions/cordis-host-runner/src/types.ts:374 cordis-host-runner ( emit ) remotes credentials/record-updated emit packages/credentials/credentials/src/types.ts:96 credentials ( events.dispatch ) authorization credentials/reference-updated emit packages/credentials/credentials/src/types.ts:84 credentials ( events.dispatch ) credentials , remotes domain/changed emit packages/storage/storage-domain/src/events.ts:46 storage-domain ( emit ) storage-domain , workspace , workspace-controller fs/edit-intent waterfall packages/fs/fs/src/index.ts:66 tool-fs ( waterfall ), tool-str-replace-editor ( waterfall ) fs-observation-policy fs/observed emit packages/fs/fs/src/index.ts:76 tool-fs ( emit ), tool-str-replace-editor ( emit ) fs-observation-policy , skill-filesystem fs/write-intent waterfall packages/fs/fs/src/index.ts:58 tool-fs ( waterfall ), tool-str-replace-editor ( waterfall ) fs-observation-policy goal/changed emit packages/goal/goal/src/domain.ts:114 goal ( emit ) goal-round-driver llm/adapters-updated emit packages/llm/llm/src/types.ts:23 llm ( events.dispatch ) acp , llm , remotes llm/stream waterfall packages/llm/llm/src/index.ts:67 llm ( waterfall ) agent-loop , llm , llm-replay , session-checkpoint-policy , session-title session-telemetry/record waterfall packages/session/session-telemetry/src/index.ts:43 session-telemetry ( waterfall ) - session/created emit packages/core/session/src/index.ts:52 session ( events.dispatch ) compaction , goal , hook-protocol , llm-retry , permission-presets , plan-mode , schedule , server , session , session-controller , session-log-deepseek , session-persistence , session-projection , session-projection-cache , session-telemetry , session-title , time-context , tool-todo , tool-workflow , tools , user-approval session/disposed emit packages/core/session/src/index.ts:62 session ( events.dispatch ) agent-loop , agent-team , session-controller , session-persistence , session-projection-cache , session-telemetry , session-title session/event emit packages/core/session/src/index.ts:74 session ( events.dispatch ) acp , agent-instructions , agent-loop , agent-presets , agent-team , compaction , compaction-basic , file-reference-local , goal , goal-round-driver , headless , hook-protocol , loader-smoke , server , session , session-controller , session-persistence , session-projection , session-projection-cache , session-telemetry , session-telemetry-otel , session-title , token-meter , tool-todo , tool-workflow , tools , user-approval session/flush parallel packages/core/session/src/index.ts:83 session ( events.dispatch ) session-persistence , session-telemetry settings/document-updated emit packages/settings/settings/src/types.ts:105 settings ( events.dispatch ) remotes settings/updated emit packages/settings/settings/src/types.ts:92 settings ( events.dispatch ) settings skills/change emit packages/skill/skill/src/index.ts:298 skill ( events.dispatch ) - subagent/end emit packages/subagent/subagent/src/index.ts:173 subagent ( events.dispatch ) hooks-claude-code , server , subagent subagent/provider-added emit packages/subagent/subagent/src/index.ts:147 subagent ( emit ) subagent , tool-subagent subagent/provider-removed emit packages/subagent/subagent/src/index.ts:153 subagent ( events.dispatch ) subagent , tool-subagent subagent/start emit packages/subagent/subagent/src/index.ts:164 subagent ( events.dispatch ) hooks-claude-code , subagent system-prompt/assemble waterfall packages/core/system-prompt/src/index.ts:31 system-prompt ( waterfall ) agent , agent-presets , system-prompt system-prompt/change emit packages/core/system-prompt/src/index.ts:37 system-prompt ( emit ) - tools/change emit packages/core/tools/src/index.ts:199 agent-presets ( emit ), tools ( emit ) tool-subagent tools/execute waterfall packages/core/tools/src/index.ts:155 tools ( waterfall ) session-checkpoint-policy , timeout-policy tools/post-execute waterfall packages/core/tools/src/index.ts:167 tools ( waterfall ) hooks-claude-code , hooks-codex , repeat-tool-reminder , spill-policy , tool-fs-search tools/pre-execute waterfall packages/core/tools/src/index.ts:144 tools ( waterfall ) hooks-claude-code , hooks-codex , tool-jobs tools/ptc-dispatch-log waterfall packages/core/tools/src/index.ts:181 tools ( waterfall ) spill-policy tools/result emit packages/core/tools/src/index.ts:189 tools ( events.dispatch ) agent-instructions , subagent-in-process-driver user-questions/request waterfall packages/interaction/user-questions/src/types.ts:85 user-questions ( waterfall ) remotes webserver/index-inject emit packages/host/webserver/src/index.ts:34 webserver ( emit ) inspector , modules workflow/agent-end emit packages/workflow/workflow/src/index.ts:79 workflow ( events.dispatch ) tool-workflow , workflow workflow/agent-start emit packages/workflow/workflow/src/index.ts:68 workflow ( events.dispatch ) tool-workflow , workflow workflow/end emit packages/workflow/workflow/src/index.ts:89 workflow ( events.dispatch ) workflow workflow/log emit packages/workflow/workflow/src/index.ts:58 workflow ( events.dispatch ) - workflow/phase emit packages/workflow/workflow/src/index.ts:51 workflow ( events.dispatch ) - workflow/start emit packages/workflow/workflow/src/index.ts:43 workflow ( events.dispatch ) workflow 包源码中出现的非 harness 或未声明事件字符串 事件字符串 派发方 监听方 internal/dispatch - agent-team , commands , compaction , fs , goal , goal-round-driver , hook-protocol , llm-retry , permission-presets , plan-mode , sandbox-policy , schedule , scope , session , session-log-deepseek , session-title , subagent , terminal-bash , time-context , tool-todo , tool-workflow , tools , user-approval , webhook , workflow internal/plugin - inspector , loader , lsp-stdio , modules internal/service - agent-presets , gateway internal/status - agent , inspector 维护模式:生成内容。Cordis 事件声明及生产方/监听方的关系边由仓库的 TypeScript Program 解析。 Agent 轮次与步骤生命周期 English | 中文 此时序图是 architecture.md 的配套图示。持久的回放事实保存在 session/event 中,实时控制与状态则保存在 agent/* 中。 sequenceDiagram participant User participant Agent participant Driver participant Hooks as hook listeners participant Prompt as ctx.systemPrompt participant LLM as ctx.llm participant Tools as ctx.tools participant Session participant SDK as UI or SDK listener User->>Agent: followup(content) Agent-->>SDK: agent/inbox/spliced Agent-->>SDK: agent/inbox/inserted { message } Agent->>Driver: queued work wakes driver Driver-->>SDK: agent/status running Driver->>Session: turn/start Note over Agent,Driver: claim pending next-step input plus one queued prompt Driver-->>SDK: agent/inbox/spliced pure deletion Driver-->>SDK: agent/inbox/claimed { message, turn } per message Driver->>Hooks: agent/pre-step waterfall Hooks-->>Driver: authoritative reject or enter(messages) alt proposed step rejected or pre-step failed Driver-->>Driver: claimed batch stays removed, the open turn spends no step else enter proposed step Driver->>Session: step/start Driver->>Session: user/message per entered message Driver->>Prompt: system-prompt/assemble waterfall Driver->>LLM: agent/request waterfall, then llm/stream waterfall LLM-->>Driver: StreamChunk* Driver->>Session: assistant/chunk* Session-->>SDK: session/event assistant/chunk* alt final adapter or terminal in-band request failure Driver->>Session: step/end Driver->>Hooks: agent/request-error waterfall Hooks-->>Driver: return retry action or preserve the original error else model request succeeded Driver->>Session: assistant/message Driver->>Tools: classify pending call by executionMode loop barriers and bounded rolling pool, reclassify before start opt call starts Driver->>Session: tool/call Driver->>Tools: ordered pre, concurrent execute Tools-->>Session: tool-owned events when applicable end opt next model-order result ready Driver->>Tools: ordered post Driver->>Session: tool/result end end Driver->>Session: step/end opt natural stop and next-step inbox empty Driver->>Hooks: agent/turn-stopping serial terminal checkpoint end opt next-step input is pending Driver-->>Driver: claim pending next-step input Driver-->>SDK: agent/inbox/claimed { message, turn } per message Driver->>Hooks: agent/pre-step waterfall Hooks-->>Driver: authoritative reject or enter(messages) end end end Driver->>Session: turn/end Driver-->>SDK: agent/status idle assistant/message 事件会记录每次成功的提供方调用,包括返回空内容或以 max-tokens 结束的调用。空内容不会进入派生历史,但该持久事件仍会保留用量,并通过 sourceEventSeqs 精确列出对应的 assistant/chunk 事件,包括显式空列表。 dsh-compaction-basic 在派生请求之前通过 agent/pre-step 处理压力,而 agent/request-error 仅用于规范的上下文溢出。任一触发条件满足后,系统都会先执行可选的工具结果剪枝,再选择摘要。恢复发生在失败步骤结束之后、失败轮次结束之前;只有当剪枝或摘要生成推进了 surface replacement generation 时,系统才会开启一个全新的重试轮次,否则仍以原始请求错误为准。 以返回的 agent/pre-step 决策为准;通过包装 next() 的监听器会保留下游消息与 startsRequestSeries ,除非有意替换。steering(中途引导)和注入的上下文在后续的认领操作取得其下一步骤批次后,会经过同一 waterfall(瀑布式事件)。 需要可回放 transcript(文本记录)数据的 SDK 用户应当消费 session/event ; agent/* 是用于队列与状态、提示词拦截、请求构造、steering、继续执行和错误处理的实时协调接口。 维护模式:英文源文件包含人工维护的 Mermaid 时序图,并由生成器写出;本中文文件作为经评审对侧通过双语配对维护。确切的事件签名位于生成的 Cordis 目录中。 工具执行流水线 English | 中文 此图展示策略、钩子、沙箱、文件系统守卫、结果重写、最终结果观察和 UI 渲染在不改变循环的情况下何时运行。 tools/pre-execute waterfall(瀑布式事件)首先运行,随后是单调守卫,然后运行 tools/execute 和 tools/post-execute waterfall;这三个 waterfall 可以改写一次调用。由定义自身控制的 finalizeContent 和 tools/result 在此之后运行。 flowchart TD model["Assistant message contains tool-call block"] toolCall["Session event: tool/call
logged before execution"] presentCall["UI pending card
presentCall(args)"] pre["tools/pre-execute waterfall
hooks, permission, sandbox"] guards["Registered monotonic guards
deny or abstain; identity protected"] denied["denied or approval refused
tool body skipped"] approval["ctx.approval one-shot prompt
absent or unanswerable: deny"] around["tools/execute waterfall
timeout, retry, metrics (around dispatch)"] toolBody["Registered tool execute() body"] fsGate["fs/write-intent or fs/edit-intent
tool-fs mutations only"] owned["Tool-owned session events
todo/write, fs/observed, hook/invoked, hook/result, tool/code-dispatch"] post["tools/post-execute waterfall
accept, block, replace, add context"] normalized["Registry outer normalization
pipeline/result snapshot throws become isError"] finalize["ToolDefinition.finalizeContent
last content-only invariant"] final["tools/result synchronous notification
frozen authoritative outcome"] context["Active-batch additionalContexts FIFO
injected user/message after recorded tool results"] toolResult["Session event: tool/result
single model-facing outcome"] allResults["Tool batch settled
recorded tool/result events complete"] presentResult["UI completed card
presentResult(args, result)"] model --> toolCall toolCall --> presentCall toolCall --> pre pre -->|allow| guards guards -->|allow| around guards -->|deny| denied guards -.->|throw| normalized around --> toolBody pre -->|deny| denied pre -->|ask| approval approval -->|allowed-once| guards approval -->|rejected, cancelled, unavailable| denied approval -.->|throw| normalized denied --> post pre -.->|throw| normalized toolBody --> fsGate fsGate --> toolBody toolBody --> owned toolBody --> around around --> post around -.->|wrapper throws| normalized post -.->|throw| normalized post --> finalize normalized --> finalize finalize --> final final --> toolResult toolResult --> presentResult toolResult --> allResults allResults --> context 文件系统的先读后编辑检查位于 tool-fs 之下,通过 fs/* 事件实现。通用的前置/后置 waterfall 承载钩子与审批策略; ctx.approval 在单调守卫之前处理询问,而不得重新排序的所有者策略仍作为已注册的守卫。超时等环绕分发关注点对 tools/execute 进行包装。注册表会对候选结果进行无损快照;如果快照失败,则会先将失败规范化,之后再由可见定义中已随快照固定的 finalizeContent 回调强制执行其同步且仅限内容的不变式。随后, tools/result 会观察不可变、可由 JSON 无损表示的结果。这样一来,钩子便可跨越不同工具系列,而无需让工具与某个策略服务耦合。PTC mode 会将保留的 run_code 传输及其序列化子调用都送入流水线;子调用携带父级 token、记录 tool/code-dispatch 、将拒绝呈现为具有约束力的驳回,并省略 additionalContexts ,以保持调用与结果相邻。 维护模式:英文源文件包含人工维护的 Mermaid 流程图,并由生成器写出;本中文文件作为经评审对侧通过双语配对维护。确切的工具 schema 与事件签名位于生成的目录中。