六大业务领域流程详解 · 含分支/回退/容错路径
📑 返回索引:项目文档索引
领域总览
| # | 领域 | 所属模块 | 核心入口 |
|---|---|---|---|
| 1 | 会话编排 | opencode + core | SessionV2.prompt / SessionRunner |
| 2 | LLM Provider 适配 | llm + opencode | LLMClient.stream / Provider.Definition |
| 3 | 上下文管理 | core | SystemContextRegistry / ContextEpoch |
| 4 | 工具与权限 | opencode + core | ToolRegistry / Permission |
| 5 | 客户端 SDK | client + sdk-next | HttpApi 代码生成 / OpenCode.create |
| 6 | 跨端交付 | tui + app + desktop | createOpencodeClient / ServerConnection |
领域一:会话编排业务
1.1 Prompt 准入与执行流程(核心链路)
graph TD
A["用户输入 Prompt"] --> B{"resume?"}
B -->|"true (默认)"| C["SessionV2.prompt 持久化 session_input<br/>(admitted_seq 定序)"]
B -->|"false (admit-only)"| C
C --> D["SessionExecution.wake(sessionID)"]
D --> E["SessionRunCoordinator<br/>按 Session Key 串行化"]
E --> F{"当前有活跃 drain?"}
F -->|"否"| G["启动新 Session Drain"]
F -->|"是"| H["wake 合并入当前 drain"]
G --> I["Safe Provider-Turn Boundary<br/>promoteNextQueued 提升输入"]
I --> J["Context Epoch 检查"]
J --> K["渲染 Baseline System Context<br/>(若 Epoch 为空)"]
K --> L["执行 Provider Turn<br/>(单次 llm.stream)"]
L --> M{"有工具调用?"}
M -->|"是"| N["工具结算<br/>(权限校验 → 执行 → 输出截断)"]
N --> O{"还需续接?"}
O -->|"是"| L
O -->|"否"| P["Drain 空闲,等待新 wake"]
L -->|"失败"| Q{"错误类型?"}
Q -->|"ContextOverflow"| R["触发 Compaction<br/>启动新 Context Epoch"]
R --> L
Q -->|"Provider 错误"| S["重试策略 SessionRetry.policy"]
S --> L
M -->|"否"| T["响应投影到 Session 历史"]
T --> P
图 1:Prompt 准入 → Drain 执行 → 工具结算主链路(含失败/压缩/续接分支)
1.2 相关实体与触发条件
| 概念 | 实体/文件 | 触发条件 | 输出 |
|---|---|---|---|
| Admitted Prompt | session_input 表,SessionInput.admit |
用户提交 Prompt | durable seq 定序的待处理输入 |
| Prompt Promotion | SessionInput.promoteNextQueued |
Safe Provider-Turn Boundary | promoted_seq 推进 + 用户消息入历史 |
| Session Drain | SessionExecution / run-coordinator.ts |
wake 且有未提升输入 | 进程本地执行段(无持久身份) |
| Interrupt | SessionExecution.interrupt |
用户中断 / 工具拒绝 | tool_use 标 interrupted:true,finalize 中断态 |
| Compaction | SessionCompaction / session/compaction.ts |
ContextOverflow / 溢出自动创建压缩任务 | 新 Context Epoch + 压缩历史 |
跨模块数据流向:opencode CLI → server handlers → SessionV2(core)→ SessionRunner → llm + tool + system-context → EventV2 → SQLite。
领域二:LLM Provider 适配业务
2.1 模型选择与流式输出流程
graph TD
A["SessionRunner 请求模型"] --> B["Catalog.available/default/small<br/>projectModel 合并 api/request"]
B --> C["SessionRunnerModel 解析"]
C --> D["Model Request Options<br/>(provider-semantic)"]
D --> E["Generation Controls<br/>(provider-neutral)"]
E --> F["LLMClient.stream 归一化 LLMRequest"]
F --> G{"路由匹配协议"}
G -->|"anthropic-messages"| H["anthropic 协议适配器"]
G -->|"openai-chat"| I["openai 协议适配器"]
G -->|"gemini"| J["gemini 协议适配器"]
G -->|"bedrock-converse"| K["bedrock 协议适配器"]
G -->|"openai-compatible"| L["openai-compatible 适配器"]
G -->|"其他 8 协议"| M["对应协议适配器"]
H --> N["LLMEvent 流式事件"]
I --> N
J --> N
K --> N
L --> N
M --> N
N --> O["发布 LLM 事件 → Session 历史投影"]
O --> P{"失败?"}
P -->|"是"| Q["LLMError 分类 → 重试/中断"]
P -->|"否"| R["流完成"]
图 2:模型路由与协议适配(多路分支按 Route 协议分发)
2.2 工具调用链路
模型返回工具调用 → ToolRuntime.dispatch(tools, call) 按”解码 → 执行 → 编码”三步处理,产出 LLMEvent.toolResult / toolError。跨协议统一:generateObject 通过强制合成工具 generate_object 实现,无需每个协议单独实现结构化输出。
| 环节 | 实现 | 文件 |
|---|---|---|
| 统一入口 | generate / stream / request | packages/llm/src/llm.ts |
| 协议路由 | Route{id, protocol, endpoint, auth, transport} | packages/llm/src/route/ |
| 工具分发 | ToolRuntime.dispatch | packages/llm/src/tool-runtime.ts |
| 缓存策略 | applyCachePolicy(仅 RESPECTS_INLINE_HINTS 协议生效) | packages/llm/src/cache-policy.ts |
领域三:上下文管理业务
3.1 Context Epoch 生命周期
stateDiagram-v2
[*] --> EpochActive: 首次 Provider Turn
EpochActive --> SnapshotInit: SystemContext.initialize<br/>(渲染 Baseline + 快照)
SnapshotInit --> Admitted: Baseline 持久化<br/>(session_context_epoch 表)
Admitted --> Sampling: 到达 Safe Provider-Turn Boundary
Sampling --> Unchanged: reconcile 无变更
Sampling --> Updated: 单一 Source 变更<br/>(Mid-Conversation System Message)
Sampling --> Replacement: reconcile 返回 replacement
Unchanged --> Sampling
Updated --> Sampling
Replacement --> Compacting: SystemContext.replace
Compacting --> EpochActive: 新 Epoch 基线 (Compaction)
EpochActive --> Blocked: Unavailable 源 (stale-while-revalidate)
Blocked --> EpochActive: 源恢复后重试
EpochActive --> [*]: Session 结束
图 3:Context Epoch 状态流转(含增量更新、替换、压缩、容错分支)
3.2 内置 Context Source
| Source | Key | 说明 |
|---|---|---|
| core/environment | 环境信息 | 系统环境上下文 |
| core/date | 当前日期 | 日历日期(保留 host-local 行为) |
| AGENTS.md 指令 | instruction 聚合 | 全局 + 向上项目发现,有序聚合,变更发 Mid-Conversation Message |
| Skill 指引 | selected-agent skill | Agent 切换时更新,保留当前 Epoch 基线 |
领域四:工具与权限业务
4.1 工具执行与权限流程
graph TD
A["模型发出工具调用"] --> B["ToolRegistry.materialize<br/>解析工具定义"]
B --> C{"工具已注册?"}
C -->|"否"| D["ToolNotFound 错误"]
C -->|"是"| E{"权限策略 evaluate"}
E -->|"allow (规则匹配)"| F["直接执行"]
E -->|"ask (默认)"| G["发布 Permission.Asked 事件<br/>await Deferred"]
G --> H{"用户响应"}
H -->|"once/always"| F
H -->|"reject"| I["拒绝执行<br/>reject 级联同 Session 其余请求"]
H -->|"超时/中断"| J["标记 interrupted:true"]
F --> K["工具执行 (Effect)"]
K --> L{"输出超限?"}
L -->|"≤2000行 / 50KB"| M["正常投影"]
L -->|"超限"| N["Managed Tool Output 落文件<br/>有界预览 + 提示用 Task/Grep/Read"]
M --> O["Tool Settlement 结算"]
N --> O
O --> P["发布 tool.execute.after 钩子"]
P --> Q["返回模型"]
图 4:工具执行全链路(含权限三分支、拒绝级联、截断分支)
4.2 内置工具清单
| 类别 | 工具 |
|---|---|
| 文件操作 | read / edit / write / patch |
| 检索 | glob / grep / search / fetch / todo |
| 执行 | shell / execute (code-mode) / task |
| 交互 | invalid / question / plan |
| 生态 | skill / lsp(实验性)/ websearch(特定 Provider) |
自定义工具扫描
{tool,tools}/*.{js,ts}与插件工具;模型过滤:gpt 系用 apply_patch 否则 edit/write。
领域五:客户端 SDK 业务
5.1 代码生成与双客户端流程
graph LR
A["Server HttpApi<br/>(权威定义 18 组)"] --> B["SDK Contract IR<br/>(src/contract.ts 编译表示)"]
B --> C["httpapi-codegen<br/>(构建期生成)"]
C --> D["Promise Emitter<br/>(generated/ 零 Effect)"]
C --> E["Effect Emitter<br/>(generated-effect/ 富投影)"]
D --> F["Promise 客户端<br/>baseUrl + fetch, ClientError 分类"]
E --> G["Effect 客户端<br/>HttpApiClient, 环境注入 HttpClient"]
B --> H["SDK-next 嵌入式 Host<br/>Scope 内构建 Core + 内存 Router"]
图 5:SDK 生成与消费链路
5.2 关键设计
- Page 分页:
sessions.list()返回{data, cursor:{previous,next}},cursor 为 base64url JSON(SessionsCursor),不透明 branded 类型,跨查询复用非法 - 事件双通道:
sessions.events({after})持久可回放流(SSE)vsevents.subscribe()实例级实时流(不可回放,断线显式失败) - 嵌入式 Host:
OpenCode.create在 Scope 内 Layer.buildWithMemoMap 构建 Core,createEmbeddedRoutes 生成 fetch 处理器,返回{...client, tools:{register}}
领域六:跨端交付业务
6.1 三端通信架构
graph TD
subgraph TUI["TUI 端 packages/tui"]
A1["createOpencodeClient<br/>(SDK v2 HTTP+SSE)"]
A2["OpenTUI 渲染<br/>20+ Solid Provider"]
A3["16ms 批量事件 flush"]
end
subgraph WEB["Web 端 packages/app"]
B1["ServerConnection<br/>(localhost:4096)"]
B2["SolidJS 路由/组件"]
B3["i18n 60 语言"]
end
subgraph DESK["桌面端 packages/desktop"]
C1["Electron 主进程"]
C2["sidecar 后台服务"]
C3["preload contextBridge"]
end
subgraph SRV["后端服务"]
S["opencode server<br/>(Node http + WebSocketTracker)"]
end
A1 --> S
B1 --> S
C2 --> S
C1 -->|"IPC"| C3
C3 --> C2
图 6:多端通信拓扑(三端共用同一后端契约,SDK client 统一)
6.2 各端要点
| 端 | 技术 | 关键文件 | 通信方式 |
|---|---|---|---|
| TUI | OpenTUI + SolidJS | packages/tui/src/app.tsx |
SDK client HTTP + SSE |
| Web | SolidJS + Vite + Tailwind | packages/app/src/context/server.tsx |
本地服务器 localhost:4096 |
| Desktop | Electron | packages/desktop/src/main/sidecar.ts |
sidecar 进程 + IPC bridge |
| Console | SolidStart + Cloudflare | packages/console/app/ |
云服务(SST 部署) |
由 opencode-project-analyzer skill 生成