【deepseek-harness】DeepSeek Harness (dsh) 系统级架构分析之二

第三部分:能力接缝模块群

以下为 dsh 能力接缝模块群的深度分析,涵盖 llm、shell、subprocess、fs、web、lsp、terminal、code-runtime、sandbox、skill、subagent、workflow、compaction、e2b、mcp 十五个模块。

1. LLM 适配层(llm)

路径packages/llm/llm/src/

核心作用 :定义提供商中立的 LLM 运行时抽象------流式调用、块组装、品牌 ID、重试策略、不变式验证。所有 LLM 提供商(如 deepseek、openai)通过实现 LlmAdapter 接口接入。

内部架构

#mermaid-svg-bu7y7WsO9unvmVs1{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bu7y7WsO9unvmVs1 .error-icon{fill:#552222;}#mermaid-svg-bu7y7WsO9unvmVs1 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bu7y7WsO9unvmVs1 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bu7y7WsO9unvmVs1 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bu7y7WsO9unvmVs1 .marker.cross{stroke:#333333;}#mermaid-svg-bu7y7WsO9unvmVs1 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bu7y7WsO9unvmVs1 p{margin:0;}#mermaid-svg-bu7y7WsO9unvmVs1 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster-label text{fill:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster-label span{color:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster-label span p{background-color:transparent;}#mermaid-svg-bu7y7WsO9unvmVs1 .label text,#mermaid-svg-bu7y7WsO9unvmVs1 span{fill:#333;color:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 .node rect,#mermaid-svg-bu7y7WsO9unvmVs1 .node circle,#mermaid-svg-bu7y7WsO9unvmVs1 .node ellipse,#mermaid-svg-bu7y7WsO9unvmVs1 .node polygon,#mermaid-svg-bu7y7WsO9unvmVs1 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bu7y7WsO9unvmVs1 .rough-node .label text,#mermaid-svg-bu7y7WsO9unvmVs1 .node .label text,#mermaid-svg-bu7y7WsO9unvmVs1 .image-shape .label,#mermaid-svg-bu7y7WsO9unvmVs1 .icon-shape .label{text-anchor:middle;}#mermaid-svg-bu7y7WsO9unvmVs1 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bu7y7WsO9unvmVs1 .rough-node .label,#mermaid-svg-bu7y7WsO9unvmVs1 .node .label,#mermaid-svg-bu7y7WsO9unvmVs1 .image-shape .label,#mermaid-svg-bu7y7WsO9unvmVs1 .icon-shape .label{text-align:center;}#mermaid-svg-bu7y7WsO9unvmVs1 .node.clickable{cursor:pointer;}#mermaid-svg-bu7y7WsO9unvmVs1 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bu7y7WsO9unvmVs1 .arrowheadPath{fill:#333333;}#mermaid-svg-bu7y7WsO9unvmVs1 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bu7y7WsO9unvmVs1 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bu7y7WsO9unvmVs1 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bu7y7WsO9unvmVs1 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bu7y7WsO9unvmVs1 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bu7y7WsO9unvmVs1 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster text{fill:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 .cluster span{color:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bu7y7WsO9unvmVs1 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bu7y7WsO9unvmVs1 rect.text{fill:none;stroke-width:0;}#mermaid-svg-bu7y7WsO9unvmVs1 .icon-shape,#mermaid-svg-bu7y7WsO9unvmVs1 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bu7y7WsO9unvmVs1 .icon-shape p,#mermaid-svg-bu7y7WsO9unvmVs1 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bu7y7WsO9unvmVs1 .icon-shape .label rect,#mermaid-svg-bu7y7WsO9unvmVs1 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bu7y7WsO9unvmVs1 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bu7y7WsO9unvmVs1 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bu7y7WsO9unvmVs1 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-bu7y7WsO9unvmVs1 .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .def tspan{fill:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .prov tspan{fill:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-bu7y7WsO9unvmVs1 .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
registerAdapter
stream/call
ctx.llm.stream
间接通过 Agent
LlmRuntime (Service)
LlmAdapter (abstract)
BlockAssembler
types.ts / brand.ts / content.ts
LlmAdapter 实现

(deepseek, openai 等)
Agent 主循环
模型工具层

关键类/函数

名称 类型 职责
LlmRuntime Service (class) 注册 LLM 适配器,提供 stream() / call() 入口,管理适配器注册表
LlmAdapter abstract class LLM 提供商实现的抽象接口:流式请求、非流式请求、模型信息解析
BlockAssembler class 将流式增量块组装为完整 ContentBlock,处理部分 JSON 和工具调用拼接
MessageId / CallId / StreamId Brand types 品牌化 ID 类型,确保消息/调用/流的全链路追踪
RetryPolicy class LLM 调用重试策略:指数退避、最大重试次数、可重试错误判定
LlmCallConfig interface 一次 LLM 调用的配置:provider、model、temperature、maxTokens 等
ContentBlock type union 统一的内容块类型:text、tool_use、tool_result、thinking 等
HarnessError class 分类错误基类,携带 machine-routable code
assertNever() function 闭联集穷尽性守卫
LlmAdapterFailure class 适配器失败包装类

与其他模块的关系

  • agent :Agent 主循环通过 ctx.llm.stream() 发起 LLM 请求。
  • session:消息和调用 ID 品牌类型用于会话事件追踪。
  • compaction :压缩后端通过 ctx.llm.stream() 生成摘要。
  • subagent:子代理通过 Agent 间接使用 LLM 运行时。
  • skill :技能内容通过 createUserMessage() 进入 LLM 消息流。
  • tools (dsh-tools):工具定义的 output.render() 产出 ContentBlock

2. Shell 执行能力(shell)

路径packages/shell/

核心作用:定义 Shell 执行的抽象服务,支持多后端(bash-local、bash-sandbox、pwsh-local、pwsh-sandbox),为模型工具(tool-bash、tool-bash-persistent、tool-pwsh)提供命令执行入口。

内部架构

#mermaid-svg-mdD5f33ZsiwP9WXw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-mdD5f33ZsiwP9WXw .error-icon{fill:#552222;}#mermaid-svg-mdD5f33ZsiwP9WXw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-mdD5f33ZsiwP9WXw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-mdD5f33ZsiwP9WXw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-mdD5f33ZsiwP9WXw .marker.cross{stroke:#333333;}#mermaid-svg-mdD5f33ZsiwP9WXw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-mdD5f33ZsiwP9WXw p{margin:0;}#mermaid-svg-mdD5f33ZsiwP9WXw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster-label text{fill:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster-label span{color:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster-label span p{background-color:transparent;}#mermaid-svg-mdD5f33ZsiwP9WXw .label text,#mermaid-svg-mdD5f33ZsiwP9WXw span{fill:#333;color:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw .node rect,#mermaid-svg-mdD5f33ZsiwP9WXw .node circle,#mermaid-svg-mdD5f33ZsiwP9WXw .node ellipse,#mermaid-svg-mdD5f33ZsiwP9WXw .node polygon,#mermaid-svg-mdD5f33ZsiwP9WXw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-mdD5f33ZsiwP9WXw .rough-node .label text,#mermaid-svg-mdD5f33ZsiwP9WXw .node .label text,#mermaid-svg-mdD5f33ZsiwP9WXw .image-shape .label,#mermaid-svg-mdD5f33ZsiwP9WXw .icon-shape .label{text-anchor:middle;}#mermaid-svg-mdD5f33ZsiwP9WXw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-mdD5f33ZsiwP9WXw .rough-node .label,#mermaid-svg-mdD5f33ZsiwP9WXw .node .label,#mermaid-svg-mdD5f33ZsiwP9WXw .image-shape .label,#mermaid-svg-mdD5f33ZsiwP9WXw .icon-shape .label{text-align:center;}#mermaid-svg-mdD5f33ZsiwP9WXw .node.clickable{cursor:pointer;}#mermaid-svg-mdD5f33ZsiwP9WXw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-mdD5f33ZsiwP9WXw .arrowheadPath{fill:#333333;}#mermaid-svg-mdD5f33ZsiwP9WXw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-mdD5f33ZsiwP9WXw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-mdD5f33ZsiwP9WXw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mdD5f33ZsiwP9WXw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-mdD5f33ZsiwP9WXw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mdD5f33ZsiwP9WXw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster text{fill:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw .cluster span{color:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-mdD5f33ZsiwP9WXw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-mdD5f33ZsiwP9WXw rect.text{fill:none;stroke-width:0;}#mermaid-svg-mdD5f33ZsiwP9WXw .icon-shape,#mermaid-svg-mdD5f33ZsiwP9WXw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-mdD5f33ZsiwP9WXw .icon-shape p,#mermaid-svg-mdD5f33ZsiwP9WXw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-mdD5f33ZsiwP9WXw .icon-shape .label rect,#mermaid-svg-mdD5f33ZsiwP9WXw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-mdD5f33ZsiwP9WXw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-mdD5f33ZsiwP9WXw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-mdD5f33ZsiwP9WXw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-mdD5f33ZsiwP9WXw .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .def tspan{fill:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .prov tspan{fill:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-mdD5f33ZsiwP9WXw .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
注册
注册
注册
ctx.shell.exec
ctx.shell.exec
ctx.shell.exec
ShellExecutor (Service)
types.ts / render.ts / invariant.ts
bash-local

(本地 Bash)
bash-sandbox

(沙箱 Bash)
pwsh-local

(本地 PowerShell)
pwsh-sandbox

(沙箱 PowerShell)
shell-env

(环境注册表)
tool-bash

(一次性 Bash 工具)
tool-bash-persistent

(持久 Bash 工具)
tool-pwsh

(PowerShell 工具)

关键类/函数

名称 类型 职责
ShellExecutor Service (class) Shell 执行服务定义,声明 exec() 抽象方法,管理生命周期
BashLocalProvider provider class 本地 Bash 执行后端,直接调用 /bin/bash
BashSandboxProvider provider class 沙箱 Bash 后端,通过沙箱隔离执行
PwshLocalProvider provider class 本地 PowerShell 后端
PwshSandboxProvider provider class 沙箱 PowerShell 后端
ShellEnvRegistry class Shell 环境变量注册表,合并系统与用户配置
ShellRender function 将 stdout/stderr 渲染为模型可读文本
background.ts (tool-bash) module 后台 Shell 进程管理:启动、轮询、终止
ShellInvariant function Shell 执行前置/后置不变式校验

与其他模块的关系

  • sandboxbash-sandbox / pwsh-sandbox 依赖 SandboxProvider 进行隔离执行。
  • terminalterminal-bash 后端复用 Shell 执行能力。
  • fs :Shell 命令的文件操作通过 ctx.fs 统一审计。
  • subprocess:Shell 执行底层依赖子进程能力。

3. 子进程能力(subprocess)

路径packages/subprocess/

核心作用:定义子进程生命周期的抽象运行时------spawn、等待退出、终止、终端会话。支持本地和远程(E2B)后端。

内部架构

