@bastani/pi-ai 0.9.43 → 0.9.44-alpha.2

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 (77) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +45 -58
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  6. package/dist/api/azure-openai-responses.js +0 -6
  7. package/dist/api/azure-openai-responses.js.map +1 -1
  8. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  9. package/dist/api/bedrock-converse-stream.js +71 -78
  10. package/dist/api/bedrock-converse-stream.js.map +1 -1
  11. package/dist/api/constrained-sampling.d.ts +11 -1
  12. package/dist/api/constrained-sampling.d.ts.map +1 -1
  13. package/dist/api/constrained-sampling.js +33 -18
  14. package/dist/api/constrained-sampling.js.map +1 -1
  15. package/dist/api/google-generative-ai.d.ts.map +1 -1
  16. package/dist/api/google-generative-ai.js +0 -6
  17. package/dist/api/google-generative-ai.js.map +1 -1
  18. package/dist/api/google-shared.d.ts +2 -1
  19. package/dist/api/google-shared.d.ts.map +1 -1
  20. package/dist/api/google-shared.js +57 -2
  21. package/dist/api/google-shared.js.map +1 -1
  22. package/dist/api/google-vertex.d.ts.map +1 -1
  23. package/dist/api/google-vertex.js +0 -6
  24. package/dist/api/google-vertex.js.map +1 -1
  25. package/dist/api/mistral-conversations.d.ts.map +1 -1
  26. package/dist/api/mistral-conversations.js +17 -44
  27. package/dist/api/mistral-conversations.js.map +1 -1
  28. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  29. package/dist/api/openai-codex-responses.js +0 -5
  30. package/dist/api/openai-codex-responses.js.map +1 -1
  31. package/dist/api/openai-completions.d.ts.map +1 -1
  32. package/dist/api/openai-completions.js +34 -53
  33. package/dist/api/openai-completions.js.map +1 -1
  34. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  35. package/dist/api/openai-responses-shared.js +58 -57
  36. package/dist/api/openai-responses-shared.js.map +1 -1
  37. package/dist/api/openai-responses.d.ts.map +1 -1
  38. package/dist/api/openai-responses.js +0 -6
  39. package/dist/api/openai-responses.js.map +1 -1
  40. package/dist/api/pi-messages.d.ts +2 -0
  41. package/dist/api/pi-messages.d.ts.map +1 -1
  42. package/dist/api/pi-messages.js +15 -9
  43. package/dist/api/pi-messages.js.map +1 -1
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +1 -0
  47. package/dist/index.js.map +1 -1
  48. package/dist/providers/data/.manifest.json +1 -1
  49. package/dist/providers/data/kimi-coding.json +1 -1
  50. package/dist/providers/data/moonshotai-cn.json +1 -1
  51. package/dist/providers/data/moonshotai.json +1 -1
  52. package/dist/providers/data/opencode-go.json +1 -1
  53. package/dist/providers/data/openrouter.json +1 -1
  54. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  55. package/dist/providers/faux.d.ts.map +1 -1
  56. package/dist/providers/faux.js +7 -2
  57. package/dist/providers/faux.js.map +1 -1
  58. package/dist/providers/radius-config.d.ts.map +1 -1
  59. package/dist/providers/radius-config.js +2 -1
  60. package/dist/providers/radius-config.js.map +1 -1
  61. package/dist/types.js.map +1 -1
  62. package/dist/utils/error-body.d.ts.map +1 -1
  63. package/dist/utils/error-body.js +2 -1
  64. package/dist/utils/error-body.js.map +1 -1
  65. package/dist/utils/streaming-json.d.ts +84 -0
  66. package/dist/utils/streaming-json.d.ts.map +1 -0
  67. package/dist/utils/streaming-json.js +513 -0
  68. package/dist/utils/streaming-json.js.map +1 -0
  69. package/dist/utils/text.d.ts +7 -0
  70. package/dist/utils/text.d.ts.map +1 -1
  71. package/dist/utils/text.js +9 -0
  72. package/dist/utils/text.js.map +1 -1
  73. package/dist/utils/version.d.ts +1 -1
  74. package/dist/utils/version.d.ts.map +1 -1
  75. package/dist/utils/version.js +1 -1
  76. package/dist/utils/version.js.map +1 -1
  77. package/package.json +1 -1
@@ -4,7 +4,6 @@ import { AssistantMessageEventStream } from "../utils/event-stream.js";
4
4
  import { shortHash } from "../utils/hash.js";
5
5
  import { headersToRecord } from "../utils/headers.js";
6
6
  import { getIdentityHeaders } from "../utils/identity.js";
