v1.1.0Pi v1.1.0 源码分析Analysis of Pi v1.1.0 · 2026-10-07

图解 Pi AgentPi Agent, Illustrated

一个可扩展编码智能体内核的架构The architecture of an extensible coding-agent core

Run modespi-coding-agentExtensionspi-agent-corepi-aipi-tui

← → 翻页 · F 全屏 · O 目录 · T 明暗 · L 语言← → navigate · F fullscreen · O overview · T theme · L language

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.001
一句话In one sentence

Pi 是四层,每层只认识下一层Pi is four layers, each knowing only the next

运行模式 → AgentSession → Agent 循环 → pi-ai 事件流。产品逻辑全部以钩子形式注入通用循环。Run mode → AgentSession → agent loop → pi-ai event stream. All product logic is injected into a generic loop as hooks.

Run modesinteractive · print · json · rpc
↓
pi-coding-agentAgentSession · tools · sessions · extensions
↓
pi-agent-coreAgent · runLoop()
↓
pi-ai42 providers → AssistantMessageEventStream
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.002
规模By the numbersInfra

一个中等体量、测试充分的 monorepoA mid-sized, well-tested monorepo

14
workspace 包packages
177k
行源码src LOC
185k
行测试test LOC
42
LLM providerLLM providers
8
内置工具built-in tools
41
扩展事件extension events
33
RPC 命令RPC commands
12
流事件类型stream event types
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.003
01 · 包01 · Packagespi-coding-agent

14 个包,运行时栈只有四层深14 packages, a runtime stack four deep

Package dependency graph运行时栈RUNTIME STACK独立库STANDALONE无内部依赖no internal deps持久化与远程会话DURABLE & REMOTE SESSIONSpi-coding-agentAgentSession · 8 工具AgentSession · toolspi-agent-coreAgent · runLoop()pi-ai42 provider · 10 种 API42 providers · 10 APIspi-telemetry遥测契约telemetry contractspi-tui差分渲染differential renderpi-mcpMCP 客户端MCP clientpi-codemode沙箱 JS 执行sandboxed JSpi-server实验性服务端experimental serverpi-client远程会话客户端remote clientpi-protocolCBOR 帧协议CBOR protocolpi-durable持久化运行时durable runtimepi-env经 SSH 远程执行remote exec · SSHpi-evals评测工具eval harnesschord应用组合运行时:services · 复制状态 · RPC · pluginsapplication composition runtime — services · replicated state · RPC · pluginspi-durable → pi-ai5 个包都依赖 chordall 5 depend on chorddevdevDependencies(仅测试):pi-server · pi-client · pi-protocoldevDependencies (tests only): pi-server · pi-client · pi-protocoldependency(运行时依赖)dependencydevDependency(开发依赖)devDependency四层运行时栈the 4-deep runtime stackpi-coding-agentpi-agent-corepi-aipi-tui其他包other packages

pi-ai 只依赖 pi-telemetry;pi-tui、pi-mcp、pi-codemode、chord 零内部依赖。pi-ai depends only on pi-telemetry; pi-tui, pi-mcp, pi-codemode and chord have no internal deps.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.004
02 · 分层02 · Layerspi-coding-agent

请求自上而下穿过四层A request flows down four layers

  • 模式层只和 AgentSessionRuntime 对话Modes only talk to AgentSessionRuntime
  • AgentSession 把策略挂到 Agent 钩子上AgentSession hangs policy on Agent hooks
  • streamFn = modelRuntime.streamSimple()streamFn = modelRuntime.streamSimple()
  • 只有 interactive 模式使用 pi-tuiOnly interactive mode uses pi-tui
