OpenCode 架构图
plain
OpenCode 架构图
┌─────────────────────────────────────────────────────────────────────────────────────┐
│ OpenCode 完整架构 │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────┐ │
│ │ TUI 输入 │ │ SDK API │ │ HTTP API │ │ /command │ │ Shell 执行 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └─────┬─────┘ │
│ └──────────────┴─────────────┴─────────────┴─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────────┐ │
│ │ SessionPrompt.Service (session/prompt.ts) │ │
│ │ │ │
│ │ prompt() ───► loop() ───► state.ensureRunning() ───► runLoop() │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ createUserMessage() shellImpl() ╔═══════════════════╗ │ │
│ │ - 解析文件/agent/MCP command() ║ while (true) ║ │ │
│ │ - 构建 UserPart - 命令模板解析 ║ 主循环 (L1337) ║ │ │
│ │ ╚═══════╤═══════════╝ │
│ └───────────────────────────────────────────────────────────┼──────────────────┘ │
│ │ │
│ ┌──────────────────────────────────────────┘ │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
│ │ runLoop() 单次迭代逻辑 │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ① 获取历史消息 messages → 找到 lastUser / lastAssistant │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ② 退出循环检查 │ │ │
│ │ │ 条件: lastAssistant.finish === "stop" │ │ │
│ │ │ && !hasToolCalls │ │ │
│ │ │ && lastUser.id < lastAssistant.id │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ (未满足则继续) │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ③ 处理待办任务 (tasks.pop) │ │ │
│ │ │ ├── subtask → handleSubtask() → 递归调用 TaskTool → continue │ │ │
│ │ │ └── compaction → compaction.process() → continue/break │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ④ Token 溢出检查 → compaction.isOverflow() → create compaction → continue│ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑤ 获取 Agent 配置 + 插入提醒 (insertReminders) │ │ │
│ │ │ - Plan模式: 插入计划模式系统提示 │ │ │
│ │ │ - Build模式: 插入构建切换提示 │ │ │
│ │ │ - 最大步骤检查 (isLastStep) + MAX_STEPS 警告 │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑥ 创建 AssistantMessage + Processor Handle │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑦ resolveTools() ─── 解析所有可用 Tool 定义 │ │ │
│ │ │ ├── ToolRegistry.tools() → 内置工具 (bash/edit/read/write/...) │ │ │
│ │ │ │ + 自定义工具 (plugin) │ │ │
│ │ │ └── MCP.tools() → MCP 服务器工具 │ │ │
│ │ │ 权限过滤: Permission.disabled() + user.tools 过滤 │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑧ 构建 SystemPrompt → [environment, skills, instructions, format] │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑨ processor.process() ─── 调用 LLM + 处理流式事件 │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌──────────────────────────────────────────────────────────────────────┐ │ │
│ │ │ ⑩ 返回结果判断 │ │ │
│ │ │ ├── "stop" → break (退出 while 循环) │ │ │
│ │ │ ├── "compact" → create compaction → continue │ │ │
│ │ │ └── "continue"→ continue (下一轮 while 循环) │ │ │
│ │ └──────────────────────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
│ │ SessionProcessor (session/processor.ts) │ │
│ │ │ │
│ │ process() │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ llm.stream() ─── Stream<LLM.Event> │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ Stream.tap(handleEvent) ─── 逐个处理流式事件 │ │
│ │ │ │ │
│ │ ├── "start" → 状态设为 busy │ │
│ │ ├── "reasoning-*" → 创建/更新/完成 ReasoningPart │ │
│ │ ├── "text-start/delta/end" → 创建/更新/完成 TextPart │ │
│ │ ├── "tool-input-start" → 创建 ToolPart (pending) │ │
│ │ ├── "tool-call" → 更新 ToolPart (running) + 死循环检测 │ │
│ │ ├── "tool-result" → 更新 ToolPart (completed) │ │
│ │ ├── "tool-error" → 更新 ToolPart (error) │ │
│ │ ├── "start-step" → 代码快照 + StepStartPart │ │
│ │ ├── "finish-step" → token 统计 + 代码补丁 + StepFinishPart │ │
│ │ ├── "error" → 设置 assistant.error │ │
│ │ └── "finish" → 流结束 │ │
│ │ │ │
│ │ 返回: "compact" | "stop" | "continue" │ │
│ └──────────────────────────────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────────────────────────┐ │
│ │ LLM (session/llm.ts) │ │
│ │ │ │
│ │ stream(input) │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ run() ────────────────────────────────────────────────────────────────────── │ │
│ │ │ │ │
│ │ ├── ① provider.getLanguage(model) → 获取厂商语言模型 │ │
│ │ ├── ② config.get() → 获取全局配置 │ │
│ │ ├── ③ provider.getProvider(id) → 获取厂商实例 │ │
│ │ ├── ④ auth.get(providerID) → 获取认证信息 │ │
│ │ ├── ⑤ 构建系统 Prompt (agent.prompt + input.system + user.system) │ │
│ │ ├── ⑥ plugin.trigger("chat.params") → 参数转换 (temperature/topP/...) │ │
│ │ ├── ⑦ plugin.trigger("chat.headers") → 请求头注入 │ │
│ │ ├── ⑧ resolveTools() → 工具过滤 (权限 + 用户禁用) │ │
│ │ ├── ⑨ LiteLLM 兼容处理 → 注入 _noop 占位工具 │ │
│ │ ├── ⑩ GitLabWorkflow 特殊处理 → 注入 toolExecutor + approvalHandler │ │
│ │ ├── ⑪ wrapLanguageModel(middleware) → ProviderTransform.message() 转换消息 │ │
│ │ └── ⑫ streamText() → Vercel AI SDK 流式调用 │ │
│ └──────────────────────────────────────────────────────────────────────────────┘ │
│ │
├─────────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────────────────────┐ ┌─────────────────────────────────────────┐ │
│ │ Provider 层 │ │ Agent 层 │ │
│ │ (provider/provider.ts) │ │ (agent/agent.ts) │ │
│ │ │ │ │ │
│ │ getLanguage(model) │ │ Agent.Info { │ │
│ │ → 动态加载厂商 SDK 适配器 │ │ name, mode (primary/subagent) │ │
│ │ → 返回 LanguageModelV3 │ │ permission, model, prompt │ │
│ │ │ │ temperature, topP, steps │ │
│ │ getModel(providerID, modelID) │ │ options, hidden, variant │ │
│ │ → 模型查找 + suggestions │ │ } │ │
│ │ │ │ │ │
│ │ ProviderTransform │ │ list() → 所有可用 Agent │ │
│ │ .message() → 消息格式转换 │ │ get() → 获取单个 Agent │ │
│ │ .options() → 参数转换 │ │ defaultAgent() → 默认 Agent │ │
│ │ .schema() → Schema 转换 │ │ │ │
│ │ .temperature/topP/topK/max │ │ │ │
│ └────────────────────────────────┘ └─────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────┐ ┌─────────────────────────────────────────┐ │
│ │ Tool 层 │ │ 基础设施层 │ │
│ │ (tool/registry.ts) │ │ │ │
│ │ │ │ Permission → 权限管理 (ask/allow/deny) │ │
│ │ 内置工具: │ │ Plugin → 插件系统 + Hook 机制 │ │
│ │ ├── BashTool │ │ Bus → 事件总线 │ │
│ │ ├── ReadTool │ │ Config → 全局配置 │ │
│ │ ├── WriteTool │ │ MCP → MCP 协议集成 │ │
│ │ ├── EditTool │ │ LSP → 语言服务器协议 │ │
│ │ ├── GlobTool │ │ Session → 会话持久化 │ │
│ │ ├── GrepTool
│ │ Snapshot → 代码快照 & Diff │ │
│ │ ├── TaskTool (子Agent委托) │ │ Compaction → 上下文压缩 │ │
│ │ ├── QuestionTool │ │ Summary → 会话摘要 │ │
│ │ ├── TodoWriteTool │ │ Instruction → 指令管理 │ │
│ │ ├── WebFetchTool │ │ Skill → 技能系统 │ │
│ │ ├── WebSearchTool │ │ │ │
│ │ ├── SkillTool │ │ │ │
│ │ ├── PlanExitTool │ │ │ │
│ │ └── InvalidTool (错误兜底) │ │ │ │
│ │ │ │ │ │
│ │ + 自定义工具 (Plugin 注入) │ │ │ │
│ │ + MCP 工具 (外部服务器) │ │ │ │
│ └────────────────────────────────┘ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────────────┘