#mermaid-svg-n4r3dHx06ekoRzkn{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-n4r3dHx06ekoRzkn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-n4r3dHx06ekoRzkn .error-icon{fill:#552222;}#mermaid-svg-n4r3dHx06ekoRzkn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-n4r3dHx06ekoRzkn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-n4r3dHx06ekoRzkn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-n4r3dHx06ekoRzkn .marker.cross{stroke:#333333;}#mermaid-svg-n4r3dHx06ekoRzkn svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-n4r3dHx06ekoRzkn p{margin:0;}#mermaid-svg-n4r3dHx06ekoRzkn .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-n4r3dHx06ekoRzkn .cluster-label text{fill:#333;}#mermaid-svg-n4r3dHx06ekoRzkn .cluster-label span{color:#333;}#mermaid-svg-n4r3dHx06ekoRzkn .cluster-label span p{background-color:transparent;}#mermaid-svg-n4r3dHx06ekoRzkn .label text,#mermaid-svg-n4r3dHx06ekoRzkn span{fill:#333;color:#333;}#mermaid-svg-n4r3dHx06ekoRzkn .node rect,#mermaid-svg-n4r3dHx06ekoRzkn .node circle,#mermaid-svg-n4r3dHx06ekoRzkn .node ellipse,#mermaid-svg-n4r3dHx06ekoRzkn .node polygon,#mermaid-svg-n4r3dHx06ekoRzkn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n4r3dHx06ekoRzkn .rough-node .label text,#mermaid-svg-n4r3dHx06ekoRzkn .node .label text,#mermaid-svg-n4r3dHx06ekoRzkn .image-shape .label,#mermaid-svg-n4r3dHx06ekoRzkn .icon-shape .label{text-anchor:middle;}#mermaid-svg-n4r3dHx06ekoRzkn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-n4r3dHx06ekoRzkn .rough-node .label,#mermaid-svg-n4r3dHx06ekoRzkn .node .label,#mermaid-svg-n4r3dHx06ekoRzkn .image-shape .label,#mermaid-svg-n4r3dHx06ekoRzkn .icon-shape .label{text-align:center;}#mermaid-svg-n4r3dHx06ekoRzkn .node.clickable{cursor:pointer;}#mermaid-svg-n4r3dHx06ekoRzkn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-n4r3dHx06ekoRzkn .arrowheadPath{fill:#333333;}#mermaid-svg-n4r3dHx06ekoRzkn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-n4r3dHx06ekoRzkn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-n4r3dHx06ekoRzkn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n4r3dHx06ekoRzkn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-n4r3dHx06ekoRzkn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n4r3dHx06ekoRzkn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-n4r3dHx06ekoRzkn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-n4r3dHx06ekoRzkn .cluster text{fill:#333;}#mermaid-svg-n4r3dHx06ekoRzkn .cluster span{color:#333;}#mermaid-svg-n4r3dHx06ekoRzkn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-n4r3dHx06ekoRzkn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-n4r3dHx06ekoRzkn rect.text{fill:none;stroke-width:0;}#mermaid-svg-n4r3dHx06ekoRzkn .icon-shape,#mermaid-svg-n4r3dHx06ekoRzkn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n4r3dHx06ekoRzkn .icon-shape p,#mermaid-svg-n4r3dHx06ekoRzkn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-n4r3dHx06ekoRzkn .icon-shape .label rect,#mermaid-svg-n4r3dHx06ekoRzkn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n4r3dHx06ekoRzkn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-n4r3dHx06ekoRzkn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-n4r3dHx06ekoRzkn :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-n4r3dHx06ekoRzkn .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .def tspan{fill:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .prov tspan{fill:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-n4r3dHx06ekoRzkn .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
注册
ctx.subprocess.spawn
ctx.subprocess.spawnTerminal
ctx.subprocess
SubprocessRuntime (Service)
types.ts
spawn.ts (本地 spawn 实现)
subprocess-local

(本地子进程)
subprocess-e2b

(E2B 远程子进程)
shell Providers
terminal-bash 后端
code-runtime worker

关键类/函数

名称 类型 职责
SubprocessRuntime Service (abstract) 子进程运行时服务定义:spawn()spawnTerminal()resolveExecutable()
SubprocessHandle interface 子进程句柄:wait()terminate()kill()、stdin/stdout/stderr 流
SubprocessSpawnSpec interface spawn 参数:argv、env、cwd、graceMs、signal
SubprocessTerminalHandle interface 终端会话句柄:resize()write()、输出流
LocalSubprocessRuntime class 本地子进程实现,基于 Node.js child_process
E2BSubprocessRuntime class E2B 远程子进程实现,通过共享沙箱执行
spawn() (local) function 本地 spawn 核心逻辑:进程创建、信号处理、优雅终止

与其他模块的关系

  • shell:Shell Provider 是 subprocess 的主要消费者。
  • terminal :终端后端通过 spawnTerminal() 创建 PTY 会话。
  • e2bsubprocess-e2b 将子进程操作映射到远程 E2B 沙箱。
  • code-runtime:代码运行时的 worker-thread 通过子进程能力管理。

4. 文件系统能力(fs)

路径packages/fs/

核心作用:定义文件系统抽象接口------路径解析、读写、编辑、目录列举、流式读取。支持本地文件系统和 E2B 远程文件系统,沙箱环境下提供路径隔离。

内部架构

#mermaid-svg-fsi63mY76LUMWRw7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fsi63mY76LUMWRw7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fsi63mY76LUMWRw7 .error-icon{fill:#552222;}#mermaid-svg-fsi63mY76LUMWRw7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fsi63mY76LUMWRw7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fsi63mY76LUMWRw7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fsi63mY76LUMWRw7 .marker.cross{stroke:#333333;}#mermaid-svg-fsi63mY76LUMWRw7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fsi63mY76LUMWRw7 p{margin:0;}#mermaid-svg-fsi63mY76LUMWRw7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fsi63mY76LUMWRw7 .cluster-label text{fill:#333;}#mermaid-svg-fsi63mY76LUMWRw7 .cluster-label span{color:#333;}#mermaid-svg-fsi63mY76LUMWRw7 .cluster-label span p{background-color:transparent;}#mermaid-svg-fsi63mY76LUMWRw7 .label text,#mermaid-svg-fsi63mY76LUMWRw7 span{fill:#333;color:#333;}#mermaid-svg-fsi63mY76LUMWRw7 .node rect,#mermaid-svg-fsi63mY76LUMWRw7 .node circle,#mermaid-svg-fsi63mY76LUMWRw7 .node ellipse,#mermaid-svg-fsi63mY76LUMWRw7 .node polygon,#mermaid-svg-fsi63mY76LUMWRw7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fsi63mY76LUMWRw7 .rough-node .label text,#mermaid-svg-fsi63mY76LUMWRw7 .node .label text,#mermaid-svg-fsi63mY76LUMWRw7 .image-shape .label,#mermaid-svg-fsi63mY76LUMWRw7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-fsi63mY76LUMWRw7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fsi63mY76LUMWRw7 .rough-node .label,#mermaid-svg-fsi63mY76LUMWRw7 .node .label,#mermaid-svg-fsi63mY76LUMWRw7 .image-shape .label,#mermaid-svg-fsi63mY76LUMWRw7 .icon-shape .label{text-align:center;}#mermaid-svg-fsi63mY76LUMWRw7 .node.clickable{cursor:pointer;}#mermaid-svg-fsi63mY76LUMWRw7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fsi63mY76LUMWRw7 .arrowheadPath{fill:#333333;}#mermaid-svg-fsi63mY76LUMWRw7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fsi63mY76LUMWRw7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fsi63mY76LUMWRw7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fsi63mY76LUMWRw7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fsi63mY76LUMWRw7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fsi63mY76LUMWRw7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fsi63mY76LUMWRw7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fsi63mY76LUMWRw7 .cluster text{fill:#333;}#mermaid-svg-fsi63mY76LUMWRw7 .cluster span{color:#333;}#mermaid-svg-fsi63mY76LUMWRw7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fsi63mY76LUMWRw7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fsi63mY76LUMWRw7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-fsi63mY76LUMWRw7 .icon-shape,#mermaid-svg-fsi63mY76LUMWRw7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fsi63mY76LUMWRw7 .icon-shape p,#mermaid-svg-fsi63mY76LUMWRw7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fsi63mY76LUMWRw7 .icon-shape .label rect,#mermaid-svg-fsi63mY76LUMWRw7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fsi63mY76LUMWRw7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fsi63mY76LUMWRw7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fsi63mY76LUMWRw7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-fsi63mY76LUMWRw7 .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .def tspan{fill:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .prov tspan{fill:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-fsi63mY76LUMWRw7 .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
注册
注册
ctx.fs.*
ctx.fs.*
FileSystem (abstract)
types.ts (FsTarget, FsInfo, FsError)
fs-local

(本地文件系统)
fs-sandbox

(沙箱文件系统)
fs-e2b

(E2B 远程文件系统)
tool-fs

(模型文件工具)
skill-filesystem

(技能文件发现)

关键类/函数

名称 类型 职责
FileSystem abstract class 文件系统服务定义:resolve()stat()readText()readBytes()writeText()editText()listDir()streamText()
FsTarget interface 路径解析结果:targetKey + displayPath,解耦显示路径与后端路径
FsInfo interface 文件/目录信息:类型、大小、版本
FsVersion brand type 文件版本标识,用于乐观并发控制
FsError class 文件系统错误类,携带稳定错误码(FS_NOT_FOUNDFS_PERMISSION_DENIED 等)
FsWriteIntent type 写入意图:createIfAbsentreplaceIfVersion
FsEditRequest interface 编辑请求:oldStringnewStringreplaceAll
LocalFileSystem class 本地 FS 实现,直接使用 Node.js fs 模块
SandboxedFileSystem class 沙箱 FS 实现,路径隔离与权限检查
E2BFileSystem class E2B 远程 FS 实现,通过共享沙箱的文件 API 操作
tool-fs tool 模型工具:read_filewrite_fileedit_filelist_directory

与其他模块的关系

  • sandboxfs-sandbox 依赖 SandboxProvider 进行路径隔离。
  • e2bfs-e2b 依赖 ctx.e2b.getSandbox() 获取远程沙箱句柄。
  • skillskill-filesystem 通过 ctx.fs 读取技能文件(当 FS 服务存在时)。
  • shell :Shell 命令的文件操作通过 ctx.fs 统一审计。
  • compaction:压缩后端读取会话事件中的文件操作记录。

5. Web 搜索/抓取能力(web)

路径packages/web/

核心作用 :定义 Web 搜索和页面抓取的抽象运行时。支持多搜索提供商(deepseek、exa、perplexity)和 HTTP 抓取,为 tool-web 模型工具提供统一接口。

内部架构

