From 21fe89affe05a27420efae97e168ac1295b114dd Mon Sep 17 00:00:00 2001
From: Tianyi Cui <53024+tianyicui@users.noreply.github.com>
Date: Mon, 5 Oct 2026 01:23:53 +0800
Subject: [PATCH] build(llm-pi-ai): upgrade @earendil-works/pi-ai to 1.0.2
pi-ai 1.0.1 and 1.0.2 bring model catalog updates and adapter fixes:
Anthropic native tool changes define later tools inline, Bedrock binds
replayed thinking blocks, OpenAI-compatible requests can pick sampling
parameters by thinking level, and "model is at capacity" is retried.
The runtime dependencies change only in @anthropic-ai/sdk (0.124.0 to
0.129.0) and @earendil-works/pi-telemetry (^1.0.2).
1.0.2 still re-parses the whole accumulated tool-argument JSON on every
stream delta (earendil-works/pi#9265), so the patch is regenerated
against the 1.0.2 sources: it removes the same six per-delta parses as
the 1.0.0 patch, and only the bedrock-converse-stream.js hunk moves, by a
line.
---
THIRD_PARTY_NOTICES.md | 2 +-
packages/llm/llm-pi-ai/README.i18n.yaml | 4 +--
packages/llm/llm-pi-ai/README.md | 2 +-
packages/llm/llm-pi-ai/README.zh.md | 2 +-
packages/llm/llm-pi-ai/package.json | 2 +-
...tch => @earendil-works__pi-ai@1.0.2.patch} | 8 ++---
pnpm-lock.yaml | 36 +++++++++----------
pnpm-workspace.yaml | 6 ++--
8 files changed, 31 insertions(+), 31 deletions(-)
rename patches/{@earendil-works__pi-ai@1.0.0.patch => @earendil-works__pi-ai@1.0.2.patch} (92%)
diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md
index f83110606f..741c98db08 100644
--- a/THIRD_PARTY_NOTICES.md
+++ b/THIRD_PARTY_NOTICES.md
@@ -141,7 +141,7 @@ External packages installed for runtime use or distributed inside the prebuilt b
pnpm applies local patches to the following packages at install time, so shipped artifacts carry modified copies; each patch file is the complete record of the modification:
-- `@earendil-works/pi-ai@1.0.0` — [`patches/@earendil-works__pi-ai@1.0.0.patch`](patches/@earendil-works__pi-ai@1.0.0.patch)
+- `@earendil-works/pi-ai@1.0.2` — [`patches/@earendil-works__pi-ai@1.0.2.patch`](patches/@earendil-works__pi-ai@1.0.2.patch)
- `@electron/osx-sign@1.3.3` — [`patches/@electron__osx-sign@1.3.3.patch`](patches/@electron__osx-sign@1.3.3.patch)
- `@fortune-sheet/core@1.0.4` — [`patches/@fortune-sheet__core@1.0.4.patch`](patches/@fortune-sheet__core@1.0.4.patch)
- `@fortune-sheet/react@1.0.4` — [`patches/@fortune-sheet__react@1.0.4.patch`](patches/@fortune-sheet__react@1.0.4.patch)
diff --git a/packages/llm/llm-pi-ai/README.i18n.yaml b/packages/llm/llm-pi-ai/README.i18n.yaml
index 84eed99c14..af6fb47b3b 100644
--- a/packages/llm/llm-pi-ai/README.i18n.yaml
+++ b/packages/llm/llm-pi-ai/README.i18n.yaml
@@ -87,8 +87,8 @@
en: b6bd570c0159ba08
zh: 7d2d91eea6a8d830
/deepseek-ai-dsh-llm-pi-ai/known-limitations-and-deferred-work:
- en: 3ac77ae061cf0683
- zh: c25abff6da8c1a22
+ en: 9c5095233a4194cc
+ zh: 044fe1c59c62e317
/deepseek-ai-dsh-llm-pi-ai/known-limitations-and-deferred-work/dev-note:
en: 3678dd0f6642c2a5
zh: 75cbdd064cc64282
diff --git a/packages/llm/llm-pi-ai/README.md b/packages/llm/llm-pi-ai/README.md
index 549310082a..6b537bb4fd 100644
--- a/packages/llm/llm-pi-ai/README.md
+++ b/packages/llm/llm-pi-ai/README.md
@@ -230,7 +230,7 @@ These limits define where the adapter stops and future work begins. They are cur
- **Only a leading in-history `system` message becomes pi-ai's `systemPrompt`** — this adapter uses pi-ai's single `systemPrompt` input, so a later `system` message, or a leading one when `GenerateOptions.system` is also set, folds into a `user` message at its position; provider-specific placement of the prompt follows pi-ai rather than a harness-owned wire override. Images in system or assistant history, including the leading system message, fail with `UNSUPPORTED_CONTENT` on both conversion paths.
- **Provider HTTP status is unavailable** — pi-ai error events do not expose a stable HTTP status across providers.
- **Retry policy is provider-owned, not an SDK retry** — pi-ai SDK retries stay disabled so durable agent steps and `llm/retry` events own every visible attempt, and direct `ctx.llm.stream()` calls remain single-attempt.
-- **Streamed tool-call arguments are parsed once, when the call ends** — the installed pi-ai carries [`patches/@earendil-works__pi-ai@1.0.0.patch`](../../../patches/@earendil-works__pi-ai@1.0.0.patch), which removes the per-delta re-parse of the whole accumulated argument JSON in every stream adapter (upstream [earendil-works/pi#9265](https://github.com/earendil-works/pi/issues/9265)); unpatched, a multi-megabyte argument stream costs O(n²) CPU on the event loop and stalls every session in the process. Until `toolcall_end`, a pi-ai partial's tool-call `arguments` stays `{}`; this adapter reads only the delta strings and the finalized arguments. Re-apply or retire the patch on every pi-ai upgrade.
+- **Streamed tool-call arguments are parsed once, when the call ends** — the installed pi-ai carries [`patches/@earendil-works__pi-ai@1.0.2.patch`](../../../patches/@earendil-works__pi-ai@1.0.2.patch), which removes the per-delta re-parse of the whole accumulated argument JSON in every stream adapter (upstream [earendil-works/pi#9265](https://github.com/earendil-works/pi/issues/9265)); unpatched, a multi-megabyte argument stream costs O(n²) CPU on the event loop and stalls every session in the process. Until `toolcall_end`, a pi-ai partial's tool-call `arguments` stays `{}`; this adapter reads only the delta strings and the finalized arguments. Re-apply or retire the patch on every pi-ai upgrade.
### Dev Note
diff --git a/packages/llm/llm-pi-ai/README.zh.md b/packages/llm/llm-pi-ai/README.zh.md
index 19fff091e6..7c7b5584b4 100644
--- a/packages/llm/llm-pi-ai/README.zh.md
+++ b/packages/llm/llm-pi-ai/README.zh.md
@@ -230,7 +230,7 @@ pi-ai 事件变成 harness 的推理、文本、工具调用、用量与 finish
- **只有历史中首条 `system` 消息会成为 pi-ai 的 `systemPrompt`**——本适配器使用 pi-ai 的单一 `systemPrompt` 输入,因此后续的 `system` 消息,或在同时设置了 `GenerateOptions.system` 时的首条消息,会在原位置折叠为 `user` 消息;系统提示词的提供方专属放置遵循 pi-ai,而非 harness 自有的协议覆盖。system 或 assistant 历史中的图片(包括首条系统消息中的图片)在两条转换路径上都会以 `UNSUPPORTED_CONTENT` 失败。
- **提供方 HTTP 状态不可用**——pi-ai 错误事件不跨提供方暴露稳定 HTTP 状态。
- **重试策略由提供方自有,而非 SDK 重试**——pi-ai SDK 重试保持禁用,因此持久 agent(智能体)步骤与 `llm/retry` 事件拥有每个可见尝试,直接 `ctx.llm.stream()` 调用仍是单次尝试。
-- **流式工具调用参数只在调用结束时解析一次**——安装的 pi-ai 带有 [`patches/@earendil-works__pi-ai@1.0.0.patch`](../../../patches/@earendil-works__pi-ai@1.0.0.patch),它移除了每个流适配器中对整段累计参数 JSON 的逐 delta 重新解析(上游 [earendil-works/pi#9265](https://github.com/earendil-works/pi/issues/9265));未打补丁时,数 MB 的参数流会在事件循环上消耗 O(n²) CPU,并使进程内所有会话停滞。在 `toolcall_end` 之前,pi-ai partial 的工具调用 `arguments` 保持为 `{}`;本适配器只读取 delta 字符串与最终参数。每次升级 pi-ai 时都要重新应用或撤销该补丁。
+- **流式工具调用参数只在调用结束时解析一次**——安装的 pi-ai 带有 [`patches/@earendil-works__pi-ai@1.0.2.patch`](../../../patches/@earendil-works__pi-ai@1.0.2.patch),它移除了每个流适配器中对整段累计参数 JSON 的逐 delta 重新解析(上游 [earendil-works/pi#9265](https://github.com/earendil-works/pi/issues/9265));未打补丁时,数 MB 的参数流会在事件循环上消耗 O(n²) CPU,并使进程内所有会话停滞。在 `toolcall_end` 之前,pi-ai partial 的工具调用 `arguments` 保持为 `{}`;本适配器只读取 delta 字符串与最终参数。每次升级 pi-ai 时都要重新应用或撤销该补丁。
### 开发备注
diff --git a/packages/llm/llm-pi-ai/package.json b/packages/llm/llm-pi-ai/package.json
index f5a9b5b4f0..ba4e7dd712 100644
--- a/packages/llm/llm-pi-ai/package.json
+++ b/packages/llm/llm-pi-ai/package.json
@@ -41,7 +41,7 @@
"@deepseek-ai/dsh-brand": "workspace:*",
"@deepseek-ai/dsh-util-values": "workspace:*",
"@deepseek-ai/schemastery": "workspace:~",
- "@earendil-works/pi-ai": "^1.0.0"
+ "@earendil-works/pi-ai": "^1.0.2"
},
"devDependencies": {
"@deepseek-ai/cordis": "workspace:~",
diff --git a/patches/@earendil-works__pi-ai@1.0.0.patch b/patches/@earendil-works__pi-ai@1.0.2.patch
similarity index 92%
rename from patches/@earendil-works__pi-ai@1.0.0.patch
rename to patches/@earendil-works__pi-ai@1.0.2.patch
index 12d8df1daf..b7190cc213 100644
--- a/patches/@earendil-works__pi-ai@1.0.0.patch
+++ b/patches/@earendil-works__pi-ai@1.0.2.patch
@@ -1,5 +1,5 @@
diff --git a/dist/api/anthropic-messages.js b/dist/api/anthropic-messages.js
-index 106f2b9617fa3b810261e067a3c965f209907af3..d841d316172c82d5b1aebcfb2bde3e84b807ae0a 100644
+index 38571b31e143e913c2bf59dad73382982e93664a..950e546197d8e84cb3edfca0012939f1db2488d8 100644
--- a/dist/api/anthropic-messages.js
+++ b/dist/api/anthropic-messages.js
@@ -553,7 +553,6 @@ export const stream = (model, context, options) => {
@@ -11,10 +11,10 @@ index 106f2b9617fa3b810261e067a3c965f209907af3..d841d316172c82d5b1aebcfb2bde3e84
type: "toolcall_delta",
contentIndex: index,
diff --git a/dist/api/bedrock-converse-stream.js b/dist/api/bedrock-converse-stream.js
-index a7f6d9cbe66546d5d418450809e92cf7289ce4a3..6fc5438c9ace36d8cb0f6bf3d077ebfa8281dcf5 100644
+index 428af807620993a4c90ceb1a1a120d553844be32..d81d290d8b8b97f8e2cdd97cff1ebaf019c5733e 100644
--- a/dist/api/bedrock-converse-stream.js
+++ b/dist/api/bedrock-converse-stream.js
-@@ -460,7 +460,6 @@ function handleContentBlockDelta(event, blocks, output, stream) {
+@@ -461,7 +461,6 @@ function handleContentBlockDelta(event, blocks, output, stream) {
}
else if (delta?.toolUse && block?.type === "toolCall") {
block.partialJson = (block.partialJson || "") + (delta.toolUse.input || "");
@@ -35,7 +35,7 @@ index fbcc5e25ee6752a9c5461b41fa8544a090a17b3f..f540825c4f934f342200db72190599fe
type: "toolcall_delta",
contentIndex: toolBlocksByKey.get(key),
diff --git a/dist/api/openai-completions.js b/dist/api/openai-completions.js
-index eecd83c753e3b758b8e44628f560b862f8252839..201ad4da96e33bcac9446093c804794d6e64fc82 100644
+index a60f39352b776d71497e55b33b3334bacfbeb2f5..6c9b98e35606c52e4f0fb29d8fd0b5ba02d92e09 100644
--- a/dist/api/openai-completions.js
+++ b/dist/api/openai-completions.js
@@ -438,7 +438,6 @@ export const stream = (model, context, options) => {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e971405d86..8824a42631 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,7 +10,7 @@ overrides:
'@deepseek-ai/schemastery': link:vendor/schemastery
patchedDependencies:
- '@earendil-works/pi-ai@1.0.0': 3b2f85a92bded8a4fd06652620a93f24a7562f5e082a8dccec09ddd76e483e0e
+ '@earendil-works/pi-ai@1.0.2': 1cc211bc358d30cb58bd975f39c03e296f8a277c3de845514d12f9ae77ebab5f
'@electron/osx-sign@1.3.3': 280e7b2816caf01423097d24e79107a66afeb563a348630ce9928ae8499a5861
'@fortune-sheet/core@1.0.4': 8791a230763dbf853fd65d627c68c31de37209992851377855e16cf08ea70532
'@fortune-sheet/react@1.0.4': 2932e52e79afcd4ced08cfa123b5eded786c85043da32f622f3e80af6fc96c37
@@ -9945,8 +9945,8 @@ importers:
specifier: link:../../../vendor/schemastery
version: link:../../../vendor/schemastery
'@earendil-works/pi-ai':
- specifier: ^1.0.0
- version: 1.0.0(patch_hash=3b2f85a92bded8a4fd06652620a93f24a7562f5e082a8dccec09ddd76e483e0e)(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(@smithy/signature-v4@5.7.4)(supports-color@9.4.0)(undici@8.10.0)(ws@8.21.0)(zod@4.4.3)
+ specifier: ^1.0.2
+ version: 1.0.2(patch_hash=1cc211bc358d30cb58bd975f39c03e296f8a277c3de845514d12f9ae77ebab5f)(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(@smithy/signature-v4@5.7.4)(undici@8.10.0)(ws@8.21.0)(zod@4.4.3)
devDependencies:
'@deepseek-ai/cordis':
specifier: workspace:~
@@ -15040,8 +15040,8 @@ packages:
'@modelcontextprotocol/sdk': ^1.29.0
zod: ^4.0.0
- '@anthropic-ai/sdk@0.124.0':
- resolution: {integrity: sha512-cN5O8i9UVxHeOQAzj/XjshWXG8KiibJDw9OGpH2Z/eR3n/RBxdoLxDJOcfqAJWvjaMDFfHTBADU04hWRJVkDyA==}
+ '@anthropic-ai/sdk@0.129.0':
+ resolution: {integrity: sha512-MH7LB20kNpGLUpPTe2OG5XvL/KhX8HUO9XyBaFjgFk6TLS4Xjt0VPIuMKywe7POKKPslX+QxSlVok9e+8kG5Nw==}
hasBin: true
peerDependencies:
zod: ^3.25.0 || ^4.0.0
@@ -15378,13 +15378,13 @@ packages:
search-insights:
optional: true
- '@earendil-works/pi-ai@1.0.0':
- resolution: {integrity: sha512-3/W1vdDaVtpeMd23ElvJC12HLA5yS/BGqqcXF+0SK082dN7cbgNcCwguTBRBC258Ke8SzSvUW1B75iAf8w8IxA==}
+ '@earendil-works/pi-ai@1.0.2':
+ resolution: {integrity: sha512-JP59xGlSAQ/HhQ6EHN5qmneBlWfDyu6FPPryAvAaSo8A38ubAsEpS9YisCM5Jbbns0srrDffLZonE0OXorHI5A==}
engines: {node: '>=22.19.0'}
hasBin: true
- '@earendil-works/pi-telemetry@1.0.0':
- resolution: {integrity: sha512-WjNBj5TYIiPZFQEz2WlULcDwPLaKwIlmsKjVeYM+LJSbnSp38kWsHUJysIDGnu23IcLbKoPtywsvYfUJCeZePA==}
+ '@earendil-works/pi-telemetry@1.0.2':
+ resolution: {integrity: sha512-Ev5h9TE8nEXHCfRKhWj0qpUFhQgVqNteS95vsM2KNGRGm533vOO2ruDPaEwImBKPMBKXy4omz3D6V2cm41gLOQ==}
engines: {node: '>=22.19.0'}
'@electron-internal/extract-zip@1.0.5':
@@ -22448,7 +22448,7 @@ snapshots:
'@anthropic-ai/claude-agent-sdk-win32-arm64': 0.3.263
'@anthropic-ai/claude-agent-sdk-win32-x64': 0.3.263
- '@anthropic-ai/sdk@0.124.0(zod@4.4.3)':
+ '@anthropic-ai/sdk@0.129.0(zod@4.4.3)':
dependencies:
json-schema-to-ts: 3.1.1
standardwebhooks: 1.1.1
@@ -22913,15 +22913,15 @@ snapshots:
transitivePeerDependencies:
- '@algolia/client-search'
- '@earendil-works/pi-ai@1.0.0(patch_hash=3b2f85a92bded8a4fd06652620a93f24a7562f5e082a8dccec09ddd76e483e0e)(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(@smithy/signature-v4@5.7.4)(supports-color@9.4.0)(undici@8.10.0)(ws@8.21.0)(zod@4.4.3)':
+ '@earendil-works/pi-ai@1.0.2(patch_hash=1cc211bc358d30cb58bd975f39c03e296f8a277c3de845514d12f9ae77ebab5f)(@aws-sdk/credential-provider-node@3.972.84)(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(@smithy/signature-v4@5.7.4)(undici@8.10.0)(ws@8.21.0)(zod@4.4.3)':
dependencies:
- '@anthropic-ai/sdk': 0.124.0(zod@4.4.3)
+ '@anthropic-ai/sdk': 0.129.0(zod@4.4.3)
'@aws-sdk/client-bedrock-runtime': 3.1127.0
- '@earendil-works/pi-telemetry': 1.0.0
+ '@earendil-works/pi-telemetry': 1.0.2
'@google/genai': 2.21.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))
'@smithy/node-http-handler': 4.12.1
- http-proxy-agent: 9.1.0(supports-color@9.4.0)
- https-proxy-agent: 9.1.0(supports-color@9.4.0)
+ http-proxy-agent: 9.1.0
+ https-proxy-agent: 9.1.0
openai: 7.19.0(@aws-sdk/credential-provider-node@3.972.84)(@smithy/signature-v4@5.7.4)(undici@8.10.0)(ws@8.21.0)(zod@4.4.3)
partial-json: 0.1.7
typebox: 1.3.27
@@ -22938,7 +22938,7 @@ snapshots:
- ws
- zod
- '@earendil-works/pi-telemetry@1.0.0': {}
+ '@earendil-works/pi-telemetry@1.0.2': {}
'@electron-internal/extract-zip@1.0.5': {}
@@ -27110,7 +27110,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- http-proxy-agent@9.1.0(supports-color@9.4.0):
+ http-proxy-agent@9.1.0:
dependencies:
agent-base: 9.0.0
debug: 4.4.3(supports-color@9.4.0)
@@ -27169,7 +27169,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- https-proxy-agent@9.1.0(supports-color@9.4.0):
+ https-proxy-agent@9.1.0:
dependencies:
agent-base: 9.0.0
debug: 4.4.3(supports-color@9.4.0)
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 72ab8cce4d..ef5d1c7b78 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -64,8 +64,8 @@ minimumReleaseAgeExclude:
- '@deepseek-ai/libreoffice-kit-wasm@0.1.5'
# Fresh pi-ai releases carry the model catalog updates that are the whole
# point of bumping it; waiting out the release age would defeat that.
- - '@earendil-works/pi-ai@1.0.0'
- - '@earendil-works/pi-telemetry@1.0.0'
+ - '@earendil-works/pi-ai@1.0.2'
+ - '@earendil-works/pi-telemetry@1.0.2'
- node-addon-native-custom-loader@0.1.6
- node-addon-require-builtin-darwin-arm64@0.1.6
- node-addon-require-builtin-darwin-x64@0.1.6
@@ -98,7 +98,7 @@ minimumReleaseAgeExclude:
- '@trycua/cua-driver-win32-x64-msvc@0.28.0'
- '@trycua/cua-driver@0.28.0'
patchedDependencies:
- '@earendil-works/pi-ai@1.0.0': patches/@earendil-works__pi-ai@1.0.0.patch
+ '@earendil-works/pi-ai@1.0.2': patches/@earendil-works__pi-ai@1.0.2.patch
'@electron/osx-sign@1.3.3': patches/@electron__osx-sign@1.3.3.patch
'@fortune-sheet/core@1.0.4': patches/@fortune-sheet__core@1.0.4.patch
'@fortune-sheet/react@1.0.4': patches/@fortune-sheet__react@1.0.4.patch