@bastani/pi-ai 0.9.26-alpha.2 → 0.9.26-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/NOTICE.md +1 -1
- package/README.md +3 -1
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +20 -32
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +25 -2
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -1
- package/dist/api/cloudflare-workers-ai-system-one.js +13 -8
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -1
- package/dist/auth/oauth/openai-chatgpt.js +5 -0
- package/dist/auth/oauth/openai-chatgpt.js.map +1 -1
- package/dist/providers/data/.manifest.json +1 -1
- package/dist/providers/data/amazon-bedrock.json +1 -1
- package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
- package/dist/providers/data/cloudflare-workers-ai.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +1 -0
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/transcript.d.ts +5 -2
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +5 -2
- package/dist/utils/transcript.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,24 @@ This package is a Bastani fork of `@earendil-works/pi-ai`. Upstream history at t
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.9.26-alpha.3] - 2026-10-03
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added Cloudflare's Clef and Clef Flash classifier models (`@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash`) to the `cloudflare-workers-ai` provider ([#10316](https://github.com/earendil-works/pi/pull/10316) by [@ndisidore](https://github.com/ndisidore), [#10322](https://github.com/earendil-works/pi/pull/10322) by [@RealAlexandreAI](https://github.com/RealAlexandreAI)).
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Native Anthropic tool changes now define added and redefined tools inline, keeping the initial tool list stable for prompt caching. `hasToolRedefinitions()` is deprecated.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Provider errors containing "Selected model is at capacity" are now retried.
|
|
20
|
+
- Cloudflare AI Gateway now uses dashed Claude model IDs accepted by its Anthropic endpoint.
|
|
21
|
+
- Fixed Sign in with ChatGPT continuing when its callback port is taken by another login, which made the browser show "OAuth state mismatch"; it now fails with a port-in-use error before opening the browser ([#10265](https://github.com/earendil-works/pi/issues/10265)).
|
|
22
|
+
- Amazon Bedrock OpenAI models are no longer costed at the short-context rate above 272k input tokens; Bedrock models now include the pricing tiers listed on models.dev ([#10326](https://github.com/earendil-works/pi/issues/10326)).
|
|
23
|
+
- Amazon Bedrock Claude requests no longer fail with "Invalid `signature` in `thinking` block" after the system prompt or tools change; Claude Opus 4.7+, Sonnet 5+, and Fable 5 now drop stale thinking blocks like the Anthropic provider ([#10324](https://github.com/earendil-works/pi/issues/10324)).
|
|
24
|
+
|
|
7
25
|
## [0.9.26-alpha.2] - 2026-10-02
|
|
8
26
|
|
|
9
27
|
### Added
|
package/NOTICE.md
CHANGED
|
@@ -6,7 +6,7 @@ monorepo at `packages/ai` and publishes at the same version as `@bastani/atomic`
|
|
|
6
6
|
|
|
7
7
|
- Upstream package: [`@earendil-works/pi-ai`](https://www.npmjs.com/package/@earendil-works/pi-ai)
|
|
8
8
|
- Original fork point: `v0.84.2` (`914cf1472e715297caa30db4b9535d534a9eb718`)
|
|
9
|
-
- Applicable Pi AI fixes synced through audited upstream `main`: `earendil-works/pi@
|
|
9
|
+
- Applicable Pi AI fixes synced through audited upstream `main`: `earendil-works/pi@c10bfb0d79dbbc998539a0a3e6c6a736a4e6db06`, with remaining registry Pi packages at `1.0.0`. Atomic retains its adaptations and does not enable upstream virtual models.
|
|
10
10
|
- Catalog JSON under `src/providers/data/` is generated at build time from models.dev, matching upstream. It is not committed.
|
|
11
11
|
|
|
12
12
|
Original work is Copyright (c) 2025 Mario Zechner and is licensed under the MIT License.
|
package/README.md
CHANGED
|
@@ -879,7 +879,7 @@ Classifier models consume structured JSON state and answer one or more typed que
|
|
|
879
879
|
| --- | --- | --- |
|
|
880
880
|
| `typesafe` | `jev-latest` | `TYPESAFE_API_KEY` |
|
|
881
881
|
| `openrouter` | `typesafe/jev-1.13`, `~typesafe/jev-latest` | `OPENROUTER_API_KEY` or OpenRouter OAuth |
|
|
882
|
-
| `cloudflare-workers-ai` | `typesafe/jev` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
882
|
+
| `cloudflare-workers-ai` | `typesafe/jev`, `@cf/cloudflare/clef`, `@cf/cloudflare/clef-flash` | `CLOUDFLARE_API_KEY` and `CLOUDFLARE_ACCOUNT_ID` |
|
|
883
883
|
| `vercel-ai-gateway` | `typesafe-ai/jev` | `AI_GATEWAY_API_KEY` |
|
|
884
884
|
| `opencode` | `jev-1.13`, `jev-1.13-free` | `OPENCODE_API_KEY` |
|
|
885
885
|
|
|
@@ -1561,6 +1561,8 @@ Later system messages append instructions, patch named sections (`null` removes
|
|
|
1561
1561
|
|
|
1562
1562
|
Models with `supportsMidConvoSystemMessages` receive updates in place. Other models receive the replayed prompt and tools as a leading checkpoint. Anthropic's `supportsMidConvoToolChanges`, OpenAI Responses' `supportsAdditionalTools`/`supportsToolSearch`, and OpenAI Completions' `supportsMidConvoToolAdditions` enable native tool transitions where representable. Unsupported transitions fall back to the current top-level tool list and may invalidate the cached prefix.
|
|
1563
1563
|
|
|
1564
|
+
With Anthropic's `supportsMidConvoToolChanges`, the `inline-tools-2026-09-15` beta keeps the initial top-level tools and a deferred placeholder fixed. Later `tool_addition` blocks carry complete definitions, including replacements under an existing name; `tool_removal` blocks reference names. This preserves the cached prefix across tool changes. At least one initial tool is required; otherwise the current tool list is sent at the top level.
|
|
1565
|
+
|
|
1564
1566
|
## Context Serialization
|
|
1565
1567
|
|
|
1566
1568
|
The `Context` object can be easily serialized and deserialized using standard JSON methods, making it simple to persist conversations, implement chat history, or transfer contexts between services:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAiBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../src/api/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,SAAiC,MAAM,mBAAmB,CAAC;AAiBlE,OAAO,KAAK,EASX,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAOb,MAAM,aAAa,CAAC;AAoKrB,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAE1E,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,SAAS,CAAC;AAmPhE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACtE;;;;OAIG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;CACnB;AAgSD,eAAO,MAAM,MAAM,EAAE,cAAc,CAAC,oBAAoB,EAAE,gBAAgB,CA4XzE,CAAC;AA4BF,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,oBAAoB,EAAE,mBAAmB,CAgDlF,CAAC"}
|
|
@@ -12,7 +12,7 @@ import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
|
12
12
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
13
13
|
import { createStreamDeadline, withStreamDeadline } from "../utils/stream-deadline.js";
|
|
14
14
|
import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
|
|
15
|
-
import { getCurrentTools,
|
|
15
|
+
import { getCurrentTools, getInitialSystemMessage, resolveTranscript, } from "../utils/transcript.js";
|
|
16
16
|
import { ANTHROPIC_STRICT_JSON_SCHEMA_PROFILE, getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
|
|
17
17
|
import { buildCopilotDynamicHeaders, hasCopilotVisionInput, preserveCopilotIntegrationHeader, } from "./github-copilot-headers.js";
|
|
18
18
|
import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
|
|
@@ -129,7 +129,7 @@ const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
|
|
|
129
129
|
const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
|
|
130
130
|
const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
|
|
131
131
|
const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
|
|
132
|
-
const
|
|
132
|
+
const INLINE_TOOLS_BETA = "inline-tools-2026-09-15";
|
|
133
133
|
const FAST_MODE_BETA = "fast-mode-2026-02-01";
|
|
134
134
|
/**
|
|
135
135
|
* Fast mode bills every token category at twice the standard rate for each supported model, across
|
|
@@ -187,10 +187,9 @@ function assertPayloadPreservesFastRoute(model, payload) {
|
|
|
187
187
|
}
|
|
188
188
|
/**
|
|
189
189
|
* Stable deferred tool declared whenever native tool changes are in use. Anthropic adds
|
|
190
|
-
* hidden prompt scaffolding
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
* It is never activated and the model cannot see it.
|
|
190
|
+
* hidden prompt scaffolding for mid-conversation tool changes; declaring this placeholder
|
|
191
|
+
* from the first request keeps that scaffolding in the cached prefix. It is never activated
|
|
192
|
+
* and the model cannot see it.
|
|
194
193
|
*/
|
|
195
194
|
const DEFERRED_TOOL_PLACEHOLDER = {
|
|
196
195
|
name: "__pi_deferred_placeholder__",
|
|
@@ -606,8 +605,7 @@ export const stream = (model, context, options) => {
|
|
|
606
605
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
607
606
|
const created = createClient(model, apiKey, model.reasoning && options?.thinkingEnabled === true && (options.interleavedThinking ?? true), shouldUseFineGrainedToolStreamingBeta(model, context), shouldUseServerSideFallbackBeta(model), options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, getAnthropicCompat(model).supportsMidConvoToolChanges &&
|
|
608
607
|
getAnthropicCompat(model).supportsMidConvoSystemMessages &&
|
|
609
|
-
(getInitialSystemMessage(normalizedContext.messages)?.toolsAdded?.length ?? 0) > 0
|
|
610
|
-
!hasToolRedefinitions(normalizedContext.messages), federation);
|
|
608
|
+
(getInitialSystemMessage(normalizedContext.messages)?.toolsAdded?.length ?? 0) > 0, federation);
|
|
611
609
|
client = created.client;
|
|
612
610
|
isOAuth = created.isOAuthToken;
|
|
613
611
|
}
|
|
@@ -983,7 +981,7 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
|
|
|
983
981
|
betaFeatures.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
|
|
984
982
|
}
|
|
985
983
|
if (useNativeToolChanges)
|
|
986
|
-
betaFeatures.push(
|
|
984
|
+
betaFeatures.push(INLINE_TOOLS_BETA);
|
|
987
985
|
if (requestedSpeed(model) === "fast")
|
|
988
986
|
betaFeatures.push(FAST_MODE_BETA);
|
|
989
987
|
const uniqueBetaFeatures = [...new Set(betaFeatures)];
|
|
@@ -1075,7 +1073,7 @@ function getNativeToolChangeBetas(model, context, isOAuth, options) {
|
|
|
1075
1073
|
.map((feature) => feature.trim())
|
|
1076
1074
|
.filter(Boolean)),
|
|
1077
1075
|
];
|
|
1078
|
-
const features = [
|
|
1076
|
+
const features = [INLINE_TOOLS_BETA];
|
|
1079
1077
|
if (isOAuth)
|
|
1080
1078
|
features.push("claude-code-20250219", "oauth-2025-04-20");
|
|
1081
1079
|
if (shouldUseFineGrainedToolStreamingBeta(model, context))
|
|
@@ -1103,15 +1101,11 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
1103
1101
|
const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
|
|
1104
1102
|
const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
|
|
1105
1103
|
const conversationMessages = initialSystemMessage ? transformedMessages.slice(1) : transformedMessages;
|
|
1106
|
-
// Native tool changes reference tools by name, so a redefined name cannot be expressed,
|
|
1107
|
-
// and Anthropic rejects a tool list where every tool is deferred, so there must be an
|
|
1108
|
-
// initial active tool to anchor the deferred ones. Otherwise the current tool list is sent.
|
|
1109
1104
|
const initialTools = initialSystemMessage?.toolsAdded ?? [];
|
|
1110
|
-
const nativeToolChanges = compat.supportsMidConvoSystemMessages &&
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, supportsMidConvoEffort(model) ? model.provider : undefined, nativeToolChanges);
|
|
1105
|
+
const nativeToolChanges = compat.supportsMidConvoSystemMessages && compat.supportsMidConvoToolChanges && initialTools.length > 0;
|
|
1106
|
+
const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, supportsMidConvoEffort(model) ? model.provider : undefined, nativeToolChanges
|
|
1107
|
+
? (tools) => convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools)
|
|
1108
|
+
: undefined);
|
|
1115
1109
|
const activeEffort = options?.effort ?? "high";
|
|
1116
1110
|
const params = {
|
|
1117
1111
|
model: upstreamModelId(model),
|
|
@@ -1162,16 +1156,9 @@ function buildParams(model, context, isOAuthToken, options) {
|
|
|
1162
1156
|
}
|
|
1163
1157
|
const toolCacheControl = compat.supportsCacheControlOnTools ? cacheControl : undefined;
|
|
1164
1158
|
if (nativeToolChanges) {
|
|
1165
|
-
// Initial tools stay active with the cache breakpoint on the last one. Every later
|
|
1166
|
-
// declaration is deferred and only surfaced by its `tool_addition` block; removed
|
|
1167
|
-
// tools stay declared and are withdrawn by `tool_removal`. The request-level list
|
|
1168
|
-
// therefore only grows, keeping the cached prefix intact across tool changes.
|
|
1169
|
-
const initialNames = new Set(initialTools.map((tool) => tool.name));
|
|
1170
|
-
const laterTools = getDeclaredTools(context.messages).filter((tool) => !initialNames.has(tool.name));
|
|
1171
1159
|
params.tools = [
|
|
1172
1160
|
...convertTools(initialTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl),
|
|
1173
1161
|
DEFERRED_TOOL_PLACEHOLDER,
|
|
1174
|
-
...convertTools(laterTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools).map((tool) => ({ ...tool, defer_loading: true })),
|
|
1175
1162
|
];
|
|
1176
1163
|
}
|
|
1177
1164
|
else {
|
|
@@ -1292,7 +1279,7 @@ function convertToolResult(msg) {
|
|
|
1292
1279
|
is_error: msg.isError,
|
|
1293
1280
|
};
|
|
1294
1281
|
}
|
|
1295
|
-
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider,
|
|
1282
|
+
function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, convertToolDefinitions) {
|
|
1296
1283
|
const params = [];
|
|
1297
1284
|
const assistantLevels = new Map();
|
|
1298
1285
|
// Later system messages are held back and emitted directly before the next assistant
|
|
@@ -1314,18 +1301,19 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
|
|
|
1314
1301
|
const blocks = [];
|
|
1315
1302
|
if (text.length > 0)
|
|
1316
1303
|
blocks.push({ type: "text", text: sanitizeSurrogates(text) });
|
|
1317
|
-
if (
|
|
1304
|
+
if (convertToolDefinitions) {
|
|
1305
|
+
const added = msg.toolsAdded ?? [];
|
|
1306
|
+
const redefined = new Set(added.map((tool) => tool.name));
|
|
1318
1307
|
for (const tool of msg.toolsRemoved ?? []) {
|
|
1308
|
+
if (redefined.has(tool.name))
|
|
1309
|
+
continue;
|
|
1319
1310
|
blocks.push({
|
|
1320
1311
|
type: "tool_removal",
|
|
1321
1312
|
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1322
1313
|
});
|
|
1323
1314
|
}
|
|
1324
|
-
for (const
|
|
1325
|
-
blocks.push({
|
|
1326
|
-
type: "tool_addition",
|
|
1327
|
-
tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
|
|
1328
|
-
});
|
|
1315
|
+
for (const definition of convertToolDefinitions(added)) {
|
|
1316
|
+
blocks.push({ type: "tool_addition", tool: { type: "tool_definition", definition } });
|
|
1329
1317
|
}
|
|
1330
1318
|
}
|
|
1331
1319
|
if (blocks.length > 0)
|