#mermaid-svg-1keRfnQhu4LYsEA9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-1keRfnQhu4LYsEA9 .error-icon{fill:#552222;}#mermaid-svg-1keRfnQhu4LYsEA9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1keRfnQhu4LYsEA9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1keRfnQhu4LYsEA9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1keRfnQhu4LYsEA9 .marker.cross{stroke:#333333;}#mermaid-svg-1keRfnQhu4LYsEA9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1keRfnQhu4LYsEA9 p{margin:0;}#mermaid-svg-1keRfnQhu4LYsEA9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster-label text{fill:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster-label span{color:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster-label span p{background-color:transparent;}#mermaid-svg-1keRfnQhu4LYsEA9 .label text,#mermaid-svg-1keRfnQhu4LYsEA9 span{fill:#333;color:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 .node rect,#mermaid-svg-1keRfnQhu4LYsEA9 .node circle,#mermaid-svg-1keRfnQhu4LYsEA9 .node ellipse,#mermaid-svg-1keRfnQhu4LYsEA9 .node polygon,#mermaid-svg-1keRfnQhu4LYsEA9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1keRfnQhu4LYsEA9 .rough-node .label text,#mermaid-svg-1keRfnQhu4LYsEA9 .node .label text,#mermaid-svg-1keRfnQhu4LYsEA9 .image-shape .label,#mermaid-svg-1keRfnQhu4LYsEA9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-1keRfnQhu4LYsEA9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-1keRfnQhu4LYsEA9 .rough-node .label,#mermaid-svg-1keRfnQhu4LYsEA9 .node .label,#mermaid-svg-1keRfnQhu4LYsEA9 .image-shape .label,#mermaid-svg-1keRfnQhu4LYsEA9 .icon-shape .label{text-align:center;}#mermaid-svg-1keRfnQhu4LYsEA9 .node.clickable{cursor:pointer;}#mermaid-svg-1keRfnQhu4LYsEA9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-1keRfnQhu4LYsEA9 .arrowheadPath{fill:#333333;}#mermaid-svg-1keRfnQhu4LYsEA9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1keRfnQhu4LYsEA9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1keRfnQhu4LYsEA9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1keRfnQhu4LYsEA9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-1keRfnQhu4LYsEA9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1keRfnQhu4LYsEA9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster text{fill:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 .cluster span{color:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1keRfnQhu4LYsEA9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-1keRfnQhu4LYsEA9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-1keRfnQhu4LYsEA9 .icon-shape,#mermaid-svg-1keRfnQhu4LYsEA9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-1keRfnQhu4LYsEA9 .icon-shape p,#mermaid-svg-1keRfnQhu4LYsEA9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-1keRfnQhu4LYsEA9 .icon-shape .label rect,#mermaid-svg-1keRfnQhu4LYsEA9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-1keRfnQhu4LYsEA9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-1keRfnQhu4LYsEA9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-1keRfnQhu4LYsEA9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-1keRfnQhu4LYsEA9 .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .def tspan{fill:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .prov tspan{fill:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-1keRfnQhu4LYsEA9 .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
注册
ctx.web.search/fetch
WebRuntime (Service)
types.ts
web-search-deepseek

(DeepSeek 搜索)
web-fetch-http

(HTTP 抓取)
tool-web

(模型 Web 工具)

关键类/函数

名称 类型 职责
WebRuntime Service (class) Web 能力服务定义:search()fetch() 抽象方法
WebSearchResult interface 搜索结果:标题、URL、摘要
WebFetchResult interface 抓取结果:URL、内容、MIME 类型
DeepseekSearchProvider class DeepSeek 搜索后端实现
HttpFetchProvider class HTTP 抓取后端实现
tool-web tool 模型工具:web_searchweb_fetch

与其他模块的关系

  • llm :搜索/抓取结果作为 ContentBlock 注入 LLM 消息流。
  • agent :Agent 主循环调用 tool-web 执行 Web 操作。

6. 语言服务器能力(lsp)

路径packages/lsp/

核心作用 :定义 LSP(语言服务器协议)服务抽象------启动/停止语言服务器、诊断查询、符号定义/引用查找。为 tool-lsp 模型工具提供代码智能能力。

内部架构

#mermaid-svg-S3Flgy19UKPocAV9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-S3Flgy19UKPocAV9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-S3Flgy19UKPocAV9 .error-icon{fill:#552222;}#mermaid-svg-S3Flgy19UKPocAV9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-S3Flgy19UKPocAV9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-S3Flgy19UKPocAV9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-S3Flgy19UKPocAV9 .marker.cross{stroke:#333333;}#mermaid-svg-S3Flgy19UKPocAV9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-S3Flgy19UKPocAV9 p{margin:0;}#mermaid-svg-S3Flgy19UKPocAV9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-S3Flgy19UKPocAV9 .cluster-label text{fill:#333;}#mermaid-svg-S3Flgy19UKPocAV9 .cluster-label span{color:#333;}#mermaid-svg-S3Flgy19UKPocAV9 .cluster-label span p{background-color:transparent;}#mermaid-svg-S3Flgy19UKPocAV9 .label text,#mermaid-svg-S3Flgy19UKPocAV9 span{fill:#333;color:#333;}#mermaid-svg-S3Flgy19UKPocAV9 .node rect,#mermaid-svg-S3Flgy19UKPocAV9 .node circle,#mermaid-svg-S3Flgy19UKPocAV9 .node ellipse,#mermaid-svg-S3Flgy19UKPocAV9 .node polygon,#mermaid-svg-S3Flgy19UKPocAV9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-S3Flgy19UKPocAV9 .rough-node .label text,#mermaid-svg-S3Flgy19UKPocAV9 .node .label text,#mermaid-svg-S3Flgy19UKPocAV9 .image-shape .label,#mermaid-svg-S3Flgy19UKPocAV9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-S3Flgy19UKPocAV9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-S3Flgy19UKPocAV9 .rough-node .label,#mermaid-svg-S3Flgy19UKPocAV9 .node .label,#mermaid-svg-S3Flgy19UKPocAV9 .image-shape .label,#mermaid-svg-S3Flgy19UKPocAV9 .icon-shape .label{text-align:center;}#mermaid-svg-S3Flgy19UKPocAV9 .node.clickable{cursor:pointer;}#mermaid-svg-S3Flgy19UKPocAV9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-S3Flgy19UKPocAV9 .arrowheadPath{fill:#333333;}#mermaid-svg-S3Flgy19UKPocAV9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-S3Flgy19UKPocAV9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-S3Flgy19UKPocAV9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S3Flgy19UKPocAV9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-S3Flgy19UKPocAV9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S3Flgy19UKPocAV9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-S3Flgy19UKPocAV9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-S3Flgy19UKPocAV9 .cluster text{fill:#333;}#mermaid-svg-S3Flgy19UKPocAV9 .cluster span{color:#333;}#mermaid-svg-S3Flgy19UKPocAV9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-S3Flgy19UKPocAV9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-S3Flgy19UKPocAV9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-S3Flgy19UKPocAV9 .icon-shape,#mermaid-svg-S3Flgy19UKPocAV9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-S3Flgy19UKPocAV9 .icon-shape p,#mermaid-svg-S3Flgy19UKPocAV9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-S3Flgy19UKPocAV9 .icon-shape .label rect,#mermaid-svg-S3Flgy19UKPocAV9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-S3Flgy19UKPocAV9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-S3Flgy19UKPocAV9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-S3Flgy19UKPocAV9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-S3Flgy19UKPocAV9 .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .def tspan{fill:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .prov tspan{fill:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-S3Flgy19UKPocAV9 .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
ctx.lsp.*
LspService (Service)
types.ts
lsp-stdio

(stdio 传输 LSP)
tool-lsp

(模型 LSP 工具)

关键类/函数

名称 类型 职责
LspService Service (abstract) LSP 服务定义:start()stop()diagnostics()definitions()references()
LspStdioProvider class stdio 传输的 LSP 后端,通过子进程启动语言服务器
tool-lsp tool 模型工具:lsp_diagnosticslsp_definitionslsp_references

与其他模块的关系

  • subprocesslsp-stdio 通过 ctx.subprocess.spawn() 启动语言服务器进程。
  • fs :LSP 操作涉及文件路径通过 ctx.fs 解析。
  • agent :Agent 调用 tool-lsp 获取代码智能信息。

7. 持久终端能力(terminal)

路径packages/terminal/

核心作用:定义持久交互式终端会话抽象------创建、写入、调整大小、读取输出。与一次性 Shell 执行不同,终端会话保持状态(工作目录、环境变量、历史),适合交互式开发场景。

内部架构

#mermaid-svg-n9ZVs3okOsAJFqOj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-n9ZVs3okOsAJFqOj .error-icon{fill:#552222;}#mermaid-svg-n9ZVs3okOsAJFqOj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-n9ZVs3okOsAJFqOj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-n9ZVs3okOsAJFqOj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-n9ZVs3okOsAJFqOj .marker.cross{stroke:#333333;}#mermaid-svg-n9ZVs3okOsAJFqOj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-n9ZVs3okOsAJFqOj p{margin:0;}#mermaid-svg-n9ZVs3okOsAJFqOj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster-label text{fill:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster-label span{color:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster-label span p{background-color:transparent;}#mermaid-svg-n9ZVs3okOsAJFqOj .label text,#mermaid-svg-n9ZVs3okOsAJFqOj span{fill:#333;color:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj .node rect,#mermaid-svg-n9ZVs3okOsAJFqOj .node circle,#mermaid-svg-n9ZVs3okOsAJFqOj .node ellipse,#mermaid-svg-n9ZVs3okOsAJFqOj .node polygon,#mermaid-svg-n9ZVs3okOsAJFqOj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-n9ZVs3okOsAJFqOj .rough-node .label text,#mermaid-svg-n9ZVs3okOsAJFqOj .node .label text,#mermaid-svg-n9ZVs3okOsAJFqOj .image-shape .label,#mermaid-svg-n9ZVs3okOsAJFqOj .icon-shape .label{text-anchor:middle;}#mermaid-svg-n9ZVs3okOsAJFqOj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-n9ZVs3okOsAJFqOj .rough-node .label,#mermaid-svg-n9ZVs3okOsAJFqOj .node .label,#mermaid-svg-n9ZVs3okOsAJFqOj .image-shape .label,#mermaid-svg-n9ZVs3okOsAJFqOj .icon-shape .label{text-align:center;}#mermaid-svg-n9ZVs3okOsAJFqOj .node.clickable{cursor:pointer;}#mermaid-svg-n9ZVs3okOsAJFqOj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-n9ZVs3okOsAJFqOj .arrowheadPath{fill:#333333;}#mermaid-svg-n9ZVs3okOsAJFqOj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-n9ZVs3okOsAJFqOj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-n9ZVs3okOsAJFqOj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n9ZVs3okOsAJFqOj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-n9ZVs3okOsAJFqOj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n9ZVs3okOsAJFqOj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster text{fill:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj .cluster span{color:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-n9ZVs3okOsAJFqOj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-n9ZVs3okOsAJFqOj rect.text{fill:none;stroke-width:0;}#mermaid-svg-n9ZVs3okOsAJFqOj .icon-shape,#mermaid-svg-n9ZVs3okOsAJFqOj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-n9ZVs3okOsAJFqOj .icon-shape p,#mermaid-svg-n9ZVs3okOsAJFqOj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-n9ZVs3okOsAJFqOj .icon-shape .label rect,#mermaid-svg-n9ZVs3okOsAJFqOj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-n9ZVs3okOsAJFqOj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-n9ZVs3okOsAJFqOj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-n9ZVs3okOsAJFqOj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-n9ZVs3okOsAJFqOj .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .def tspan{fill:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .prov tspan{fill:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-n9ZVs3okOsAJFqOj .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
ctx.terminals.*
TerminalSessionService (Service)
types.ts
terminal-bash

