@tanstack/openai-base 0.10.2 → 0.10.5
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/esm/adapters/chat-completions-text.d.ts +6 -6
- package/dist/esm/adapters/chat-completions-text.js +7 -2
- package/dist/esm/adapters/chat-completions-text.js.map +1 -1
- package/dist/esm/adapters/responses-text.d.ts +19 -8
- package/dist/esm/adapters/responses-text.js +104 -101
- package/dist/esm/adapters/responses-text.js.map +1 -1
- package/package.json +3 -3
- package/src/adapters/chat-completions-text.ts +19 -12
- package/src/adapters/responses-text.ts +141 -127
|
@@ -134,7 +134,8 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
134
134
|
* Stream structured output via the Responses API: single request with
|
|
135
135
|
* `text.format: json_schema` + `stream: true`. Consumes Responses-API
|
|
136
136
|
* events (`response.output_text.delta`, `response.reasoning_text.delta`,
|
|
137
|
-
* `response.reasoning_summary_text.delta`,
|
|
137
|
+
* `response.reasoning_summary_text.delta`, the legacy
|
|
138
|
+
* `response.reasoning.delta`, `response.refusal.delta`,
|
|
138
139
|
* `response.completed`, `response.failed`) and re-emits the standard AG-UI
|
|
139
140
|
* lifecycle ending with `CUSTOM 'structured-output.complete'`.
|
|
140
141
|
*
|
|
@@ -184,6 +185,9 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
184
185
|
timestamp: Date.now(),
|
|
185
186
|
content: accumulatedReasoning
|
|
186
187
|
};
|
|
188
|
+
reasoningMessageId = void 0;
|
|
189
|
+
stepId = void 0;
|
|
190
|
+
hasClosedReasoning = false;
|
|
187
191
|
}
|
|
188
192
|
}.bind(this);
|
|
189
193
|
const openReasoning = function* () {
|
|
@@ -265,7 +269,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
265
269
|
};
|
|
266
270
|
return;
|
|
267
271
|
}
|
|
268
|
-
if (chunk.type === "response.reasoning_text.delta" || chunk.type === "response.reasoning_summary_text.delta") {
|
|
272
|
+
if (chunk.type === "response.reasoning_text.delta" || chunk.type === "response.reasoning_summary_text.delta" || chunk.type === "response.reasoning.delta") {
|
|
269
273
|
const raw = chunk.delta;
|
|
270
274
|
const reasoningDelta = Array.isArray(raw) ? raw.join("") : typeof raw === "string" ? raw : "";
|
|
271
275
|
if (!reasoningDelta) continue;
|
|
@@ -504,6 +508,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
504
508
|
* - response.created / response.incomplete / response.failed
|
|
505
509
|
* - response.output_text.delta
|
|
506
510
|
* - response.reasoning_text.delta
|
|
511
|
+
* - response.reasoning.delta (the legacy type used before response.reasoning_text.delta)
|
|
507
512
|
* - response.reasoning_summary_text.delta
|
|
508
513
|
* - response.content_part.added / response.content_part.done
|
|
509
514
|
* - response.output_item.added
|
|
@@ -520,8 +525,83 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
520
525
|
let model = options.model;
|
|
521
526
|
let stepId = null;
|
|
522
527
|
let hasEmittedTextMessageStart = false;
|
|
523
|
-
let
|
|
528
|
+
let reasoningMessageId;
|
|
529
|
+
let hasClosedReasoning = false;
|
|
524
530
|
let runFinishedEmitted = false;
|
|
531
|
+
const adapterName = this.name;
|
|
532
|
+
const emitModel = () => model || options.model;
|
|
533
|
+
const openReasoning = function* () {
|
|
534
|
+
if (reasoningMessageId) return;
|
|
535
|
+
reasoningMessageId = generateId(adapterName);
|
|
536
|
+
stepId = generateId(adapterName);
|
|
537
|
+
const timestamp = Date.now();
|
|
538
|
+
const currentModel = emitModel();
|
|
539
|
+
yield {
|
|
540
|
+
type: EventType.REASONING_START,
|
|
541
|
+
messageId: reasoningMessageId,
|
|
542
|
+
model: currentModel,
|
|
543
|
+
timestamp
|
|
544
|
+
};
|
|
545
|
+
yield {
|
|
546
|
+
type: EventType.REASONING_MESSAGE_START,
|
|
547
|
+
messageId: reasoningMessageId,
|
|
548
|
+
role: "reasoning",
|
|
549
|
+
model: currentModel,
|
|
550
|
+
timestamp
|
|
551
|
+
};
|
|
552
|
+
yield {
|
|
553
|
+
type: EventType.STEP_STARTED,
|
|
554
|
+
stepName: stepId,
|
|
555
|
+
stepId,
|
|
556
|
+
model: currentModel,
|
|
557
|
+
timestamp,
|
|
558
|
+
stepType: "thinking"
|
|
559
|
+
};
|
|
560
|
+
};
|
|
561
|
+
const closeReasoning = function* () {
|
|
562
|
+
if (!reasoningMessageId || hasClosedReasoning) return;
|
|
563
|
+
hasClosedReasoning = true;
|
|
564
|
+
const timestamp = Date.now();
|
|
565
|
+
const currentModel = emitModel();
|
|
566
|
+
yield {
|
|
567
|
+
type: EventType.REASONING_MESSAGE_END,
|
|
568
|
+
messageId: reasoningMessageId,
|
|
569
|
+
model: currentModel,
|
|
570
|
+
timestamp
|
|
571
|
+
};
|
|
572
|
+
yield {
|
|
573
|
+
type: EventType.REASONING_END,
|
|
574
|
+
messageId: reasoningMessageId,
|
|
575
|
+
model: currentModel,
|
|
576
|
+
timestamp
|
|
577
|
+
};
|
|
578
|
+
if (stepId) yield {
|
|
579
|
+
type: EventType.STEP_FINISHED,
|
|
580
|
+
stepName: stepId,
|
|
581
|
+
stepId,
|
|
582
|
+
model: currentModel,
|
|
583
|
+
timestamp,
|
|
584
|
+
content: accumulatedReasoning
|
|
585
|
+
};
|
|
586
|
+
reasoningMessageId = void 0;
|
|
587
|
+
stepId = null;
|
|
588
|
+
hasClosedReasoning = false;
|
|
589
|
+
accumulatedReasoning = "";
|
|
590
|
+
};
|
|
591
|
+
const emitReasoningDelta = function* (text) {
|
|
592
|
+
if (!text) return;
|
|
593
|
+
yield* openReasoning();
|
|
594
|
+
if (!reasoningMessageId) return;
|
|
595
|
+
accumulatedReasoning += text;
|
|
596
|
+
hasStreamedReasoningDeltas = true;
|
|
597
|
+
yield {
|
|
598
|
+
type: EventType.REASONING_MESSAGE_CONTENT,
|
|
599
|
+
messageId: reasoningMessageId,
|
|
600
|
+
delta: text,
|
|
601
|
+
model: emitModel(),
|
|
602
|
+
timestamp: Date.now()
|
|
603
|
+
};
|
|
604
|
+
};
|
|
525
605
|
try {
|
|
526
606
|
for await (const chunk of stream) {
|
|
527
607
|
options.logger.provider(`provider=${this.name} type=${chunk.type}`, {
|
|
@@ -551,19 +631,6 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
551
631
|
content: accumulatedContent
|
|
552
632
|
};
|
|
553
633
|
}
|
|
554
|
-
if (contentPart.type === "reasoning_text") {
|
|
555
|
-
accumulatedReasoning += contentPart.text || "";
|
|
556
|
-
if (!stepId) stepId = generateId(this.name);
|
|
557
|
-
return {
|
|
558
|
-
type: EventType.STEP_FINISHED,
|
|
559
|
-
stepName: stepId,
|
|
560
|
-
stepId,
|
|
561
|
-
model: model || options.model,
|
|
562
|
-
timestamp: Date.now(),
|
|
563
|
-
delta: contentPart.text || "",
|
|
564
|
-
content: accumulatedReasoning
|
|
565
|
-
};
|
|
566
|
-
}
|
|
567
634
|
const isRefusal = contentPart.type === "refusal";
|
|
568
635
|
const message = isRefusal ? contentPart.refusal || "Refused without explanation" : `Unsupported response content_part type: ${contentPart.type}`;
|
|
569
636
|
const code = isRefusal ? "refusal" : contentPart.type;
|
|
@@ -584,11 +651,14 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
584
651
|
hasStreamedContentDeltas = false;
|
|
585
652
|
hasStreamedReasoningDeltas = false;
|
|
586
653
|
hasEmittedTextMessageStart = false;
|
|
587
|
-
|
|
654
|
+
reasoningMessageId = void 0;
|
|
655
|
+
hasClosedReasoning = false;
|
|
656
|
+
stepId = null;
|
|
588
657
|
accumulatedContent = "";
|
|
589
658
|
accumulatedReasoning = "";
|
|
590
659
|
}
|
|
591
660
|
if (chunk.type === "response.failed" || chunk.type === "response.incomplete") {
|
|
661
|
+
yield* closeReasoning();
|
|
592
662
|
if (hasEmittedTextMessageStart) {
|
|
593
663
|
yield {
|
|
594
664
|
type: EventType.TEXT_MESSAGE_END,
|
|
@@ -617,6 +687,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
617
687
|
if (chunk.type === "response.output_text.delta" && chunk.delta) {
|
|
618
688
|
const textDelta = Array.isArray(chunk.delta) ? chunk.delta.join("") : typeof chunk.delta === "string" ? chunk.delta : "";
|
|
619
689
|
if (textDelta) {
|
|
690
|
+
yield* closeReasoning();
|
|
620
691
|
if (!hasEmittedTextMessageStart) {
|
|
621
692
|
hasEmittedTextMessageStart = true;
|
|
622
693
|
yield {
|
|
@@ -639,68 +710,17 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
639
710
|
};
|
|
640
711
|
}
|
|
641
712
|
}
|
|
642
|
-
if (chunk.type === "response.reasoning_text.delta" && chunk.delta)
|
|
643
|
-
|
|
644
|
-
if (reasoningDelta) {
|
|
645
|
-
if (!hasEmittedStepStarted) {
|
|
646
|
-
hasEmittedStepStarted = true;
|
|
647
|
-
stepId = generateId(this.name);
|
|
648
|
-
yield {
|
|
649
|
-
type: EventType.STEP_STARTED,
|
|
650
|
-
stepName: stepId,
|
|
651
|
-
stepId,
|
|
652
|
-
model: model || options.model,
|
|
653
|
-
timestamp: Date.now(),
|
|
654
|
-
stepType: "thinking"
|
|
655
|
-
};
|
|
656
|
-
}
|
|
657
|
-
accumulatedReasoning += reasoningDelta;
|
|
658
|
-
hasStreamedReasoningDeltas = true;
|
|
659
|
-
const fallbackStepId = stepId || generateId(this.name);
|
|
660
|
-
yield {
|
|
661
|
-
type: EventType.STEP_FINISHED,
|
|
662
|
-
stepName: fallbackStepId,
|
|
663
|
-
stepId: fallbackStepId,
|
|
664
|
-
model: model || options.model,
|
|
665
|
-
timestamp: Date.now(),
|
|
666
|
-
delta: reasoningDelta,
|
|
667
|
-
content: accumulatedReasoning
|
|
668
|
-
};
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
if (chunk.type === "response.reasoning_summary_text.delta" && chunk.delta) {
|
|
672
|
-
const summaryDelta = typeof chunk.delta === "string" ? chunk.delta : "";
|
|
673
|
-
if (summaryDelta) {
|
|
674
|
-
if (!hasEmittedStepStarted) {
|
|
675
|
-
hasEmittedStepStarted = true;
|
|
676
|
-
stepId = generateId(this.name);
|
|
677
|
-
yield {
|
|
678
|
-
type: EventType.STEP_STARTED,
|
|
679
|
-
stepName: stepId,
|
|
680
|
-
stepId,
|
|
681
|
-
model: model || options.model,
|
|
682
|
-
timestamp: Date.now(),
|
|
683
|
-
stepType: "thinking"
|
|
684
|
-
};
|
|
685
|
-
}
|
|
686
|
-
accumulatedReasoning += summaryDelta;
|
|
687
|
-
hasStreamedReasoningDeltas = true;
|
|
688
|
-
const fallbackStepId = stepId || generateId(this.name);
|
|
689
|
-
yield {
|
|
690
|
-
type: EventType.STEP_FINISHED,
|
|
691
|
-
stepName: fallbackStepId,
|
|
692
|
-
stepId: fallbackStepId,
|
|
693
|
-
model: model || options.model,
|
|
694
|
-
timestamp: Date.now(),
|
|
695
|
-
delta: summaryDelta,
|
|
696
|
-
content: accumulatedReasoning
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
}
|
|
713
|
+
if ((chunk.type === "response.reasoning_text.delta" || chunk.type === "response.reasoning.delta") && chunk.delta) yield* emitReasoningDelta(Array.isArray(chunk.delta) ? chunk.delta.join("") : typeof chunk.delta === "string" ? chunk.delta : "");
|
|
714
|
+
if (chunk.type === "response.reasoning_summary_text.delta" && chunk.delta) yield* emitReasoningDelta(typeof chunk.delta === "string" ? chunk.delta : "");
|
|
700
715
|
if (chunk.type === "response.content_part.added") {
|
|
701
716
|
const contentPart = chunk.part;
|
|
702
717
|
if ((contentPart.type === "output_text" || contentPart.type === "reasoning_text") && !contentPart.text) continue;
|
|
718
|
+
if (contentPart.type === "reasoning_text") {
|
|
719
|
+
yield* emitReasoningDelta(contentPart.text || "");
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
703
722
|
if (contentPart.type === "output_text" && !hasEmittedTextMessageStart) {
|
|
723
|
+
yield* closeReasoning();
|
|
704
724
|
hasEmittedTextMessageStart = true;
|
|
705
725
|
yield {
|
|
706
726
|
type: EventType.TEXT_MESSAGE_START,
|
|
@@ -710,20 +730,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
710
730
|
role: "assistant"
|
|
711
731
|
};
|
|
712
732
|
}
|
|
713
|
-
if (contentPart.type === "reasoning_text" && !hasEmittedStepStarted) {
|
|
714
|
-
hasEmittedStepStarted = true;
|
|
715
|
-
stepId = generateId(this.name);
|
|
716
|
-
yield {
|
|
717
|
-
type: EventType.STEP_STARTED,
|
|
718
|
-
stepName: stepId,
|
|
719
|
-
stepId,
|
|
720
|
-
model: model || options.model,
|
|
721
|
-
timestamp: Date.now(),
|
|
722
|
-
stepType: "thinking"
|
|
723
|
-
};
|
|
724
|
-
}
|
|
725
733
|
if (contentPart.type === "output_text") hasStreamedContentDeltas = true;
|
|
726
|
-
else if (contentPart.type === "reasoning_text") hasStreamedReasoningDeltas = true;
|
|
727
734
|
const partChunk = handleContentPart(contentPart);
|
|
728
735
|
yield partChunk;
|
|
729
736
|
if (partChunk.type === "RUN_ERROR") {
|
|
@@ -735,7 +742,12 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
735
742
|
const contentPart = chunk.part;
|
|
736
743
|
if (contentPart.type === "output_text" && hasStreamedContentDeltas) continue;
|
|
737
744
|
if (contentPart.type === "reasoning_text" && hasStreamedReasoningDeltas) continue;
|
|
745
|
+
if (contentPart.type === "reasoning_text") {
|
|
746
|
+
yield* emitReasoningDelta(contentPart.text || "");
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
738
749
|
if (contentPart.type === "output_text" && !hasEmittedTextMessageStart) {
|
|
750
|
+
yield* closeReasoning();
|
|
739
751
|
hasEmittedTextMessageStart = true;
|
|
740
752
|
yield {
|
|
741
753
|
type: EventType.TEXT_MESSAGE_START,
|
|
@@ -744,17 +756,6 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
744
756
|
timestamp: Date.now(),
|
|
745
757
|
role: "assistant"
|
|
746
758
|
};
|
|
747
|
-
} else if (contentPart.type === "reasoning_text" && !hasEmittedStepStarted) {
|
|
748
|
-
hasEmittedStepStarted = true;
|
|
749
|
-
stepId = generateId(this.name);
|
|
750
|
-
yield {
|
|
751
|
-
type: EventType.STEP_STARTED,
|
|
752
|
-
stepName: stepId,
|
|
753
|
-
stepId,
|
|
754
|
-
model: model || options.model,
|
|
755
|
-
timestamp: Date.now(),
|
|
756
|
-
stepType: "thinking"
|
|
757
|
-
};
|
|
758
759
|
}
|
|
759
760
|
const doneChunk = handleContentPart(contentPart);
|
|
760
761
|
yield doneChunk;
|
|
@@ -996,6 +997,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
996
997
|
metadata.pendingArguments = void 0;
|
|
997
998
|
}
|
|
998
999
|
}
|
|
1000
|
+
yield* closeReasoning();
|
|
999
1001
|
if (hasEmittedTextMessageStart) {
|
|
1000
1002
|
yield {
|
|
1001
1003
|
type: EventType.TEXT_MESSAGE_END,
|
|
@@ -1037,6 +1039,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1037
1039
|
}
|
|
1038
1040
|
}
|
|
1039
1041
|
if (!runFinishedEmitted && aguiState.hasEmittedRunStarted) {
|
|
1042
|
+
yield* closeReasoning();
|
|
1040
1043
|
if (hasEmittedTextMessageStart) yield {
|
|
1041
1044
|
type: EventType.TEXT_MESSAGE_END,
|
|
1042
1045
|
messageId: aguiState.messageId,
|
|
@@ -1235,7 +1238,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1235
1238
|
* Handles backward compatibility with string content.
|
|
1236
1239
|
*/
|
|
1237
1240
|
normalizeContent(content) {
|
|
1238
|
-
if (content === null) return [];
|
|
1241
|
+
if (content === null || content === void 0) return [];
|
|
1239
1242
|
if (typeof content === "string") return [{
|
|
1240
1243
|
type: "text",
|
|
1241
1244
|
content
|
|
@@ -1246,7 +1249,7 @@ var OpenAIBaseResponsesTextAdapter = class extends BaseTextAdapter {
|
|
|
1246
1249
|
* Extracts text content from a content value that may be string, null, or ContentPart array.
|
|
1247
1250
|
*/
|
|
1248
1251
|
extractTextContent(content) {
|
|
1249
|
-
if (content === null) return "";
|
|
1252
|
+
if (content === null || content === void 0) return "";
|
|
1250
1253
|
if (typeof content === "string") return content;
|
|
1251
1254
|
return content.filter((p) => p.type === "text").map((p) => p.content).join("");
|
|
1252
1255
|
}
|