@earendil-works/pi-ai 1.1.0 → 1.3.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.
Files changed (103) hide show
  1. package/README.md +5 -34
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +120 -74
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/bedrock-converse-stream.js +16 -18
  6. package/dist/api/bedrock-converse-stream.js.map +1 -1
  7. package/dist/api/google-shared.d.ts.map +1 -1
  8. package/dist/api/google-shared.js +2 -0
  9. package/dist/api/google-shared.js.map +1 -1
  10. package/dist/api/mistral-conversations.d.ts.map +1 -1
  11. package/dist/api/mistral-conversations.js +31 -15
  12. package/dist/api/mistral-conversations.js.map +1 -1
  13. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  14. package/dist/api/openai-codex-responses.js +2 -1
  15. package/dist/api/openai-codex-responses.js.map +1 -1
  16. package/dist/api/openai-completions.d.ts.map +1 -1
  17. package/dist/api/openai-completions.js +29 -27
  18. package/dist/api/openai-completions.js.map +1 -1
  19. package/dist/api/openai-responses-shared.d.ts +10 -0
  20. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  21. package/dist/api/openai-responses-shared.js +15 -2
  22. package/dist/api/openai-responses-shared.js.map +1 -1
  23. package/dist/api/openai-responses.d.ts.map +1 -1
  24. package/dist/api/openai-responses.js +21 -4
  25. package/dist/api/openai-responses.js.map +1 -1
  26. package/dist/api/transform-messages.d.ts +16 -1
  27. package/dist/api/transform-messages.d.ts.map +1 -1
  28. package/dist/api/transform-messages.js +28 -15
  29. package/dist/api/transform-messages.js.map +1 -1
  30. package/dist/index.d.ts +0 -1
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +0 -1
  33. package/dist/index.js.map +1 -1
  34. package/dist/models.d.ts +5 -0
  35. package/dist/models.d.ts.map +1 -1
  36. package/dist/models.js +1 -0
  37. package/dist/models.js.map +1 -1
  38. package/dist/providers/compat-schema.d.ts +341 -0
  39. package/dist/providers/compat-schema.d.ts.map +1 -0
  40. package/dist/providers/compat-schema.js +383 -0
  41. package/dist/providers/compat-schema.js.map +1 -0
  42. package/dist/providers/data/.manifest.json +1 -1
  43. package/dist/providers/data/amazon-bedrock.json +1 -1
  44. package/dist/providers/data/anthropic.json +1 -1
  45. package/dist/providers/data/baseten.json +1 -1
  46. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  47. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  48. package/dist/providers/data/github-copilot.json +1 -1
  49. package/dist/providers/data/google-vertex.json +1 -1
  50. package/dist/providers/data/google.json +1 -1
  51. package/dist/providers/data/huggingface.json +1 -1
  52. package/dist/providers/data/kimi-coding.json +1 -1
  53. package/dist/providers/data/meta.json +1 -1
  54. package/dist/providers/data/mistral.json +1 -1
  55. package/dist/providers/data/nvidia.json +1 -1
  56. package/dist/providers/data/openai-codex.json +1 -1
  57. package/dist/providers/data/openai.json +1 -1
  58. package/dist/providers/data/opencode-go.json +1 -1
  59. package/dist/providers/data/opencode.json +1 -1
  60. package/dist/providers/data/openrouter.json +1 -1
  61. package/dist/providers/data/radius.json +1 -1
  62. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  63. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  64. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  65. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  66. package/dist/providers/data/xiaomi.json +1 -1
  67. package/dist/providers/kimi-coding.d.ts +1 -1
  68. package/dist/providers/kimi-coding.js +3 -3
  69. package/dist/providers/kimi-coding.js.map +1 -1
  70. package/dist/providers/model-schema.d.ts +91 -0
  71. package/dist/providers/model-schema.d.ts.map +1 -0
  72. package/dist/providers/model-schema.js +55 -0
  73. package/dist/providers/model-schema.js.map +1 -0
  74. package/dist/providers/opencode-go.d.ts +3 -1
  75. package/dist/providers/opencode-go.d.ts.map +1 -1
  76. package/dist/providers/opencode-go.js +2 -0
  77. package/dist/providers/opencode-go.js.map +1 -1
  78. package/dist/providers/openrouter-api.d.ts +40 -0
  79. package/dist/providers/openrouter-api.d.ts.map +1 -0
  80. package/dist/providers/openrouter-api.js +41 -0
  81. package/dist/providers/openrouter-api.js.map +1 -0
  82. package/dist/providers/openrouter.d.ts +11 -1
  83. package/dist/providers/openrouter.d.ts.map +1 -1
  84. package/dist/providers/openrouter.js +52 -1
  85. package/dist/providers/openrouter.js.map +1 -1
  86. package/dist/types.d.ts +10 -303
  87. package/dist/types.d.ts.map +1 -1
  88. package/dist/types.js.map +1 -1
  89. package/dist/utils/json-parse.d.ts +10 -0
  90. package/dist/utils/json-parse.d.ts.map +1 -1
  91. package/dist/utils/json-parse.js +26 -1
  92. package/dist/utils/json-parse.js.map +1 -1
  93. package/dist/utils/retry.d.ts.map +1 -1
  94. package/dist/utils/retry.js +8 -3
  95. package/dist/utils/retry.js.map +1 -1
  96. package/dist/utils/validation.d.ts.map +1 -1
  97. package/dist/utils/validation.js +3 -0
  98. package/dist/utils/validation.js.map +1 -1
  99. package/package.json +2 -2
  100. package/dist/utils/assistant-message-frame.d.ts +0 -77
  101. package/dist/utils/assistant-message-frame.d.ts.map +0 -1
  102. package/dist/utils/assistant-message-frame.js +0 -425
  103. package/dist/utils/assistant-message-frame.js.map +0 -1
@@ -4,7 +4,7 @@ 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 { parseStreamingJson } from "../utils/json-parse.js";
7
+ import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
8
8
  import { getPiUserAgent } from "../utils/pi-user-agent.js";
9
9
  import { getProviderEnvValue } from "../utils/provider-env.js";
10
10
  import { retryProviderRequest } from "../utils/provider-retry.js";
@@ -258,7 +258,7 @@ export const stream = (model, context, options) => {
258
258
  }
259
259
  }
260
260
  else {
261
- block.arguments = parseStreamingJson(block.partialArgs);
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
- if (choice.delta.content !== null &&
385
- choice.delta.content !== undefined &&
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) {