(Bash 终端后端)
tool-terminal

(模型终端工具)

关键类/函数

名称 类型 职责
TerminalSessionService Service (abstract) 终端服务定义:create()write()resize()kill()、输出流
TerminalSession interface 终端会话句柄:输入/输出流、尺寸、退出码
TerminalBashBackend class Bash 终端后端,通过 PTY 创建交互式会话
tool-terminal tool 模型工具:terminal_createterminal_writeterminal_resizeterminal_kill

与其他模块的关系

  • subprocessterminal-bash 通过 ctx.subprocess.spawnTerminal() 创建 PTY。
  • shell :终端后端复用 Shell 环境配置(shell-env)。
  • fs :终端会话的 cwd 通过 ctx.fs 验证。

8. 代码运行时能力(code-runtime)

路径packages/code-runtime/

核心作用:定义代码执行运行时抽象------在隔离的 Worker Thread 中执行 JavaScript 代码,支持超时和取消。为模型提供安全的代码执行能力。

内部架构

#mermaid-svg-2OJuCQJlzSnO3P83{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-2OJuCQJlzSnO3P83 .error-icon{fill:#552222;}#mermaid-svg-2OJuCQJlzSnO3P83 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-2OJuCQJlzSnO3P83 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-2OJuCQJlzSnO3P83 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-2OJuCQJlzSnO3P83 .marker.cross{stroke:#333333;}#mermaid-svg-2OJuCQJlzSnO3P83 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-2OJuCQJlzSnO3P83 p{margin:0;}#mermaid-svg-2OJuCQJlzSnO3P83 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster-label text{fill:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster-label span{color:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster-label span p{background-color:transparent;}#mermaid-svg-2OJuCQJlzSnO3P83 .label text,#mermaid-svg-2OJuCQJlzSnO3P83 span{fill:#333;color:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 .node rect,#mermaid-svg-2OJuCQJlzSnO3P83 .node circle,#mermaid-svg-2OJuCQJlzSnO3P83 .node ellipse,#mermaid-svg-2OJuCQJlzSnO3P83 .node polygon,#mermaid-svg-2OJuCQJlzSnO3P83 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-2OJuCQJlzSnO3P83 .rough-node .label text,#mermaid-svg-2OJuCQJlzSnO3P83 .node .label text,#mermaid-svg-2OJuCQJlzSnO3P83 .image-shape .label,#mermaid-svg-2OJuCQJlzSnO3P83 .icon-shape .label{text-anchor:middle;}#mermaid-svg-2OJuCQJlzSnO3P83 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-2OJuCQJlzSnO3P83 .rough-node .label,#mermaid-svg-2OJuCQJlzSnO3P83 .node .label,#mermaid-svg-2OJuCQJlzSnO3P83 .image-shape .label,#mermaid-svg-2OJuCQJlzSnO3P83 .icon-shape .label{text-align:center;}#mermaid-svg-2OJuCQJlzSnO3P83 .node.clickable{cursor:pointer;}#mermaid-svg-2OJuCQJlzSnO3P83 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-2OJuCQJlzSnO3P83 .arrowheadPath{fill:#333333;}#mermaid-svg-2OJuCQJlzSnO3P83 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-2OJuCQJlzSnO3P83 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-2OJuCQJlzSnO3P83 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2OJuCQJlzSnO3P83 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-2OJuCQJlzSnO3P83 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2OJuCQJlzSnO3P83 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster text{fill:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 .cluster span{color:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-2OJuCQJlzSnO3P83 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-2OJuCQJlzSnO3P83 rect.text{fill:none;stroke-width:0;}#mermaid-svg-2OJuCQJlzSnO3P83 .icon-shape,#mermaid-svg-2OJuCQJlzSnO3P83 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-2OJuCQJlzSnO3P83 .icon-shape p,#mermaid-svg-2OJuCQJlzSnO3P83 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-2OJuCQJlzSnO3P83 .icon-shape .label rect,#mermaid-svg-2OJuCQJlzSnO3P83 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-2OJuCQJlzSnO3P83 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-2OJuCQJlzSnO3P83 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-2OJuCQJlzSnO3P83 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-2OJuCQJlzSnO3P83 .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .def tspan{fill:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .prov tspan{fill:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-2OJuCQJlzSnO3P83 .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
ctx.codeRuntime.*
CodeRuntime (Service)
types.ts
code-runtime-worker-thread

(Worker Thread 执行器)
tool-code (隐含)

(模型代码执行工具)

关键类/函数

名称 类型 职责
CodeRuntime Service (abstract) 代码运行时服务定义:execute() 抽象方法
CodeExecutionContext interface 执行上下文:代码字符串、超时、信号
CodeExecutionResult interface 执行结果:输出值、stdout、stderr、异常
WorkerThreadCodeRuntime class Worker Thread 实现,在隔离线程中执行 JS 代码
index.ts (worker-thread) module Worker 端入口:vm 沙箱、超时控制、结果序列化

与其他模块的关系

  • subprocess:Worker Thread 的生命周期管理通过子进程能力。
  • llm :代码执行结果作为 ContentBlock 注入 LLM 上下文。
  • workflow:工作流引擎的脚本执行机制与代码运行时共享 vm 沙箱理念。

9. 沙箱能力(sandbox)

路径packages/sandbox/

核心作用 :定义沙箱提供商抽象------为 Shell、FS、子进程等能力提供隔离执行环境。sandbox-local 提供本地命名空间隔离,sandbox-policy 定义安全策略。

内部架构

#mermaid-svg-C6eHR8EJmzY3U0Eg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-C6eHR8EJmzY3U0Eg .error-icon{fill:#552222;}#mermaid-svg-C6eHR8EJmzY3U0Eg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-C6eHR8EJmzY3U0Eg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .marker.cross{stroke:#333333;}#mermaid-svg-C6eHR8EJmzY3U0Eg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-C6eHR8EJmzY3U0Eg p{margin:0;}#mermaid-svg-C6eHR8EJmzY3U0Eg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster-label text{fill:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster-label span{color:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster-label span p{background-color:transparent;}#mermaid-svg-C6eHR8EJmzY3U0Eg .label text,#mermaid-svg-C6eHR8EJmzY3U0Eg span{fill:#333;color:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .node rect,#mermaid-svg-C6eHR8EJmzY3U0Eg .node circle,#mermaid-svg-C6eHR8EJmzY3U0Eg .node ellipse,#mermaid-svg-C6eHR8EJmzY3U0Eg .node polygon,#mermaid-svg-C6eHR8EJmzY3U0Eg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .rough-node .label text,#mermaid-svg-C6eHR8EJmzY3U0Eg .node .label text,#mermaid-svg-C6eHR8EJmzY3U0Eg .image-shape .label,#mermaid-svg-C6eHR8EJmzY3U0Eg .icon-shape .label{text-anchor:middle;}#mermaid-svg-C6eHR8EJmzY3U0Eg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .rough-node .label,#mermaid-svg-C6eHR8EJmzY3U0Eg .node .label,#mermaid-svg-C6eHR8EJmzY3U0Eg .image-shape .label,#mermaid-svg-C6eHR8EJmzY3U0Eg .icon-shape .label{text-align:center;}#mermaid-svg-C6eHR8EJmzY3U0Eg .node.clickable{cursor:pointer;}#mermaid-svg-C6eHR8EJmzY3U0Eg .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .arrowheadPath{fill:#333333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-C6eHR8EJmzY3U0Eg .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-C6eHR8EJmzY3U0Eg .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-C6eHR8EJmzY3U0Eg .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster text{fill:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cluster span{color:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-C6eHR8EJmzY3U0Eg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-C6eHR8EJmzY3U0Eg rect.text{fill:none;stroke-width:0;}#mermaid-svg-C6eHR8EJmzY3U0Eg .icon-shape,#mermaid-svg-C6eHR8EJmzY3U0Eg .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-C6eHR8EJmzY3U0Eg .icon-shape p,#mermaid-svg-C6eHR8EJmzY3U0Eg .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-C6eHR8EJmzY3U0Eg .icon-shape .label rect,#mermaid-svg-C6eHR8EJmzY3U0Eg .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-C6eHR8EJmzY3U0Eg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-C6eHR8EJmzY3U0Eg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-C6eHR8EJmzY3U0Eg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-C6eHR8EJmzY3U0Eg .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .def tspan{fill:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .prov tspan{fill:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-C6eHR8EJmzY3U0Eg .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
策略注入
ctx.sandbox.*
ctx.sandbox.*
SandboxProvider (abstract)
sandbox/src/index.ts
sandbox-local

(本地沙箱)
sandbox-policy

(安全策略)
bash-sandbox Provider
fs-sandbox Provider

关键类/函数

名称 类型 职责
SandboxProvider abstract class 沙箱服务定义:创建隔离环境、路径映射、资源限制
SandboxLocalProvider class 本地沙箱实现:命名空间隔离、路径重映射
SandboxPolicy module 安全策略定义:允许/拒绝的路径、命令、网络访问
SandboxConfig interface 沙箱配置:根目录、挂载点、权限

与其他模块的关系

  • shellbash-sandbox / pwsh-sandbox 依赖沙箱进行隔离执行。
  • fsfs-sandbox 依赖沙箱进行路径隔离。
  • subprocess:沙箱内的子进程操作受限。

10. 技能注册能力(skill)

路径packages/skill/

核心作用 :定义技能提供商注册表和技能发现/加载机制。技能是可复用的指令模板,从项目、用户、自定义和内置目录发现,按 rank 优先级合并。tool-skill 将技能目录暴露给模型,模型可按名称加载技能内容。

内部架构

