内置的 pi-mono:四个包与补丁台账

MiniMax Code 把开源的 pi-mono 四个包按 v0.79.1 原样放进 third_party:各包规模、第一方代码实际用到哪几块、34 条本地补丁,以及为什么选择 vendor 源码。

作者 David更新于 第 5 篇(共 33 篇)

MiniMax Code 的 Agent 循环、模型协议层,以及 read、write、edit、bash 这几个内置工具的底层实现,都不是从零写的,而是来自开源项目 pi-mono(包的作者署名 Mario Zechner,npm scope 为 @earendil-works)。它没有作为 npm 依赖安装,而是整份源码放进了 third_party/pi-mono,和第一方包一起编译进 mcode。

这一篇先把这块“内置底座”摸清楚:四个包各是什么、有多大,第一方代码到底用了哪几块,MINIMAX_CHANGES.md 里记了哪些本地补丁,以及为什么要 vendor 源码。后面三篇再分别拆 Agent 循环、模型协议层和模型系统。

怎么引进来的

引入基线记在 third_party/pi-mono/.minimax-vendor.json:5:

  "upstream": {
    "type": "git",
    "url": "https://github.com/earendil-works/pi-mono.git",
    "ref": "refs/tags/v0.79.1",
    "commit": "28df940f0d07b65284849a483be7b06e2ca046ee"
  },
  "importedAt": "2026-06-16",
  "strategy": "source-vendor",