Layered architecture运行模式RUN MODES共享同一个运行时all share one runtimepi-coding-agent会话编排session orchestrationAgentSessionprompt() · steer() · followUp() · compact() · bindExtensions()pi-agent-coreAgentSession 注入的钩子hooks set by AgentSessionpi-aipi-tui仅 interactiveinteractive onlyJSONL宿主应用 / IDEHost app / IDEpipe脚本 / CIScripts / CITTY开发者DeveloperrunRpcMode()33 种 JSONL 命令 · 事件33 JSONL commands · eventsrunPrintMode()text · json,一次性text · json, one-shotInteractiveMode编辑器 · 聊天视图 · /命令editor · chat view · /commandsAgentSessionRuntime持有当前会话 · newSession() · switchSession() · fork() 时整体替换owns the current session · replaced wholesale on newSession() · switchSession() · fork()SessionManager只追加的 JSONL 树append-only JSONL treeExtensionRunner41 种事件 · register*41 events · register*8 个内置工具8 built-in toolsread · bash · edit · write …compaction摘要 + 保留尾部summary + kept tailModelRuntime实现 pi-ai 的 Modelsimplements pi-ai ModelsResourceLoader扩展 · skills · promptsextensions · skills · promptsAgent状态 · 两个消息队列state · two message queuesrunLoop()内层 + 外层循环inner + outer looptransformContextconvertToLlmprepareNextTurnprepareRequestbeforeToolCallafterToolCallfinishTurnModelsgetModel · checkAuthproviders/*42 个内置 provider42 built-in providersapi/*.lazy.ts10 种对话 API · 懒加载10 chat APIs · lazyAssistantMessageEventStreamstart · text_* · thinking_* · toolcall_* · done · errorTuiMainScreen主屏 · 保留 scrollbackmain buffer · scrollbackTuiAltScreen备用屏 · 全屏alt screen · fullscreenComponentrender(width) → string[]ProcessTerminalStdinBuffer → 按键StdinBuffer → keysEditorMarkdownSelectListLoaderImageScrollView内置组件,还有 Input、Stack …built-ins, plus Input, Stack …prompt ↓ · 事件 ↑prompt ↓ · events ↑agent.prompt()注入installsstreamFn = modelRuntime.streamSimple()事件流回到循环events back to the loop12345
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.005
03 · Agent 循环03 · Agent looppi-agent-core

两层循环驱动一切Two nested loops drive everything

  • 内层:有工具调用或 steering 消息就继续Inner: continue while tool calls or steering remain
  • 外层:follow-up 消息到达时重启Outer: restart when follow-ups arrive
  • stopReason: length → 所有工具调用失败stopReason: length → every tool call fails
  • finishTurn 可返回 end / continuefinishTurn may return end / continue
Agent loop消息队列MESSAGE QUEUESrunLoop()prompt() / continue()Steering 队列Steering queueagent.steer()Follow-up 队列Follow-up queueagent.followUp()注入待处理消息Inject pending messagesprepared + steering → message_start/endstreamAssistantResponse()transformContext → convertToLlm → streamFnexecuteToolCalls()sequential | parallel · length → 全部失败sequential | parallel · length → all failfinishTurn() · turn_end决策 end | continue,再轮询 steeringdecision end | continue, then poll steeringgetFollowUpMessages()Agent 本该停止时才检查checked only when the agent would stopagent_end运行结束,回到 idlerun finished → idle用户在 Agent 运行时输入typed while the agent runs模式:one-at-a-time(默认)| allmode: one-at-a-time (default) | all有工具调用tool calls无工具调用no tool callsprepareNextTurn() · turn_start仍有工具调用 / steeringtool calls or steering left轮询poll都没有neither决策 = enddecision = end无 follow-upnone queuederror / aborted外层循环:follow-up 到达(或 finishTurn → continue)outer loop: follow-ups arrived (or finishTurn → continue)内层inner循环loop012345
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.006
03 · 消息队列03 · Message queuespi-agent-core

用户可以在 Agent 运行时插话Users can talk while the agent works

SteeringSteering

当前轮工具执行完成后、下一次 LLM 请求前注入。适合“停,换个方向”。Injected after the current turn's tools finish, before the next LLM request. For “stop, go another way”.

agent.steer() · getSteeringMessages()
Follow-upFollow-up

只在 Agent 本该停止时投递,触发外层循环。适合“做完之后再……”。Delivered only when the agent would stop, driving the outer loop. For “when you’re done, also…”.

agent.followUp() · getFollowUpMessages()
finishTurnfinishTurn

每轮结束的决策钩子:end 立即结束;continue 在无新消息时再跑一轮仅含上下文的请求。End-of-turn decision hook: end stops now; continue runs one more context-only turn when nothing is queued.

AgentLoopConfig.finishTurn
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.007
04 · 工具执行04 · Tool executionpi-agent-core

每个工具调用走同一条管道One pipeline for every tool call

Tool call execution扩展(经 ExtensionRunner)EXTENSIONS (via ExtensionRunner)一批工具调用A BATCH OF TOOL CALLSassistant 消息含多个 toolCall 时when one assistant message has several tool calls查找工具Find tooltools.find(name)准备参数Prepare argsprepareArguments()校验ValidatevalidateToolArguments()beforeToolCall()ext · tool_calltool.execute()(…, signal, onUpdate)afterToolCall()ext · tool_result完成Finishtool_execution_endtoolCall来自 assistant 消息from assistant messageToolResultMessagemessage_start / endtool_call可阻止 · blockmay blocktool_result可改写结果may rewrite resulttool_execution_update流式输出 · 例如 bashstreamed output, e.g. bashcreateErrorToolResult(message)isError: true —— 失败是结果,不是异常isError: true — a failure is a result, never a throwexecute 抛错execute throws→ isError 结果→ isError resulttool_execution_startonUpdate未找到not found抛错throws不合法invalidblock / abort跳过 afterToolCallskips afterToolCallsequentialparallelprep 1exec 1msg 1prep 2exec 2msg 2prep 3exec 3msg 3prep 1prep 2prep 3并发执行 · 每个完成即发 tool_execution_endrun concurrently · tool_execution_end as each finishesmsg 1msg 2msg 3结果按原顺序发出results in source order任一工具声明 executionMode: "sequential" → 整批串行any tool with executionMode: "sequential" serializes the batch1234567

失败永远是结果而不是异常。并行模式:准备按顺序、执行并发、结果按原顺序发出;任何一个 sequential 工具会让整批串行。Failures are results, never throws. Parallel mode: prepare in order, execute concurrently, emit results in source order; one sequential tool serializes the batch.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.008
05 · 时序05 · Sequencepi-coding-agent

一次提示:两次请求,一次工具调用One prompt: two requests, one tool call

  • 扩展先拦截:input → before_agent_startExtensions intercept first: input → before_agent_start
  • 每个 delta 变成 message_updateEvery delta becomes message_update
  • 工具结果回到上下文,循环自动发起第二次请求Tool results rejoin the context; the loop sends request 2
  • 每个 message_end 都写入 JSONLEvery message_end is written to JSONL
One prompt, end to end运行模式run modepi-coding-agentpi-agent-corepi-aiInteractiveModeAgentSessionExtensionRunnerSessionManager工具 · bashTool · bashAgent · runLoopstreamFn · pi-ai1 · 预处理1 · Preprocess2 · 请求 12 · Request 13 · 工具调用3 · Tool call4 · 请求 24 · Request 2prompt(text)input · 可改写或接管input · may rewrite / handle展开 skill 与模板expand skills · templatesbefore_agent_startagent.prompt() → runAgentLoop()message_end(user)appendMessage()context · 每次请求前context · before every requeststreamFn(model, ctx)text_delta …message_update重绘(批处理)re-render (batched)done(toolUse)message_end(assistant)appendMessage()tool_call · 可阻止tool_call · may blockexecute(…)onUpdate … 结果onUpdate … resulttool_result · 可改写tool_result · may rewritemessage_end(toolResult)appendMessage()streamFn(含结果)streamFn(+ result)done(stop)message_end · turn_end · agent_endappendMessage()idle · 等待输入idle · ready for input每个 message_end 都追加到会话 JSONLevery message_end is appended to the session JSONL1234567891011121314151617181920212223242526调用call事件 / 返回event / return1顺序编号,颜色 = 发起方order · colour = caller
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.009
05 · 事件05 · Eventspi-ai

一个协议贯穿所有 providerOne protocol across every provider

pi-ai · AssistantMessageEvent · 12
starttext_starttext_deltatext_endthinking_startthinking_deltathinking_endtoolcall_starttoolcall_deltatoolcall_enddoneerror
→
pi-agent-core · AgentEvent
agent_startturn_startmessage_startmessage_updatemessage_endtool_execution_starttool_execution_updatetool_execution_endturn_endagent_end

provider 增量在 agent 层变成 message_update;工具与轮次事件由循环自己发出。StreamFn 约定:不抛异常,失败以 error 事件编码。Provider deltas become message_update in the agent layer; tool and turn events are emitted by the loop itself. StreamFn contract: never throw, encode failures as error.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.010
06 · 核心类型06 · Key typespi-coding-agent

谁持有谁Who owns what

Key typesAgentSessionRuntime+session: AgentSession+services+newSession()+switchSession()+fork()+importFromJsonl()+dispose()SessionManager−byId · leafId+appendMessage()+appendCompaction()+getBranch() · getTree()+branch() · branchWithSummary()+buildSessionContext()+createBranchedSession()AgentSession+agent: Agent+sessionManager+settingsManager−_extensionRunner · _modelRuntime+prompt(text, options)+steer() · followUp()+setModel() · cycleModel()+compact() · navigateTree()+bindExtensions() · reload()+executeBash() · subscribe()ExtensionRunner+bindCore(actions)+setUIContext(ui, mode)+emit(event)+emitToolCall() · emitToolResult()Agent+state: AgentState+streamFunction: StreamFn+toolExecution+convertToLlm · transformContext+beforeToolCall · afterToolCall+prepareRequest · prepareNextTurn+finishTurn+prompt() · continue()+steer() · followUp()+abort() · waitForIdle()«interface»AgentTool+name · label · parameters+executionMode?+prepareArguments?(args)+execute(toolCallId, params, …)ModelRuntime+streamSimple(model, ctx)+getAuth() · checkAuth()+registerProvider(id, config)+resolveModel()«interface» pi-aiModels+getProviders() · getModel()+getAvailable() · refresh()+streamSimple()«interface»Provider+id · name · auth+getModels()+stream() · streamSimple()sessionagentsessionManager创建并 bindCore()creates · bindCore()_modelRuntimestate.tools *implementsgetProviders() *字段与方法均为节选members are a selection组合(持有)composition (owns)聚合 / 引用aggregation / reference实现接口implements调用 / 依赖calls / uses

ModelRuntime 实现 pi-ai 的 Models 接口;ExtensionRunner 由 AgentSession 创建。ModelRuntime implements pi-ai's Models; ExtensionRunner is created by AgentSession.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.011
07 · 会话07 · Sessionspi-coding-agent

一个 JSONL 文件就是一棵树One JSONL file is a tree

  • 每个条目带 id + parentIdEvery entry has id + parentId
  • leafId 指向当前位置leafId marks the current position
  • 分支 = 移动 leaf,从不改写历史Branching = moving the leaf, never rewriting
  • 11 种条目类型,含 compaction、context_edit11 entry types incl. compaction, context_edit
Session persistence & branching~/.pi/agent/sessions/<cwd>/<id>.jsonl只追加append-onlysessionmessagemessagemessagemessagemodel_changemessagemessagebranch_summarymessagea1f0 · messageuser · 修复失败的测试user · fix the failing testb2c4 · messageassistant · toolCall(bash)c3d9 · messagetoolResult · exit 0d4e1 · messageassistant · “已修复”assistant · “fixed”e5a2 · model_changeprovider · modelIdf6b3 · messageuser · 顺便加测试user · also add testsg7c8 · messageassistant · …h8d5 · branch_summaryfromId: g7c8 · summaryi9e6 · messageuser · 换个思路user · try another approachleafIdmessagethinking_level_changemodel_changeusagecompactionbranch_summarycustomcustom_messagelabelsession_infocontext_edit1文件头 · version 3 · id · cwd · parentSession?header · version 3 · id · cwd · parentSession?2a1f0← nulluser · 修复失败的测试user · fix the failing test3b2c4← a1f0assistant · toolCall(bash)4c3d9← b2c4toolResult · exit 05d4e1← c3d9assistant · “已修复”assistant · “fixed”6e5a2← d4e1provider · modelId7f6b3← e5a2user · 顺便加测试user · also add tests8g7c8← f6b3assistant · …9h8d5← d4e1fromId: g7c8 · summary10i9e6← h8d5user · 换个思路user · try another approach每行一个 JSON 对象;id 为 8 位 hex,← 是 parentIdone JSON object per line · 8-hex ids · ← is parentId分支点branch pointleaf 移回 d4e1 后追加leaf → d4e1, then appendfromId被放弃的路径仍留在文件里abandoned path stays in the filebuildSessionContext()leaf → root11 种条目11 entry types当前分支(进入上下文)active branch (in context)引用字段reference field上下文重建方向context rebuild direction
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.012
08 · 压缩08 · Compactionpi-coding-agent

三种触发,一条路径Three triggers, one path

16,384
默认 reserveTokensdefault reserveTokens
20,000
默认 keepRecentTokensdefault keepRecentTokens
1×
溢出后只重试一次retry once after overflow
Compaction上下文窗口里发生了什么WHAT HAPPENS TO THE CONTEXT WINDOW手动manual/compact · compact()阈值threshold超过 window − reservetokens > window − reserve溢出overflow上下文溢出 / 截断context overflow / truncationprepareCompaction()getBranch() → findCutPoint()compaction_start(reason)session_before_compact扩展钩子extension hook已取消cancelled不追加任何条目nothing appended扩展自带结果extension's resultfromExtension: truecompact()generateSummary() · LLMappendCompaction(summary, firstKeptEntryId, tokensBefore, …)随后 session_compact · compaction_endthen session_compact · compaction_endagent.continue()overflow 且 willRetry:仅一次overflow + willRetry: once完成done否则:等待下一次提示otherwise: wait for next promptcancelcompaction无nonewillRetry压缩前before较早的条目 → 交给 LLM 总结older entries → summarized by the LLM保留尾部 ≈ keepRecentTokens 20,000kept tail ≈ keepRecentTokens 20,000reserveTokens 16,384切点:user 或 assistant 消息,绝不切在 toolResult(firstKeptEntryId)cut point: a user or assistant message, never a toolResult (firstKeptEntryId)压缩后aftercompaction 摘要compaction summary同一段保留尾部the same kept tail腾出的空间freed space阈值:contextTokens > contextWindow − reserveTokens · 保留尾部按 estimateTokens()(chars/4)累加threshold: contextTokens > contextWindow − reserveTokens · kept tail sized with estimateTokens() (chars / 4)12345
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.013
09 · 扩展09 · ExtensionsExtensions

从发现到事件分发From discovery to dispatch

  • 来源:~/.pi/agent/extensions、.pi/extensions、settings packages、-eSources: ~/.pi/agent/extensions, .pi/extensions, settings packages, -e
  • jiti 直接加载 TypeScript,无需构建jiti loads TypeScript directly, no build step
  • bindCore() 之后注册才连到真实会话Registrations reach the real session after bindCore()
  • UI 由运行模式通过 bindExtensions() 提供UI is supplied by the mode via bindExtensions()
Extension lifecyclemain.ts · ResourceLoader扩展模块extension moduleAgentSession · ExtensionRunner运行模式run modereload()packageManager.resolve()loadExtensionsCached()按路径加载by resolved pathAgentSession由运行时创建created by runtime~/.pi/agent/extensions.pi/extensionssettings 里的包settings packages-e <path>factory(pi)jiti.import(path)registerTool · on(event)…ExtensionRunnerbindCore():接上真实动作bindCore(): real actionsbindExtensions(){ uiContext, mode }setUIContext()UI 由模式提供UI from the modesession_startresources_discoveremit(event)分发 41 种事件dispatches 41 event typesinputcontexttool_calltool_resultturn_endmessage_endagent_endmodel_selectsession_compactsession_shutdown发现Discover加载Load绑定核心Bind core绑定 UIBind UI运行期Runtime动作先是占位桩actions start as stubsregisterProvider 排队registerProvider queued来源sourcesimportnew注册表registrations事件为 41 种中的节选 · 实心 = 处理器可改写数据events: a selection of 41 · solid = handler may change data12345主流程main flow事件 / 回传event / hand-back调用call
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.014
09 · ExtensionAPI09 · ExtensionAPIExtensions

扩展几乎能改变一切Extensions can change almost anything

注册能力Register
registerToolregisterCommandregisterShortcutregisterFlagregisterProviderregisterMcpServerregisterMessageRendererregisterEntryRendererregisterToolRendererregisterVirtualModel
会话动作Act on the session
sendMessagesendUserMessageappendEntryexecsetActiveToolssetSessionNamesetLabelon(event)
41 种事件中可改写数据的Of 41 events, the ones that change data
input改写或吞掉输入rewrite or swallow input
context改写发给模型的消息rewrite messages sent to the model
before_provider_request改写请求负载rewrite the request payload
tool_call阻止工具调用block a tool call
tool_result改写工具结果rewrite a tool result
session_before_compact取消或替换压缩cancel or replace compaction
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.015
10 · 运行模式10 · Run modesRun modes

四种模式,一个运行时Four modes, one runtime

Run modespi <args>命令行入口CLI entryresolveAppMode()1--mode rpc→ rpc2--mode json→ json3-p · stdin/stdout ≠ TTY→ print4否则otherwise→ interactivestdiorunRpcMode()33 种 JSONL 命令 · 响应与事件33 JSONL commands · events outstdoutrunPrintMode() · json每个事件一行 JSONevery event as a JSON linestdoutrunPrintMode() · text一次性运行,只输出最终文本one-shot, prints the final textTTYInteractiveMode编辑器 · 聊天视图 · /命令editor · chat viewport · /commandsAgentSessionRuntime→ AgentSession四种模式驱动同一个运行时all four modes drive one runtime并各自调用and each callsbindExtensions({ mode })非交互模式会先接管non-interactive modesstdout,日志转到 stderrtake over stdout firstso logs go to stderrRPC 把扩展 UI 请求RPC forwards extension转成UI requests asextension_ui_requestpi-tuiTuiMainScreen | TuiAltScreencreateInteractiveTui()调用 / 驱动calls / drives运行模式run modepi-coding-agentpi-tui

RPC 模式:33 种 JSONL 命令,扩展 UI 请求以 extension_ui_request 代理给宿主。RPC mode: 33 JSONL command types; extension UI requests are proxied as extension_ui_request.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.016
11 · Provider11 · Providerspi-ai

42 个 provider,10 种对话 API42 providers, 10 chat APIs

Provider abstractionproviders/*.ts42 个内置 · createProvider()42 built-in · createProvider()api/*.lazy.ts10 种对话 API(KnownApi)10 chat APIs (KnownApi)AssistantMessageEventStream每个 API 都归一成这 12 种事件 · 失败也是事件,从不抛出every API normalizes to these 12 events · failures are events, never throwsrunLoop()streamFn(model, context)ModelRuntime实现 Models · registerProvider()implements Models · registerProvider()ant-lingbasetencerebrascloudflare-workers-aideepseekgroqhuggingfacemoonshotaimoonshotai-cnnvidiaqwen-token-planqwen-token-plan-cnqwen-token-plan-individualtogetherxiaomixiaomi-token-plan-amsxiaomi-token-plan-cnxiaomi-token-plan-sgpzaizai-coding-cnanthropickimi-codingminimaxminimax-cnvercel-ai-gatewaymetaopenaixaigoogleopenai-codexmistralgoogle-vertexamazon-bedrockradiustypesafecloudflare-ai-gatewayfireworksgithub-copilotopencodeopencode-goopenrouterazureModelsprovider / model 注册表provider · model registrygetModel(provider, id)checkAuth · getAuthprovider.streamSimple()×27openai-completions×11anthropic-messages×7openai-responses×2google-generative-ai×1azure-openai-responses×1openai-codex-responses×1mistral-conversations×1google-vertex×1bedrock-converse-stream×1pi-messagesstarttext_starttext_deltatext_endthinking_startthinking_deltathinking_endtoolcall_starttoolcall_deltatoolcall_enddoneerrorinterface Provider {id · name · baseUrl? · headers? · authgetModels() · stream() · streamSimple() }= provider 使用的对话 API(typesafe 只有分类器 API)= chat APIs a provider uses (typesafe has only a classifier API)streamSimple()lazyApi():首次流式调用时才 import 模块lazyApi(): module imported on its first stream callstream() · streamSimple()1调用call事件流回到 runLoopevent stream back to runLoop1顺序order234

API 模块经 lazyApi() 在首次调用时才 import;失败编码为 error 事件,从不抛出。API modules are imported on first use via lazyApi(); failures become error events, never throws.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.017
12 · TUI12 · TUIpi-tui

只重写变化的行Rewrite only what changed

TUI renderingstdin批量到达的字节bytes arrive in batchesProcessTerminalStdinBuffer 切分按键StdinBuffer splits keys焦点组件focused ComponenthandleInput(data)requestRender()nextTick 合并coalesced on nextTickscheduleRender()帧间隔 ≥ 16 ms≥ 16 ms between framesagent 事件agent eventsInteractiveMode 更新InteractiveMode updatesdoRender()render(width) → string[]合成 overlaycomposite overlays弹窗、选择器叠在上面dialogs · selectors on top对比 previousLinesdiff previousLines找出变化的行find changed lines只写变化的行write changed linesCSI ?2026h … ?2026l> fix the failing test● read math.test.ts● bash npm test ✓ 41 passed ✓ 1 fixedDone. The test now…──────────────────────▌render(width): string[]handleInput?(data)invalidate()force = true高亮 = 本帧重写的行highlighted = rewritten this frame组件契约COMPONENT CONTRACT123456789一帧的路径one frame异步事件async eventforce:重置并立即全量重绘force: reset + immediate full redraw

组件只实现 render(width) → string[];requestRender() 在 nextTick 合并,两帧间隔 ≥ 16 ms,再与 previousLines 做差分,在同步输出中只写变化的行。Components implement only render(width) → string[]; requestRender() coalesces on nextTick, frames are ≥ 16 ms apart, then a diff against previousLines writes only changed lines inside synchronized output.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.018
13 · 仓库13 · RepositoryInfra

代码都在哪里Where the code lives

48%
的源码在 coding-agentof source is coding-agent
1.04×
测试 / 源码 行数比test-to-source line ratio

实色 = 源码,浅色 = 测试。仅 .ts,不含 .d.ts。Solid = source, light = tests. .ts only, no .d.ts.

coding-agent85,816
ai26,797
durable20,404
tui19,409
chord8,817
mcp3,243
agent2,519
env2,073
server1,958
codemode1,837
evals1,446
client1,135
telemetry935
protocol869
图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.019
总结Takeawayspi-coding-agent

值得借鉴的五个设计Five design choices worth stealing

1
通用循环 + 钩子Generic loop + hooks

pi-agent-core 不知道“编码”;压缩、权限、工具清单全部通过 AgentLoopConfig 注入。pi-agent-core knows nothing about coding; compaction, permissions and tool loadout arrive through AgentLoopConfig.

2
失败即数据Failures are data

流错误是 error 事件,工具错误是 isError 结果——循环从不需要 try/catch 逃逸。Stream errors are error events and tool errors are isError results — the loop never unwinds.

3
追加式会话树Append-only session tree

分支、压缩、上下文编辑都是新条目,历史永不改写。Branches, compactions and context edits are all new entries; history is never rewritten.

4
Provider ≠ APIProvider ≠ API

42 个 provider 复用 10 种对话 API(KnownApi),并且按需懒加载。42 providers reuse 10 chat APIs (KnownApi), loaded lazily.

5
一切皆可扩展Everything is extensible

41 种事件 + register* API,用 jiti 直接加载 TypeScript。41 events plus the register* API, TypeScript loaded directly with jiti.

图解 Pi Agent · Pi v1.1.0Pi Agent, Illustrated · Pi v1.1.020
←
1 / 20