#mermaid-svg-BUpIHWz0U3AT1NzV{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-BUpIHWz0U3AT1NzV .error-icon{fill:#552222;}#mermaid-svg-BUpIHWz0U3AT1NzV .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BUpIHWz0U3AT1NzV .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BUpIHWz0U3AT1NzV .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BUpIHWz0U3AT1NzV .marker.cross{stroke:#333333;}#mermaid-svg-BUpIHWz0U3AT1NzV svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BUpIHWz0U3AT1NzV p{margin:0;}#mermaid-svg-BUpIHWz0U3AT1NzV .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster-label text{fill:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster-label span{color:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster-label span p{background-color:transparent;}#mermaid-svg-BUpIHWz0U3AT1NzV .label text,#mermaid-svg-BUpIHWz0U3AT1NzV span{fill:#333;color:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV .node rect,#mermaid-svg-BUpIHWz0U3AT1NzV .node circle,#mermaid-svg-BUpIHWz0U3AT1NzV .node ellipse,#mermaid-svg-BUpIHWz0U3AT1NzV .node polygon,#mermaid-svg-BUpIHWz0U3AT1NzV .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-BUpIHWz0U3AT1NzV .rough-node .label text,#mermaid-svg-BUpIHWz0U3AT1NzV .node .label text,#mermaid-svg-BUpIHWz0U3AT1NzV .image-shape .label,#mermaid-svg-BUpIHWz0U3AT1NzV .icon-shape .label{text-anchor:middle;}#mermaid-svg-BUpIHWz0U3AT1NzV .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-BUpIHWz0U3AT1NzV .rough-node .label,#mermaid-svg-BUpIHWz0U3AT1NzV .node .label,#mermaid-svg-BUpIHWz0U3AT1NzV .image-shape .label,#mermaid-svg-BUpIHWz0U3AT1NzV .icon-shape .label{text-align:center;}#mermaid-svg-BUpIHWz0U3AT1NzV .node.clickable{cursor:pointer;}#mermaid-svg-BUpIHWz0U3AT1NzV .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-BUpIHWz0U3AT1NzV .arrowheadPath{fill:#333333;}#mermaid-svg-BUpIHWz0U3AT1NzV .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-BUpIHWz0U3AT1NzV .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-BUpIHWz0U3AT1NzV .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BUpIHWz0U3AT1NzV .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-BUpIHWz0U3AT1NzV .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BUpIHWz0U3AT1NzV .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster text{fill:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV .cluster span{color:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BUpIHWz0U3AT1NzV .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-BUpIHWz0U3AT1NzV rect.text{fill:none;stroke-width:0;}#mermaid-svg-BUpIHWz0U3AT1NzV .icon-shape,#mermaid-svg-BUpIHWz0U3AT1NzV .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-BUpIHWz0U3AT1NzV .icon-shape p,#mermaid-svg-BUpIHWz0U3AT1NzV .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-BUpIHWz0U3AT1NzV .icon-shape .label rect,#mermaid-svg-BUpIHWz0U3AT1NzV .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-BUpIHWz0U3AT1NzV .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-BUpIHWz0U3AT1NzV .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-BUpIHWz0U3AT1NzV :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-BUpIHWz0U3AT1NzV .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .def tspan{fill:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .prov tspan{fill:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-BUpIHWz0U3AT1NzV .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
registerProvider
registerProvider
ctx.skills.list/get
ctx.skills (Service)
SkillSummary / SkillDefinition
invariant.ts
skill-filesystem

(文件系统技能发现)
skill-badge

(内置 dsh-badge 技能)
tool-skill

(模型技能加载工具)

关键类/函数

名称 类型 职责
SkillService Service (class) 技能注册表:registerProvider()list()get(),按 rank 合并多提供商目录
SkillSummary interface 技能摘要:name、description、whenToUse、invocation 策略、source、provider
SkillDefinition interface 完整技能定义:包含 content(Markdown 指令体)和 metadata
SkillCandidate interface 提供商目录条目:SkillSummary + rank + locator
SkillProvider interface 提供商接口:list() 返回候选列表,get() 加载完整技能
SkillInvocationPolicy interface 调用策略:modelInvocable(模型可见)、userInvocable(用户命令可见)
isSkillName() function kebab-case 技能名验证
isModelInvocable() / isUserInvocable() function 调用策略判定
FileSystemSkillProvider class 文件系统技能发现:扫描 project/user/custom/bundled 根目录,解析 YAML frontmatter
SkillWatchManager class 技能文件监听管理器:Chokidar 监听 + 稳定性检查 + 失效通知
skill-badge provider 内置 dsh-badge 技能提供商
tool-skill tool 模型工具:发布技能目录 <available_skills>,按名称加载技能内容
SkillCatalogSource interface 持久化技能目录源,记录会话中发布的技能条目
renderSkillContent() function 渲染技能内容供模型消费
BUNDLED_SKILL_RANK constant 内置技能优先级常量 (600)

与其他模块的关系

  • fsskill-filesystem 通过 ctx.fs 读取技能文件(当 FS 服务存在时),否则直接使用 Node.js fs
  • llm :技能内容通过 createUserMessage() 注入 LLM 消息流;assertNever 从 llm 模块导入。
  • scope:技能支持作用域分层(project-dsh、project-agents、user-dsh、user-agents、custom、bundled)。
  • agent :Agent 启动时 tool-skill 发布技能目录,模型按需加载。
  • home-paths :技能根目录解析依赖 resolveDshHome()DSH_AGENTS_HOME

11. 子代理能力(subagent)

路径packages/subagent/

核心作用 :定义子代理委派抽象------命名提供商注册表 + 能力验证的异步启动 API。支持多种后端:spawn(新鲜子进程)、fork(继承父上下文)、acp(外部代理通信协议)、claude-code、codex、dsh-sdk。模型通过 tool-subagent 委派任务给子代理。

内部架构

#mermaid-svg-RrPhNzjt7Hh3XP7Q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .error-icon{fill:#552222;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .marker.cross{stroke:#333333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q p{margin:0;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster-label text{fill:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster-label span{color:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster-label span p{background-color:transparent;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .label text,#mermaid-svg-RrPhNzjt7Hh3XP7Q span{fill:#333;color:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .node rect,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node circle,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node ellipse,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node polygon,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .rough-node .label text,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node .label text,#mermaid-svg-RrPhNzjt7Hh3XP7Q .image-shape .label,#mermaid-svg-RrPhNzjt7Hh3XP7Q .icon-shape .label{text-anchor:middle;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .rough-node .label,#mermaid-svg-RrPhNzjt7Hh3XP7Q .node .label,#mermaid-svg-RrPhNzjt7Hh3XP7Q .image-shape .label,#mermaid-svg-RrPhNzjt7Hh3XP7Q .icon-shape .label{text-align:center;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .node.clickable{cursor:pointer;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .arrowheadPath{fill:#333333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-RrPhNzjt7Hh3XP7Q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RrPhNzjt7Hh3XP7Q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster text{fill:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cluster span{color:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-RrPhNzjt7Hh3XP7Q rect.text{fill:none;stroke-width:0;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .icon-shape,#mermaid-svg-RrPhNzjt7Hh3XP7Q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .icon-shape p,#mermaid-svg-RrPhNzjt7Hh3XP7Q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .icon-shape .label rect,#mermaid-svg-RrPhNzjt7Hh3XP7Q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-RrPhNzjt7Hh3XP7Q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-RrPhNzjt7Hh3XP7Q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .def tspan{fill:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .prov tspan{fill:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-RrPhNzjt7Hh3XP7Q .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
registerProvider
registerProvider
registerProvider
registerProvider
registerProvider
registerProvider
ctx.subagents.start
ctx.subagents
ctx.subagents
SubagentRuntime (Service)
types.ts
continuation.ts
lifecycle.ts
depth.ts
descriptor.ts
subagent-spawn-in-process

(新鲜子进程)
subagent-fork-in-process

(继承上下文子进程)
subagent-acp

(ACP 协议)
subagent-claude-code
subagent-codex
subagent-dsh-sdk
tool-subagent

(模型委派工具)
tool-subagent-control

(子代理控制)
tool-subagent-report

(子代理报告)

关键类/函数

名称 类型 职责
SubagentRuntime Service (class) 子代理运行时:registerProvider()start()startContinuable()followup(),命名提供商注册表
SubagentProvider interface 提供商接口:namecapabilitiesinheritsParentContextstart()prepareContinuable?()
SubagentCapabilities interface 能力声明:outputSchemadepthLimittoolFilterpersona
SubagentStartRequest interface 启动请求:prompt、parent、signal、agentOptions、outputSchema、maxDepth、toolFilter、persona
SubagentRun interface 一次性运行句柄:idlocalAgentresultdispose()
SubagentResult interface 运行结果:output(ContentBlock\[\])、structured?stopReason
SubagentStopReason type 停止原因:completed、aborted、error、max-tokens、refusal
SubagentContinuationManager class 可继续子代理管理器:身份预留、组合、提示投递、冷恢复
assertSubagentMaxDepth() function 递归深度断言
settleRun() function 运行结算:将 SubagentRun.result 映射到 SubagentResult
snapshotSubagentDescriptor() function 子代理描述符快照
SpawnInProcessProvider class spawn 后端:新鲜子 Agent,不继承父上下文
ForkInProcessProvider class fork 后端:子 Agent 继承父已完成轮次的前缀
tool-subagent tool 模型委派工具:provider 配置选择后端,backgroundMode 选择 one-shot/continuable

与其他模块的关系

  • agent:子代理是子 Agent 实例,复用 Agent 工厂和主循环。
  • llm:子代理通过 Agent 间接使用 LLM 运行时。
  • session :子代理有自己的 Session,记录 parentSession 关系。
  • workflow :工作流的 agent() 调用通过 ctx.subagents.start() 委派。
  • tools (dsh-tools):子代理的工具过滤通过 tools.restrict() 实现。
  • system-prompt :子代理的 persona 通过 systemPrompt 覆盖部署默认值。
  • scope:子代理的作用域链继承父代理。

12. 工作流能力(workflow)

路径packages/workflow/

核心作用 :定义工作流引擎抽象------执行模型编写的 JavaScript 编排脚本,脚本中可调用 agent() 扇出子代理、使用 parallel()/pipeline() 组合器。Worker Thread 引擎在隔离线程中执行脚本,防止同步脚本阻塞宿主。

内部架构

#mermaid-svg-fZuteJYNlV4GJfXm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fZuteJYNlV4GJfXm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fZuteJYNlV4GJfXm .error-icon{fill:#552222;}#mermaid-svg-fZuteJYNlV4GJfXm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fZuteJYNlV4GJfXm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fZuteJYNlV4GJfXm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fZuteJYNlV4GJfXm .marker.cross{stroke:#333333;}#mermaid-svg-fZuteJYNlV4GJfXm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fZuteJYNlV4GJfXm p{margin:0;}#mermaid-svg-fZuteJYNlV4GJfXm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fZuteJYNlV4GJfXm .cluster-label text{fill:#333;}#mermaid-svg-fZuteJYNlV4GJfXm .cluster-label span{color:#333;}#mermaid-svg-fZuteJYNlV4GJfXm .cluster-label span p{background-color:transparent;}#mermaid-svg-fZuteJYNlV4GJfXm .label text,#mermaid-svg-fZuteJYNlV4GJfXm span{fill:#333;color:#333;}#mermaid-svg-fZuteJYNlV4GJfXm .node rect,#mermaid-svg-fZuteJYNlV4GJfXm .node circle,#mermaid-svg-fZuteJYNlV4GJfXm .node ellipse,#mermaid-svg-fZuteJYNlV4GJfXm .node polygon,#mermaid-svg-fZuteJYNlV4GJfXm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fZuteJYNlV4GJfXm .rough-node .label text,#mermaid-svg-fZuteJYNlV4GJfXm .node .label text,#mermaid-svg-fZuteJYNlV4GJfXm .image-shape .label,#mermaid-svg-fZuteJYNlV4GJfXm .icon-shape .label{text-anchor:middle;}#mermaid-svg-fZuteJYNlV4GJfXm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fZuteJYNlV4GJfXm .rough-node .label,#mermaid-svg-fZuteJYNlV4GJfXm .node .label,#mermaid-svg-fZuteJYNlV4GJfXm .image-shape .label,#mermaid-svg-fZuteJYNlV4GJfXm .icon-shape .label{text-align:center;}#mermaid-svg-fZuteJYNlV4GJfXm .node.clickable{cursor:pointer;}#mermaid-svg-fZuteJYNlV4GJfXm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fZuteJYNlV4GJfXm .arrowheadPath{fill:#333333;}#mermaid-svg-fZuteJYNlV4GJfXm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fZuteJYNlV4GJfXm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fZuteJYNlV4GJfXm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fZuteJYNlV4GJfXm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fZuteJYNlV4GJfXm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fZuteJYNlV4GJfXm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fZuteJYNlV4GJfXm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fZuteJYNlV4GJfXm .cluster text{fill:#333;}#mermaid-svg-fZuteJYNlV4GJfXm .cluster span{color:#333;}#mermaid-svg-fZuteJYNlV4GJfXm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fZuteJYNlV4GJfXm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fZuteJYNlV4GJfXm rect.text{fill:none;stroke-width:0;}#mermaid-svg-fZuteJYNlV4GJfXm .icon-shape,#mermaid-svg-fZuteJYNlV4GJfXm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fZuteJYNlV4GJfXm .icon-shape p,#mermaid-svg-fZuteJYNlV4GJfXm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fZuteJYNlV4GJfXm .icon-shape .label rect,#mermaid-svg-fZuteJYNlV4GJfXm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fZuteJYNlV4GJfXm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fZuteJYNlV4GJfXm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fZuteJYNlV4GJfXm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-fZuteJYNlV4GJfXm .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .def tspan{fill:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .prov tspan{fill:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-fZuteJYNlV4GJfXm .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
ctx.workflowEngine.start
ctx.workflowEngine.start
WorkflowEngine (Service)
types.ts / runtime-types.ts
invariant.ts
workflow-worker-thread