四个包在 pnpm-workspace.yaml:2 起被列为工作区包,第一方包用 workspace:* 引用它们(如 packages/agent-core/package.json:73)。构建时 scripts/build.mjs 里的 esbuild 插件把工作区包 exports 指向的 ./dist/*.js 改写成 ./src/*.ts,直接打包源码(scripts/build.mjs:60):

      const source = target
        .replace(/^\.\/dist\//, "./src/")
        .replace(/\.d\.ts$/, ".ts")
        .replace(/\.js$/, ".ts");

所以 pi 没有任何预编译产物参与,改一行源码、重新 pnpm build 就进了 dist/cli.js。公开仓库里这四个包的 package.json 都没有 scripts 字段,都标着 "private": true(如 third_party/pi-mono/packages/ai/package.json:96);pi 自带的测试(test/ 目录下 317 个文件)也不在本仓库的验证范围内,AGENTS.md:8 明说第三方目录的测试套件不属于本发行版的验证。

四个包

行数按全书统一口径(git 跟踪的 .ts/.tsx/.mts,排除测试目录与 *.test.*、*.spec.*)统计,四个包合计 369 个文件、120731 行:

目录包名文件 / 行数内容
packages/agent@earendil-works/pi-agent-core27 / 8264Agent 类与 agentLoop,外加一套 harness(压缩、JSONL 会话、技能、提示词模板)
packages/ai@earendil-works/pi-ai60 / 34346统一的大模型调用层:9 种 API 形态的 provider、统一事件流、OAuth;其中 src/models.generated.ts 一个生成文件就有 17267 行
packages/coding-agent@earendil-works/pi-coding-agent254 / 66352pi 自己的命令行产品:src/core 64 个文件 26384 行,src/modes(交互模式等)45 个文件 16854 行,examples/extensions 14218 行
packages/tui@earendil-works/pi-tui28 / 11769差分渲染的终端 UI 库

依赖方向是 pi-coding-agent 依赖其余三个包,pi-agent-core 依赖 pi-ai,pi-tui 不依赖任何兄弟包。

第一方代码用了哪几块

在 packages/ 下的非测试源文件里,一共 117 个文件 import 了 pi 的包(含一处动态 import):local-runtime 52 个、local-runtime-v2 34 个、agent-core 14 个、agent-tools 8 个、agent-modules/context-manager 5 个、tui 2 个,agent-runtime 与 agent-modules/goal 各 1 个。按被引用的 pi 包看:

pi 包引用它的文件用得最多的符号实际用途
pi-agent-core86AgentMessage(66 处 import)、StreamFn(17)、ThinkingLevel(9)大多只借类型;Agent 类只在 agent-core/src/pi-turn-runner 的 7 个文件里出现
pi-ai56Api(38)、Model(30)、Tool 与 Context(各 13)消息与模型类型、streamSimple(8 个文件)、模型目录查询
pi-coding-agent19四个工具工厂、AuthStorage、convertToLlm只取零件
pi-tui0—第一方代码没有 import

几个值得注意的事实:

  • Agent 只在一处被创建。整个第一方代码里 new Agent(...) 只出现在 packages/agent-core/src/pi-turn-runner/agent.ts:34,其余地方都经由 agent-core 的 PiTurnRunner 使用它,详见下一篇。agent-core 还特意把与 pi 相关的代码放在子路径里:packages/agent-core/src/index.ts:11 的注释说,这样只需要协议类型的消费者就不必承担加载 @earendil-works/* 的开销。
  • pi-coding-agent 最大,用得最少。第一方只拿了它的零件:createBashTool、createEditTool、createReadTool、createWriteTool 四个工具工厂与 createLocalBashOperations、getShellConfig,Codex 登录用的 AuthStorage,消息转换 convertToLlm,压缩默认值 DEFAULT_COMPACTION_SETTINGS,以及 calculateContextTokens、resizeImage。pi 自己的会话外壳 AgentSession、交互模式、扩展系统和 JSONL 会话管理一概没用;pi-agent-core 里的 AgentHarness 同样没有被引用,只借了 harness 里的 generateSummary、CustomMessage、CompactionSummaryMessage。
  • pi-tui 实际上没进产品界面。产品 TUI 用的是另一份 fork:packages/tui/src/tui/engine,基线是 pi-tui 的 0.84.2(packages/tui/src/tui/engine/BASELINE.json:9),比 third_party 里的 v0.79.1 新。packages/tui/src/tui/engine/UPSTREAM.md:14 这样定位它与 pi 的关系:

Pi is provenance and a future selective-sync input, not a runtime boundary.

third_party 里的 pi-tui 于是只作为 pi-coding-agent 的依赖留在工作区(third_party/pi-mono/packages/coding-agent/package.json:28)。docs/architecture.md:10 说 third_party/pi-mono 提供 agent、模型协议与终端基础设施,前两项属实,终端这一项与代码不符:UPSTREAM.md:21 写明引擎是产品启动路径上唯一的终端、输入与渲染基础。引擎 fork 的细节见 TUI 引擎。

图表加载中…

补丁台账

third_party/pi-mono/MINIMAX_CHANGES.md:14 声明基线导入时没有改动任何上游源文件,此后每个本地补丁记一条,MINIMAX_CHANGES.md:288 规定每条要写清原因与受影响的包、属于可上游的通用改动还是 MiniMax 专用胶水、验证命令与结果。

截至快照共 34 条,最早 2026-06-16,最晚 2026-09-08,文件里的排列并不严格按时间。按 pi 的包计(跨包的条目分别计入):coding-agent 17 条、ai 13 条、agent 6 条、tui 2 条,其中 3 条只改测试。只有 1 条自认是 MiniMax 专用胶水(MINIMAX_CHANGES.md:53),其余都标为可上游的通用改动。上游 PR 方面,只有 2026-07-31 保留 thinking 签名的那条是把已合并的上游 PR #6457 挑回来(MINIMAX_CHANGES.md:156),2026-07-15 的 GPT-5.6 回移注明通用行为已在上游,其余都写着“未提”,2026-09-05 与 2026-09-08 两条没写这一项。按时间顺序整理如下(均为 2026 年):

日期包改了什么上游 PR
06-16aibuild 只编译已提交的模型目录,刷新目录改为单独的 refresh-models 脚本未提
06-19ai测试:自适应思考模型的断言加入 Fable 5未提
06-19coding-agent测试:删掉一条不稳定的会话 ID 断言未提
07-04coding-agentedit 模糊匹配只规范化命中片段,不再整文件改写全角字符与尾随空白未提
07-07coding-agentbash 停止与超时改为 SIGTERM、宽限期、SIGKILL,让清理 trap 能执行未提
07-08ai从包入口导出 convertResponsesMessages 与 convertResponsesTools未提
07-09coding-agentedit 模糊匹配加保真守卫,拒绝吞掉兼容字符的扩宽片段未提
07-15agent在 Agent 上暴露已有的 shouldStopAfterTurn未提
07-15ai、agent、coding-agent回移 GPT-5.6 目录与 max 思考档未提(上游已有)
07-22aistream 选项新增 fetch,由宿主接管模型请求的出站未提
07-26ai注入了 fetch 且传输为 auto 时,Codex 改走 SSE未提
07-28ai、coding-agentOAuth token 刷新也可注入 fetch未提
07-29coding-agent加固 Windows 下 taskkill 的解析与 spawn 失败处理未提
07-31ai回放时保留只有签名、内容为空的 Anthropic thinking 块已合并(回移 #6457)
07-31coding-agent测试:几条测试对组合与调度变化更稳健未提
08-04coding-agent升级打包依赖 undici 与 minimatch未提
08-08ai新增 onProviderError,把 SDK 原始异常同步交给宿主未提
08-10tuiOSC 8 超链接改用 BEL 结尾,修 macOS 终端的点击命中未提
08-11coding-agent复制资源改用 Node 脚本,不再依赖 shx未提
08-12coding-agent打包后的 MCode 仍能读取本地图片(修正 Photon WASM 定位)未提
08-14tuiCancellableLoader 显式声明构造参数类型未提
08-15coding-agentPhoton 不可用时,尺寸已合规的图片原样返回未提
08-18ai新增 onProviderStreamEvent,向宿主暴露解析后的原生流事件未提
08-18ai、coding-agentCodex 浏览器登录的授权码交换也走宿主 fetch未提
08-20coding-agent可选的父进程死亡守护:宿主被杀后仍回收 bash 进程组未提
08-22coding-agent内置 Bash 与 Read 在结果里保留分流输出与分页事实未提
08-22agentsteering 受理后可优雅停止(shouldStopAfterSteering),唯一的专用胶水未提
08-22agent工具钩子可返回 terminateAgent,结束整个 Agent 运行未提
08-22agent新增 onToolExecutionStart,在参数校验与准入全部通过后才触发未提
08-26aiCodex SSE 响应头超时从 10 秒放宽到 30 秒未提
08-27aiClaude 默认思考模型不再发送显式 thinking 字段未提
08-31coding-agent兼容 Windows PowerShell 的 ConstrainedLanguage 模式未提
09-05coding-agentBash 可选的进程事实观察 onProcessEvent未写
09-08agentAgent.steerBatch:一批 steering 消息在一次模型请求里消费未写

落在 ai 包的补丁(Claude 默认思考、Codex SSE 超时、fetch 注入等)在 pi-ai 一篇对照代码细讲,agent 包的几个接缝在 pi-agent 一篇讲。这里只看那条唯一的专用胶水。third_party/pi-mono/packages/agent/src/types.ts:215 的注释直说它是给 MiniMax 宿主开的口子:

Called immediately after steering messages have been polled and before another provider request.
This is a MiniMax host seam for a steering admission hook to stop the current run gracefully.

循环里的用法在 third_party/pi-mono/packages/agent/src/agent-loop.ts:253:

pendingMessages = (await config.getSteeringMessages?.()) || [];
if ((await config.shouldStopAfterSteering?.()) === true) {
	await emit({ type: "agent_end", messages: newMessages });
	return;
}

插件的 UserPromptSubmit 钩子若对一条 steering 消息返回 continue: false(packages/local-runtime-v2/src/service/turn-system/agent-host/execution/user-input-control.ts:211),宿主就让 shouldStopAfterSteering 返回真(同文件 :113),当前运行在下一次模型请求之前正常收尾,而不是报失败。受理与排队的上层逻辑见回合系统。

台账与代码有两处对不上:2026-08-04 那条写的是固定 undici 8.10.0,而 coding-agent/package.json:41 现在是 8.10.2,后续升级没有补记;.minimax-vendor.json:14 与 MINIMAX_CHANGES.md:125 都指向一份 third_party/AGENTS.md(vendor 代码的热修、验证与同步流程),公开仓库里没有这个文件。台账里的验证命令(如 pnpm check:pi-vendor-resolution)同样只存在于内部 monorepo。

为什么 vendor 源码

台账开头第一句就是答案(MINIMAX_CHANGES.md:3):

This directory vendors pi-mono as source so MiniMax can patch, validate, and ship agent-loop fixes without waiting on upstream release cadence.

从台账内容看,补丁主要有三类:宿主需要的循环接缝(terminateAgent、onToolExecutionStart、steerBatch、shouldStopAfterSteering),企业网络环境要求的出站控制(三条 fetch 注入与 Codex 传输选择),以及 Windows 与进程管理的稳健性修复;此外还有 edit 工具保真与图片读取的修复。它们要跟着产品版本一起发布,等上游发版就太慢;而源码直接参与构建,改完即生效。

代价同样清楚:基线停在 v0.79.1,上游后来的修复只能挑着回移(GPT-5.6 目录、#6457);绝大多数补丁没有提上游 PR,本地分叉会越积越多,每次同步都要逐条核对台账。TUI 引擎另起了一份 0.84.2 的 fork,而不是在 third_party 里升级,从代码看,这两部分的同步节奏已经分开。

与 Kimi Code 的对照

Kimi Code 也 vendored 了 pi-mono,但范围小得多。据《Kimi Code 源码解读》的 pi-tui 一篇,它只把 pi-tui 复制成 packages/pi-tui(基线上游 0.80.2),本地分歧登记在包内的 AGENTS.md;Agent 循环是自研的(见其 Agent 循环一篇)。

Kimi CodeMiniMax Code
vendored 范围只有 pi-tuiagent、ai、coding-agent、tui 四个包
基线上游 0.80.2v0.79.1;产品 TUI 引擎另 fork 自 0.84.2
位置packages/pi-tuithird_party/pi-mono;引擎在 packages/tui/src/tui/engine
改动登记包内 AGENTS.md 列出必须保留的分歧MINIMAX_CHANGES.md 台账;引擎另有 BASELINE.json 逐文件哈希与 LOCAL_CHANGES.md
Agent 循环与模型层自研直接用 pi-agent-core 与 pi-ai

两家在终端 UI 上殊途同归:都选了 pi-tui 的差分渲染,并直接改源码。区别在 Agent 与模型这两层:Kimi Code 只借了界面,MiniMax Code 连循环和协议层一起借,再在外面包自己的回合执行器与模型系统。

下一篇:pi 的 Agent 循环与回合执行器——pi 的 runLoop 一轮怎么调模型、执行工具、停下来,MiniMax 又怎样把它包成一个回合。

本页目录