7
- import { parseStreamingJson, parseToolCallArguments } from "../utils/json-parse.js";
8
7
  import { applyOpenRouterReportedCost, isOpenRouterModel, } from "../utils/openrouter-cost.js";
9
8
  import { getProviderEnvValue } from "../utils/provider-env.js";
10
9
  import { retryProviderRequest } from "../utils/provider-retry.js";
@@ -12,9 +11,10 @@ import { admitOpenAIRequests, getFetchAdmission } from "../utils/request-admissi
12
11
  import { getProviderRetryAfterMs } from "../utils/retry-hints.js";
13
12
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
14
13
  import { createStreamDeadline, withStreamDeadline } from "../utils/stream-deadline.js";
14
+ import { ToolCallArgumentsStream } from "../utils/streaming-json.js";
15
15
  import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
16
16
  import { getDeclaredTools, resolveTranscript, resolveTranscriptTools, } from "../utils/transcript.js";
17
- import { appendGrammarToolInputJsonDelta, createGrammarToolInputProperties, getGrammarToolInput, getJsonSchemaToolParameters, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
17
+ import { appendGrammarToolInputJsonDelta, closeGrammarToolInputJson, createGrammarToolInputProperties, getGrammarToolInput, getJsonSchemaToolParameters, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
18
18
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput, preserveCopilotIntegrationHeader, } from "./github-copilot-headers.js";
19
19
  import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
20
20
  import { RetryHintOpenAI } from "./openai-retry-hint-client.js";
@@ -222,23 +222,14 @@ export const stream = (model, context, options) => {
222
222
  let hasFinishReason = false;
223
223
  const toolCallBlocksByIndex = new Map();
224
224
  const toolCallBlocksById = new Map();
225
+ const toolCallStates = new Map();
225
226
  const blocks = output.content;
226
227
  const getContentIndex = (block) => blocks.indexOf(block);
227
- const getCustomToolCallInput = (block) => {
228
- const property = block.customInput?.property;
229
- if (property === undefined)
230
- return "";
231
- const value = block.arguments[property];
232
- return typeof value === "string" ? value : "";
233
- };
234
- const appendCustomToolCallInput = (block, nextInput, close) => {
235
- const customInput = block.customInput;
236
- if (!customInput)
237
- return undefined;
238
- const delta = appendGrammarToolInputJsonDelta(customInput.jsonBuffer, customInput.property, nextInput, close);
239
- block.arguments = { [customInput.property]: nextInput };
240
- return delta;
241
- };
228
+ const customInput = (property) => ({
229
+ kind: "custom",
230
+ property,
231
+ buffer: { input: "", started: false, closed: false },
232
+ });
242
233
  const finishBlock = (block) => {
243
234
  const contentIndex = getContentIndex(block);
244
235
  if (contentIndex === -1) {
@@ -262,8 +253,10 @@ export const stream = (model, context, options) => {
262
253
  });
263
254
  }
264
255
  else if (block.type === "toolCall") {
265
- if (block.customInput) {
266
- const delta = appendCustomToolCallInput(block, getCustomToolCallInput(block), true);
256
+ const input = toolCallStates.get(block).input;
257
+ toolCallStates.delete(block);
258
+ if (input.kind === "custom") {
259
+ const delta = closeGrammarToolInputJson(input.buffer, input.property, undefined);
267
260
  if (delta !== undefined) {
268
261
  stream.push({
269
262
  type: "toolcall_delta",
@@ -274,13 +267,8 @@ export const stream = (model, context, options) => {
274
267
  }
275
268
  }
276
269
  else {
277
- Object.assign(block, parseToolCallArguments(block.partialArgs));
270
+ Object.assign(block, input.arguments.finish());
278
271
  }
279
- // Finalize in-place and strip the scratch buffers so replay only
280
- // carries parsed arguments.
281
- delete block.partialArgs;
282
- delete block.customInput;
283
- delete block.streamIndex;
284
272
  stream.push({
285
273
  type: "toolcall_end",
286
274
  contentIndex,
@@ -320,18 +308,18 @@ export const stream = (model, context, options) => {
320
308
  // Note: the "input" fallback here should/must not be taken. in case the LLM makes up
321
309
  // a tool we don't knwo about, we at least have a place to stash our stuff.
322
310
  const customInputProperty = toolCall.custom && !toolCall.function ? (grammarToolInputProperties.get(name) ?? "input") : undefined;
323
- const hasCustomInput = customInputProperty !== undefined;
324
311
  block = {
325
312
  type: "toolCall",
326
313
  id: toolCall.id || "",
327
314
  name,
328
- arguments: hasCustomInput ? { [customInputProperty]: "" } : {},
329
- partialArgs: hasCustomInput ? undefined : "",
330
- customInput: hasCustomInput
331
- ? { property: customInputProperty, jsonBuffer: { input: "", started: false, closed: false } }
332
- : undefined,
333
- streamIndex,
315
+ arguments: customInputProperty !== undefined ? { [customInputProperty]: "" } : {},
334
316
  };
317
+ toolCallStates.set(block, {
318
+ streamIndex,
319
+ input: customInputProperty !== undefined
320
+ ? customInput(customInputProperty)
321
+ : { kind: "json", arguments: new ToolCallArgumentsStream() },
322
+ });
335
323
  if (streamIndex !== undefined) {
336
324
  toolCallBlocksByIndex.set(streamIndex, block);
337
325
  }
@@ -345,8 +333,9 @@ export const stream = (model, context, options) => {
345
333
  partial: output,
346
334
  });
347
335
  }
348
- if (streamIndex !== undefined && block.streamIndex === undefined) {
349
- block.streamIndex = streamIndex;
336
+ const state = toolCallStates.get(block);
337
+ if (streamIndex !== undefined && state.streamIndex === undefined) {
338
+ state.streamIndex = streamIndex;
350
339
  toolCallBlocksByIndex.set(streamIndex, block);
351
340
  }
352
341
  if (toolCall.id) {
@@ -355,16 +344,12 @@ export const stream = (model, context, options) => {
355
344
  if (!block.name && name) {
356
345
  block.name = name;
357
346
  }
358
- if (toolCall.custom && !toolCall.function && !block.customInput) {
347
+ if (toolCall.custom && !toolCall.function && state.input.kind !== "custom") {
359
348
  const customInputProperty = grammarToolInputProperties.get(block.name) ?? "input";
360
349
  block.arguments = { [customInputProperty]: "" };
361
- block.customInput = {
362
- property: customInputProperty,
363
- jsonBuffer: { input: "", started: false, closed: false },
364
- };
365
- delete block.partialArgs;
350
+ state.input = customInput(customInputProperty);
366
351
  }
367
- return block;
352
+ return { block, state };
368
353
  };
369
354
  for await (const chunk of withStreamDeadline(openaiStream, streamDeadline.deadlineMs, streamDeadline.abort)) {
370
355
  await options?.onProviderStreamEvent?.(chunk, model);
@@ -454,7 +439,7 @@ export const stream = (model, context, options) => {
454
439
  }
455
440
  if (choice?.delta?.tool_calls) {
456
441
  for (const toolCall of choice.delta.tool_calls) {
457
- const block = ensureToolCallBlock(toolCall);
442
+ const { block, state } = ensureToolCallBlock(toolCall);
458
443
  if (!block.id && toolCall.id) {
459
444
  block.id = toolCall.id;
460
445
  toolCallBlocksById.set(toolCall.id, block);
@@ -464,14 +449,15 @@ export const stream = (model, context, options) => {
464
449
  block.name = name;
465
450
  }
466
451
  let delta = "";
467
- if (toolCall.function?.arguments) {
452
+ const input = state.input;
453
+ if (toolCall.function?.arguments && input.kind === "json") {
468
454
  delta = toolCall.function.arguments;
469
- block.partialArgs = (block.partialArgs ?? "") + toolCall.function.arguments;
470
- block.arguments = parseStreamingJson(block.partialArgs);
455
+ block.arguments = input.arguments.append(delta);
471
456
  }
472
- else if (toolCall.custom?.input) {
473
- const nextInput = getCustomToolCallInput(block) + toolCall.custom.input;
474
- delta = appendCustomToolCallInput(block, nextInput, false) ?? "";
457
+ else if (toolCall.custom?.input && input.kind === "custom") {
458
+ delta =
459
+ appendGrammarToolInputJsonDelta(input.buffer, input.property, toolCall.custom.input) ?? "";
460
+ block.arguments = { [input.property]: input.buffer.input };
475
461
  }
476
462
  stream.push({
477
463
  type: "toolcall_delta",
@@ -509,11 +495,6 @@ export const stream = (model, context, options) => {
509
495
  if (block.type === "thinking") {
510
496
  applyStreamedReasoningDetails(block);
511
497
  }
512
- delete block.index;
513
- // Streaming scratch buffers are only used during parsing; never persist them.
514
- delete block.partialArgs;
515
- delete block.customInput;
516
- delete block.streamIndex;
517
498
  }
518
499
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
519
500
  output.errorMessage = formatProviderError(normalizeProviderError(error));