(Worker Thread 引擎)
tool-workflow

(模型工作流工具)
tool-ralph

(Ralph 工作流工具)

关键类/函数

名称 类型 职责
WorkflowEngine Service (abstract) 工作流引擎服务定义:start() 抽象方法,emitWorkflowEvent() 事件分发
WorkflowStartRequest interface 启动请求:script、meta、args、subagentProvider、maxTotalAgents、parent、signal
WorkflowRun interface 运行句柄:idmetaresultcancel()dispose()
WorkflowResult interface 运行结果:valuestopReasonerror?agentsStarted
WorkflowMeta interface 脚本身份块:name、description、whenToUse、phases
WorkflowStopReason type 停止原因:completed、cancelled、error
WorkflowError class 工作流错误:携带 code(SCRIPT_PARSE、META_INVALID 等)和 fatal 标志
WorkflowErrorCode type 错误码闭联集
WorkflowEventName type 事件名:workflow/start、phase、log、agent-start、agent-end、end
WorkerThreadWorkflowEngine class Worker Thread 引擎实现:vm 沙箱、子代理桥接、超时控制
WorkerRun (host.ts) class Worker 运行管理:消息协议、子代理调度、取消与处置
validateMeta() function meta 块验证
assertBodyParses() function 脚本体解析检查(同步抛出 SCRIPT_PARSE)
tool-workflow tool 模型工具:执行编排脚本,返回脚本最终值
tool-ralph tool Ralph 工作流工具变体

与其他模块的关系

  • subagent :工作流的 agent() 调用通过 ctx.subagents.start() 委派给子代理提供商。
  • llmWorkflowError 继承 HarnessError(来自 llm 模块)。
  • session:工作流事件投影到父会话。
  • agentWorkflowStartRequest.parent 是发起工作流的 Agent。
  • code-runtime:Worker Thread 执行机制与代码运行时共享隔离理念。

13. 上下文压缩能力(compaction)

路径packages/compaction/

核心作用 :定义上下文压缩服务抽象------当对话历史超过阈值时,将一段历史替换为 LLM 生成的摘要节点。支持自动压力触发和手动触发,compaction-basic 是默认后端,compaction-tool-result-pruner 提供工具结果裁剪。

内部架构

#mermaid-svg-LJtStXW3gttoyfcz{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LJtStXW3gttoyfcz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LJtStXW3gttoyfcz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LJtStXW3gttoyfcz .error-icon{fill:#552222;}#mermaid-svg-LJtStXW3gttoyfcz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LJtStXW3gttoyfcz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LJtStXW3gttoyfcz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LJtStXW3gttoyfcz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LJtStXW3gttoyfcz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LJtStXW3gttoyfcz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LJtStXW3gttoyfcz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LJtStXW3gttoyfcz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LJtStXW3gttoyfcz .marker.cross{stroke:#333333;}#mermaid-svg-LJtStXW3gttoyfcz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LJtStXW3gttoyfcz p{margin:0;}#mermaid-svg-LJtStXW3gttoyfcz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LJtStXW3gttoyfcz .cluster-label text{fill:#333;}#mermaid-svg-LJtStXW3gttoyfcz .cluster-label span{color:#333;}#mermaid-svg-LJtStXW3gttoyfcz .cluster-label span p{background-color:transparent;}#mermaid-svg-LJtStXW3gttoyfcz .label text,#mermaid-svg-LJtStXW3gttoyfcz span{fill:#333;color:#333;}#mermaid-svg-LJtStXW3gttoyfcz .node rect,#mermaid-svg-LJtStXW3gttoyfcz .node circle,#mermaid-svg-LJtStXW3gttoyfcz .node ellipse,#mermaid-svg-LJtStXW3gttoyfcz .node polygon,#mermaid-svg-LJtStXW3gttoyfcz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LJtStXW3gttoyfcz .rough-node .label text,#mermaid-svg-LJtStXW3gttoyfcz .node .label text,#mermaid-svg-LJtStXW3gttoyfcz .image-shape .label,#mermaid-svg-LJtStXW3gttoyfcz .icon-shape .label{text-anchor:middle;}#mermaid-svg-LJtStXW3gttoyfcz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LJtStXW3gttoyfcz .rough-node .label,#mermaid-svg-LJtStXW3gttoyfcz .node .label,#mermaid-svg-LJtStXW3gttoyfcz .image-shape .label,#mermaid-svg-LJtStXW3gttoyfcz .icon-shape .label{text-align:center;}#mermaid-svg-LJtStXW3gttoyfcz .node.clickable{cursor:pointer;}#mermaid-svg-LJtStXW3gttoyfcz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LJtStXW3gttoyfcz .arrowheadPath{fill:#333333;}#mermaid-svg-LJtStXW3gttoyfcz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LJtStXW3gttoyfcz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LJtStXW3gttoyfcz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LJtStXW3gttoyfcz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LJtStXW3gttoyfcz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LJtStXW3gttoyfcz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LJtStXW3gttoyfcz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LJtStXW3gttoyfcz .cluster text{fill:#333;}#mermaid-svg-LJtStXW3gttoyfcz .cluster span{color:#333;}#mermaid-svg-LJtStXW3gttoyfcz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LJtStXW3gttoyfcz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LJtStXW3gttoyfcz rect.text{fill:none;stroke-width:0;}#mermaid-svg-LJtStXW3gttoyfcz .icon-shape,#mermaid-svg-LJtStXW3gttoyfcz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LJtStXW3gttoyfcz .icon-shape p,#mermaid-svg-LJtStXW3gttoyfcz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LJtStXW3gttoyfcz .icon-shape .label rect,#mermaid-svg-LJtStXW3gttoyfcz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LJtStXW3gttoyfcz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LJtStXW3gttoyfcz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LJtStXW3gttoyfcz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-LJtStXW3gttoyfcz .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .def tspan{fill:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .prov tspan{fill:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-LJtStXW3gttoyfcz .cons tspan{fill:#fff!important;} Consumer
Service Provider
Service Definition
注册
可选注册
ctx.compaction.compactNow
ctx.compaction.compactIfNeeded
CompactionEngine (abstract Service)
types.ts
brand.ts (CompactionId)
checkpoint.ts
tool-pairing.ts
compaction-basic

(基础压缩后端)
compaction-tool-result-pruner

(工具结果裁剪)
command-compact

(手动压缩命令)
Agent 主循环

(自动压力触发)
ctx

关键类/函数

名称 类型 职责
CompactionEngine abstract Service 压缩服务定义:compactIfNeeded()compactNow()compactRegion() 抽象方法
CompactionResult interface 压缩结果:compactionId、startSeq/summarySeq/endSeq、summary、shadowedRange、shadowedSeqs、shadowedTokenCount
CompactionTrigger type 触发原因:pressure(压力)、context-overflow(上下文溢出)
ManualCompactionError class 手动压缩错误:busy、cancelled、changed、summary、commit、persistence
CompactionId brand type 压缩事务唯一标识
compactCheckpointSource() function 压缩检查点源构造器
toolPairingBalancedBefore/After() function 工具配对平衡检查(压缩前后)
BasicCompactionEngine class 基础压缩后端:token 计量、区域选择、LLM 摘要、重试
compaction-basic/summarizer.ts module LLM 摘要器:复用会话前缀(系统提示+工具+消息)保持 KV 缓存
compaction-basic/region.ts module 区域选择:选择可压缩的历史范围
compaction-basic/config.ts module 配置解析:thresholdRatio、retainRatio、retainTokens、modelPolicies
compaction-tool-result-pruner provider 工具结果裁剪后端:在摘要前先裁剪过大的工具结果
command-compact command 手动压缩命令

与其他模块的关系

  • llmcompaction-basic 通过 ctx.llm.stream() 生成摘要;HarnessErrorassertNeverCONTEXT_WINDOW_EXCEEDED_CODE 来自 llm 模块。
  • session :压缩操作修改会话 surface(替换历史范围),发出 compaction/startcompaction/summarycompaction/endcompaction/prune 事件。
  • token-metercompaction-basic 依赖 ctx.tokenMeter 进行 token 计量。
  • agent :自动压缩在 agent/pre-step 事件中触发;上下文溢出在 agent/request-error 中恢复。
  • commands :手动压缩命令通过 CommandId 关联。
  • sessions :手动压缩后通过 ctx.sessions.flush() 持久化。

14. E2B 沙箱能力(e2b)

路径packages/e2b/

核心作用 :共享 E2B 沙箱拥有者------创建一个 E2B SDK 句柄,文件系统和子进程操作共享同一个远程 Linux 世界。e2b 是服务定义+提供者合一的运行时,fs-e2bsubprocess-e2b 是适配器。

内部架构

