@caupulican/pi-ai 0.90.12 → 0.91.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.
- package/dist/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/providers/amazon-bedrock.js +4 -4
- package/dist/providers/amazon-bedrock.js.map +1 -1
- package/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/dist/providers/openai-codex-responses.js +0 -6
- package/dist/providers/openai-codex-responses.js.map +1 -1
- package/dist/providers/openai-completions.d.ts.map +1 -1
- package/dist/providers/openai-completions.js +4 -4
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses-shared.d.ts.map +1 -1
- package/dist/providers/openai-responses-shared.js +297 -190
- package/dist/providers/openai-responses-shared.js.map +1 -1
- package/dist/providers/provider-runtime.d.ts +10 -1
- package/dist/providers/provider-runtime.d.ts.map +1 -1
- package/dist/providers/provider-runtime.js +22 -3
- package/dist/providers/provider-runtime.js.map +1 -1
- package/dist/stream.d.ts.map +1 -1
- package/dist/stream.js +28 -1
- package/dist/stream.js.map +1 -1
- package/dist/utils/event-stream.d.ts +8 -0
- package/dist/utils/event-stream.d.ts.map +1 -1
- package/dist/utils/event-stream.js +58 -3
- package/dist/utils/event-stream.js.map +1 -1
- package/dist/utils/tool-repair/registry.d.ts +18 -0
- package/dist/utils/tool-repair/registry.d.ts.map +1 -1
- package/dist/utils/tool-repair/registry.js +29 -0
- package/dist/utils/tool-repair/registry.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { shortHash } from "../utils/hash.js";
|
|
|
3
3
|
import { parseStreamingJson } from "../utils/json-parse.js";
|
|
4
4
|
import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
|
|
5
5
|
import { createToolNameMap } from "../utils/tool-names.js";
|
|
6
|
+
import { commitSuccessfulAssistantParse } from "./provider-runtime.js";
|
|
6
7
|
import { joinTextContent, transformMessages } from "./transform-messages.js";
|
|
7
8
|
// =============================================================================
|
|
8
9
|
// Utilities
|
|
@@ -279,6 +280,7 @@ export async function processResponsesStream(openaiStream, output, stream, model
|
|
|
279
280
|
let currentBlock = null;
|
|
280
281
|
let currentReasoningSummaryPartText = "";
|
|
281
282
|
let sawTerminalResponseEvent = false;
|
|
283
|
+
let committedSuccessfulTerminal = false;
|
|
282
284
|
const reasoningBlocksById = new Map();
|
|
283
285
|
const blocks = output.content;
|
|
284
286
|
const blockIndex = () => blocks.length - 1;
|
|
@@ -315,6 +317,149 @@ export async function processResponsesStream(openaiStream, output, stream, model
|
|
|
315
317
|
block.thinkingSignature = JSON.stringify({ ...storedItem, encrypted_content: item.encrypted_content });
|
|
316
318
|
}
|
|
317
319
|
};
|
|
320
|
+
const finalizedOutputItemKeys = new Set();
|
|
321
|
+
const outputItemKey = (item) => {
|
|
322
|
+
if (item.type === "reasoning" || item.type === "message") {
|
|
323
|
+
return item.id ? `${item.type}:${item.id}` : undefined;
|
|
324
|
+
}
|
|
325
|
+
if (item.type === "function_call") {
|
|
326
|
+
return `function_call:${item.call_id ?? ""}|${item.id ?? ""}`;
|
|
327
|
+
}
|
|
328
|
+
return undefined;
|
|
329
|
+
};
|
|
330
|
+
const contentIndexOf = (block) => output.content.indexOf(block);
|
|
331
|
+
const applyCompletedOutputItem = (item, emit) => {
|
|
332
|
+
const key = outputItemKey(item);
|
|
333
|
+
if (key && finalizedOutputItemKeys.has(key))
|
|
334
|
+
return;
|
|
335
|
+
if (item.type === "reasoning") {
|
|
336
|
+
if (item.summary) {
|
|
337
|
+
item.summary = item.summary
|
|
338
|
+
.map((part) => ({ ...part, text: cleanReasoningSummaryText(part.text ?? "") }))
|
|
339
|
+
.filter((part) => part.text.trim().length > 0);
|
|
340
|
+
}
|
|
341
|
+
const summaryText = normalizeReasoningSummaryText(item.summary);
|
|
342
|
+
const contentText = item.content?.map((part) => part.text).join("\n\n") || "";
|
|
343
|
+
let block = item.id ? reasoningBlocksById.get(item.id) : undefined;
|
|
344
|
+
if (!block && currentBlock?.type === "thinking")
|
|
345
|
+
block = currentBlock;
|
|
346
|
+
const isNew = !block;
|
|
347
|
+
if (!block) {
|
|
348
|
+
block = { type: "thinking", thinking: "" };
|
|
349
|
+
output.content.push(block);
|
|
350
|
+
}
|
|
351
|
+
block.thinking = summaryText || contentText || block.thinking;
|
|
352
|
+
block.thinkingSignature = JSON.stringify(item);
|
|
353
|
+
if (item.id)
|
|
354
|
+
reasoningBlocksById.set(item.id, block);
|
|
355
|
+
if (emit) {
|
|
356
|
+
const contentIndex = contentIndexOf(block);
|
|
357
|
+
if (isNew) {
|
|
358
|
+
stream.push({ type: "thinking_start", contentIndex, partial: output });
|
|
359
|
+
}
|
|
360
|
+
stream.push({
|
|
361
|
+
type: "thinking_end",
|
|
362
|
+
contentIndex,
|
|
363
|
+
content: block.thinking,
|
|
364
|
+
partial: output,
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
if (currentBlock === block)
|
|
368
|
+
currentBlock = null;
|
|
369
|
+
if (key)
|
|
370
|
+
finalizedOutputItemKeys.add(key);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
if (item.type === "message") {
|
|
374
|
+
const text = (item.content ?? [])
|
|
375
|
+
.map((part) => (part.type === "output_text" ? part.text : part.refusal))
|
|
376
|
+
.join("");
|
|
377
|
+
let block;
|
|
378
|
+
if (currentBlock?.type === "text") {
|
|
379
|
+
block = currentBlock;
|
|
380
|
+
}
|
|
381
|
+
else if (item.id) {
|
|
382
|
+
block = output.content.find((candidate) => candidate.type === "text" && parseTextSignature(candidate.textSignature)?.id === item.id);
|
|
383
|
+
}
|
|
384
|
+
const isNew = !block;
|
|
385
|
+
if (!block) {
|
|
386
|
+
block = { type: "text", text: "" };
|
|
387
|
+
output.content.push(block);
|
|
388
|
+
}
|
|
389
|
+
if (text.length > 0)
|
|
390
|
+
block.text = text;
|
|
391
|
+
if (item.id)
|
|
392
|
+
block.textSignature = encodeTextSignatureV1(item.id, item.phase ?? undefined);
|
|
393
|
+
if (emit) {
|
|
394
|
+
const contentIndex = contentIndexOf(block);
|
|
395
|
+
if (isNew) {
|
|
396
|
+
stream.push({ type: "text_start", contentIndex, partial: output });
|
|
397
|
+
}
|
|
398
|
+
stream.push({ type: "text_end", contentIndex, content: block.text, partial: output });
|
|
399
|
+
}
|
|
400
|
+
if (currentBlock === block)
|
|
401
|
+
currentBlock = null;
|
|
402
|
+
if (key)
|
|
403
|
+
finalizedOutputItemKeys.add(key);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const id = `${item.call_id}|${item.id}`;
|
|
407
|
+
let block = output.content.find((candidate) => candidate.type === "toolCall" && candidate.id === id);
|
|
408
|
+
if (!block && currentBlock?.type === "toolCall") {
|
|
409
|
+
block = currentBlock;
|
|
410
|
+
block.id = id;
|
|
411
|
+
block.name = options?.toolNameMap?.toOriginalName(item.name) ?? item.name;
|
|
412
|
+
}
|
|
413
|
+
const isNew = !block;
|
|
414
|
+
if (!block) {
|
|
415
|
+
block = {
|
|
416
|
+
type: "toolCall",
|
|
417
|
+
id,
|
|
418
|
+
name: options?.toolNameMap?.toOriginalName(item.name) ?? item.name,
|
|
419
|
+
arguments: {},
|
|
420
|
+
};
|
|
421
|
+
output.content.push(block);
|
|
422
|
+
}
|
|
423
|
+
block.arguments = parseStreamingJson(block.partialJson || item.arguments || "{}");
|
|
424
|
+
delete block.partialJson;
|
|
425
|
+
if (emit) {
|
|
426
|
+
const contentIndex = contentIndexOf(block);
|
|
427
|
+
if (isNew) {
|
|
428
|
+
stream.push({ type: "toolcall_start", contentIndex, partial: output });
|
|
429
|
+
}
|
|
430
|
+
stream.push({ type: "toolcall_end", contentIndex, toolCall: block, partial: output });
|
|
431
|
+
}
|
|
432
|
+
if (currentBlock === block)
|
|
433
|
+
currentBlock = null;
|
|
434
|
+
if (key)
|
|
435
|
+
finalizedOutputItemKeys.add(key);
|
|
436
|
+
};
|
|
437
|
+
const applyResponseOutput = (responseOutput) => {
|
|
438
|
+
for (const item of responseOutput) {
|
|
439
|
+
if (item.type === "reasoning" || item.type === "message" || item.type === "function_call") {
|
|
440
|
+
applyCompletedOutputItem(item, true);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (!currentBlock)
|
|
444
|
+
return;
|
|
445
|
+
const contentIndex = blockIndex();
|
|
446
|
+
if (currentBlock.type === "text") {
|
|
447
|
+
stream.push({ type: "text_end", contentIndex, content: currentBlock.text, partial: output });
|
|
448
|
+
}
|
|
449
|
+
else if (currentBlock.type === "thinking") {
|
|
450
|
+
stream.push({
|
|
451
|
+
type: "thinking_end",
|
|
452
|
+
contentIndex,
|
|
453
|
+
content: currentBlock.thinking,
|
|
454
|
+
partial: output,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
else {
|
|
458
|
+
delete currentBlock.partialJson;
|
|
459
|
+
stream.push({ type: "toolcall_end", contentIndex, toolCall: currentBlock, partial: output });
|
|
460
|
+
}
|
|
461
|
+
currentBlock = null;
|
|
462
|
+
};
|
|
318
463
|
const finalizeResponse = (response) => {
|
|
319
464
|
sawTerminalResponseEvent = true;
|
|
320
465
|
backfillReasoningSignatures((response.output ?? []).filter((item) => item.type === "reasoning"));
|
|
@@ -362,235 +507,197 @@ export async function processResponsesStream(openaiStream, output, stream, model
|
|
|
362
507
|
: (response?.service_tier ?? options.serviceTier);
|
|
363
508
|
options.applyServiceTierPricing(output.usage, serviceTier);
|
|
364
509
|
}
|
|
510
|
+
applyResponseOutput(response.output ?? []);
|
|
365
511
|
// Map status to stop reason
|
|
366
512
|
output.stopReason = mapStopReason(response?.status);
|
|
367
513
|
if (output.content.some((b) => b.type === "toolCall") && output.stopReason === "stop") {
|
|
368
514
|
output.stopReason = "toolUse";
|
|
369
515
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
output.responseId = event.response.id;
|
|
516
|
+
if (output.stopReason !== "error" && output.stopReason !== "aborted") {
|
|
517
|
+
committedSuccessfulTerminal = true;
|
|
518
|
+
commitSuccessfulAssistantParse(output);
|
|
374
519
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
currentReasoningSummaryPartText = "";
|
|
381
|
-
output.content.push(currentBlock);
|
|
382
|
-
stream.push({ type: "thinking_start", contentIndex: blockIndex(), partial: output });
|
|
383
|
-
}
|
|
384
|
-
else if (item.type === "message") {
|
|
385
|
-
currentItem = item;
|
|
386
|
-
currentBlock = { type: "text", text: "" };
|
|
387
|
-
output.content.push(currentBlock);
|
|
388
|
-
stream.push({ type: "text_start", contentIndex: blockIndex(), partial: output });
|
|
520
|
+
};
|
|
521
|
+
try {
|
|
522
|
+
for await (const event of openaiStream) {
|
|
523
|
+
if (event.type === "response.created") {
|
|
524
|
+
output.responseId = event.response.id;
|
|
389
525
|
}
|
|
390
|
-
else if (
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
|
|
526
|
+
else if (event.type === "response.output_item.added") {
|
|
527
|
+
const item = event.item;
|
|
528
|
+
if (item.type === "reasoning") {
|
|
529
|
+
currentItem = item;
|
|
530
|
+
currentBlock = { type: "thinking", thinking: "" };
|
|
531
|
+
currentReasoningSummaryPartText = "";
|
|
532
|
+
output.content.push(currentBlock);
|
|
533
|
+
stream.push({ type: "thinking_start", contentIndex: blockIndex(), partial: output });
|
|
534
|
+
}
|
|
535
|
+
else if (item.type === "message") {
|
|
536
|
+
currentItem = item;
|
|
537
|
+
currentBlock = { type: "text", text: "" };
|
|
538
|
+
output.content.push(currentBlock);
|
|
539
|
+
stream.push({ type: "text_start", contentIndex: blockIndex(), partial: output });
|
|
540
|
+
}
|
|
541
|
+
else if (item.type === "function_call") {
|
|
542
|
+
currentItem = item;
|
|
543
|
+
currentBlock = {
|
|
544
|
+
type: "toolCall",
|
|
545
|
+
id: `${item.call_id}|${item.id}`,
|
|
546
|
+
name: options?.toolNameMap?.toOriginalName(item.name) ?? item.name,
|
|
547
|
+
arguments: {},
|
|
548
|
+
partialJson: item.arguments || "",
|
|
549
|
+
};
|
|
550
|
+
output.content.push(currentBlock);
|
|
551
|
+
stream.push({ type: "toolcall_start", contentIndex: blockIndex(), partial: output });
|
|
552
|
+
}
|
|
401
553
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
554
|
+
else if (event.type === "response.reasoning_summary_part.added") {
|
|
555
|
+
if (currentItem && currentItem.type === "reasoning") {
|
|
556
|
+
currentItem.summary = currentItem.summary || [];
|
|
557
|
+
currentItem.summary.push(event.part);
|
|
558
|
+
currentReasoningSummaryPartText = event.part.text ?? "";
|
|
559
|
+
}
|
|
408
560
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
561
|
+
else if (event.type === "response.reasoning_summary_text.delta") {
|
|
562
|
+
if (currentItem?.type === "reasoning") {
|
|
563
|
+
currentItem.summary = currentItem.summary || [];
|
|
564
|
+
const lastPart = currentItem.summary[currentItem.summary.length - 1];
|
|
565
|
+
if (lastPart) {
|
|
566
|
+
lastPart.text += event.delta;
|
|
567
|
+
currentReasoningSummaryPartText += event.delta;
|
|
568
|
+
}
|
|
417
569
|
}
|
|
418
570
|
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
571
|
+
else if (event.type === "response.reasoning_summary_part.done") {
|
|
572
|
+
if (currentItem?.type === "reasoning" && currentBlock?.type === "thinking") {
|
|
573
|
+
currentItem.summary = currentItem.summary || [];
|
|
574
|
+
const lastPart = currentItem.summary[currentItem.summary.length - 1];
|
|
575
|
+
const partText = cleanReasoningSummaryText(lastPart?.text ?? currentReasoningSummaryPartText);
|
|
576
|
+
if (lastPart) {
|
|
577
|
+
lastPart.text = partText;
|
|
578
|
+
}
|
|
579
|
+
if (partText.trim().length > 0) {
|
|
580
|
+
const delta = `${partText}\n\n`;
|
|
581
|
+
currentBlock.thinking += delta;
|
|
582
|
+
stream.push({
|
|
583
|
+
type: "thinking_delta",
|
|
584
|
+
contentIndex: blockIndex(),
|
|
585
|
+
delta,
|
|
586
|
+
partial: output,
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
currentReasoningSummaryPartText = "";
|
|
427
590
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
591
|
+
}
|
|
592
|
+
else if (event.type === "response.reasoning_text.delta") {
|
|
593
|
+
if (currentItem?.type === "reasoning" && currentBlock?.type === "thinking") {
|
|
594
|
+
currentBlock.thinking += event.delta;
|
|
431
595
|
stream.push({
|
|
432
596
|
type: "thinking_delta",
|
|
433
597
|
contentIndex: blockIndex(),
|
|
434
|
-
delta,
|
|
598
|
+
delta: event.delta,
|
|
435
599
|
partial: output,
|
|
436
600
|
});
|
|
437
601
|
}
|
|
438
|
-
currentReasoningSummaryPartText = "";
|
|
439
602
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
partial: output,
|
|
449
|
-
});
|
|
603
|
+
else if (event.type === "response.content_part.added") {
|
|
604
|
+
if (currentItem?.type === "message") {
|
|
605
|
+
currentItem.content = currentItem.content || [];
|
|
606
|
+
// Filter out ReasoningText, only accept output_text and refusal
|
|
607
|
+
if (event.part.type === "output_text" || event.part.type === "refusal") {
|
|
608
|
+
currentItem.content.push(event.part);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
450
611
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
612
|
+
else if (event.type === "response.output_text.delta") {
|
|
613
|
+
if (currentItem?.type === "message" && currentBlock?.type === "text") {
|
|
614
|
+
const lastPart = ensureMessageOutputTextPart();
|
|
615
|
+
if (lastPart) {
|
|
616
|
+
currentBlock.text += event.delta;
|
|
617
|
+
lastPart.text += event.delta;
|
|
618
|
+
stream.push({
|
|
619
|
+
type: "text_delta",
|
|
620
|
+
contentIndex: blockIndex(),
|
|
621
|
+
delta: event.delta,
|
|
622
|
+
partial: output,
|
|
623
|
+
});
|
|
624
|
+
}
|
|
458
625
|
}
|
|
459
626
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
627
|
+
else if (event.type === "response.refusal.delta") {
|
|
628
|
+
if (currentItem?.type === "message" && currentBlock?.type === "text") {
|
|
629
|
+
const lastPart = ensureMessageRefusalPart();
|
|
630
|
+
if (lastPart) {
|
|
631
|
+
currentBlock.text += event.delta;
|
|
632
|
+
lastPart.refusal += event.delta;
|
|
633
|
+
stream.push({
|
|
634
|
+
type: "text_delta",
|
|
635
|
+
contentIndex: blockIndex(),
|
|
636
|
+
delta: event.delta,
|
|
637
|
+
partial: output,
|
|
638
|
+
});
|
|
639
|
+
}
|
|
473
640
|
}
|
|
474
641
|
}
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
if (lastPart) {
|
|
480
|
-
currentBlock.text += event.delta;
|
|
481
|
-
lastPart.refusal += event.delta;
|
|
642
|
+
else if (event.type === "response.function_call_arguments.delta") {
|
|
643
|
+
if (currentItem?.type === "function_call" && currentBlock?.type === "toolCall") {
|
|
644
|
+
currentBlock.partialJson = (currentBlock.partialJson ?? "") + event.delta;
|
|
645
|
+
currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
|
|
482
646
|
stream.push({
|
|
483
|
-
type: "
|
|
647
|
+
type: "toolcall_delta",
|
|
484
648
|
contentIndex: blockIndex(),
|
|
485
649
|
delta: event.delta,
|
|
486
650
|
partial: output,
|
|
487
651
|
});
|
|
488
652
|
}
|
|
489
653
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
const previousPartialJson = currentBlock.partialJson;
|
|
506
|
-
currentBlock.partialJson = event.arguments;
|
|
507
|
-
currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
|
|
508
|
-
if (event.arguments.startsWith(previousPartialJson)) {
|
|
509
|
-
const delta = event.arguments.slice(previousPartialJson.length);
|
|
510
|
-
if (delta.length > 0) {
|
|
511
|
-
stream.push({
|
|
512
|
-
type: "toolcall_delta",
|
|
513
|
-
contentIndex: blockIndex(),
|
|
514
|
-
delta,
|
|
515
|
-
partial: output,
|
|
516
|
-
});
|
|
654
|
+
else if (event.type === "response.function_call_arguments.done") {
|
|
655
|
+
if (currentItem?.type === "function_call" && currentBlock?.type === "toolCall") {
|
|
656
|
+
const previousPartialJson = currentBlock.partialJson;
|
|
657
|
+
currentBlock.partialJson = event.arguments;
|
|
658
|
+
currentBlock.arguments = parseStreamingJson(currentBlock.partialJson);
|
|
659
|
+
if (previousPartialJson !== undefined && event.arguments.startsWith(previousPartialJson)) {
|
|
660
|
+
const delta = event.arguments.slice(previousPartialJson.length);
|
|
661
|
+
if (delta.length > 0) {
|
|
662
|
+
stream.push({
|
|
663
|
+
type: "toolcall_delta",
|
|
664
|
+
contentIndex: blockIndex(),
|
|
665
|
+
delta,
|
|
666
|
+
partial: output,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
517
669
|
}
|
|
518
670
|
}
|
|
519
671
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (item.summary) {
|
|
525
|
-
item.summary = item.summary
|
|
526
|
-
.map((part) => ({ ...part, text: cleanReasoningSummaryText(part.text ?? "") }))
|
|
527
|
-
.filter((part) => part.text.trim().length > 0);
|
|
672
|
+
else if (event.type === "response.output_item.done") {
|
|
673
|
+
const item = event.item;
|
|
674
|
+
if (item.type === "reasoning" || item.type === "message" || item.type === "function_call") {
|
|
675
|
+
applyCompletedOutputItem(item, true);
|
|
528
676
|
}
|
|
529
|
-
const summaryText = normalizeReasoningSummaryText(item.summary);
|
|
530
|
-
const contentText = item.content?.map((c) => c.text).join("\n\n") || "";
|
|
531
|
-
currentBlock.thinking = summaryText || contentText || currentBlock.thinking;
|
|
532
|
-
currentBlock.thinkingSignature = JSON.stringify(item);
|
|
533
|
-
reasoningBlocksById.set(item.id, currentBlock);
|
|
534
|
-
stream.push({
|
|
535
|
-
type: "thinking_end",
|
|
536
|
-
contentIndex: blockIndex(),
|
|
537
|
-
content: currentBlock.thinking,
|
|
538
|
-
partial: output,
|
|
539
|
-
});
|
|
540
|
-
currentBlock = null;
|
|
541
677
|
}
|
|
542
|
-
else if (
|
|
543
|
-
|
|
544
|
-
currentBlock.textSignature = encodeTextSignatureV1(item.id, item.phase ?? undefined);
|
|
545
|
-
stream.push({
|
|
546
|
-
type: "text_end",
|
|
547
|
-
contentIndex: blockIndex(),
|
|
548
|
-
content: currentBlock.text,
|
|
549
|
-
partial: output,
|
|
550
|
-
});
|
|
551
|
-
currentBlock = null;
|
|
678
|
+
else if (event.type === "response.completed" || event.type === "response.incomplete") {
|
|
679
|
+
finalizeResponse(event.response);
|
|
552
680
|
}
|
|
553
|
-
else if (
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
toolCall = {
|
|
567
|
-
type: "toolCall",
|
|
568
|
-
id: `${item.call_id}|${item.id}`,
|
|
569
|
-
name: options?.toolNameMap?.toOriginalName(item.name) ?? item.name,
|
|
570
|
-
arguments: args,
|
|
571
|
-
};
|
|
572
|
-
}
|
|
573
|
-
currentBlock = null;
|
|
574
|
-
stream.push({ type: "toolcall_end", contentIndex: blockIndex(), toolCall, partial: output });
|
|
681
|
+
else if (event.type === "error") {
|
|
682
|
+
throw new Error(`Error Code ${event.code}: ${event.message}` || "Unknown error");
|
|
683
|
+
}
|
|
684
|
+
else if (event.type === "response.failed") {
|
|
685
|
+
sawTerminalResponseEvent = true;
|
|
686
|
+
const error = event.response?.error;
|
|
687
|
+
const details = event.response?.incomplete_details;
|
|
688
|
+
const msg = error
|
|
689
|
+
? `${error.code || "unknown"}: ${error.message || "no message"}`
|
|
690
|
+
: details?.reason
|
|
691
|
+
? `incomplete: ${details.reason}`
|
|
692
|
+
: "Unknown error (no error details in response)";
|
|
693
|
+
throw new Error(msg);
|
|
575
694
|
}
|
|
576
695
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
}
|
|
583
|
-
else if (event.type === "response.failed") {
|
|
584
|
-
sawTerminalResponseEvent = true;
|
|
585
|
-
const error = event.response?.error;
|
|
586
|
-
const details = event.response?.incomplete_details;
|
|
587
|
-
const msg = error
|
|
588
|
-
? `${error.code || "unknown"}: ${error.message || "no message"}`
|
|
589
|
-
: details?.reason
|
|
590
|
-
? `incomplete: ${details.reason}`
|
|
591
|
-
: "Unknown error (no error details in response)";
|
|
592
|
-
throw new Error(msg);
|
|
593
|
-
}
|
|
696
|
+
}
|
|
697
|
+
catch (error) {
|
|
698
|
+
if (committedSuccessfulTerminal)
|
|
699
|
+
return;
|
|
700
|
+
throw error;
|
|
594
701
|
}
|
|
595
702
|
if (!sawTerminalResponseEvent) {
|
|
596
703
|
throw new Error("OpenAI Responses stream ended before a terminal response event");
|