@kenkaiiii/gg-ai 4.2.90 → 4.2.91

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/index.cjs CHANGED
@@ -104,44 +104,62 @@ var EventStream = class {
104
104
  }
105
105
  };
106
106
  var StreamResult = class {
107
- events;
108
107
  response;
108
+ buffer = [];
109
+ done = false;
110
+ error = null;
109
111
  resolveResponse;
110
112
  rejectResponse;
111
- hasConsumer = false;
112
- constructor() {
113
- this.events = new EventStream();
113
+ resolveWait = null;
114
+ constructor(generator) {
114
115
  this.response = new Promise((resolve, reject) => {
115
116
  this.resolveResponse = resolve;
116
117
  this.rejectResponse = reject;
117
118
  });
119
+ this.pump(generator);
118
120
  }
119
- push(event) {
120
- this.events.push(event);
121
- }
122
- complete(response) {
123
- this.events.close();
124
- this.resolveResponse(response);
125
- }
126
- abort(error) {
127
- this.events.abort(error);
128
- this.rejectResponse(error);
121
+ async pump(generator) {
122
+ try {
123
+ let next = await generator.next();
124
+ while (!next.done) {
125
+ this.buffer.push(next.value);
126
+ this.resolveWait?.();
127
+ this.resolveWait = null;
128
+ next = await generator.next();
129
+ }
130
+ this.done = true;
131
+ this.resolveResponse(next.value);
132
+ this.resolveWait?.();
133
+ this.resolveWait = null;
134
+ } catch (err) {
135
+ const error = err instanceof Error ? err : new Error(String(err));
136
+ this.error = error;
137
+ this.done = true;
138
+ this.rejectResponse(error);
139
+ this.resolveWait?.();
140
+ this.resolveWait = null;
141
+ }
129
142
  }
130
- [Symbol.asyncIterator]() {
131
- this.hasConsumer = true;
132
- return this.events[Symbol.asyncIterator]();
143
+ async *[Symbol.asyncIterator]() {
144
+ let index = 0;
145
+ while (true) {
146
+ while (index < this.buffer.length) {
147
+ yield this.buffer[index++];
148
+ }
149
+ if (this.error) throw this.error;
150
+ if (this.done) return;
151
+ await new Promise((r) => {
152
+ this.resolveWait = r;
153
+ if (this.buffer.length > index || this.done || this.error) {
154
+ this.resolveWait = null;
155
+ r();
156
+ }
157
+ });
158
+ }
133
159
  }
134
160
  then(onfulfilled, onrejected) {
135
- this.drainEvents().catch(() => {
136
- });
137
161
  return this.response.then(onfulfilled, onrejected);
138
162
  }
139
- async drainEvents() {
140
- if (this.hasConsumer) return;
141
- this.hasConsumer = true;
142
- for await (const _ of this.events) {
143
- }
144
- }
145
163
  };
146
164
 
147
165
  // src/providers/anthropic.ts
@@ -451,11 +469,9 @@ function normalizeOpenAIStopReason(reason) {
451
469
 
452
470
  // src/providers/anthropic.ts
453
471
  function streamAnthropic(options) {
454
- const result = new StreamResult();
455
- runStream(options, result).catch((err) => result.abort(toError(err)));
456
- return result;
472
+ return new StreamResult(runStream(options));
457
473
  }
458
- async function runStream(options, result) {
474
+ async function* runStream(options) {
459
475
  const isOAuth = options.apiKey?.startsWith("sk-ant-oat");
460
476
  const client = new import_sdk.default({
461
477
  ...isOAuth ? { apiKey: null, authToken: options.apiKey } : { apiKey: options.apiKey },
@@ -525,116 +541,185 @@ async function runStream(options, result) {
525
541
  ...betaHeaders.length ? { headers: { "anthropic-beta": betaHeaders.join(",") } } : {}
526
542
  });
527
543
  const contentParts = [];
528
- let currentToolId = "";
529
- let currentToolName = "";
530
- stream2.on("text", (text) => {
531
- result.push({ type: "text_delta", text });
532
- });
533
- stream2.on("thinking", (thinkingDelta) => {
534
- result.push({ type: "thinking_delta", text: thinkingDelta });
535
- });
536
- stream2.on("streamEvent", (event) => {
537
- if (event.type === "content_block_start") {
538
- if (event.content_block.type === "tool_use") {
539
- currentToolId = event.content_block.id;
540
- currentToolName = event.content_block.name;
541
- }
542
- if (event.content_block.type === "server_tool_use") {
543
- currentToolId = event.content_block.id;
544
- currentToolName = event.content_block.name;
545
- }
546
- }
547
- });
548
- stream2.on("inputJson", (delta) => {
549
- result.push({
550
- type: "toolcall_delta",
551
- id: currentToolId,
552
- name: currentToolName,
553
- argsJson: delta
554
- });
555
- });
556
- stream2.on("contentBlock", (block) => {
557
- if (block.type === "text") {
558
- contentParts.push({ type: "text", text: block.text });
559
- } else if (block.type === "thinking") {
560
- contentParts.push({ type: "thinking", text: block.thinking, signature: block.signature });
561
- } else if (block.type === "tool_use") {
562
- const tc = {
563
- type: "tool_call",
564
- id: block.id,
565
- name: block.name,
566
- args: block.input
567
- };
568
- contentParts.push(tc);
569
- result.push({
570
- type: "toolcall_done",
571
- id: tc.id,
572
- name: tc.name,
573
- args: tc.args
574
- });
575
- } else if (block.type === "server_tool_use") {
576
- const stc = {
577
- type: "server_tool_call",
578
- id: block.id,
579
- name: block.name,
580
- input: block.input
581
- };
582
- contentParts.push(stc);
583
- result.push({
584
- type: "server_toolcall",
585
- id: stc.id,
586
- name: stc.name,
587
- input: stc.input
588
- });
589
- } else {
590
- const raw = block;
591
- const blockType = raw.type;
592
- if (blockType === "web_search_tool_result") {
593
- const str = {
594
- type: "server_tool_result",
595
- toolUseId: raw.tool_use_id,
596
- resultType: blockType,
597
- data: raw
598
- };
599
- contentParts.push(str);
600
- result.push({
601
- type: "server_toolresult",
602
- toolUseId: str.toolUseId,
603
- resultType: str.resultType,
604
- data: str.data
605
- });
606
- } else {
607
- contentParts.push({ type: "raw", data: raw });
608
- }
609
- }
610
- });
544
+ const blocks = /* @__PURE__ */ new Map();
545
+ let inputTokens = 0;
546
+ let outputTokens = 0;
547
+ let cacheRead;
548
+ let cacheWrite;
549
+ let stopReason = null;
611
550
  try {
612
- const finalMessage = await stream2.finalMessage();
613
- const stopReason = normalizeAnthropicStopReason(finalMessage.stop_reason);
614
- const response = {
615
- message: {
616
- role: "assistant",
617
- content: contentParts.length > 0 ? contentParts : ""
618
- },
619
- stopReason,
620
- usage: {
621
- inputTokens: finalMessage.usage.input_tokens,
622
- outputTokens: finalMessage.usage.output_tokens,
623
- ...finalMessage.usage.cache_read_input_tokens != null && {
624
- cacheRead: finalMessage.usage.cache_read_input_tokens
625
- },
626
- ...finalMessage.usage.cache_creation_input_tokens != null && {
627
- cacheWrite: finalMessage.usage.cache_creation_input_tokens
551
+ for await (const event of stream2) {
552
+ switch (event.type) {
553
+ case "message_start": {
554
+ const usage = event.message.usage;
555
+ inputTokens = usage.input_tokens;
556
+ const usageAny = usage;
557
+ if (usageAny.cache_read_input_tokens != null) {
558
+ cacheRead = usageAny.cache_read_input_tokens;
559
+ }
560
+ if (usageAny.cache_creation_input_tokens != null) {
561
+ cacheWrite = usageAny.cache_creation_input_tokens;
562
+ }
563
+ break;
564
+ }
565
+ case "content_block_start": {
566
+ const block = event.content_block;
567
+ const idx = event.index;
568
+ const accum = {
569
+ type: block.type,
570
+ text: "",
571
+ thinking: "",
572
+ signature: "",
573
+ toolId: "",
574
+ toolName: "",
575
+ argsJson: "",
576
+ input: void 0,
577
+ raw: null
578
+ };
579
+ if (block.type === "tool_use") {
580
+ accum.toolId = block.id;
581
+ accum.toolName = block.name;
582
+ } else if (block.type === "server_tool_use") {
583
+ accum.toolId = block.id;
584
+ accum.toolName = block.name;
585
+ } else if (block.type === "redacted_thinking") {
586
+ accum.raw = block;
587
+ }
588
+ blocks.set(idx, accum);
589
+ break;
590
+ }
591
+ case "content_block_delta": {
592
+ const accum = blocks.get(event.index);
593
+ if (!accum) break;
594
+ const delta = event.delta;
595
+ const deltaType = delta.type;
596
+ if (deltaType === "text_delta") {
597
+ const text = delta.text;
598
+ accum.text += text;
599
+ yield { type: "text_delta", text };
600
+ } else if (deltaType === "thinking_delta") {
601
+ const text = delta.thinking;
602
+ accum.thinking += text;
603
+ yield { type: "thinking_delta", text };
604
+ } else if (deltaType === "input_json_delta") {
605
+ const partialJson = delta.partial_json;
606
+ accum.argsJson += partialJson;
607
+ yield {
608
+ type: "toolcall_delta",
609
+ id: accum.toolId,
610
+ name: accum.toolName,
611
+ argsJson: partialJson
612
+ };
613
+ } else if (deltaType === "signature_delta") {
614
+ accum.signature = delta.signature;
615
+ }
616
+ break;
617
+ }
618
+ case "content_block_stop": {
619
+ const accum = blocks.get(event.index);
620
+ if (!accum) break;
621
+ if (accum.type === "text") {
622
+ contentParts.push({ type: "text", text: accum.text });
623
+ } else if (accum.type === "thinking") {
624
+ contentParts.push({
625
+ type: "thinking",
626
+ text: accum.thinking,
627
+ signature: accum.signature
628
+ });
629
+ } else if (accum.type === "tool_use") {
630
+ let args = {};
631
+ try {
632
+ args = JSON.parse(accum.argsJson);
633
+ } catch {
634
+ }
635
+ const tc = {
636
+ type: "tool_call",
637
+ id: accum.toolId,
638
+ name: accum.toolName,
639
+ args
640
+ };
641
+ contentParts.push(tc);
642
+ yield {
643
+ type: "toolcall_done",
644
+ id: tc.id,
645
+ name: tc.name,
646
+ args: tc.args
647
+ };
648
+ } else if (accum.type === "server_tool_use") {
649
+ const stc = {
650
+ type: "server_tool_call",
651
+ id: accum.toolId,
652
+ name: accum.toolName,
653
+ input: accum.input
654
+ };
655
+ contentParts.push(stc);
656
+ yield {
657
+ type: "server_toolcall",
658
+ id: stc.id,
659
+ name: stc.name,
660
+ input: stc.input
661
+ };
662
+ } else if (accum.type === "redacted_thinking" && accum.raw) {
663
+ contentParts.push({ type: "raw", data: accum.raw });
664
+ } else {
665
+ const msg = stream2.currentMessage;
666
+ const rawBlock = msg?.content[event.index];
667
+ if (rawBlock) {
668
+ const blockType = rawBlock.type;
669
+ if (blockType === "web_search_tool_result") {
670
+ const str = {
671
+ type: "server_tool_result",
672
+ toolUseId: rawBlock.tool_use_id,
673
+ resultType: blockType,
674
+ data: rawBlock
675
+ };
676
+ contentParts.push(str);
677
+ yield {
678
+ type: "server_toolresult",
679
+ toolUseId: str.toolUseId,
680
+ resultType: str.resultType,
681
+ data: str.data
682
+ };
683
+ } else {
684
+ contentParts.push({ type: "raw", data: rawBlock });
685
+ }
686
+ }
687
+ }
688
+ blocks.delete(event.index);
689
+ break;
690
+ }
691
+ case "message_delta": {
692
+ const delta = event.delta;
693
+ if (delta.stop_reason) {
694
+ stopReason = delta.stop_reason;
695
+ }
696
+ const usage = event.usage;
697
+ if (usage?.output_tokens != null) {
698
+ outputTokens = usage.output_tokens;
699
+ }
700
+ break;
628
701
  }
629
702
  }
630
- };
631
- result.push({ type: "done", stopReason });
632
- result.complete(response);
703
+ }
633
704
  } catch (err) {
634
- const error = toError(err);
635
- result.push({ type: "error", error });
636
- result.abort(error);
705
+ throw toError(err);
637
706
  }
707
+ const normalizedStop = normalizeAnthropicStopReason(stopReason);
708
+ const response = {
709
+ message: {
710
+ role: "assistant",
711
+ content: contentParts.length > 0 ? contentParts : ""
712
+ },
713
+ stopReason: normalizedStop,
714
+ usage: {
715
+ inputTokens,
716
+ outputTokens,
717
+ ...cacheRead != null && { cacheRead },
718
+ ...cacheWrite != null && { cacheWrite }
719
+ }
720
+ };
721
+ yield { type: "done", stopReason: normalizedStop };
722
+ return response;
638
723
  }
639
724
  function toError(err) {
640
725
  if (err instanceof import_sdk.default.APIError) {
@@ -652,12 +737,10 @@ function toError(err) {
652
737
  // src/providers/openai.ts
653
738
  var import_openai = __toESM(require("openai"), 1);
654
739
  function streamOpenAI(options) {
655
- const result = new StreamResult();
656
- const providerName = options.provider ?? "openai";
657
- runStream2(options, result).catch((err) => result.abort(toError2(err, providerName)));
658
- return result;
740
+ return new StreamResult(runStream2(options));
659
741
  }
660
- async function runStream2(options, result) {
742
+ async function* runStream2(options) {
743
+ const providerName = options.provider ?? "openai";
661
744
  const client = new import_openai.default({
662
745
  apiKey: options.apiKey,
663
746
  ...options.baseUrl ? { baseURL: options.baseUrl } : {},
@@ -691,9 +774,14 @@ async function runStream2(options, result) {
691
774
  if (usesThinkingParam) {
692
775
  params.thinking = options.thinking ? { type: "enabled" } : { type: "disabled" };
693
776
  }
694
- const stream2 = await client.chat.completions.create(params, {
695
- signal: options.signal ?? void 0
696
- });
777
+ let stream2;
778
+ try {
779
+ stream2 = await client.chat.completions.create(params, {
780
+ signal: options.signal ?? void 0
781
+ });
782
+ } catch (err) {
783
+ throw toError2(err, providerName);
784
+ }
697
785
  const contentParts = [];
698
786
  const toolCallAccum = /* @__PURE__ */ new Map();
699
787
  let textAccum = "";
@@ -720,11 +808,11 @@ async function runStream2(options, result) {
720
808
  const reasoningContent = delta.reasoning_content;
721
809
  if (typeof reasoningContent === "string" && reasoningContent) {
722
810
  thinkingAccum += reasoningContent;
723
- result.push({ type: "thinking_delta", text: reasoningContent });
811
+ yield { type: "thinking_delta", text: reasoningContent };
724
812
  }
725
813
  if (delta.content) {
726
814
  textAccum += delta.content;
727
- result.push({ type: "text_delta", text: delta.content });
815
+ yield { type: "text_delta", text: delta.content };
728
816
  }
729
817
  if (delta.tool_calls) {
730
818
  for (const tc of delta.tool_calls) {
@@ -741,12 +829,12 @@ async function runStream2(options, result) {
741
829
  if (tc.function?.name) accum.name = tc.function.name;
742
830
  if (tc.function?.arguments) {
743
831
  accum.argsJson += tc.function.arguments;
744
- result.push({
832
+ yield {
745
833
  type: "toolcall_delta",
746
834
  id: accum.id,
747
835
  name: accum.name,
748
836
  argsJson: tc.function.arguments
749
- });
837
+ };
750
838
  }
751
839
  }
752
840
  }
@@ -770,12 +858,12 @@ async function runStream2(options, result) {
770
858
  args
771
859
  };
772
860
  contentParts.push(toolCall);
773
- result.push({
861
+ yield {
774
862
  type: "toolcall_done",
775
863
  id: tc.id,
776
864
  name: tc.name,
777
865
  args
778
- });
866
+ };
779
867
  }
780
868
  const stopReason = normalizeOpenAIStopReason(finishReason);
781
869
  const response = {
@@ -786,8 +874,8 @@ async function runStream2(options, result) {
786
874
  stopReason,
787
875
  usage: { inputTokens, outputTokens, ...cacheRead > 0 && { cacheRead } }
788
876
  };
789
- result.push({ type: "done", stopReason });
790
- result.complete(response);
877
+ yield { type: "done", stopReason };
878
+ return response;
791
879
  }
792
880
  function toError2(err, provider = "openai") {
793
881
  if (err instanceof import_openai.default.APIError) {
@@ -811,11 +899,9 @@ function toError2(err, provider = "openai") {
811
899
  var import_node_os = __toESM(require("os"), 1);
812
900
  var DEFAULT_BASE_URL = "https://chatgpt.com/backend-api";
813
901
  function streamOpenAICodex(options) {
814
- const result = new StreamResult();
815
- runStream3(options, result).catch((err) => result.abort(toError3(err)));
816
- return result;
902
+ return new StreamResult(runStream3(options));
817
903
  }
818
- async function runStream3(options, result) {
904
+ async function* runStream3(options) {
819
905
  const baseUrl = (options.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
820
906
  const url = `${baseUrl}/codex/responses`;
821
907
  const { system, input } = toCodexInput(options.messages);
@@ -892,11 +978,11 @@ Hint: Codex models require a ChatGPT Plus ($20/mo) or Pro ($200/mo) subscription
892
978
  if (type === "response.output_text.delta") {
893
979
  const delta = event.delta;
894
980
  textAccum += delta;
895
- result.push({ type: "text_delta", text: delta });
981
+ yield { type: "text_delta", text: delta };
896
982
  }
897
983
  if (type === "response.reasoning_summary_text.delta") {
898
984
  const delta = event.delta;
899
- result.push({ type: "thinking_delta", text: delta });
985
+ yield { type: "thinking_delta", text: delta };
900
986
  }
901
987
  if (type === "response.output_item.added") {
902
988
  const item = event.item;
@@ -914,12 +1000,12 @@ Hint: Codex models require a ChatGPT Plus ($20/mo) or Pro ($200/mo) subscription
914
1000
  for (const [key, tc] of toolCalls) {
915
1001
  if (key.endsWith(`|${itemId}`)) {
916
1002
  tc.argsJson += delta;
917
- result.push({
1003
+ yield {
918
1004
  type: "toolcall_delta",
919
1005
  id: tc.id,
920
1006
  name: tc.name,
921
1007
  argsJson: delta
922
- });
1008
+ };
923
1009
  break;
924
1010
  }
925
1011
  }
@@ -947,12 +1033,12 @@ Hint: Codex models require a ChatGPT Plus ($20/mo) or Pro ($200/mo) subscription
947
1033
  args = JSON.parse(tc.argsJson);
948
1034
  } catch {
949
1035
  }
950
- result.push({
1036
+ yield {
951
1037
  type: "toolcall_done",
952
1038
  id: tc.id,
953
1039
  name: tc.name,
954
1040
  args
955
- });
1041
+ };
956
1042
  }
957
1043
  }
958
1044
  }
@@ -992,8 +1078,8 @@ Hint: Codex models require a ChatGPT Plus ($20/mo) or Pro ($200/mo) subscription
992
1078
  stopReason,
993
1079
  usage: { inputTokens, outputTokens }
994
1080
  };
995
- result.push({ type: "done", stopReason });
996
- result.complete(streamResponse);
1081
+ yield { type: "done", stopReason };
1082
+ return streamResponse;
997
1083
  }
998
1084
  async function* parseSSE(body) {
999
1085
  const reader = body.getReader();
@@ -1107,13 +1193,6 @@ function toCodexTools(tools) {
1107
1193
  strict: null
1108
1194
  }));
1109
1195
  }
1110
- function toError3(err) {
1111
- if (err instanceof ProviderError) return err;
1112
- if (err instanceof Error) {
1113
- return new ProviderError("openai", err.message, { cause: err });
1114
- }
1115
- return new ProviderError("openai", String(err));
1116
- }
1117
1196
 
1118
1197
  // src/provider-registry.ts
1119
1198
  var ProviderRegistryImpl = class {
@@ -1187,32 +1266,28 @@ function stream(options) {
1187
1266
  return entry.stream(options);
1188
1267
  }
1189
1268
  function streamGLMWithFallback(options) {
1190
- const result = new StreamResult();
1191
- runGLMWithFallback(options, result).catch((err) => {
1192
- result.abort(err instanceof Error ? err : new Error(String(err)));
1193
- });
1194
- return result;
1269
+ return new StreamResult(runGLMWithFallback(options));
1195
1270
  }
1196
- async function runGLMWithFallback(options, result) {
1197
- const codingResult = streamOpenAI({ ...options, baseUrl: GLM_CODING_BASE_URL });
1198
- codingResult.response.catch(() => {
1271
+ async function* runGLMWithFallback(options) {
1272
+ const coding = streamOpenAI({ ...options, baseUrl: GLM_CODING_BASE_URL });
1273
+ coding.response.catch(() => {
1199
1274
  });
1200
1275
  try {
1201
- for await (const event of codingResult) {
1202
- result.push(event);
1276
+ for await (const event of coding) {
1277
+ yield event;
1203
1278
  }
1204
- result.complete(await codingResult.response);
1279
+ return await coding.response;
1205
1280
  } catch {
1206
- const regularResult = streamOpenAI({ ...options, baseUrl: GLM_REGULAR_BASE_URL });
1207
- regularResult.response.catch(() => {
1281
+ const regular = streamOpenAI({ ...options, baseUrl: GLM_REGULAR_BASE_URL });
1282
+ regular.response.catch(() => {
1208
1283
  });
1209
1284
  try {
1210
- for await (const event of regularResult) {
1211
- result.push(event);
1285
+ for await (const event of regular) {
1286
+ yield event;
1212
1287
  }
1213
- result.complete(await regularResult.response);
1288
+ return await regular.response;
1214
1289
  } catch (fallbackErr) {
1215
- result.abort(fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr)));
1290
+ throw fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr));
1216
1291
  }
1217
1292
  }
1218
1293
  }
@@ -1243,31 +1318,29 @@ function chunkText(text, size) {
1243
1318
  }
1244
1319
  return chunks.length > 0 ? chunks : [""];
1245
1320
  }
1246
- function simulateStream(message, stopReason, result, signal, cacheUsage) {
1321
+ async function* simulateStream(message, stopReason, signal, cacheUsage) {
1247
1322
  if (signal?.aborted) {
1248
- result.abort(new Error("aborted"));
1249
- return;
1323
+ throw new Error("aborted");
1250
1324
  }
1251
1325
  const content = typeof message.content === "string" ? message.content ? [{ type: "text", text: message.content }] : [] : message.content;
1252
1326
  let outputChars = 0;
1253
1327
  for (const part of content) {
1254
1328
  if (signal?.aborted) {
1255
- result.abort(new Error("aborted"));
1256
- return;
1329
+ throw new Error("aborted");
1257
1330
  }
1258
1331
  if (part.type === "text") {
1259
1332
  const chunks = chunkText(part.text, DEFAULT_CHUNK_SIZE);
1260
1333
  for (const chunk of chunks) {
1261
- result.push({ type: "text_delta", text: chunk });
1334
+ yield { type: "text_delta", text: chunk };
1262
1335
  outputChars += chunk.length;
1263
1336
  }
1264
1337
  } else if (part.type === "thinking") {
1265
- result.push({ type: "thinking_delta", text: part.text });
1338
+ yield { type: "thinking_delta", text: part.text };
1266
1339
  outputChars += part.text.length;
1267
1340
  } else if (part.type === "tool_call") {
1268
1341
  const argsJson = JSON.stringify(part.args);
1269
- result.push({ type: "toolcall_delta", id: part.id, name: part.name, argsJson });
1270
- result.push({ type: "toolcall_done", id: part.id, name: part.name, args: part.args });
1342
+ yield { type: "toolcall_delta", id: part.id, name: part.name, argsJson };
1343
+ yield { type: "toolcall_done", id: part.id, name: part.name, args: part.args };
1271
1344
  outputChars += argsJson.length;
1272
1345
  }
1273
1346
  }
@@ -1278,8 +1351,8 @@ function simulateStream(message, stopReason, result, signal, cacheUsage) {
1278
1351
  ...cacheUsage?.cacheRead ? { cacheRead: cacheUsage.cacheRead } : {},
1279
1352
  ...cacheUsage?.cacheWrite ? { cacheWrite: cacheUsage.cacheWrite } : {}
1280
1353
  };
1281
- result.push({ type: "done", stopReason });
1282
- result.complete({ message, stopReason, usage });
1354
+ yield { type: "done", stopReason };
1355
+ return { message, stopReason, usage };
1283
1356
  }
1284
1357
  function computeCacheUsage(current, previous) {
1285
1358
  if (!previous) {
@@ -1351,24 +1424,21 @@ function registerPalsuProvider(config) {
1351
1424
  state.callCount++;
1352
1425
  const ms = modelStates.get(options.model);
1353
1426
  const responseDef = (ms && ms.responses.length > 0 ? ms.responses.shift() : void 0) ?? (responses.length > 0 ? responses.shift() : void 0) ?? ms?.defaultResponse ?? defaultResponse;
1354
- const result = new StreamResult();
1355
1427
  let cacheUsage;
1356
1428
  if (enableCache) {
1357
1429
  const serialized = JSON.stringify(options.messages);
1358
1430
  cacheUsage = computeCacheUsage(serialized, lastMessagesSerialized);
1359
1431
  lastMessagesSerialized = serialized;
1360
1432
  }
1361
- const rawMessage = typeof responseDef === "function" ? responseDef(options.messages, options, state) : responseDef;
1362
- Promise.resolve(rawMessage).then(
1363
- (message) => {
1364
- const hasToolCalls = Array.isArray(message.content) && message.content.some((p) => p.type === "tool_call");
1365
- const explicitStop = message._stopReason;
1366
- const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
1367
- simulateStream(message, stopReason, result, options.signal, cacheUsage);
1368
- },
1369
- (err) => result.abort(err instanceof Error ? err : new Error(String(err)))
1370
- );
1371
- return result;
1433
+ const gen = (async function* () {
1434
+ const rawMessage = typeof responseDef === "function" ? responseDef(options.messages, options, state) : responseDef;
1435
+ const message = await Promise.resolve(rawMessage);
1436
+ const hasToolCalls = Array.isArray(message.content) && message.content.some((p) => p.type === "tool_call");
1437
+ const explicitStop = message._stopReason;
1438
+ const stopReason = explicitStop ?? (hasToolCalls ? "tool_use" : "end_turn");
1439
+ return yield* simulateStream(message, stopReason, options.signal, cacheUsage);
1440
+ })();
1441
+ return new StreamResult(gen);
1372
1442
  }
1373
1443
  });
1374
1444
  return handle;