@tanstack/openai-base 0.10.1 → 0.10.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/README.md +2 -2
- package/dist/esm/adapters/chat-completions-text.d.ts +15 -7
- package/dist/esm/adapters/chat-completions-text.js +23 -7
- package/dist/esm/adapters/chat-completions-text.js.map +1 -1
- package/dist/esm/adapters/chat-completions-tool-converter.test.d.ts +1 -0
- package/dist/esm/adapters/responses-text.d.ts +15 -7
- package/dist/esm/adapters/responses-text.js +141 -105
- package/dist/esm/adapters/responses-text.js.map +1 -1
- package/dist/esm/adapters/responses-tool-converter.test.d.ts +1 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/tools/function-tool.test.d.ts +1 -0
- package/dist/esm/utils/schema-converter.d.ts +14 -0
- package/dist/esm/utils/schema-converter.js +106 -18
- package/dist/esm/utils/schema-converter.js.map +1 -1
- package/dist/esm/utils/tool-input-normalizer.d.ts +12 -0
- package/dist/esm/utils/tool-input-normalizer.js +36 -0
- package/dist/esm/utils/tool-input-normalizer.js.map +1 -0
- package/dist/esm/utils/tool-input-normalizer.test.d.ts +1 -0
- package/package.json +3 -3
- package/src/adapters/chat-completions-text.ts +51 -18
- package/src/adapters/chat-completions-tool-converter.test.ts +64 -0
- package/src/adapters/responses-text.ts +198 -130
- package/src/adapters/responses-tool-converter.test.ts +69 -0
- package/src/index.ts +4 -1
- package/src/tools/function-tool.test.ts +62 -0
- package/src/utils/schema-converter.ts +165 -20
- package/src/utils/tool-input-normalizer.test.ts +146 -0
- package/src/utils/tool-input-normalizer.ts +55 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { makeStructuredOutputCompatibleWithMap } from "../utils/schema-converter.js";
|
|
2
2
|
import { buildResponsesUsage } from "../usage.js";
|
|
3
3
|
import { extractRequestOptions } from "../utils/request-options.js";
|
|
4
|
+
import { createToolInputNormalizer } from "../utils/tool-input-normalizer.js";
|
|
4
5
|
import { convertToolsToResponsesFormat } from "./responses-tool-converter.js";
|
|
5
6
|
import { EventType, normalizeSystemPrompts } from "@tanstack/ai";
|
|
6
7
|
import { toRunErrorPayload, toRunErrorRawEvent } from "@tanstack/ai/adapter-internals";
|
|
@@ -183,6 +184,9 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
183
184
|
timestamp: Date.now(),
|
|
184
185
|
content: accumulatedReasoning
|
|
185
186
|
};
|
|
187
|
+
reasoningMessageId = void 0;
|
|
188
|
+
stepId = void 0;
|
|
189
|
+
hasClosedReasoning = false;
|
|
186
190
|
}
|
|
187
191
|
}.bind(this);
|
|
188
192
|
const openReasoning = function* () {
|
|
@@ -437,11 +441,20 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
437
441
|
return e.name === "APIUserAbortError" || e.name === "AbortError" || e.code === "ERR_CANCELED";
|
|
438
442
|
}
|
|
439
443
|
/**
|
|
444
|
+
* Strict conversion plus the inverse null-widening map for this request.
|
|
445
|
+
* Override this when schema conversion changes, so tool-input undo matches
|
|
446
|
+
* the wire schema.
|
|
447
|
+
*/
|
|
448
|
+
makeStructuredOutputCompatibleWithMap(schema, originalRequired) {
|
|
449
|
+
return makeStructuredOutputCompatibleWithMap(schema, originalRequired);
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
440
452
|
* Applies provider-specific transformations for structured output compatibility.
|
|
441
|
-
* Override
|
|
453
|
+
* Override `makeStructuredOutputCompatibleWithMap` when you need the inverse map
|
|
454
|
+
* to match the wire schema.
|
|
442
455
|
*/
|
|
443
456
|
makeStructuredOutputCompatible(schema, originalRequired) {
|
|
444
|
-
return
|
|
457
|
+
return this.makeStructuredOutputCompatibleWithMap(schema, originalRequired).schema;
|
|
445
458
|
}
|
|
446
459
|
/**
|
|
447
460
|
* Final shaping pass applied to parsed structured-output JSON before it is
|
|
@@ -502,6 +515,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
502
515
|
* - error
|
|
503
516
|
*/
|
|
504
517
|
async *processStreamChunks(stream, toolCallMetadata, options, aguiState) {
|
|
518
|
+
const normalizeToolInput = createToolInputNormalizer(options.tools, (schema, required) => this.makeStructuredOutputCompatibleWithMap(schema, required));
|
|
505
519
|
let accumulatedContent = "";
|
|
506
520
|
let accumulatedReasoning = "";
|
|
507
521
|
let hasStreamedContentDeltas = false;
|
|
@@ -509,8 +523,83 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
509
523
|
let model = options.model;
|
|
510
524
|
let stepId = null;
|
|
511
525
|
let hasEmittedTextMessageStart = false;
|
|
512
|
-
let
|
|
526
|
+
let reasoningMessageId;
|
|
527
|
+
let hasClosedReasoning = false;
|
|
513
528
|
let runFinishedEmitted = false;
|
|
529
|
+
const adapterName = this.name;
|
|
530
|
+
const emitModel = () => model || options.model;
|
|
531
|
+
const openReasoning = function* () {
|
|
532
|
+
if (reasoningMessageId) return;
|
|
533
|
+
reasoningMessageId = generateId(adapterName);
|
|
534
|
+
stepId = generateId(adapterName);
|
|
535
|
+
const timestamp = Date.now();
|
|
536
|
+
const currentModel = emitModel();
|
|
537
|
+
yield {
|
|
538
|
+
type: EventType.REASONING_START,
|
|
539
|
+
messageId: reasoningMessageId,
|
|
540
|
+
model: currentModel,
|
|
541
|
+
timestamp
|
|
542
|
+
};
|
|
543
|
+
yield {
|
|
544
|
+
type: EventType.REASONING_MESSAGE_START,
|
|
545
|
+
messageId: reasoningMessageId,
|
|
546
|
+
role: "reasoning",
|
|
547
|
+
model: currentModel,
|
|
548
|
+
timestamp
|
|
549
|
+
};
|
|
550
|
+
yield {
|
|
551
|
+
type: EventType.STEP_STARTED,
|
|
552
|
+
stepName: stepId,
|
|
553
|
+
stepId,
|
|
554
|
+
model: currentModel,
|
|
555
|
+
timestamp,
|
|
556
|
+
stepType: "thinking"
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
const closeReasoning = function* () {
|
|
560
|
+
if (!reasoningMessageId || hasClosedReasoning) return;
|
|
561
|
+
hasClosedReasoning = true;
|
|
562
|
+
const timestamp = Date.now();
|
|
563
|
+
const currentModel = emitModel();
|
|
564
|
+
yield {
|
|
565
|
+
type: EventType.REASONING_MESSAGE_END,
|
|
566
|
+
messageId: reasoningMessageId,
|
|
567
|
+
model: currentModel,
|
|
568
|
+
timestamp
|
|
569
|
+
};
|
|
570
|
+
yield {
|
|
571
|
+
type: EventType.REASONING_END,
|
|
572
|
+
messageId: reasoningMessageId,
|
|
573
|
+
model: currentModel,
|
|
574
|
+
timestamp
|
|
575
|
+
};
|
|
576
|
+
if (stepId) yield {
|
|
577
|
+
type: EventType.STEP_FINISHED,
|
|
578
|
+
stepName: stepId,
|
|
579
|
+
stepId,
|
|
580
|
+
model: currentModel,
|
|
581
|
+
timestamp,
|
|
582
|
+
content: accumulatedReasoning
|
|
583
|
+
};
|
|
584
|
+
reasoningMessageId = void 0;
|
|
585
|
+
stepId = null;
|
|
586
|
+
hasClosedReasoning = false;
|
|
587
|
+
accumulatedReasoning = "";
|
|
588
|
+
};
|
|
589
|
+
const emitReasoningDelta = function* (text) {
|
|
590
|
+
if (!text) return;
|
|
591
|
+
yield* openReasoning();
|
|
592
|
+
if (!reasoningMessageId) return;
|
|
593
|
+
accumulatedReasoning += text;
|
|
594
|
+
hasStreamedReasoningDeltas = true;
|
|
595
|
+
yield {
|
|
596
|
+
type: EventType.REASONING_MESSAGE_CONTENT,
|
|
597
|
+
messageId: reasoningMessageId,
|
|
598
|
+
delta: text,
|
|
599
|
+
model: emitModel(),
|
|
600
|
+
timestamp: Date.now()
|
|
601
|
+
};
|
|
602
|
+
};
|
|
514
603
|
try {
|
|
515
604
|
for await (const chunk of stream) {
|
|
516
605
|
options.logger.provider(`provider=${this.name} type=${chunk.type}`, {
|
|
@@ -540,19 +629,6 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
540
629
|
content: accumulatedContent
|
|
541
630
|
};
|
|
542
631
|
}
|
|
543
|
-
if (contentPart.type === "reasoning_text") {
|
|
544
|
-
accumulatedReasoning += contentPart.text || "";
|
|
545
|
-
if (!stepId) stepId = generateId(this.name);
|
|
546
|
-
return {
|
|
547
|
-
type: EventType.STEP_FINISHED,
|
|
548
|
-
stepName: stepId,
|
|
549
|
-
stepId,
|
|
550
|
-
model: model || options.model,
|
|
551
|
-
timestamp: Date.now(),
|
|
552
|
-
delta: contentPart.text || "",
|
|
553
|
-
content: accumulatedReasoning
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
632
|
const isRefusal = contentPart.type === "refusal";
|
|
557
633
|
const message = isRefusal ? contentPart.refusal || "Refused without explanation" : `Unsupported response content_part type: ${contentPart.type}`;
|
|
558
634
|
const code = isRefusal ? "refusal" : contentPart.type;
|
|
@@ -573,11 +649,14 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
573
649
|
hasStreamedContentDeltas = false;
|
|
574
650
|
hasStreamedReasoningDeltas = false;
|
|
575
651
|
hasEmittedTextMessageStart = false;
|
|
576
|
-
|
|
652
|
+
reasoningMessageId = void 0;
|
|
653
|
+
hasClosedReasoning = false;
|
|
654
|
+
stepId = null;
|
|
577
655
|
accumulatedContent = "";
|
|
578
656
|
accumulatedReasoning = "";
|
|
579
657
|
}
|
|
580
658
|
if (chunk.type === "response.failed" || chunk.type === "response.incomplete") {
|
|
659
|
+
yield* closeReasoning();
|
|
581
660
|
if (hasEmittedTextMessageStart) {
|
|
582
661
|
yield {
|
|
583
662
|
type: EventType.TEXT_MESSAGE_END,
|
|
@@ -606,6 +685,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
606
685
|
if (chunk.type === "response.output_text.delta" && chunk.delta) {
|
|
607
686
|
const textDelta = Array.isArray(chunk.delta) ? chunk.delta.join("") : typeof chunk.delta === "string" ? chunk.delta : "";
|
|
608
687
|
if (textDelta) {
|
|
688
|
+
yield* closeReasoning();
|
|
609
689
|
if (!hasEmittedTextMessageStart) {
|
|
610
690
|
hasEmittedTextMessageStart = true;
|
|
611
691
|
yield {
|
|
@@ -628,67 +708,17 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
628
708
|
};
|
|
629
709
|
}
|
|
630
710
|
}
|
|
631
|
-
if (chunk.type === "response.reasoning_text.delta" && chunk.delta)
|
|
632
|
-
|
|
633
|
-
if (reasoningDelta) {
|
|
634
|
-
if (!hasEmittedStepStarted) {
|
|
635
|
-
hasEmittedStepStarted = true;
|
|
636
|
-
stepId = generateId(this.name);
|
|
637
|
-
yield {
|
|
638
|
-
type: EventType.STEP_STARTED,
|
|
639
|
-
stepName: stepId,
|
|
640
|
-
stepId,
|
|
641
|
-
model: model || options.model,
|
|
642
|
-
timestamp: Date.now(),
|
|
643
|
-
stepType: "thinking"
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
accumulatedReasoning += reasoningDelta;
|
|
647
|
-
hasStreamedReasoningDeltas = true;
|
|
648
|
-
const fallbackStepId = stepId || generateId(this.name);
|
|
649
|
-
yield {
|
|
650
|
-
type: EventType.STEP_FINISHED,
|
|
651
|
-
stepName: fallbackStepId,
|
|
652
|
-
stepId: fallbackStepId,
|
|
653
|
-
model: model || options.model,
|
|
654
|
-
timestamp: Date.now(),
|
|
655
|
-
delta: reasoningDelta,
|
|
656
|
-
content: accumulatedReasoning
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
}
|
|
660
|
-
if (chunk.type === "response.reasoning_summary_text.delta" && chunk.delta) {
|
|
661
|
-
const summaryDelta = typeof chunk.delta === "string" ? chunk.delta : "";
|
|
662
|
-
if (summaryDelta) {
|
|
663
|
-
if (!hasEmittedStepStarted) {
|
|
664
|
-
hasEmittedStepStarted = true;
|
|
665
|
-
stepId = generateId(this.name);
|
|
666
|
-
yield {
|
|
667
|
-
type: EventType.STEP_STARTED,
|
|
668
|
-
stepName: stepId,
|
|
669
|
-
stepId,
|
|
670
|
-
model: model || options.model,
|
|
671
|
-
timestamp: Date.now(),
|
|
672
|
-
stepType: "thinking"
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
accumulatedReasoning += summaryDelta;
|
|
676
|
-
hasStreamedReasoningDeltas = true;
|
|
677
|
-
const fallbackStepId = stepId || generateId(this.name);
|
|
678
|
-
yield {
|
|
679
|
-
type: EventType.STEP_FINISHED,
|
|
680
|
-
stepName: fallbackStepId,
|
|
681
|
-
stepId: fallbackStepId,
|
|
682
|
-
model: model || options.model,
|
|
683
|
-
timestamp: Date.now(),
|
|
684
|
-
delta: summaryDelta,
|
|
685
|
-
content: accumulatedReasoning
|
|
686
|
-
};
|
|
687
|
-
}
|
|
688
|
-
}
|
|
711
|
+
if (chunk.type === "response.reasoning_text.delta" && chunk.delta) yield* emitReasoningDelta(Array.isArray(chunk.delta) ? chunk.delta.join("") : typeof chunk.delta === "string" ? chunk.delta : "");
|
|
712
|
+
if (chunk.type === "response.reasoning_summary_text.delta" && chunk.delta) yield* emitReasoningDelta(typeof chunk.delta === "string" ? chunk.delta : "");
|
|
689
713
|
if (chunk.type === "response.content_part.added") {
|
|
690
714
|
const contentPart = chunk.part;
|
|
715
|
+
if ((contentPart.type === "output_text" || contentPart.type === "reasoning_text") && !contentPart.text) continue;
|
|
716
|
+
if (contentPart.type === "reasoning_text") {
|
|
717
|
+
yield* emitReasoningDelta(contentPart.text || "");
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
691
720
|
if (contentPart.type === "output_text" && !hasEmittedTextMessageStart) {
|
|
721
|
+
yield* closeReasoning();
|
|
692
722
|
hasEmittedTextMessageStart = true;
|
|
693
723
|
yield {
|
|
694
724
|
type: EventType.TEXT_MESSAGE_START,
|
|
@@ -698,20 +728,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
698
728
|
role: "assistant"
|
|
699
729
|
};
|
|
700
730
|
}
|
|
701
|
-
if (contentPart.type === "reasoning_text" && !hasEmittedStepStarted) {
|
|
702
|
-
hasEmittedStepStarted = true;
|
|
703
|
-
stepId = generateId(this.name);
|
|
704
|
-
yield {
|
|
705
|
-
type: EventType.STEP_STARTED,
|
|
706
|
-
stepName: stepId,
|
|
707
|
-
stepId,
|
|
708
|
-
model: model || options.model,
|
|
709
|
-
timestamp: Date.now(),
|
|
710
|
-
stepType: "thinking"
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
731
|
if (contentPart.type === "output_text") hasStreamedContentDeltas = true;
|
|
714
|
-
else if (contentPart.type === "reasoning_text") hasStreamedReasoningDeltas = true;
|
|
715
732
|
const partChunk = handleContentPart(contentPart);
|
|
716
733
|
yield partChunk;
|
|
717
734
|
if (partChunk.type === "RUN_ERROR") {
|
|
@@ -723,7 +740,12 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
723
740
|
const contentPart = chunk.part;
|
|
724
741
|
if (contentPart.type === "output_text" && hasStreamedContentDeltas) continue;
|
|
725
742
|
if (contentPart.type === "reasoning_text" && hasStreamedReasoningDeltas) continue;
|
|
743
|
+
if (contentPart.type === "reasoning_text") {
|
|
744
|
+
yield* emitReasoningDelta(contentPart.text || "");
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
726
747
|
if (contentPart.type === "output_text" && !hasEmittedTextMessageStart) {
|
|
748
|
+
yield* closeReasoning();
|
|
727
749
|
hasEmittedTextMessageStart = true;
|
|
728
750
|
yield {
|
|
729
751
|
type: EventType.TEXT_MESSAGE_START,
|
|
@@ -732,17 +754,6 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
732
754
|
timestamp: Date.now(),
|
|
733
755
|
role: "assistant"
|
|
734
756
|
};
|
|
735
|
-
} else if (contentPart.type === "reasoning_text" && !hasEmittedStepStarted) {
|
|
736
|
-
hasEmittedStepStarted = true;
|
|
737
|
-
stepId = generateId(this.name);
|
|
738
|
-
yield {
|
|
739
|
-
type: EventType.STEP_STARTED,
|
|
740
|
-
stepName: stepId,
|
|
741
|
-
stepId,
|
|
742
|
-
model: model || options.model,
|
|
743
|
-
timestamp: Date.now(),
|
|
744
|
-
stepType: "thinking"
|
|
745
|
-
};
|
|
746
757
|
}
|
|
747
758
|
const doneChunk = handleContentPart(contentPart);
|
|
748
759
|
yield doneChunk;
|
|
@@ -820,7 +831,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
820
831
|
let parsedInput = {};
|
|
821
832
|
if (chunk.arguments) try {
|
|
822
833
|
const parsed = JSON.parse(chunk.arguments);
|
|
823
|
-
parsedInput = parsed && typeof parsed === "object" ? parsed : {};
|
|
834
|
+
parsedInput = normalizeToolInput(name, parsed && typeof parsed === "object" ? parsed : {});
|
|
824
835
|
} catch (parseError) {
|
|
825
836
|
options.logger.errors(`${this.name}.processStreamChunks tool-args JSON parse failed`, {
|
|
826
837
|
error: toRunErrorPayload(parseError, `tool ${name} (${metadata.callId}) returned malformed JSON arguments`),
|
|
@@ -876,7 +887,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
876
887
|
let parsedInput = {};
|
|
877
888
|
if (rawArgs) try {
|
|
878
889
|
const parsed = JSON.parse(rawArgs);
|
|
879
|
-
parsedInput = parsed && typeof parsed === "object" ? parsed : {};
|
|
890
|
+
parsedInput = normalizeToolInput(name, parsed && typeof parsed === "object" ? parsed : {});
|
|
880
891
|
} catch (parseError) {
|
|
881
892
|
options.logger.errors(`${this.name}.processStreamChunks tool-args JSON parse failed (output_item.done backfill)`, {
|
|
882
893
|
error: toRunErrorPayload(parseError, `tool ${name} (${metadata.callId}) returned malformed JSON arguments`),
|
|
@@ -903,6 +914,29 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
903
914
|
}
|
|
904
915
|
}
|
|
905
916
|
if (chunk.type === "response.completed") {
|
|
917
|
+
const completedText = chunk.response.output.flatMap((item) => item.type === "message" ? item.content : []).filter((part) => part.type === "output_text").map((part) => part.text).join("");
|
|
918
|
+
if (accumulatedContent.length === 0 && completedText.length > 0) {
|
|
919
|
+
if (!hasEmittedTextMessageStart) {
|
|
920
|
+
hasEmittedTextMessageStart = true;
|
|
921
|
+
yield {
|
|
922
|
+
type: EventType.TEXT_MESSAGE_START,
|
|
923
|
+
messageId: aguiState.messageId,
|
|
924
|
+
model: model || options.model,
|
|
925
|
+
timestamp: Date.now(),
|
|
926
|
+
role: "assistant"
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
accumulatedContent = completedText;
|
|
930
|
+
hasStreamedContentDeltas = true;
|
|
931
|
+
yield {
|
|
932
|
+
type: EventType.TEXT_MESSAGE_CONTENT,
|
|
933
|
+
messageId: aguiState.messageId,
|
|
934
|
+
model: model || options.model,
|
|
935
|
+
timestamp: Date.now(),
|
|
936
|
+
delta: completedText,
|
|
937
|
+
content: accumulatedContent
|
|
938
|
+
};
|
|
939
|
+
}
|
|
906
940
|
for (const item of chunk.response.output) {
|
|
907
941
|
if (item.type !== "function_call" || !item.id) continue;
|
|
908
942
|
const metadata = toolCallMetadata.get(item.id) ?? {
|
|
@@ -936,7 +970,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
936
970
|
let parsedInput = {};
|
|
937
971
|
if (rawArgs) try {
|
|
938
972
|
const parsed = JSON.parse(rawArgs);
|
|
939
|
-
parsedInput = parsed && typeof parsed === "object" ? parsed : {};
|
|
973
|
+
parsedInput = normalizeToolInput(name, parsed && typeof parsed === "object" ? parsed : {});
|
|
940
974
|
} catch (parseError) {
|
|
941
975
|
options.logger.errors(`${this.name}.processStreamChunks tool-args JSON parse failed (response.completed backfill)`, {
|
|
942
976
|
error: toRunErrorPayload(parseError, `tool ${name} (${metadata.callId}) returned malformed JSON arguments`),
|
|
@@ -961,6 +995,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
961
995
|
metadata.pendingArguments = void 0;
|
|
962
996
|
}
|
|
963
997
|
}
|
|
998
|
+
yield* closeReasoning();
|
|
964
999
|
if (hasEmittedTextMessageStart) {
|
|
965
1000
|
yield {
|
|
966
1001
|
type: EventType.TEXT_MESSAGE_END,
|
|
@@ -1002,6 +1037,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1002
1037
|
}
|
|
1003
1038
|
}
|
|
1004
1039
|
if (!runFinishedEmitted && aguiState.hasEmittedRunStarted) {
|
|
1040
|
+
yield* closeReasoning();
|
|
1005
1041
|
if (hasEmittedTextMessageStart) yield {
|
|
1006
1042
|
type: EventType.TEXT_MESSAGE_END,
|
|
1007
1043
|
messageId: aguiState.messageId,
|
|
@@ -1200,7 +1236,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1200
1236
|
* Handles backward compatibility with string content.
|
|
1201
1237
|
*/
|
|
1202
1238
|
normalizeContent(content) {
|
|
1203
|
-
if (content === null) return [];
|
|
1239
|
+
if (content === null || content === void 0) return [];
|
|
1204
1240
|
if (typeof content === "string") return [{
|
|
1205
1241
|
type: "text",
|
|
1206
1242
|
content
|
|
@@ -1211,7 +1247,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1211
1247
|
* Extracts text content from a content value that may be string, null, or ContentPart array.
|
|
1212
1248
|
*/
|
|
1213
1249
|
extractTextContent(content) {
|
|
1214
|
-
if (content === null) return "";
|
|
1250
|
+
if (content === null || content === void 0) return "";
|
|
1215
1251
|
if (typeof content === "string") return content;
|
|
1216
1252
|
return content.filter((p) => p.type === "text").map((p) => p.content).join("");
|
|
1217
1253
|
}
|