# 运行架构(architecture) > 本文件是运行结构、模块契约、架构决策、调研事实与技术路线图的权威位置。 > 用户可见语义见 [`behavior.md`](behavior.md),本插件实现约束和热挂例外见 [`development.md`](development.md)。 ## 运行结构 插件把智谱 GLM Coding Plan 的三个 MCP 服务接入 DSH,但不向模型暴露原始 MCP 会话: | 能力 | 智谱 MCP | DSH 接入点 | 模型侧名称 | | --- | --- | --- | --- | | 联网搜索 | `web_search_prime` | `ctx.web.registerSearchProvider`,由 patch 配置 `searchProvider` | 保持内置 `web_search` | | 网页读取 | `webReader` | `ctx.web.registerFetchProvider`,由 patch 配置 `fetchProvider` | 保持内置 `web_fetch` | | 开源仓库 | `search_doc` / `get_repo_structure` / `read_file` | `ctx.tools.register(defineTool(...))` | 三个 `github_*` 工具 | 搜索和读取是 **provider 替换**;仓库能力是 **原生工具注册**。设置默认值、停用语义以及 `web_fetch` 的独立开关见 [`behavior.md`](behavior.md)。 ## 组件与数据流 ```text 模型工具调用 ├─ web_search / web_fetch │ └─ DSH web provider registry │ └─ zhipu-search / zhipu-reader └─ github_* └─ DSH tools registry └─ zhipu-zread 三类调用 → credentials → mcp-http → 智谱 MCP → 结果映射 / 稳定错误码 设置页 → settings namespace → live watch → provider 可用性、工具和提示动态装卸 构建产物变化 → self-hot-reload → DSH HMR partialReload ``` 模块边界: | 模块 | 契约 | | --- | --- | | `src/index.ts` | 聚合 provider、工具、system prompt、settings 与自监视;在 `open-design` profile 把信息日志写 stderr,保护 stdout JSONL;副作用随 Fiber 清理 | | `src/credentials.ts` | 解析凭据并实现 `${DSH_HOME:-~/.dsh}` 回退;不泄露 Key | | `src/mcp-http.ts` | 完成 MCP 初始化、通知、工具调用和尽力清理;解析 JSON/SSE,映射稳定错误 | | `src/zhipu-search.ts` | provider id `zhipu-web-search-prime`;传递 `search_query` 并映射搜索来源 | | `src/zhipu-reader.ts` | provider id `zhipu-web-reader`;请求 Markdown,解析双层 JSON 并映射 `WebFetchResult` | | `src/zhipu-zread.ts` | 注册三个 `github_*` 工具、参数 schema、60 秒协作超时与通用展示卡片 | | `src/settings-schema.ts` / `src/client.ts` | 注册 `dsh-zhipu` 设置命名空间和浏览器设置卡片,实时同步六个字段 | | `src/self-hot-reload.ts` | 精确监视 host 构建产物,并通过官方 HMR API 局部重载 | | `src/bin/` | 管理持久行、临时热行和桥接行;按可用能力选择热挂载通道 | ## 挂载契约 随包发布的 `cordis.patch.yml` 只承担两件事: ```yaml - id: web config: searchProvider: zhipu-web-search-prime fetchProvider: zhipu-web-reader - insert: - id: dsh-zhipu name: deepseek-harness-zhipu_plan_tools ``` - `web` 行把内置工具路由到插件 provider,不修改 `tool-web.fetch`; - `dsh-zhipu` 行挂载插件本体;开发期的其他行 id 及清理规则见 [`development.md#不可破坏的约束`](development.md#不可破坏的约束)。 ## 关键架构决策 ### 原生 provider 与工具,而非通用 MCP 组合行 通用 MCP 配置的请求头是静态字符串,容易迫使 API Key 落入配置。原生接入可以统一使用 DSH credentials 服务、支持凭据热更新,并保持模型熟悉的 `web_search` / `web_fetch` 名称。 ### 每次调用使用独立 MCP 会话 `mcp-http` 当前按 `initialize` → `notifications/initialized` → `tools/call` → `DELETE` 执行。清理使用短超时并尽力而为;取消后不等待清理。用户可见的延迟边界见 [`behavior.md#调用边界与失败模式`](behavior.md#调用边界与失败模式)。 ### provider 常驻、关闭即回退,工具按设置装卸 搜索和读取 provider 常驻 registry;`available()` 在开启态看智谱凭据,关闭态看回退可用性(搜索看 `DEEPSEEK_API_KEY`,读取恒可用)。三个仓库工具随 `zread` 动态注册或卸载。具体设置语义只在 [`behavior.md#设置语义`](behavior.md#设置语义) 定义。 ### web_search 工具与说明的 Agent 作用域阴影 `search` 开启时,仅对继承视图中原 `web_search` 可见的 Agent 注册同名工具与 `tool:web_search` 说明(systemPrompt.section scope 层阴影全局),沿 dsh-hashline 的 scoped-shadow 模式(`src/search-tool.ts`),不突破 preset 隐藏策略;其中**极简模式(minimal 预设)——“仅持久 shell + str_replace_editor”的双工具组合——直接豁免**,不注册阴影(`index.ts` 的 `isMinimalAgent` 经 `agentPresets.composedPreset(agent.ctx)` 判定);`zread` 开启时还在极简 Agent 作用域以 `restrict` deny 全局 `github_*` 工具——与 hashline 同理:极简 agent 的继承视图暴露 host 全局注册的工具,必须显式 deny 才能保持双工具承诺,且 deny 与 `search` 开关无关(由 `installAgentSurface` 统一建立表面)。替代工具保留内置的查询数、来源数、工具预算与同批失败取消语义。工具 description 为静态字符串,随 `zhPrompt` 变化由 refresh() 对所有 live Agent 重装;说明 text 为函数,组装时按设置实时取值。新 Agent 由 `agent/created` 事件自动接管。 会话中途切换预设(如 cordis → minimal,DSH `recompose`)时,经官方 `agent-preset/selected` 对目标 Agent 重新评估,撤销已装阴影/改挂 deny,避免残留注入;不得监听 `tools/change` 兜底——工具注册/注销会同步触发它,重装表面又触发它,形成无限递归卡死会话创建。 ### 关闭开关不依赖 seam 回退,由 provider 自回退 `web` 行的 `searchProvider` / `fetchProvider` 被 bundle patch 静态 pin 到本插件;`WebRuntime` 在构造时固化 configuredId(只读,运行时不可改),configured provider 不可用时报 `WEB_PROVIDER_CONFIGURED_UNAVAILABLE`,seam 不会自动选其他 provider。因此关闭开关后:搜索由 provider 内部按 DSH 请求形状直连 DeepSeek 搜索端点(`deepseek-fallback`),读取由 provider 内部执行受限 HTTP(S) 文本抓取(`http-fallback`)。后者负责 URL、同源重定向、内容类型、传输预算与 Fiber 外无持久副作用的边界;剩余 DNS 风险和其他插件兼容边界见 [`behavior.md#关闭后的回退语义`](behavior.md#关闭后的回退语义)。 ### 凭据解析带 DSH home 回退 宿主进程不保证导出 `DSH_HOME`。解析遵循“非空 `$DSH_HOME`,否则 `~/.dsh`”,再由 credentials 服务、环境变量与凭据文件组成调用链。安全边界见 [`behavior.md#凭据与数据边界`](behavior.md#凭据与数据边界),实现硬约束见 [`development.md#不可破坏的约束`](development.md#不可破坏的约束)。 ### 动态 Loader 与单文件 host bundle 可靠的运行时挂载使用动态 Loader;query URL 用于绕过 ESM 入口缓存。因为入口 query 不会刷新多模块包的相对导入,host 产物必须保持单文件 bundle。完整热路径与缓存事实集中在 [`development.md#热路径选择智谱专属例外`](development.md#热路径选择智谱专属例外)。 ## 调研事实 以下内容只记录影响实现选择的上游事实: - MCP 端点: - 搜索:`https://open.bigmodel.cn/api/mcp/web_search_prime/mcp`; - 读取:`https://open.bigmodel.cn/api/mcp/web_reader/mcp`; - 仓库:`https://open.bigmodel.cn/api/mcp/zread/mcp`。 - 三个服务均使用 `ZAI_CODING_CN_API_KEY` Bearer 认证;曾验证的 `vision/mcp`、`reader/mcp` 等候选地址不适用。 - `webReader` 支持 `url`、`timeout`、`no_cache`、`return_format`、`retain_images`、`no_gfm`、`keep_img_data_url`、`with_images_summary`、`with_links_summary`;正文位于双层 JSON 编码结果中。 - `web_search_prime` 参数为 `search_query`(必填)、`search_domain_filter`、`search_recency_filter`、`content_size`、`location`;`additionalProperties:false`,**没有任何结果条数参数**。实测 `count` / `numResults` / `maxResults` / `limit` 一律被静默忽略。单查询返回上限恒为 **10 条**(2026-09 实测:宽泛/精确/中英文/单字符/生僻术语/热词/recency/content_size 等 10 组查询观测最大值均为 10,`tools/list` 亦无 `nextCursor` 分页),结果不足时更少。上游无法给出单查询 10 条以上的结果,需要更多来源只能拆成多条查询。 - zread 的工具 schema 为 `search_doc{repo_name,query,language?}`、`get_repo_structure{repo_name,dir_path?}`、`read_file{repo_name,file_path}`。 - DSH 相关契约位于上游 web provider、tool-web、core tools 与 mcp-client 包;查阅上游源码时以实际运行版本为准,不以本地 checkout HEAD 推断运行行为。 ## 技术路线图 | 项目 | 方向 | 状态说明 | | --- | --- | --- | | 视觉理解 | 将 GLM-4.6V `chat/completions` 能力封装为原生工具,覆盖图像、视频、OCR、UI、图表与 diff | 已完成端点、消息结构、prompt 来源和模型选项调研,待实现 | | MCP 会话复用 | 连接池或受控会话复用,减少每次调用的初始化往返 | 待设计取消、并发与失效边界 | 版本与 npm 发布状态不属于技术路线图,统一见 [`release.md`](release.md)。