{"id":183,"date":"2026-03-21T22:47:21","date_gmt":"2026-03-21T14:47:21","guid":{"rendered":"https:\/\/pa.yingzhi8.cn\/index.php\/2026\/03\/21\/pi\/"},"modified":"2026-03-21T23:08:51","modified_gmt":"2026-03-21T15:08:51","slug":"pi","status":"publish","type":"post","link":"https:\/\/pa.yingzhi8.cn\/index.php\/2026\/03\/21\/pi\/","title":{"rendered":"Pi \u96c6\u6210\u67b6\u6784"},"content":{"rendered":"<h1>Pi \u96c6\u6210\u67b6\u6784<\/h1>\n<p>\u672c\u6587\u6863\u63cf\u8ff0\u4e86 OpenClaw \u5982\u4f55\u4e0e <a href=\"https:\/\/github.com\/badlogic\/pi-mono\/tree\/main\/packages\/coding-agent\">pi-coding-agent<\/a> \u53ca\u5176\u76f8\u5173\u5305\uff08<code>pi-ai<\/code>\u3001<code>pi-agent-core<\/code>\u3001<code>pi-tui<\/code>\uff09\u96c6\u6210\u4ee5\u5b9e\u73b0\u5176 AI \u667a\u80fd\u4f53\u80fd\u529b\u3002<\/p>\n<h2>\u6982\u8ff0<\/h2>\n<p>OpenClaw \u4f7f\u7528 pi SDK \u5c06 AI \u7f16\u7801\u667a\u80fd\u4f53\u5d4c\u5165\u5230\u5176\u6d88\u606f Gateway \u7f51\u5173\u67b6\u6784\u4e2d\u3002OpenClaw \u4e0d\u662f\u5c06 pi \u4f5c\u4e3a\u5b50\u8fdb\u7a0b\u751f\u6210\u6216\u4f7f\u7528 RPC \u6a21\u5f0f\uff0c\u800c\u662f\u901a\u8fc7 <code>createAgentSession()<\/code> \u76f4\u63a5\u5bfc\u5165\u5e76\u5b9e\u4f8b\u5316 pi \u7684 <code>AgentSession<\/code>\u3002\u8fd9\u79cd\u5d4c\u5165\u5f0f\u65b9\u6cd5\u63d0\u4f9b\u4e86\uff1a<\/p>\n<ul>\n<li>\u5bf9\u4f1a\u8bdd\u751f\u547d\u5468\u671f\u548c\u4e8b\u4ef6\u5904\u7406\u7684\u5b8c\u5168\u63a7\u5236<\/li>\n<li>\u81ea\u5b9a\u4e49\u5de5\u5177\u6ce8\u5165\uff08\u6d88\u606f\u3001\u6c99\u7bb1\u3001\u6e20\u9053\u7279\u5b9a\u64cd\u4f5c\uff09<\/li>\n<li>\u6bcf\u4e2a\u6e20\u9053\/\u4e0a\u4e0b\u6587\u7684\u7cfb\u7edf\u63d0\u793a\u81ea\u5b9a\u4e49<\/li>\n<li>\u652f\u6301\u5206\u652f\/\u538b\u7f29\u7684\u4f1a\u8bdd\u6301\u4e45\u5316<\/li>\n<li>\u5e26\u6545\u969c\u8f6c\u79fb\u7684\u591a\u8d26\u6237\u8ba4\u8bc1\u914d\u7f6e\u6587\u4ef6\u8f6e\u6362<\/li>\n<li>\u4e0e\u63d0\u4f9b\u5546\u65e0\u5173\u7684\u6a21\u578b\u5207\u6362<\/li>\n<\/ul>\n<h2>\u5305\u4f9d\u8d56<\/h2>\n<p>&#8220;`json  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\n{<br \/>\n  &#8220;@mariozechner\/pi-agent-core&#8221;: &#8220;0.49.3&#8221;,<br \/>\n  &#8220;@mariozechner\/pi-ai&#8221;: &#8220;0.49.3&#8221;,<br \/>\n  &#8220;@mariozechner\/pi-coding-agent&#8221;: &#8220;0.49.3&#8221;,<br \/>\n  &#8220;@mariozechner\/pi-tui&#8221;: &#8220;0.49.3&#8221;<br \/>\n}<\/p>\n<pre><code>\n| \u5305                 | \u7528\u9014                                                                              |\n| ----------------- | ------------------------------------------------------------------------------- |\n| `pi-ai`           | \u6838\u5fc3 LLM \u62bd\u8c61\uff1a`Model`\u3001`streamSimple`\u3001\u6d88\u606f\u7c7b\u578b\u3001\u63d0\u4f9b\u5546 API                                   |\n| `pi-agent-core`   | \u667a\u80fd\u4f53\u5faa\u73af\u3001\u5de5\u5177\u6267\u884c\u3001`AgentMessage` \u7c7b\u578b                                                    |\n| `pi-coding-agent` | \u9ad8\u7ea7 SDK\uff1a`createAgentSession`\u3001`SessionManager`\u3001`AuthStorage`\u3001`ModelRegistry`\u3001\u5185\u7f6e\u5de5\u5177 |\n| `pi-tui`          | \u7ec8\u7aef UI \u7ec4\u4ef6\uff08\u7528\u4e8e OpenClaw \u7684\u672c\u5730 TUI \u6a21\u5f0f\uff09                                                |\n\n## \u6587\u4ef6\u7ed3\u6784\n\n<\/code><\/pre>\n<p>src\/agents\/<br \/>\n\u251c\u2500\u2500 pi-embedded-runner.ts          # Re-exports from pi-embedded-runner\/<br \/>\n\u251c\u2500\u2500 pi-embedded-runner\/<br \/>\n\u2502   \u251c\u2500\u2500 run.ts                     # Main entry: runEmbeddedPiAgent()<br \/>\n\u2502   \u251c\u2500\u2500 run\/<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 attempt.ts             # Single attempt logic with session setup<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 params.ts              # RunEmbeddedPiAgentParams type<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 payloads.ts            # Build response payloads from run results<br \/>\n\u2502   \u2502   \u251c\u2500\u2500 images.ts              # Vision model image injection<br \/>\n\u2502   \u2502   \u2514\u2500\u2500 types.ts               # EmbeddedRunAttemptResult<br \/>\n\u2502   \u251c\u2500\u2500 abort.ts                   # Abort error detection<br \/>\n\u2502   \u251c\u2500\u2500 cache-ttl.ts               # Cache TTL tracking for context pruning<br \/>\n\u2502   \u251c\u2500\u2500 compact.ts                 # Manual\/auto compaction logic<br \/>\n\u2502   \u251c\u2500\u2500 extensions.ts              # Load pi extensions for embedded runs<br \/>\n\u2502   \u251c\u2500\u2500 extra-params.ts            # Provider-specific stream params<br \/>\n\u2502   \u251c\u2500\u2500 google.ts                  # Google\/Gemini turn ordering fixes<br \/>\n\u2502   \u251c\u2500\u2500 history.ts                 # History limiting (DM vs group)<br \/>\n\u2502   \u251c\u2500\u2500 lanes.ts                   # Session\/global command lanes<br \/>\n\u2502   \u251c\u2500\u2500 logger.ts                  # Subsystem logger<br \/>\n\u2502   \u251c\u2500\u2500 model.ts                   # Model resolution via ModelRegistry<br \/>\n\u2502   \u251c\u2500\u2500 runs.ts                    # Active run tracking, abort, queue<br \/>\n\u2502   \u251c\u2500\u2500 sandbox-info.ts            # Sandbox info for system prompt<br \/>\n\u2502   \u251c\u2500\u2500 session-manager-cache.ts   # SessionManager instance caching<br \/>\n\u2502   \u251c\u2500\u2500 session-manager-init.ts    # Session file initialization<br \/>\n\u2502   \u251c\u2500\u2500 system-prompt.ts           # System prompt builder<br \/>\n\u2502   \u251c\u2500\u2500 tool-split.ts              # Split tools into builtIn vs custom<br \/>\n\u2502   \u251c\u2500\u2500 types.ts                   # EmbeddedPiAgentMeta, EmbeddedPiRunResult<br \/>\n\u2502   \u2514\u2500\u2500 utils.ts                   # ThinkLevel mapping, error description<br \/>\n\u251c\u2500\u2500 pi-embedded-subscribe.ts       # Session event subscription\/dispatch<br \/>\n\u251c\u2500\u2500 pi-embedded-subscribe.types.ts # SubscribeEmbeddedPiSessionParams<br \/>\n\u251c\u2500\u2500 pi-embedded-subscribe.handlers.ts # Event handler factory<br \/>\n\u251c\u2500\u2500 pi-embedded-subscribe.handlers.lifecycle.ts<br \/>\n\u251c\u2500\u2500 pi-embedded-subscribe.handlers.types.ts<br \/>\n\u251c\u2500\u2500 pi-embedded-block-chunker.ts   # Streaming block reply chunking<br \/>\n\u251c\u2500\u2500 pi-embedded-messaging.ts       # Messaging tool sent tracking<br \/>\n\u251c\u2500\u2500 pi-embedded-helpers.ts         # Error classification, turn validation<br \/>\n\u251c\u2500\u2500 pi-embedded-helpers\/           # Helper modules<br \/>\n\u251c\u2500\u2500 pi-embedded-utils.ts           # Formatting utilities<br \/>\n\u251c\u2500\u2500 pi-tools.ts                    # createOpenClawCodingTools()<br \/>\n\u251c\u2500\u2500 pi-tools.abort.ts              # AbortSignal wrapping for tools<br \/>\n\u251c\u2500\u2500 pi-tools.policy.ts             # Tool allowlist\/denylist policy<br \/>\n\u251c\u2500\u2500 pi-tools.read.ts               # Read tool customizations<br \/>\n\u251c\u2500\u2500 pi-tools.schema.ts             # Tool schema normalization<br \/>\n\u251c\u2500\u2500 pi-tools.types.ts              # AnyAgentTool type alias<br \/>\n\u251c\u2500\u2500 pi-tool-definition-adapter.ts  # AgentTool -&gt; ToolDefinition adapter<br \/>\n\u251c\u2500\u2500 pi-settings.ts                 # Settings overrides<br \/>\n\u251c\u2500\u2500 pi-extensions\/                 # Custom pi extensions<br \/>\n\u2502   \u251c\u2500\u2500 compaction-safeguard.ts    # Safeguard extension<br \/>\n\u2502   \u251c\u2500\u2500 compaction-safeguard-runtime.ts<br \/>\n\u2502   \u251c\u2500\u2500 context-pruning.ts         # Cache-TTL context pruning extension<br \/>\n\u2502   \u2514\u2500\u2500 context-pruning\/<br \/>\n\u251c\u2500\u2500 model-auth.ts                  # Auth profile resolution<br \/>\n\u251c\u2500\u2500 auth-profiles.ts               # Profile store, cooldown, failover<br \/>\n\u251c\u2500\u2500 model-selection.ts             # Default model resolution<br \/>\n\u251c\u2500\u2500 models-config.ts               # models.json generation<br \/>\n\u251c\u2500\u2500 model-catalog.ts               # Model catalog cache<br \/>\n\u251c\u2500\u2500 context-window-guard.ts        # Context window validation<br \/>\n\u251c\u2500\u2500 failover-error.ts              # FailoverError class<br \/>\n\u251c\u2500\u2500 defaults.ts                    # DEFAULT_PROVIDER, DEFAULT_MODEL<br \/>\n\u251c\u2500\u2500 system-prompt.ts               # buildAgentSystemPrompt()<br \/>\n\u251c\u2500\u2500 system-prompt-params.ts        # System prompt parameter resolution<br \/>\n\u251c\u2500\u2500 system-prompt-report.ts        # Debug report generation<br \/>\n\u251c\u2500\u2500 tool-summaries.ts              # Tool description summaries<br \/>\n\u251c\u2500\u2500 tool-policy.ts                 # Tool policy resolution<br \/>\n\u251c\u2500\u2500 transcript-policy.ts           # Transcript validation policy<br \/>\n\u251c\u2500\u2500 skills.ts                      # Skill snapshot\/prompt building<br \/>\n\u251c\u2500\u2500 skills\/                        # Skill subsystem<br \/>\n\u251c\u2500\u2500 sandbox.ts                     # Sandbox context resolution<br \/>\n\u251c\u2500\u2500 sandbox\/                       # Sandbox subsystem<br \/>\n\u251c\u2500\u2500 channel-tools.ts               # Channel-specific tool injection<br \/>\n\u251c\u2500\u2500 openclaw-tools.ts              # OpenClaw-specific tools<br \/>\n\u251c\u2500\u2500 bash-tools.ts                  # exec\/process tools<br \/>\n\u251c\u2500\u2500 apply-patch.ts                 # apply_patch tool (OpenAI)<br \/>\n\u251c\u2500\u2500 tools\/                         # Individual tool implementations<br \/>\n\u2502   \u251c\u2500\u2500 browser-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 canvas-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 cron-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 discord-actions<em>.ts<br \/>\n\u2502   \u251c\u2500\u2500 gateway-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 image-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 message-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 nodes-tool.ts<br \/>\n\u2502   \u251c\u2500\u2500 session<\/em>.ts<br \/>\n\u2502   \u251c\u2500\u2500 slack-actions.ts<br \/>\n\u2502   \u251c\u2500\u2500 telegram-actions.ts<br \/>\n\u2502   \u251c\u2500\u2500 web-*.ts<br \/>\n\u2502   \u2514\u2500\u2500 whatsapp-actions.ts<br \/>\n\u2514\u2500\u2500 &#8230;<\/p>\n<pre><code>\n## \u6838\u5fc3\u96c6\u6210\u6d41\u7a0b\n\n### 1. \u8fd0\u884c\u5d4c\u5165\u5f0f\u667a\u80fd\u4f53\n\n\u4e3b\u5165\u53e3\u70b9\u662f `pi-embedded-runner\/run.ts` \u4e2d\u7684 `runEmbeddedPiAgent()`\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nimport { runEmbeddedPiAgent } from &quot;.\/agents\/pi-embedded-runner.js&quot;;\n\nconst result = await runEmbeddedPiAgent({\n  sessionId: &quot;user-123&quot;,\n  sessionKey: &quot;main:whatsapp:+1234567890&quot;,\n  sessionFile: &quot;\/path\/to\/session.jsonl&quot;,\n  workspaceDir: &quot;\/path\/to\/workspace&quot;,\n  config: openclawConfig,\n  prompt: &quot;Hello, how are you?&quot;,\n  provider: &quot;anthropic&quot;,\n  model: &quot;claude-sonnet-4-20250514&quot;,\n  timeoutMs: 120_000,\n  runId: &quot;run-abc&quot;,\n  onBlockReply: async (payload) =&gt; {\n    await sendToChannel(payload.text, payload.mediaUrls);\n  },\n});\n<\/code><\/pre>\n<h3>2. \u4f1a\u8bdd\u521b\u5efa<\/h3>\n<p>\u5728 <code>runEmbeddedAttempt()<\/code>\uff08\u7531 <code>runEmbeddedPiAgent()<\/code> \u8c03\u7528\uff09\u5185\u90e8\uff0c\u4f7f\u7528 pi SDK\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nimport {<br \/>\n  createAgentSession,<br \/>\n  DefaultResourceLoader,<br \/>\n  SessionManager,<br \/>\n  SettingsManager,<br \/>\n} from &#8220;@mariozechner\/pi-coding-agent&#8221;;<\/p>\n<p>const resourceLoader = new DefaultResourceLoader({<br \/>\n  cwd: resolvedWorkspace,<br \/>\n  agentDir,<br \/>\n  settingsManager,<br \/>\n  additionalExtensionPaths,<br \/>\n});<br \/>\nawait resourceLoader.reload();<\/p>\n<p>const { session } = await createAgentSession({<br \/>\n  cwd: resolvedWorkspace,<br \/>\n  agentDir,<br \/>\n  authStorage: params.authStorage,<br \/>\n  modelRegistry: params.modelRegistry,<br \/>\n  model: params.model,<br \/>\n  thinkingLevel: mapThinkingLevel(params.thinkLevel),<br \/>\n  tools: builtInTools,<br \/>\n  customTools: allCustomTools,<br \/>\n  sessionManager,<br \/>\n  settingsManager,<br \/>\n  resourceLoader,<br \/>\n});<\/p>\n<p>applySystemPromptOverrideToSession(session, systemPromptOverride);<\/p>\n<pre><code>\n### 3. \u4e8b\u4ef6\u8ba2\u9605\n\n`subscribeEmbeddedPiSession()` \u8ba2\u9605 pi \u7684 `AgentSession` \u4e8b\u4ef6\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst subscription = subscribeEmbeddedPiSession({\n  session: activeSession,\n  runId: params.runId,\n  verboseLevel: params.verboseLevel,\n  reasoningMode: params.reasoningLevel,\n  toolResultFormat: params.toolResultFormat,\n  onToolResult: params.onToolResult,\n  onReasoningStream: params.onReasoningStream,\n  onBlockReply: params.onBlockReply,\n  onPartialReply: params.onPartialReply,\n  onAgentEvent: params.onAgentEvent,\n});\n<\/code><\/pre>\n<p>\u5904\u7406\u7684\u4e8b\u4ef6\u5305\u62ec\uff1a<\/p>\n<ul>\n<li><code>message_start<\/code> \/ <code>message_end<\/code> \/ <code>message_update<\/code>\uff08\u6d41\u5f0f\u6587\u672c\/\u601d\u8003\uff09<\/li>\n<li><code>tool_execution_start<\/code> \/ <code>tool_execution_update<\/code> \/ <code>tool_execution_end<\/code><\/li>\n<li><code>turn_start<\/code> \/ <code>turn_end<\/code><\/li>\n<li><code>agent_start<\/code> \/ <code>agent_end<\/code><\/li>\n<li><code>auto_compaction_start<\/code> \/ <code>auto_compaction_end<\/code><\/li>\n<\/ul>\n<h3>4. \u63d0\u793a<\/h3>\n<p>\u8bbe\u7f6e\u5b8c\u6210\u540e\uff0c\u4f1a\u8bdd\u88ab\u63d0\u793a\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nawait session.prompt(effectivePrompt, { images: imageResult.images });<\/p>\n<pre><code>\nSDK \u5904\u7406\u5b8c\u6574\u7684\u667a\u80fd\u4f53\u5faa\u73af\uff1a\u53d1\u9001\u5230 LLM\u3001\u6267\u884c\u5de5\u5177\u8c03\u7528\u3001\u6d41\u5f0f\u54cd\u5e94\u3002\n\n## \u5de5\u5177\u67b6\u6784\n\n### \u5de5\u5177\u7ba1\u9053\n\n1. **\u57fa\u7840\u5de5\u5177**\uff1api \u7684 `codingTools`\uff08read\u3001bash\u3001edit\u3001write\uff09\n2. **\u81ea\u5b9a\u4e49\u66ff\u6362**\uff1aOpenClaw \u5c06 bash \u66ff\u6362\u4e3a `exec`\/`process`\uff0c\u4e3a\u6c99\u7bb1\u81ea\u5b9a\u4e49 read\/edit\/write\n3. **OpenClaw \u5de5\u5177**\uff1a\u6d88\u606f\u3001\u6d4f\u89c8\u5668\u3001\u753b\u5e03\u3001\u4f1a\u8bdd\u3001\u5b9a\u65f6\u4efb\u52a1\u3001Gateway \u7f51\u5173\u7b49\n4. **\u6e20\u9053\u5de5\u5177**\uff1aDiscord\/Telegram\/Slack\/WhatsApp \u7279\u5b9a\u7684\u64cd\u4f5c\u5de5\u5177\n5. **\u7b56\u7565\u8fc7\u6ee4**\uff1a\u5de5\u5177\u6309\u914d\u7f6e\u6587\u4ef6\u3001\u63d0\u4f9b\u5546\u3001\u667a\u80fd\u4f53\u3001\u7fa4\u7ec4\u3001\u6c99\u7bb1\u7b56\u7565\u8fc7\u6ee4\n6. **Schema \u89c4\u8303\u5316**\uff1a\u4e3a Gemini\/OpenAI \u7684\u7279\u6b8a\u60c5\u51b5\u6e05\u7406 Schema\n7. **AbortSignal \u5305\u88c5**\uff1a\u5de5\u5177\u88ab\u5305\u88c5\u4ee5\u5c0a\u91cd\u4e2d\u6b62\u4fe1\u53f7\n\n### \u5de5\u5177\u5b9a\u4e49\u9002\u914d\u5668\n\npi-agent-core \u7684 `AgentTool` \u4e0e pi-coding-agent \u7684 `ToolDefinition` \u6709\u4e0d\u540c\u7684 `execute` \u7b7e\u540d\u3002`pi-tool-definition-adapter.ts` \u4e2d\u7684\u9002\u914d\u5668\u6865\u63a5\u4e86\u8fd9\u4e00\u70b9\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nexport function toToolDefinitions(tools: AnyAgentTool[]): ToolDefinition[] {\n  return tools.map((tool) =&gt; ({\n    name: tool.name,\n    label: tool.label ?? name,\n    description: tool.description ?? &quot;&quot;,\n    parameters: tool.parameters,\n    execute: async (toolCallId, params, onUpdate, _ctx, signal) =&gt; {\n      \/\/ pi-coding-agent signature differs from pi-agent-core\n      return await tool.execute(toolCallId, params, signal, onUpdate);\n    },\n  }));\n}\n<\/code><\/pre>\n<h3>\u5de5\u5177\u62c6\u5206\u7b56\u7565<\/h3>\n<p><code>splitSdkTools()<\/code> \u901a\u8fc7 <code>customTools<\/code> \u4f20\u9012\u6240\u6709\u5de5\u5177\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nexport function splitSdkTools(options: { tools: AnyAgentTool[]; sandboxEnabled: boolean }) {<br \/>\n  return {<br \/>\n    builtInTools: [], \/\/ Empty. We override everything<br \/>\n    customTools: toToolDefinitions(options.tools),<br \/>\n  };<br \/>\n}<\/p>\n<pre><code>\n\u8fd9\u786e\u4fdd OpenClaw \u7684\u7b56\u7565\u8fc7\u6ee4\u3001\u6c99\u7bb1\u96c6\u6210\u548c\u6269\u5c55\u5de5\u5177\u96c6\u5728\u5404\u63d0\u4f9b\u5546\u4e4b\u95f4\u4fdd\u6301\u4e00\u81f4\u3002\n\n## \u7cfb\u7edf\u63d0\u793a\u6784\u5efa\n\n\u7cfb\u7edf\u63d0\u793a\u5728 `buildAgentSystemPrompt()`\uff08`system-prompt.ts`\uff09\u4e2d\u6784\u5efa\u3002\u5b83\u7ec4\u88c5\u4e00\u4e2a\u5b8c\u6574\u7684\u63d0\u793a\uff0c\u5305\u542b\u5de5\u5177\u3001\u5de5\u5177\u8c03\u7528\u98ce\u683c\u3001\u5b89\u5168\u62a4\u680f\u3001OpenClaw CLI \u53c2\u8003\u3001Skills\u3001\u6587\u6863\u3001\u5de5\u4f5c\u533a\u3001\u6c99\u7bb1\u3001\u6d88\u606f\u3001\u56de\u590d\u6807\u7b7e\u3001\u8bed\u97f3\u3001\u9759\u9ed8\u56de\u590d\u3001\u5fc3\u8df3\u3001\u8fd0\u884c\u65f6\u5143\u6570\u636e\u7b49\u90e8\u5206\uff0c\u4ee5\u53ca\u542f\u7528\u65f6\u7684\u8bb0\u5fc6\u548c\u53cd\u5e94\uff0c\u8fd8\u6709\u53ef\u9009\u7684\u4e0a\u4e0b\u6587\u6587\u4ef6\u548c\u989d\u5916\u7cfb\u7edf\u63d0\u793a\u5185\u5bb9\u3002\u90e8\u5206\u5185\u5bb9\u5728\u5b50\u667a\u80fd\u4f53\u4f7f\u7528\u7684\u6700\u5c0f\u63d0\u793a\u6a21\u5f0f\u4e0b\u4f1a\u88ab\u88c1\u526a\u3002\n\n\u63d0\u793a\u5728\u4f1a\u8bdd\u521b\u5efa\u540e\u901a\u8fc7 `applySystemPromptOverrideToSession()` \u5e94\u7528\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst systemPromptOverride = createSystemPromptOverride(appendPrompt);\napplySystemPromptOverrideToSession(session, systemPromptOverride);\n<\/code><\/pre>\n<h2>\u4f1a\u8bdd\u7ba1\u7406<\/h2>\n<h3>\u4f1a\u8bdd\u6587\u4ef6<\/h3>\n<p>\u4f1a\u8bdd\u662f\u5177\u6709\u6811\u7ed3\u6784\uff08id\/parentId \u94fe\u63a5\uff09\u7684 JSONL \u6587\u4ef6\u3002Pi \u7684 <code>SessionManager<\/code> \u5904\u7406\u6301\u4e45\u5316\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nconst sessionManager = SessionManager.open(params.sessionFile);<\/p>\n<pre><code>\nOpenClaw \u7528 `guardSessionManager()` \u5305\u88c5\u5b83\u4ee5\u786e\u4fdd\u5de5\u5177\u7ed3\u679c\u5b89\u5168\u3002\n\n### \u4f1a\u8bdd\u7f13\u5b58\n\n`session-manager-cache.ts` \u7f13\u5b58 SessionManager \u5b9e\u4f8b\u4ee5\u907f\u514d\u91cd\u590d\u7684\u6587\u4ef6\u89e3\u6790\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nawait prewarmSessionFile(params.sessionFile);\nsessionManager = SessionManager.open(params.sessionFile);\ntrackSessionManagerAccess(params.sessionFile);\n<\/code><\/pre>\n<h3>\u5386\u53f2\u9650\u5236<\/h3>\n<p><code>limitHistoryTurns()<\/code> \u6839\u636e\u6e20\u9053\u7c7b\u578b\uff08\u79c1\u4fe1 vs \u7fa4\u7ec4\uff09\u88c1\u526a\u5bf9\u8bdd\u5386\u53f2\u3002<\/p>\n<h3>\u538b\u7f29<\/h3>\n<p>\u81ea\u52a8\u538b\u7f29\u5728\u4e0a\u4e0b\u6587\u6ea2\u51fa\u65f6\u89e6\u53d1\u3002<code>compactEmbeddedPiSessionDirect()<\/code> \u5904\u7406\u624b\u52a8\u538b\u7f29\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nconst compactResult = await compactEmbeddedPiSessionDirect({<br \/>\n  sessionId, sessionFile, provider, model, &#8230;<br \/>\n});<\/p>\n<pre><code>\n## \u8ba4\u8bc1\u4e0e\u6a21\u578b\u89e3\u6790\n\n### \u8ba4\u8bc1\u914d\u7f6e\u6587\u4ef6\n\nOpenClaw \u7ef4\u62a4\u4e00\u4e2a\u8ba4\u8bc1\u914d\u7f6e\u6587\u4ef6\u5b58\u50a8\uff0c\u6bcf\u4e2a\u63d0\u4f9b\u5546\u6709\u591a\u4e2a API \u5bc6\u94a5\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst authStore = ensureAuthProfileStore(agentDir, { allowKeychainPrompt: false });\nconst profileOrder = resolveAuthProfileOrder({ cfg, store: authStore, provider, preferredProfile });\n<\/code><\/pre>\n<p>\u914d\u7f6e\u6587\u4ef6\u5728\u5931\u8d25\u65f6\u8f6e\u6362\uff0c\u5e76\u5e26\u6709\u51b7\u5374\u8ddf\u8e2a\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nawait markAuthProfileFailure({ store, profileId, reason, cfg, agentDir });<br \/>\nconst rotated = await advanceAuthProfile();<\/p>\n<pre><code>\n### \u6a21\u578b\u89e3\u6790\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nimport { resolveModel } from &quot;.\/pi-embedded-runner\/model.js&quot;;\n\nconst { model, error, authStorage, modelRegistry } = resolveModel(\n  provider,\n  modelId,\n  agentDir,\n  config,\n);\n\n\/\/ Uses pi's ModelRegistry and AuthStorage\nauthStorage.setRuntimeApiKey(model.provider, apiKeyInfo.apiKey);\n<\/code><\/pre>\n<h3>\u6545\u969c\u8f6c\u79fb<\/h3>\n<p><code>FailoverError<\/code> \u5728\u914d\u7f6e\u4e86\u56de\u9000\u65f6\u89e6\u53d1\u6a21\u578b\u56de\u9000\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nif (fallbackConfigured &amp;&amp; isFailoverErrorMessage(errorText)) {<br \/>\n  throw new FailoverError(errorText, {<br \/>\n    reason: promptFailoverReason ?? &#8220;unknown&#8221;,<br \/>\n    provider,<br \/>\n    model: modelId,<br \/>\n    profileId,<br \/>\n    status: resolveFailoverStatus(promptFailoverReason),<br \/>\n  });<br \/>\n}<\/p>\n<pre><code>\n## Pi \u6269\u5c55\n\nOpenClaw \u52a0\u8f7d\u81ea\u5b9a\u4e49 pi \u6269\u5c55\u4ee5\u5b9e\u73b0\u7279\u6b8a\u884c\u4e3a\uff1a\n\n### \u538b\u7f29\u5b89\u5168\u62a4\u680f\n\n`pi-extensions\/compaction-safeguard.ts` \u4e3a\u538b\u7f29\u6dfb\u52a0\u62a4\u680f\uff0c\u5305\u62ec\u81ea\u9002\u5e94\u4ee4\u724c\u9884\u7b97\u4ee5\u53ca\u5de5\u5177\u5931\u8d25\u548c\u6587\u4ef6\u64cd\u4f5c\u6458\u8981\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nif (resolveCompactionMode(params.cfg) === &quot;safeguard&quot;) {\n  setCompactionSafeguardRuntime(params.sessionManager, { maxHistoryShare });\n  paths.push(resolvePiExtensionPath(&quot;compaction-safeguard&quot;));\n}\n<\/code><\/pre>\n<h3>\u4e0a\u4e0b\u6587\u88c1\u526a<\/h3>\n<p><code>pi-extensions\/context-pruning.ts<\/code> \u5b9e\u73b0\u57fa\u4e8e\u7f13\u5b58 TTL \u7684\u4e0a\u4e0b\u6587\u88c1\u526a\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nif (cfg?.agents?.defaults?.contextPruning?.mode === &#8220;cache-ttl&#8221;) {<br \/>\n  setContextPruningRuntime(params.sessionManager, {<br \/>\n    settings,<br \/>\n    contextWindowTokens,<br \/>\n    isToolPrunable,<br \/>\n    lastCacheTouchAt,<br \/>\n  });<br \/>\n  paths.push(resolvePiExtensionPath(&#8220;context-pruning&#8221;));<br \/>\n}<\/p>\n<pre><code>\n## \u6d41\u5f0f\u4f20\u8f93\u4e0e\u5757\u56de\u590d\n\n### \u5757\u5206\u5757\n\n`EmbeddedBlockChunker` \u7ba1\u7406\u5c06\u6d41\u5f0f\u6587\u672c\u5206\u6210\u79bb\u6563\u7684\u56de\u590d\u5757\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst blockChunker = blockChunking ? new EmbeddedBlockChunker(blockChunking) : null;\n<\/code><\/pre>\n<h3>\u601d\u8003\/\u6700\u7ec8\u6807\u7b7e\u5265\u79bb<\/h3>\n<p>\u6d41\u5f0f\u8f93\u51fa\u88ab\u5904\u7406\u4ee5\u5265\u79bb <code>&lt;think&gt;<\/code>\/<code>&lt;thinking&gt;<\/code> \u5757\u5e76\u63d0\u53d6 <code>&lt;final&gt;<\/code> \u5185\u5bb9\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nconst stripBlockTags = (text: string, state: { thinking: boolean; final: boolean }) =&gt; {<br \/>\n  \/\/ Strip &#8230; content<br \/>\n  \/\/ If enforceFinalTag, only return &#8230; content<br \/>\n};<\/p>\n<pre><code>\n### \u56de\u590d\u6307\u4ee4\n\n\u56de\u590d\u6307\u4ee4\u5982 `[[media:url]]`\u3001`[[voice]]`\u3001`[[reply:id]]` \u88ab\u89e3\u6790\u548c\u63d0\u53d6\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst { text: cleanedText, mediaUrls, audioAsVoice, replyToId } = consumeReplyDirectives(chunk);\n<\/code><\/pre>\n<h2>\u9519\u8bef\u5904\u7406<\/h2>\n<h3>\u9519\u8bef\u5206\u7c7b<\/h3>\n<p><code>pi-embedded-helpers.ts<\/code> \u5bf9\u9519\u8bef\u8fdb\u884c\u5206\u7c7b\u4ee5\u8fdb\u884c\u9002\u5f53\u5904\u7406\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nisContextOverflowError(errorText)     \/\/ Context too large<br \/>\nisCompactionFailureError(errorText)   \/\/ Compaction failed<br \/>\nisAuthAssistantError(lastAssistant)   \/\/ Auth failure<br \/>\nisRateLimitAssistantError(&#8230;)        \/\/ Rate limited<br \/>\nisFailoverAssistantError(&#8230;)         \/\/ Should failover<br \/>\nclassifyFailoverReason(errorText)     \/\/ &#8220;auth&#8221; | &#8220;rate_limit&#8221; | &#8220;quota&#8221; | &#8220;timeout&#8221; | &#8230;<\/p>\n<pre><code>\n### \u601d\u8003\u7ea7\u522b\u56de\u9000\n\n\u5982\u679c\u601d\u8003\u7ea7\u522b\u4e0d\u53d7\u652f\u6301\uff0c\u5b83\u4f1a\u56de\u9000\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\nconst fallbackThinking = pickFallbackThinkingLevel({\n  message: errorText,\n  attempted: attemptedThinking,\n});\nif (fallbackThinking) {\n  thinkLevel = fallbackThinking;\n  continue;\n}\n<\/code><\/pre>\n<h2>\u6c99\u7bb1\u96c6\u6210<\/h2>\n<p>\u5f53\u542f\u7528\u6c99\u7bb1\u6a21\u5f0f\u65f6\uff0c\u5de5\u5177\u548c\u8def\u5f84\u53d7\u5230\u7ea6\u675f\uff1a<\/p>\n<p>&#8220;`typescript  theme={&#8220;theme&#8221;:{&#8220;light&#8221;:&#8221;min-light&#8221;,&#8221;dark&#8221;:&#8221;min-dark&#8221;}}<br \/>\nconst sandbox = await resolveSandboxContext({<br \/>\n  config: params.config,<br \/>\n  sessionKey: sandboxSessionKey,<br \/>\n  workspaceDir: resolvedWorkspace,<br \/>\n});<\/p>\n<p>if (sandboxRoot) {<br \/>\n  \/\/ Use sandboxed read\/edit\/write tools<br \/>\n  \/\/ Exec runs in container<br \/>\n  \/\/ Browser uses bridge URL<br \/>\n}<\/p>\n<pre><code>\n## \u63d0\u4f9b\u5546\u7279\u5b9a\u5904\u7406\n\n### Anthropic\n\n* \u62d2\u7edd\u9b54\u672f\u5b57\u7b26\u4e32\u6e05\u9664\n* \u8fde\u7eed\u89d2\u8272\u7684\u56de\u5408\u9a8c\u8bc1\n* Claude Code \u53c2\u6570\u517c\u5bb9\u6027\n\n### Google\/Gemini\n\n* \u56de\u5408\u6392\u5e8f\u4fee\u590d\uff08`applyGoogleTurnOrderingFix`\uff09\n* \u5de5\u5177 schema \u6e05\u7406\uff08`sanitizeToolsForGoogle`\uff09\n* \u4f1a\u8bdd\u5386\u53f2\u6e05\u7406\uff08`sanitizeSessionHistory`\uff09\n\n### OpenAI\n\n* Codex \u6a21\u578b\u7684 `apply_patch` \u5de5\u5177\n* \u601d\u8003\u7ea7\u522b\u964d\u7ea7\u5904\u7406\n\n## TUI \u96c6\u6210\n\nOpenClaw \u8fd8\u6709\u4e00\u4e2a\u672c\u5730 TUI \u6a21\u5f0f\uff0c\u76f4\u63a5\u4f7f\u7528 pi-tui \u7ec4\u4ef6\uff1a\n\n```typescript  theme={&quot;theme&quot;:{&quot;light&quot;:&quot;min-light&quot;,&quot;dark&quot;:&quot;min-dark&quot;}}\n\/\/ src\/tui\/tui.ts\nimport { ... } from &quot;@mariozechner\/pi-tui&quot;;\n<\/code><\/pre>\n<p>\u8fd9\u63d0\u4f9b\u4e86\u4e0e pi \u539f\u751f\u6a21\u5f0f\u7c7b\u4f3c\u7684\u4ea4\u4e92\u5f0f\u7ec8\u7aef\u4f53\u9a8c\u3002<\/p>\n<h2>\u4e0e Pi CLI \u7684\u4e3b\u8981\u533a\u522b<\/h2>\n<table>\n<thead>\n<tr>\n<th>\u65b9\u9762<\/th>\n<th>Pi CLI<\/th>\n<th>OpenClaw \u5d4c\u5165\u5f0f<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u8c03\u7528\u65b9\u5f0f<\/td>\n<td><code>pi<\/code> \u547d\u4ee4 \/ RPC<\/td>\n<td>\u901a\u8fc7 <code>createAgentSession()<\/code> \u7684 SDK<\/td>\n<\/tr>\n<tr>\n<td>\u5de5\u5177<\/td>\n<td>\u9ed8\u8ba4\u7f16\u7801\u5de5\u5177<\/td>\n<td>\u81ea\u5b9a\u4e49 OpenClaw \u5de5\u5177\u5957\u4ef6<\/td>\n<\/tr>\n<tr>\n<td>\u7cfb\u7edf\u63d0\u793a<\/td>\n<td>AGENTS.md + prompts<\/td>\n<td>\u6309\u6e20\u9053\/\u4e0a\u4e0b\u6587\u52a8\u6001\u751f\u6210<\/td>\n<\/tr>\n<tr>\n<td>\u4f1a\u8bdd\u5b58\u50a8<\/td>\n<td><code>~\/.pi\/agent\/sessions\/<\/code><\/td>\n<td><code>~\/.openclaw\/agents\/&lt;agentId&gt;\/sessions\/<\/code>\uff08\u6216 <code>$OPENCLAW_STATE_DIR\/agents\/&lt;agentId&gt;\/sessions\/<\/code>\uff09<\/td>\n<\/tr>\n<tr>\n<td>\u8ba4\u8bc1<\/td>\n<td>\u5355\u4e00\u51ed\u8bc1<\/td>\n<td>\u5e26\u8f6e\u6362\u7684\u591a\u914d\u7f6e\u6587\u4ef6<\/td>\n<\/tr>\n<tr>\n<td>\u6269\u5c55<\/td>\n<td>\u4ece\u78c1\u76d8\u52a0\u8f7d<\/td>\n<td>\u7f16\u7a0b\u65b9\u5f0f + \u78c1\u76d8\u8def\u5f84<\/td>\n<\/tr>\n<tr>\n<td>\u4e8b\u4ef6\u5904\u7406<\/td>\n<td>TUI \u6e32\u67d3<\/td>\n<td>\u57fa\u4e8e\u56de\u8c03\uff08onBlockReply \u7b49\uff09<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>\u672a\u6765\u8003\u8651<\/h2>\n<p>\u53ef\u80fd\u9700\u8981\u91cd\u6784\u7684\u9886\u57df\uff1a<\/p>\n<ol>\n<li><strong>\u5de5\u5177\u7b7e\u540d\u5bf9\u9f50<\/strong>\uff1a\u76ee\u524d\u5728 pi-agent-core \u548c pi-coding-agent \u7b7e\u540d\u4e4b\u95f4\u9002\u914d<\/li>\n<li><strong>\u4f1a\u8bdd\u7ba1\u7406\u5668\u5305\u88c5<\/strong>\uff1a<code>guardSessionManager<\/code> \u589e\u52a0\u4e86\u5b89\u5168\u6027\u4f46\u589e\u52a0\u4e86\u590d\u6742\u6027<\/li>\n<li><strong>\u6269\u5c55\u52a0\u8f7d<\/strong>\uff1a\u53ef\u4ee5\u66f4\u76f4\u63a5\u5730\u4f7f\u7528 pi \u7684 <code>ResourceLoader<\/code><\/li>\n<li><strong>\u6d41\u5f0f\u5904\u7406\u5668\u590d\u6742\u6027<\/strong>\uff1a<code>subscribeEmbeddedPiSession<\/code> \u5df2\u7ecf\u53d8\u5f97\u5f88\u5927<\/li>\n<li><strong>\u63d0\u4f9b\u5546\u7279\u6b8a\u60c5\u51b5<\/strong>\uff1a\u8bb8\u591a\u63d0\u4f9b\u5546\u7279\u5b9a\u7684\u4ee3\u7801\u8def\u5f84\uff0cpi \u53ef\u80fd\u53ef\u4ee5\u5904\u7406<\/li>\n<\/ol>\n<h2>\u6d4b\u8bd5<\/h2>\n<p>\u6240\u6709\u6db5\u76d6 pi \u96c6\u6210\u53ca\u5176\u6269\u5c55\u7684\u73b0\u6709\u6d4b\u8bd5\uff1a<\/p>\n<ul>\n<li><code>src\/agents\/pi-embedded-block-chunker.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.buildbootstrapcontextfiles.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.classifyfailoverreason.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.downgradeopenai-reasoning.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.formatassistanterrortext.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.formatrawassistanterrorforui.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.image-dimension-error.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.image-size-error.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.isautherrormessage.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.isbillingerrormessage.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.iscloudcodeassistformaterror.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.iscompactionfailureerror.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.iscontextoverflowerror.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.isfailovererrormessage.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.islikelycontextoverflowerror.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.ismessagingtoolduplicate.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.messaging-duplicate.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.normalizetextforcomparison.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.resolvebootstrapmaxchars.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitize-session-messages-images.keeps-tool-call-tool-result-ids-unchanged.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitize-session-messages-images.removes-empty-assistant-text-blocks-but-preserves.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitizegoogleturnordering.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitizesessionmessagesimages-thought-signature-stripping.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitizetoolcallid.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.sanitizeuserfacingtext.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.stripthoughtsignatures.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-helpers.validate-turns.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner-extraparams.live.test.ts<\/code>\uff08\u5b9e\u65f6\uff09<\/li>\n<li><code>src\/agents\/pi-embedded-runner-extraparams.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.applygoogleturnorderingfix.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.buildembeddedsandboxinfo.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.createsystempromptoverride.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.get-dm-history-limit-from-session-key.falls-back-provider-default-per-dm-not.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.get-dm-history-limit-from-session-key.returns-undefined-sessionkey-is-undefined.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.google-sanitize-thinking.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.guard.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.limithistoryturns.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.resolvesessionagentids.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.run-embedded-pi-agent.auth-profile-rotation.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.sanitize-session-history.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.splitsdktools.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-runner.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.code-span-awareness.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.reply-tags.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.calls-onblockreplyflush-before-tool-execution-start-preserve.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-append-text-end-content-is.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-call-onblockreplyflush-callback-is-not.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-duplicate-text-end-repeats-full.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.does-not-emit-duplicate-block-replies-text.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-block-replies-text-end-does-not.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.emits-reasoning-as-separate-message-enabled.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.filters-final-suppresses-output-without-start-tag.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.includes-canvas-action-metadata-tool-summaries.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-assistanttexts-final-answer-block-replies-are.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.keeps-indented-fenced-blocks-intact.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.reopens-fenced-blocks-splitting-inside-them.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.splits-long-single-line-fenced-blocks-reopen.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.streams-soft-chunks-paragraph-preference.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.subscribeembeddedpisession.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.suppresses-message-end-block-replies-message-tool.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.subscribe-embedded-pi-session.waits-multiple-compaction-retries-before-resolving.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-subscribe.tools.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-embedded-utils.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-extensions\/compaction-safeguard.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-extensions\/context-pruning.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-settings.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tool-definition-adapter.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools-agent-config.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-b.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-d.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping-f.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.create-openclaw-coding-tools.adds-claude-style-aliases-schemas-without-dropping.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.policy.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.safe-bins.test.ts<\/code><\/li>\n<li><code>src\/agents\/pi-tools.workspace-paths.test.ts<\/code><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Pi \u96c6\u6210\u67b6\u6784 \u672c\u6587\u6863\u63cf\u8ff0\u4e86 OpenClaw \u5982\u4f55\u4e0e pi-coding-agent \u53ca\u5176\u76f8\u5173\u5305\uff08pi-ai [&hellip;]<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-183","post","type-post","status-publish","format-standard","hentry","category-docs"],"_links":{"self":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/comments?post=183"}],"version-history":[{"count":1,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/183\/revisions"}],"predecessor-version":[{"id":478,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/posts\/183\/revisions\/478"}],"wp:attachment":[{"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/media?parent=183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/categories?post=183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/pa.yingzhi8.cn\/index.php\/wp-json\/wp\/v2\/tags?post=183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}