#mermaid-svg-KvXDlCjJqsr9yP5q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KvXDlCjJqsr9yP5q .error-icon{fill:#552222;}#mermaid-svg-KvXDlCjJqsr9yP5q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KvXDlCjJqsr9yP5q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KvXDlCjJqsr9yP5q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KvXDlCjJqsr9yP5q .marker.cross{stroke:#333333;}#mermaid-svg-KvXDlCjJqsr9yP5q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KvXDlCjJqsr9yP5q p{margin:0;}#mermaid-svg-KvXDlCjJqsr9yP5q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster-label text{fill:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster-label span{color:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster-label span p{background-color:transparent;}#mermaid-svg-KvXDlCjJqsr9yP5q .label text,#mermaid-svg-KvXDlCjJqsr9yP5q span{fill:#333;color:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q .node rect,#mermaid-svg-KvXDlCjJqsr9yP5q .node circle,#mermaid-svg-KvXDlCjJqsr9yP5q .node ellipse,#mermaid-svg-KvXDlCjJqsr9yP5q .node polygon,#mermaid-svg-KvXDlCjJqsr9yP5q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KvXDlCjJqsr9yP5q .rough-node .label text,#mermaid-svg-KvXDlCjJqsr9yP5q .node .label text,#mermaid-svg-KvXDlCjJqsr9yP5q .image-shape .label,#mermaid-svg-KvXDlCjJqsr9yP5q .icon-shape .label{text-anchor:middle;}#mermaid-svg-KvXDlCjJqsr9yP5q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KvXDlCjJqsr9yP5q .rough-node .label,#mermaid-svg-KvXDlCjJqsr9yP5q .node .label,#mermaid-svg-KvXDlCjJqsr9yP5q .image-shape .label,#mermaid-svg-KvXDlCjJqsr9yP5q .icon-shape .label{text-align:center;}#mermaid-svg-KvXDlCjJqsr9yP5q .node.clickable{cursor:pointer;}#mermaid-svg-KvXDlCjJqsr9yP5q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KvXDlCjJqsr9yP5q .arrowheadPath{fill:#333333;}#mermaid-svg-KvXDlCjJqsr9yP5q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KvXDlCjJqsr9yP5q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KvXDlCjJqsr9yP5q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KvXDlCjJqsr9yP5q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KvXDlCjJqsr9yP5q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KvXDlCjJqsr9yP5q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster text{fill:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q .cluster span{color:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KvXDlCjJqsr9yP5q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KvXDlCjJqsr9yP5q rect.text{fill:none;stroke-width:0;}#mermaid-svg-KvXDlCjJqsr9yP5q .icon-shape,#mermaid-svg-KvXDlCjJqsr9yP5q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KvXDlCjJqsr9yP5q .icon-shape p,#mermaid-svg-KvXDlCjJqsr9yP5q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KvXDlCjJqsr9yP5q .icon-shape .label rect,#mermaid-svg-KvXDlCjJqsr9yP5q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KvXDlCjJqsr9yP5q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KvXDlCjJqsr9yP5q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KvXDlCjJqsr9yP5q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-KvXDlCjJqsr9yP5q .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .def tspan{fill:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .prov tspan{fill:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .cons tspan{fill:#fff!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .ifc>*{fill:#f8f9fa!important;stroke:#6c757d!important;color:#212529!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .ifc span{fill:#f8f9fa!important;stroke:#6c757d!important;color:#212529!important;}#mermaid-svg-KvXDlCjJqsr9yP5q .ifc tspan{fill:#212529!important;} Consumer
Adapters (Provider for other seams)
Service Definition + Provider
getSandbox()
getSandbox()
注册到 ctx.fs
注册到 ctx.subprocess
ctx.fs / ctx.subprocess
ctx.fs / ctx.subprocess
E2BRuntime (Service)
Config (apiKey, cwd, timeoutMs)
fs-e2b

(E2B 文件系统适配器)
subprocess-e2b

(E2B 子进程适配器)
模型工具

(通过 ctx.fs / ctx.subprocess)
文件系统接口
子进程运行时接口

关键类/函数

名称 类型 职责
E2BRuntime Service (class) E2B 沙箱运行时:懒创建 SDK 句柄、超时自动删除、共享 cwd 和 runtimeRoot
Config interface E2B 配置:apiKey(或 E2B_API_KEY)、cwd、timeoutMs
getSandbox() method 获取共享 SDK 句柄
quoteE2BShellArg() function E2B shell 参数引用(SDK 强制 /bin/bash -l -c
e2bControlEnvs() function 隔离 E2B 登录 shell 的随机 HOME 路径
E2BFileSystem class E2B FS 适配器:路径解析(realpath)、原子写入(staging 目录+rename)、版本追踪
E2BSubprocessRuntime class E2B 子进程适配器:远程命令执行、终端会话、轮询状态
E2BSubprocessHandle class 远程子进程句柄

与其他模块的关系

  • fsfs-e2b 实现 FileSystem 抽象,注册到 ctx.fs
  • subprocesssubprocess-e2b 实现 SubprocessRuntime,注册到 ctx.subprocess
  • shell:E2B 沙箱可为 Shell 执行提供远程隔离环境。
  • terminalsubprocess-e2b 支持 spawnTerminal() 创建远程终端。

15. MCP 协议能力(mcp)

路径packages/mcp/mcp-client/

核心作用 :MCP 客户端桥接插件------连接外部 MCP 服务器,将其工具注册到 ctx.tools 上,使用服务器限定的公开名称 mcp__<serverName>__<rawName>。支持 stdio 和 Streamable HTTP 两种传输方式,自动重连。

内部架构

#mermaid-svg-ozyTlX1xrg4V2uZI{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ozyTlX1xrg4V2uZI .error-icon{fill:#552222;}#mermaid-svg-ozyTlX1xrg4V2uZI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ozyTlX1xrg4V2uZI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ozyTlX1xrg4V2uZI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ozyTlX1xrg4V2uZI .marker.cross{stroke:#333333;}#mermaid-svg-ozyTlX1xrg4V2uZI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ozyTlX1xrg4V2uZI p{margin:0;}#mermaid-svg-ozyTlX1xrg4V2uZI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster-label text{fill:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster-label span{color:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster-label span p{background-color:transparent;}#mermaid-svg-ozyTlX1xrg4V2uZI .label text,#mermaid-svg-ozyTlX1xrg4V2uZI span{fill:#333;color:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI .node rect,#mermaid-svg-ozyTlX1xrg4V2uZI .node circle,#mermaid-svg-ozyTlX1xrg4V2uZI .node ellipse,#mermaid-svg-ozyTlX1xrg4V2uZI .node polygon,#mermaid-svg-ozyTlX1xrg4V2uZI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ozyTlX1xrg4V2uZI .rough-node .label text,#mermaid-svg-ozyTlX1xrg4V2uZI .node .label text,#mermaid-svg-ozyTlX1xrg4V2uZI .image-shape .label,#mermaid-svg-ozyTlX1xrg4V2uZI .icon-shape .label{text-anchor:middle;}#mermaid-svg-ozyTlX1xrg4V2uZI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ozyTlX1xrg4V2uZI .rough-node .label,#mermaid-svg-ozyTlX1xrg4V2uZI .node .label,#mermaid-svg-ozyTlX1xrg4V2uZI .image-shape .label,#mermaid-svg-ozyTlX1xrg4V2uZI .icon-shape .label{text-align:center;}#mermaid-svg-ozyTlX1xrg4V2uZI .node.clickable{cursor:pointer;}#mermaid-svg-ozyTlX1xrg4V2uZI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ozyTlX1xrg4V2uZI .arrowheadPath{fill:#333333;}#mermaid-svg-ozyTlX1xrg4V2uZI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ozyTlX1xrg4V2uZI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ozyTlX1xrg4V2uZI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ozyTlX1xrg4V2uZI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ozyTlX1xrg4V2uZI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ozyTlX1xrg4V2uZI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster text{fill:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI .cluster span{color:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ozyTlX1xrg4V2uZI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ozyTlX1xrg4V2uZI rect.text{fill:none;stroke-width:0;}#mermaid-svg-ozyTlX1xrg4V2uZI .icon-shape,#mermaid-svg-ozyTlX1xrg4V2uZI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ozyTlX1xrg4V2uZI .icon-shape p,#mermaid-svg-ozyTlX1xrg4V2uZI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ozyTlX1xrg4V2uZI .icon-shape .label rect,#mermaid-svg-ozyTlX1xrg4V2uZI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ozyTlX1xrg4V2uZI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ozyTlX1xrg4V2uZI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ozyTlX1xrg4V2uZI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-ozyTlX1xrg4V2uZI .def>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .def span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .def tspan{fill:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .prov>*{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .prov span{fill:#F5A623!important;stroke:#D4860B!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .prov tspan{fill:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .cons>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .cons span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-ozyTlX1xrg4V2uZI .cons tspan{fill:#fff!important;} Consumer
Tool Bridge
Connection Layer
Service Definition
syncTools
ctx.tools.register
调用 mcp__ 工具
mcp-client (plugin)
Config (stdio / streamable-http)
connection.ts

(连接监督器)
transport.ts

(stdio / HTTP 传输)
tools.ts

(工具同步桥)
ctx.tools

(Harness 工具注册表)
Agent 主循环

关键类/函数

名称 类型 职责
apply() function 插件入口:连接 MCP 服务器、初始工具发现、注册到 ctx.tools
Config type union 传输配置:stdio(command/args/env/cwd)或 streamable-http(url/headers)
startConnection() function 连接监督器:世代管理、自动重连(指数退避)、工具同步
resolveReconnectPolicy() function 重连策略解析:enabled、initialDelayMs、maxDelayMs、maxAttempts
syncTools() function 工具同步桥:分页 tools/list、构建 ToolDefinition、交换世代、注册到 ctx.tools
publicToolName() function 公开名称生成:mcp__<serverName>__<rawName>,规范化+哈希防碰撞
createExecutor() function 工具执行器:发送 tools/call(使用 rawName)、信号/超时、结果映射
createOutput() function 输出 schema 构建:content + structuredContent
RECONNECT_DEFAULTS const 默认重连参数:initialDelay=500ms、maxDelay=30s、maxAttempts=10
activeServerNames WeakMap 活跃服务器名注册表,防止命名空间冲突

与其他模块的关系

  • tools (dsh-tools):MCP 工具注册到 ctx.tools,使用 ToolDefinitionToolExecution 接口。
  • timeout :重连策略使用 MAX_TIMER_DELAY_MS 边界。
  • agent :Agent 主循环通过 ToolRuntime 调用 mcp__* 工具。
  • llm :MCP 工具的输出通过 ContentBlock 注入 LLM 上下文。

能力接缝整体协作

中心枢纽架构

所有能力接缝通过 Cordis 的 Contextctx)对象作为中心枢纽连接。每个接缝通过 declare module '@deepseek-ai/cordis' 的接口合并(declaration merging)将自己的服务声明添加到 Context 上:

  • ctx.llm --- LLM 运行时
  • ctx.shell --- Shell 执行器
  • ctx.subprocess --- 子进程运行时
  • ctx.fs --- 文件系统
  • ctx.web --- Web 搜索/抓取
  • ctx.lsp --- 语言服务器
  • ctx.terminals --- 终端会话
  • ctx.codeRuntime --- 代码运行时
  • ctx.sandbox --- 沙箱提供商
  • ctx.skills --- 技能注册表
  • ctx.subagents --- 子代理运行时
  • ctx.workflowEngine --- 工作流引擎
  • ctx.compaction --- 上下文压缩
  • ctx.e2b --- E2B 沙箱
  • ctx.tools --- 工具注册表(dsh-tools,非本分析范围但 MCP 依赖)

整体协作图

