@earendil-works/pi-ai 1.2.0 → 1.4.0
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/README.md +83 -37
- package/dist/api/anthropic-messages.d.ts.map +1 -1
- package/dist/api/anthropic-messages.js +66 -64
- package/dist/api/anthropic-messages.js.map +1 -1
- package/dist/api/azure-openai-responses.d.ts.map +1 -1
- package/dist/api/azure-openai-responses.js +8 -4
- package/dist/api/azure-openai-responses.js.map +1 -1
- package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
- package/dist/api/bedrock-converse-stream.js +28 -18
- package/dist/api/bedrock-converse-stream.js.map +1 -1
- package/dist/api/classifier-shared.d.ts.map +1 -1
- package/dist/api/classifier-shared.js +4 -3
- package/dist/api/classifier-shared.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 +8 -0
- package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -1
- package/dist/api/google-generative-ai.js +4 -4
- package/dist/api/google-generative-ai.js.map +1 -1
- package/dist/api/google-shared.d.ts.map +1 -1
- package/dist/api/google-shared.js +3 -1
- package/dist/api/google-shared.js.map +1 -1
- package/dist/api/google-vertex.d.ts.map +1 -1
- package/dist/api/google-vertex.js +9 -9
- package/dist/api/google-vertex.js.map +1 -1
- package/dist/api/lazy.d.ts +7 -2
- package/dist/api/lazy.d.ts.map +1 -1
- package/dist/api/lazy.js +24 -5
- package/dist/api/lazy.js.map +1 -1
- package/dist/api/llama-cpp-classify.d.ts.map +1 -1
- package/dist/api/llama-cpp-classify.js +2 -1
- package/dist/api/llama-cpp-classify.js.map +1 -1
- package/dist/api/mistral-conversations.js +4 -4
- package/dist/api/mistral-conversations.js.map +1 -1
- package/dist/api/openai-codex-responses.d.ts.map +1 -1
- package/dist/api/openai-codex-responses.js +17 -11
- package/dist/api/openai-codex-responses.js.map +1 -1
- package/dist/api/openai-completions.d.ts.map +1 -1
- package/dist/api/openai-completions.js +43 -35
- package/dist/api/openai-completions.js.map +1 -1
- package/dist/api/openai-responses-shared.d.ts +26 -0
- package/dist/api/openai-responses-shared.d.ts.map +1 -1
- package/dist/api/openai-responses-shared.js +76 -11
- package/dist/api/openai-responses-shared.js.map +1 -1
- package/dist/api/openai-responses.d.ts.map +1 -1
- package/dist/api/openai-responses.js +38 -13
- package/dist/api/openai-responses.js.map +1 -1
- package/dist/api/openrouter-images.d.ts.map +1 -1
- package/dist/api/openrouter-images.js +4 -3
- package/dist/api/openrouter-images.js.map +1 -1
- package/dist/api/pi-messages.d.ts.map +1 -1
- package/dist/api/pi-messages.js +3 -3
- package/dist/api/pi-messages.js.map +1 -1
- package/dist/api/simple-options.d.ts.map +1 -1
- package/dist/api/simple-options.js +2 -1
- package/dist/api/simple-options.js.map +1 -1
- package/dist/api/system-one-shared.d.ts +29 -2
- package/dist/api/system-one-shared.d.ts.map +1 -1
- package/dist/api/system-one-shared.js +55 -3
- package/dist/api/system-one-shared.js.map +1 -1
- package/dist/api/transform-messages.d.ts +16 -1
- package/dist/api/transform-messages.d.ts.map +1 -1
- package/dist/api/transform-messages.js +28 -15
- package/dist/api/transform-messages.js.map +1 -1
- package/dist/api/typesafe-system-one.d.ts.map +1 -1
- package/dist/api/typesafe-system-one.js +10 -0
- package/dist/api/typesafe-system-one.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/models.d.ts +4 -0
- package/dist/models.d.ts.map +1 -1
- package/dist/models.js +19 -6
- package/dist/models.js.map +1 -1
- package/dist/providers/compat-schema.d.ts +171 -0
- package/dist/providers/compat-schema.d.ts.map +1 -1
- package/dist/providers/compat-schema.js +23 -2
- package/dist/providers/compat-schema.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/anthropic.json +1 -1
- package/dist/providers/data/azure.json +1 -1
- package/dist/providers/data/baseten.json +1 -1
- package/dist/providers/data/cerebras.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/fireworks.json +1 -1
- package/dist/providers/data/github-copilot.json +1 -1
- package/dist/providers/data/google-vertex.json +1 -1
- package/dist/providers/data/google.json +1 -1
- package/dist/providers/data/groq.json +1 -1
- package/dist/providers/data/huggingface.json +1 -1
- package/dist/providers/data/kimi-coding.json +1 -1
- package/dist/providers/data/meta.json +1 -1
- package/dist/providers/data/minimax-cn.json +1 -1
- package/dist/providers/data/minimax.json +1 -1
- package/dist/providers/data/mistral.json +1 -1
- package/dist/providers/data/moonshotai-cn.json +1 -1
- package/dist/providers/data/nvidia.json +1 -1
- package/dist/providers/data/openai-codex.json +1 -1
- package/dist/providers/data/openai.json +1 -1
- package/dist/providers/data/opencode-go.json +1 -1
- package/dist/providers/data/opencode.json +1 -1
- package/dist/providers/data/openrouter.json +1 -1
- package/dist/providers/data/qwen-token-plan-cn.json +1 -1
- package/dist/providers/data/qwen-token-plan.json +1 -1
- package/dist/providers/data/radius.json +1 -1
- package/dist/providers/data/together.json +1 -1
- package/dist/providers/data/typesafe.json +1 -1
- package/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/dist/providers/data/xai.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
- package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
- package/dist/providers/data/xiaomi.json +1 -1
- package/dist/providers/data/zai-coding-cn.json +1 -1
- package/dist/providers/kimi-coding.d.ts +1 -1
- package/dist/providers/kimi-coding.js +3 -3
- package/dist/providers/kimi-coding.js.map +1 -1
- package/dist/providers/model-schema.d.ts.map +1 -1
- package/dist/providers/model-schema.js +4 -2
- package/dist/providers/model-schema.js.map +1 -1
- package/dist/providers/opencode-go.d.ts +3 -1
- package/dist/providers/opencode-go.d.ts.map +1 -1
- package/dist/providers/opencode-go.js +2 -0
- package/dist/providers/opencode-go.js.map +1 -1
- package/dist/telemetry.d.ts +288 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +191 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +18 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/identity.d.ts +65 -0
- package/dist/utils/identity.d.ts.map +1 -0
- package/dist/utils/identity.js +141 -0
- package/dist/utils/identity.js.map +1 -0
- package/dist/utils/json-parse.d.ts +10 -0
- package/dist/utils/json-parse.d.ts.map +1 -1
- package/dist/utils/json-parse.js +26 -1
- package/dist/utils/json-parse.js.map +1 -1
- package/dist/utils/overflow.d.ts +1 -0
- package/dist/utils/overflow.d.ts.map +1 -1
- package/dist/utils/overflow.js +6 -1
- package/dist/utils/overflow.js.map +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js +21 -8
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/transcript.d.ts +22 -8
- package/dist/utils/transcript.d.ts.map +1 -1
- package/dist/utils/transcript.js +29 -18
- package/dist/utils/transcript.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +3 -0
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +3 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +2 -2
- package/dist/utils/assistant-message-frame.d.ts +0 -77
- package/dist/utils/assistant-message-frame.d.ts.map +0 -1
- package/dist/utils/assistant-message-frame.js +0 -425
- package/dist/utils/assistant-message-frame.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -12
- package/dist/utils/pi-user-agent.js.map +0 -1
|
@@ -4,8 +4,8 @@ import { formatProviderError, normalizeProviderError } from "../utils/error-body
|
|
|
4
4
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
5
5
|
import { shortHash } from "../utils/hash.js";
|
|
6
6
|
import { headersToRecord } from "../utils/headers.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { getIdentityHeaders } from "../utils/identity.js";
|
|
8
|
+
import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
|
|
9
9
|
import { getProviderEnvValue } from "../utils/provider-env.js";
|
|
10
10
|
import { retryProviderRequest } from "../utils/provider-retry.js";
|
|
11
11
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
@@ -183,7 +183,7 @@ export const stream = (model, context, options) => {
|
|
|
183
183
|
const grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(normalizedContext.messages), compat.supportsOpenAIGrammarTools);
|
|
184
184
|
const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
|
|
185
185
|
const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
|
|
186
|
-
const client = createClient(model, normalizedContext, apiKey, options?.headers, options?.fetch, cacheSessionId, compat);
|
|
186
|
+
const client = createClient(model, normalizedContext, apiKey, options?.headers, options?.identity, options?.fetch, cacheSessionId, compat);
|
|
187
187
|
let params = buildParams(model, normalizedContext, options, compat, cacheRetention, grammarToolInputProperties);
|
|
188
188
|
const nextParams = await options?.onPayload?.(params, model);
|
|
189
189
|
if (nextParams !== undefined) {
|
|
@@ -258,7 +258,7 @@ export const stream = (model, context, options) => {
|
|
|
258
258
|
}
|
|
259
259
|
}
|
|
260
260
|
else {
|
|
261
|
-
block
|
|
261
|
+
Object.assign(block, parseToolCallArguments(block.partialArgs));
|
|
262
262
|
}
|
|
263
263
|
// Finalize in-place and strip the scratch buffers so replay only
|
|
264
264
|
// carries parsed arguments.
|
|
@@ -381,18 +381,8 @@ export const stream = (model, context, options) => {
|
|
|
381
381
|
hasFinishReason = true;
|
|
382
382
|
}
|
|
383
383
|
if (choice.delta) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
choice.delta.content.length > 0) {
|
|
387
|
-
const block = ensureTextBlock();
|
|
388
|
-
block.text += choice.delta.content;
|
|
389
|
-
stream.push({
|
|
390
|
-
type: "text_delta",
|
|
391
|
-
contentIndex: getContentIndex(block),
|
|
392
|
-
delta: choice.delta.content,
|
|
393
|
-
partial: output,
|
|
394
|
-
});
|
|
395
|
-
}
|
|
384
|
+
// Handle reasoning before content: some proxies (e.g. LiteLLM) aggregate reasoning and
|
|
385
|
+
// answer into one delta, and the thinking block must precede the text block.
|
|
396
386
|
// Some endpoints return reasoning in reasoning_content (llama.cpp),
|
|
397
387
|
// or reasoning (other openai compatible endpoints)
|
|
398
388
|
// Use the first non-empty reasoning field to avoid duplication
|
|
@@ -423,6 +413,31 @@ export const stream = (model, context, options) => {
|
|
|
423
413
|
});
|
|
424
414
|
}
|
|
425
415
|
}
|
|
416
|
+
const reasoningDetails = choice.delta.reasoning_details;
|
|
417
|
+
if (Array.isArray(reasoningDetails)) {
|
|
418
|
+
for (const detail of reasoningDetails) {
|
|
419
|
+
if (!isOpenAIReasoningDetail(detail))
|
|
420
|
+
continue;
|
|
421
|
+
ensureThinkingBlock("");
|
|
422
|
+
streamedReasoningDetails ??= [];
|
|
423
|
+
// Keep provider replay data in the existing signature slot. OpenRouter streams
|
|
424
|
+
// reasoning_details as deltas: consecutive text/summary deltas are merged into
|
|
425
|
+
// logical entries, while encrypted entries remain opaque and discrete.
|
|
426
|
+
appendOpenAIReasoningDetail(streamedReasoningDetails, detail);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (choice.delta.content !== null &&
|
|
430
|
+
choice.delta.content !== undefined &&
|
|
431
|
+
choice.delta.content.length > 0) {
|
|
432
|
+
const block = ensureTextBlock();
|
|
433
|
+
block.text += choice.delta.content;
|
|
434
|
+
stream.push({
|
|
435
|
+
type: "text_delta",
|
|
436
|
+
contentIndex: getContentIndex(block),
|
|
437
|
+
delta: choice.delta.content,
|
|
438
|
+
partial: output,
|
|
439
|
+
});
|
|
440
|
+
}
|
|
426
441
|
if (choice?.delta?.tool_calls) {
|
|
427
442
|
for (const toolCall of choice.delta.tool_calls) {
|
|
428
443
|
const block = ensureToolCallBlock(toolCall);
|
|
@@ -452,19 +467,6 @@ export const stream = (model, context, options) => {
|
|
|
452
467
|
});
|
|
453
468
|
}
|
|
454
469
|
}
|
|
455
|
-
const reasoningDetails = choice.delta.reasoning_details;
|
|
456
|
-
if (Array.isArray(reasoningDetails)) {
|
|
457
|
-
for (const detail of reasoningDetails) {
|
|
458
|
-
if (!isOpenAIReasoningDetail(detail))
|
|
459
|
-
continue;
|
|
460
|
-
ensureThinkingBlock("");
|
|
461
|
-
streamedReasoningDetails ??= [];
|
|
462
|
-
// Keep provider replay data in the existing signature slot. OpenRouter streams
|
|
463
|
-
// reasoning_details as deltas: consecutive text/summary deltas are merged into
|
|
464
|
-
// logical entries, while encrypted entries remain opaque and discrete.
|
|
465
|
-
appendOpenAIReasoningDetail(streamedReasoningDetails, detail);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
470
|
}
|
|
469
471
|
}
|
|
470
472
|
for (const block of blocks) {
|
|
@@ -529,8 +531,8 @@ export const streamSimple = (model, context, options) => {
|
|
|
529
531
|
thinkingBudgets: options?.thinkingBudgets,
|
|
530
532
|
});
|
|
531
533
|
};
|
|
532
|
-
function createClient(model, context, apiKey, optionsHeaders, fetch, sessionId, compat = getCompat(model)) {
|
|
533
|
-
const headers = {
|
|
534
|
+
function createClient(model, context, apiKey, optionsHeaders, identity, fetch, sessionId, compat = getCompat(model)) {
|
|
535
|
+
const headers = { ...getIdentityHeaders(model, identity), ...model.headers };
|
|
534
536
|
if (model.provider === "github-copilot") {
|
|
535
537
|
const hasImages = hasCopilotVisionInput(context.messages);
|
|
536
538
|
const copilotHeaders = buildCopilotDynamicHeaders({
|
|
@@ -564,7 +566,9 @@ function createClient(model, context, apiKey, optionsHeaders, fetch, sessionId,
|
|
|
564
566
|
});
|
|
565
567
|
}
|
|
566
568
|
function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env), grammarToolInputProperties = createGrammarToolInputProperties(getDeclaredTools(context.messages), compat.supportsOpenAIGrammarTools)) {
|
|
567
|
-
const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
|
|
569
|
+
const transcriptTools = resolveTranscriptTools(context.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
|
|
570
|
+
? "additions"
|
|
571
|
+
: "none");
|
|
568
572
|
const messages = convertMessages(model, context, compat, {
|
|
569
573
|
grammarToolInputProperties,
|
|
570
574
|
});
|
|
@@ -895,9 +899,12 @@ export function convertMessages(model, context, compat, options) {
|
|
|
895
899
|
return id;
|
|
896
900
|
};
|
|
897
901
|
const transformedMessages = transformMessages(normalizedContext.messages, model, (id) => normalizeToolCallId(id));
|
|
898
|
-
const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
|
|
902
|
+
const transcriptTools = resolveTranscriptTools(normalizedContext.messages, compat.supportsMidConvoSystemMessages === true && compat.supportsMidConvoToolAdditions === true
|
|
903
|
+
? "additions"
|
|
904
|
+
: "none");
|
|
899
905
|
const instructionRole = model.reasoning && compat.supportsDeveloperRole ? "developer" : "system";
|
|
900
906
|
let lastRole = null;
|
|
907
|
+
let systemIndex = 0;
|
|
901
908
|
for (let i = 0; i < transformedMessages.length; i++) {
|
|
902
909
|
const msg = transformedMessages[i];
|
|
903
910
|
// Some providers don't allow user messages directly after tool results
|
|
@@ -909,7 +916,8 @@ export function convertMessages(model, context, compat, options) {
|
|
|
909
916
|
});
|
|
910
917
|
}
|
|
911
918
|
if (msg.role === "system") {
|
|
912
|
-
|
|
919
|
+
// transformMessages keeps system messages in order, so their position matches the transcript.
|
|
920
|
+
const addedTools = systemIndex++ >= transcriptTools.foldedSystemMessages ? (msg.toolsAdded ?? []) : [];
|
|
913
921
|
if (addedTools.length > 0) {
|
|
914
922
|
const kimiToolMessage = {
|
|
915
923
|
role: "system",
|
|
@@ -1074,7 +1082,7 @@ export function convertMessages(model, context, compat, options) {
|
|
|
1074
1082
|
.join("\n");
|
|
1075
1083
|
const hasImages = toolMsg.content.some((c) => c.type === "image");
|
|
1076
1084
|
// Always send tool result with text (or placeholder if only images)
|
|
1077
|
-
const hasText = textResult.length > 0;
|
|
1085
|
+
const hasText = textResult.trim().length > 0;
|
|
1078
1086
|
const toolResultText = hasText ? textResult : hasImages ? "(see attached image)" : "(no tool output)";
|
|
1079
1087
|
// Some providers require the 'name' field in tool results
|
|
1080
1088
|
const toolResultMsg = {
|