#mermaid-svg-gtQlE6VzdsBwlhlz{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-gtQlE6VzdsBwlhlz .error-icon{fill:#552222;}#mermaid-svg-gtQlE6VzdsBwlhlz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-gtQlE6VzdsBwlhlz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-gtQlE6VzdsBwlhlz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-gtQlE6VzdsBwlhlz .marker.cross{stroke:#333333;}#mermaid-svg-gtQlE6VzdsBwlhlz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-gtQlE6VzdsBwlhlz p{margin:0;}#mermaid-svg-gtQlE6VzdsBwlhlz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster-label text{fill:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster-label span{color:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster-label span p{background-color:transparent;}#mermaid-svg-gtQlE6VzdsBwlhlz .label text,#mermaid-svg-gtQlE6VzdsBwlhlz span{fill:#333;color:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz .node rect,#mermaid-svg-gtQlE6VzdsBwlhlz .node circle,#mermaid-svg-gtQlE6VzdsBwlhlz .node ellipse,#mermaid-svg-gtQlE6VzdsBwlhlz .node polygon,#mermaid-svg-gtQlE6VzdsBwlhlz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-gtQlE6VzdsBwlhlz .rough-node .label text,#mermaid-svg-gtQlE6VzdsBwlhlz .node .label text,#mermaid-svg-gtQlE6VzdsBwlhlz .image-shape .label,#mermaid-svg-gtQlE6VzdsBwlhlz .icon-shape .label{text-anchor:middle;}#mermaid-svg-gtQlE6VzdsBwlhlz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-gtQlE6VzdsBwlhlz .rough-node .label,#mermaid-svg-gtQlE6VzdsBwlhlz .node .label,#mermaid-svg-gtQlE6VzdsBwlhlz .image-shape .label,#mermaid-svg-gtQlE6VzdsBwlhlz .icon-shape .label{text-align:center;}#mermaid-svg-gtQlE6VzdsBwlhlz .node.clickable{cursor:pointer;}#mermaid-svg-gtQlE6VzdsBwlhlz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-gtQlE6VzdsBwlhlz .arrowheadPath{fill:#333333;}#mermaid-svg-gtQlE6VzdsBwlhlz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-gtQlE6VzdsBwlhlz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-gtQlE6VzdsBwlhlz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gtQlE6VzdsBwlhlz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-gtQlE6VzdsBwlhlz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gtQlE6VzdsBwlhlz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster text{fill:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz .cluster span{color:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-gtQlE6VzdsBwlhlz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-gtQlE6VzdsBwlhlz rect.text{fill:none;stroke-width:0;}#mermaid-svg-gtQlE6VzdsBwlhlz .icon-shape,#mermaid-svg-gtQlE6VzdsBwlhlz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-gtQlE6VzdsBwlhlz .icon-shape p,#mermaid-svg-gtQlE6VzdsBwlhlz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-gtQlE6VzdsBwlhlz .icon-shape .label rect,#mermaid-svg-gtQlE6VzdsBwlhlz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-gtQlE6VzdsBwlhlz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-gtQlE6VzdsBwlhlz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-gtQlE6VzdsBwlhlz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}#mermaid-svg-gtQlE6VzdsBwlhlz .hub>*{fill:#9B59B6!important;stroke:#7D3C98!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .hub span{fill:#9B59B6!important;stroke:#7D3C98!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .hub tspan{fill:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .seam>*{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .seam span{fill:#4A90D9!important;stroke:#2C5F8A!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .seam tspan{fill:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .agent>*{fill:#E74C3C!important;stroke:#C0392B!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .agent span{fill:#E74C3C!important;stroke:#C0392B!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .agent tspan{fill:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .tool>*{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .tool span{fill:#7ED321!important;stroke:#5DA016!important;color:#fff!important;}#mermaid-svg-gtQlE6VzdsBwlhlz .tool tspan{fill:#fff!important;} Model Tools (Consumers)
Agent 主循环
Capability Seams
Cordis Context (ctx) --- 中心枢纽
ctx.llm.stream
ctx.compaction
ctx.subagents
ctx.tools
ctx.tools.register
Context
ctx.llm
ctx.shell
ctx.subprocess
ctx.fs
ctx.web
ctx.lsp
ctx.terminals
ctx.codeRuntime
ctx.sandbox
ctx.skills
ctx.subagents
ctx.workflowEngine
ctx.compaction
ctx.e2b
mcp-client → ctx.tools
Agent Loop
systemPrompt
tool-bash
tool-fs
tool-web
tool-lsp
tool-terminal
tool-skill
tool-subagent
tool-workflow
mcp__* tools

典型调用链路

链路 1:模型执行 Shell 命令
复制代码
Agent → tool-bash → ctx.shell.exec(command)
  → ShellExecutor (bash-local 或 bash-sandbox)
    → ctx.subprocess.spawn(argv)  [如果需要子进程]
      → LocalSubprocessRuntime / E2BSubprocessRuntime
    → 返回 stdout/stderr/exitCode
  → 渲染为 ContentBlock
  → 注入会话历史
  → 下一轮 LLM 调用 (ctx.llm.stream)
链路 2:模型委派子代理
复制代码
Agent → tool-subagent → ctx.subagents.start(request)
  → SubagentRuntime 选择命名 Provider (spawn/fork/acp)
    → SpawnInProcessProvider.start()
      → 创建子 Agent (复用 Agent 工厂)
        → 子 Agent 主循环
          → ctx.llm.stream() [子代理的 LLM 调用]
          → 可递归调用工具 (ctx.shell, ctx.fs, ...)
        → 子 Agent 完成
      → SubagentRun.result 解析
  → 返回 SubagentResult.output
  → 注入父会话历史
链路 3:模型执行工作流脚本
复制代码
Agent → tool-workflow → ctx.workflowEngine.start(request)
  → WorkerThreadWorkflowEngine.start()
    → 验证 meta + 解析脚本体
    → 创建 Worker Thread
    → Worker 执行脚本 (vm 沙箱)
      → agent() 调用 → ctx.subagents.start() [桥接到宿主]
        → 子代理执行并返回结果
      → parallel() / pipeline() 组合器
      → phase() / log() 进度事件
    → 脚本 return 值
  → WorkflowRun.result 解析
  → 返回 value
  → 注入会话历史
链路 4:自动上下文压缩
复制代码
Agent 主循环 → agent/pre-step 事件
  → BasicCompactionEngine.compactIfNeeded(agent, 'pressure')
    → ctx.tokenMeter.measure(session) [token 计量]
    → 超过阈值?
      → compaction-tool-result-pruner.pruneSession() [可选裁剪]
      → 重新计量
      → selectCompactableRange() [选择压缩范围]
      → summarizeWithLlm() [通过 ctx.llm.stream() 生成摘要]
        → 复用会话前缀 (系统提示 + 工具 + 消息) 保持 KV 缓存
      → compactSurfaceRegion() [替换历史范围为摘要节点]
        → 发出 compaction/start, compaction/summary, compaction/end 事件
    → 返回 CompactionResult
链路 5:MCP 工具调用
复制代码
Agent → 模型选择 mcp__<server>__<tool> 工具
  → ctx.tools 执行注册的 execute 函数
    → mcp-client createExecutor()
      → client.request('tools/call', { name: rawName, arguments })
        → MCP 服务器进程 (stdio 或 HTTP)
      → 返回 content + structuredContent
    → 映射为 ContentBlock
  → 注入会话历史
链路 6:E2B 远程隔离执行
复制代码
Agent → tool-bash → ctx.shell.exec(command)
  → bash-sandbox Provider
    → ctx.sandbox (或直接) → E2BSubprocessRuntime
      → ctx.e2b.getSandbox() [获取共享 E2B 沙箱]
      → sandbox.commands.run(command)
        → 远程 Linux 沙箱执行
      → 返回 stdout/stderr/exitCode

模型读取远程文件:
Agent → tool-fs → ctx.fs.readText(target)
  → E2BFileSystem
    → ctx.e2b.getSandbox()
    → sandbox.files.read(path)
    → 返回文件内容

设计模式总结

  1. 定义→提供者→消费者三方分离 :每个能力接缝严格遵循三层分离,Service Definition 只声明接口和类型,Service Provider 实现接口并注册,Consumer(通常是 tool)通过 ctx.<capability> 调用。这使得同一接口可以有多种后端实现(本地、沙箱、远程)而不影响消费者代码。

  2. 命名提供商注册表 vs 单一服务:某些接缝(shell、fs、subprocess)是单一服务模式------一个上下文只加载一个 Provider,第二次加载抛异常。另一些(subagent、llm)是命名注册表模式------多 Provider 共存,调用方按名称选择。后者镜像了 LLM 适配器注册表的设计。

  3. 能力验证(Fail Loud)SubagentProvider.capabilities 声明支持的功能(outputSchema、depthLimit、toolFilter、persona),服务在委派前验证请求的能力是否被支持------不支持则抛出类型化错误,而非静默降级。

  4. 品牌 ID 与不变式 :LLM 模块定义了 MessageIdCallIdStreamId 等品牌 ID,compaction 定义 CompactionId,subagent 定义 SubagentRunId、workflow 定义 WorkflowRunId------品牌类型防止跨模块的 ID 混用,不变式函数在关键边界断言合法性。

  5. 事件驱动的生命周期 :每个接缝通过 Cordis 的 declare module 机制向 Events 接口合并自己的事件(如 workflow/startsubagent/startcompaction/start),观察者可以订阅这些事件而不持有运行句柄。

  6. E2B 作为跨接缝共享层 :E2B 沙箱是一个特殊的"元接缝"------它不直接暴露给模型工具,而是作为 fssubprocess 接缝的远程后端,通过共享 SDK 句柄让文件系统和子进程操作处于同一个远程 Linux 世界。

  7. Worker Thread 隔离code-runtimeworkflow 都使用 Worker Thread 执行不可信代码(模型生成的 JS 脚本),vm 沙箱提供 containment 而非安全边界------这是"隔离但非安全"的明确设计选择。

  8. MCP 桥接的命名空间隔离 :MCP 客户端通过 mcp__<serverName>__<rawName> 命名约定将外部工具注册到 ctx.tools,使用 SHA-256 哈希防碰撞,确保多个 MCP 服务器的工具不会命名冲突。连接监督器管理世代交替和自动重连。


相关推荐
DevOps老兵2 小时前
AI全栈知识07:向量数据库 - Milvus/Chroma实战
数据库·ai·milvus
故作春风2 小时前
钱包顶不住了:从 FRP 内网穿透本地 Ollama 到 DeepSeek Harness 多模型实战全记录
agent·deepseek
阿里云大数据AI技术2 小时前
基于 EMR Serverless Ray 实现 Qwen 模型批量推理实践
人工智能·算法·agent
华尔街的幻觉AI3 小时前
全网都在推 DeepSeek Harness 插件,skill 还有必要装吗?
deepseek
牧艺3 小时前
DeepSeek Harness 上手:一切皆插件的 Agent 运行时,核心流程怎么走
llm·agent·deepseek
wujian83113 小时前
AI手机版怎么直接生成word?用“AI 导出鸭”把碎片时间变成专业文档
人工智能·ai·chatgpt·智能手机·word·ai导出鸭
魔术师Grace4 小时前
模型“开源”了,就能直接拿来做 Agent 吗?
llm·aigc·agent