@assistant-ui/react 0.4.4 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
package/dist/edge.mjs CHANGED
@@ -34,6 +34,15 @@ function assistantEncoderStream() {
34
34
  }
35
35
  case "tool-call":
36
36
  break;
37
+ case "tool-result": {
38
+ controller.enqueue(
39
+ formatStreamPart("3" /* ToolCallResult */, {
40
+ id: chunk.toolCallId,
41
+ result: chunk.result
42
+ })
43
+ );
44
+ break;
45
+ }
37
46
  case "finish": {
38
47
  const { type, ...rest } = chunk;
39
48
  controller.enqueue(
@@ -60,6 +69,80 @@ function formatStreamPart(...[code, value]) {
60
69
  `;
61
70
  }
62
71
 
72
+ // src/types/ModelConfigTypes.ts
73
+ import { z } from "zod";
74
+ var LanguageModelV1CallSettingsSchema = z.object({
75
+ maxTokens: z.number().int().positive().optional(),
76
+ temperature: z.number().optional(),
77
+ topP: z.number().optional(),
78
+ presencePenalty: z.number().optional(),
79
+ frequencyPenalty: z.number().optional(),
80
+ seed: z.number().int().optional(),
81
+ headers: z.record(z.string().optional()).optional()
82
+ });
83
+ var LanguageModelConfigSchema = z.object({
84
+ apiKey: z.string().optional(),
85
+ baseUrl: z.string().optional(),
86
+ modelName: z.string().optional()
87
+ });
88
+
89
+ // src/runtimes/edge/EdgeRuntimeRequestOptions.ts
90
+ import { z as z2 } from "zod";
91
+ var LanguageModelV1FunctionToolSchema = z2.object({
92
+ type: z2.literal("function"),
93
+ name: z2.string(),
94
+ description: z2.string().optional(),
95
+ parameters: z2.unknown()
96
+ });
97
+ var TextContentPartSchema = z2.object({
98
+ type: z2.literal("text"),
99
+ text: z2.string()
100
+ });
101
+ var ImageContentPartSchema = z2.object({
102
+ type: z2.literal("image"),
103
+ image: z2.string()
104
+ });
105
+ var CoreToolCallContentPartSchema = z2.object({
106
+ type: z2.literal("tool-call"),
107
+ toolCallId: z2.string(),
108
+ toolName: z2.string(),
109
+ args: z2.record(z2.union([z2.string(), z2.number()]), z2.unknown()),
110
+ result: z2.unknown().optional(),
111
+ isError: z2.boolean().optional()
112
+ });
113
+ var CoreUserMessageSchema = z2.object({
114
+ role: z2.literal("user"),
115
+ content: z2.array(
116
+ z2.discriminatedUnion("type", [
117
+ TextContentPartSchema,
118
+ ImageContentPartSchema
119
+ ])
120
+ ).min(1)
121
+ });
122
+ var CoreAssistantMessageSchema = z2.object({
123
+ role: z2.literal("assistant"),
124
+ content: z2.array(
125
+ z2.discriminatedUnion("type", [
126
+ TextContentPartSchema,
127
+ CoreToolCallContentPartSchema
128
+ ])
129
+ ).min(1)
130
+ });
131
+ var CoreSystemMessageSchema = z2.object({
132
+ role: z2.literal("system"),
133
+ content: z2.tuple([TextContentPartSchema])
134
+ });
135
+ var CoreMessageSchema = z2.discriminatedUnion("role", [
136
+ CoreSystemMessageSchema,
137
+ CoreUserMessageSchema,
138
+ CoreAssistantMessageSchema
139
+ ]);
140
+ var EdgeRuntimeRequestOptionsSchema = z2.object({
141
+ system: z2.string().optional(),
142
+ messages: z2.array(CoreMessageSchema).min(1),
143
+ tools: z2.array(LanguageModelV1FunctionToolSchema)
144
+ }).merge(LanguageModelV1CallSettingsSchema).merge(LanguageModelConfigSchema);
145
+
63
146
  // src/runtimes/edge/converters/toLanguageModelMessages.ts
64
147
  var assistantMessageSplitter = () => {
65
148
  const stash = [];
@@ -176,22 +259,662 @@ function toLanguageModelMessages(message) {
176
259
  });
177
260
  }
178
261
 
262
+ // src/runtimes/edge/converters/toLanguageModelTools.ts
263
+ import { z as z3 } from "zod";
264
+ import zodToJsonSchema from "zod-to-json-schema";
265
+ var toLanguageModelTools = (tools) => {
266
+ if (!tools) return [];
267
+ return Object.entries(tools).map(([name, tool]) => ({
268
+ type: "function",
269
+ name,
270
+ ...tool.description ? { description: tool.description } : void 0,
271
+ parameters: tool.parameters instanceof z3.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters
272
+ }));
273
+ };
274
+
275
+ // src/runtimes/edge/streams/toolResultStream.ts
276
+ import { z as z4 } from "zod";
277
+ import sjson from "secure-json-parse";
278
+ function toolResultStream(tools) {
279
+ const toolCallExecutions = /* @__PURE__ */ new Map();
280
+ return new TransformStream({
281
+ transform(chunk, controller) {
282
+ controller.enqueue(chunk);
283
+ const chunkType = chunk.type;
284
+ switch (chunkType) {
285
+ case "tool-call": {
286
+ const { toolCallId, toolCallType, toolName, args: argsText } = chunk;
287
+ const tool = tools?.[toolName];
288
+ if (!tool || !tool.execute) return;
289
+ const args = sjson.parse(argsText);
290
+ if (tool.parameters instanceof z4.ZodType) {
291
+ const result = tool.parameters.safeParse(args);
292
+ if (!result.success) {
293
+ controller.enqueue({
294
+ type: "tool-result",
295
+ toolCallType,
296
+ toolCallId,
297
+ toolName,
298
+ result: "Function parameter validation failed. " + JSON.stringify(result.error.issues),
299
+ isError: true
300
+ });
301
+ return;
302
+ } else {
303
+ toolCallExecutions.set(
304
+ toolCallId,
305
+ (async () => {
306
+ try {
307
+ const result2 = await tool.execute(args);
308
+ controller.enqueue({
309
+ type: "tool-result",
310
+ toolCallType,
311
+ toolCallId,
312
+ toolName,
313
+ result: result2
314
+ });
315
+ } catch (error) {
316
+ console.error("Error: ", error);
317
+ controller.enqueue({
318
+ type: "tool-result",
319
+ toolCallType,
320
+ toolCallId,
321
+ toolName,
322
+ result: "Error: " + error,
323
+ isError: true
324
+ });
325
+ } finally {
326
+ toolCallExecutions.delete(toolCallId);
327
+ }
328
+ })()
329
+ );
330
+ }
331
+ }
332
+ break;
333
+ }
334
+ case "text-delta":
335
+ case "tool-call-delta":
336
+ case "tool-result":
337
+ case "finish":
338
+ case "error":
339
+ break;
340
+ default: {
341
+ const unhandledType = chunkType;
342
+ throw new Error(`Unhandled chunk type: ${unhandledType}`);
343
+ }
344
+ }
345
+ },
346
+ async flush() {
347
+ await Promise.all(toolCallExecutions.values());
348
+ }
349
+ });
350
+ }
351
+
352
+ // src/runtimes/edge/partial-json/parse-partial-json.ts
353
+ import sjson2 from "secure-json-parse";
354
+
355
+ // src/runtimes/edge/partial-json/fix-json.ts
356
+ function fixJson(input) {
357
+ const stack = ["ROOT"];
358
+ let lastValidIndex = -1;
359
+ let literalStart = null;
360
+ function processValueStart(char, i, swapState) {
361
+ {
362
+ switch (char) {
363
+ case '"': {
364
+ lastValidIndex = i;
365
+ stack.pop();
366
+ stack.push(swapState);
367
+ stack.push("INSIDE_STRING");
368
+ break;
369
+ }
370
+ case "f":
371
+ case "t":
372
+ case "n": {
373
+ lastValidIndex = i;
374
+ literalStart = i;
375
+ stack.pop();
376
+ stack.push(swapState);
377
+ stack.push("INSIDE_LITERAL");
378
+ break;
379
+ }
380
+ case "-": {
381
+ stack.pop();
382
+ stack.push(swapState);
383
+ stack.push("INSIDE_NUMBER");
384
+ break;
385
+ }
386
+ case "0":
387
+ case "1":
388
+ case "2":
389
+ case "3":
390
+ case "4":
391
+ case "5":
392
+ case "6":
393
+ case "7":
394
+ case "8":
395
+ case "9": {
396
+ lastValidIndex = i;
397
+ stack.pop();
398
+ stack.push(swapState);
399
+ stack.push("INSIDE_NUMBER");
400
+ break;
401
+ }
402
+ case "{": {
403
+ lastValidIndex = i;
404
+ stack.pop();
405
+ stack.push(swapState);
406
+ stack.push("INSIDE_OBJECT_START");
407
+ break;
408
+ }
409
+ case "[": {
410
+ lastValidIndex = i;
411
+ stack.pop();
412
+ stack.push(swapState);
413
+ stack.push("INSIDE_ARRAY_START");
414
+ break;
415
+ }
416
+ }
417
+ }
418
+ }
419
+ function processAfterObjectValue(char, i) {
420
+ switch (char) {
421
+ case ",": {
422
+ stack.pop();
423
+ stack.push("INSIDE_OBJECT_AFTER_COMMA");
424
+ break;
425
+ }
426
+ case "}": {
427
+ lastValidIndex = i;
428
+ stack.pop();
429
+ break;
430
+ }
431
+ }
432
+ }
433
+ function processAfterArrayValue(char, i) {
434
+ switch (char) {
435
+ case ",": {
436
+ stack.pop();
437
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
438
+ break;
439
+ }
440
+ case "]": {
441
+ lastValidIndex = i;
442
+ stack.pop();
443
+ break;
444
+ }
445
+ }
446
+ }
447
+ for (let i = 0; i < input.length; i++) {
448
+ const char = input[i];
449
+ const currentState = stack[stack.length - 1];
450
+ switch (currentState) {
451
+ case "ROOT":
452
+ processValueStart(char, i, "FINISH");
453
+ break;
454
+ case "INSIDE_OBJECT_START": {
455
+ switch (char) {
456
+ case '"': {
457
+ stack.pop();
458
+ stack.push("INSIDE_OBJECT_KEY");
459
+ break;
460
+ }
461
+ case "}": {
462
+ lastValidIndex = i;
463
+ stack.pop();
464
+ break;
465
+ }
466
+ }
467
+ break;
468
+ }
469
+ case "INSIDE_OBJECT_AFTER_COMMA": {
470
+ switch (char) {
471
+ case '"': {
472
+ stack.pop();
473
+ stack.push("INSIDE_OBJECT_KEY");
474
+ break;
475
+ }
476
+ }
477
+ break;
478
+ }
479
+ case "INSIDE_OBJECT_KEY": {
480
+ switch (char) {
481
+ case '"': {
482
+ stack.pop();
483
+ stack.push("INSIDE_OBJECT_AFTER_KEY");
484
+ break;
485
+ }
486
+ }
487
+ break;
488
+ }
489
+ case "INSIDE_OBJECT_AFTER_KEY": {
490
+ switch (char) {
491
+ case ":": {
492
+ stack.pop();
493
+ stack.push("INSIDE_OBJECT_BEFORE_VALUE");
494
+ break;
495
+ }
496
+ }
497
+ break;
498
+ }
499
+ case "INSIDE_OBJECT_BEFORE_VALUE": {
500
+ processValueStart(char, i, "INSIDE_OBJECT_AFTER_VALUE");
501
+ break;
502
+ }
503
+ case "INSIDE_OBJECT_AFTER_VALUE": {
504
+ processAfterObjectValue(char, i);
505
+ break;
506
+ }
507
+ case "INSIDE_STRING": {
508
+ switch (char) {
509
+ case '"': {
510
+ stack.pop();
511
+ lastValidIndex = i;
512
+ break;
513
+ }
514
+ case "\\": {
515
+ stack.push("INSIDE_STRING_ESCAPE");
516
+ break;
517
+ }
518
+ default: {
519
+ lastValidIndex = i;
520
+ }
521
+ }
522
+ break;
523
+ }
524
+ case "INSIDE_ARRAY_START": {
525
+ switch (char) {
526
+ case "]": {
527
+ lastValidIndex = i;
528
+ stack.pop();
529
+ break;
530
+ }
531
+ default: {
532
+ lastValidIndex = i;
533
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
534
+ break;
535
+ }
536
+ }
537
+ break;
538
+ }
539
+ case "INSIDE_ARRAY_AFTER_VALUE": {
540
+ switch (char) {
541
+ case ",": {
542
+ stack.pop();
543
+ stack.push("INSIDE_ARRAY_AFTER_COMMA");
544
+ break;
545
+ }
546
+ case "]": {
547
+ lastValidIndex = i;
548
+ stack.pop();
549
+ break;
550
+ }
551
+ default: {
552
+ lastValidIndex = i;
553
+ break;
554
+ }
555
+ }
556
+ break;
557
+ }
558
+ case "INSIDE_ARRAY_AFTER_COMMA": {
559
+ processValueStart(char, i, "INSIDE_ARRAY_AFTER_VALUE");
560
+ break;
561
+ }
562
+ case "INSIDE_STRING_ESCAPE": {
563
+ stack.pop();
564
+ lastValidIndex = i;
565
+ break;
566
+ }
567
+ case "INSIDE_NUMBER": {
568
+ switch (char) {
569
+ case "0":
570
+ case "1":
571
+ case "2":
572
+ case "3":
573
+ case "4":
574
+ case "5":
575
+ case "6":
576
+ case "7":
577
+ case "8":
578
+ case "9": {
579
+ lastValidIndex = i;
580
+ break;
581
+ }
582
+ case "e":
583
+ case "E":
584
+ case "-":
585
+ case ".": {
586
+ break;
587
+ }
588
+ case ",": {
589
+ stack.pop();
590
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
591
+ processAfterArrayValue(char, i);
592
+ }
593
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
594
+ processAfterObjectValue(char, i);
595
+ }
596
+ break;
597
+ }
598
+ case "}": {
599
+ stack.pop();
600
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
601
+ processAfterObjectValue(char, i);
602
+ }
603
+ break;
604
+ }
605
+ case "]": {
606
+ stack.pop();
607
+ if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
608
+ processAfterArrayValue(char, i);
609
+ }
610
+ break;
611
+ }
612
+ default: {
613
+ stack.pop();
614
+ break;
615
+ }
616
+ }
617
+ break;
618
+ }
619
+ case "INSIDE_LITERAL": {
620
+ const partialLiteral = input.substring(literalStart, i + 1);
621
+ if (!"false".startsWith(partialLiteral) && !"true".startsWith(partialLiteral) && !"null".startsWith(partialLiteral)) {
622
+ stack.pop();
623
+ if (stack[stack.length - 1] === "INSIDE_OBJECT_AFTER_VALUE") {
624
+ processAfterObjectValue(char, i);
625
+ } else if (stack[stack.length - 1] === "INSIDE_ARRAY_AFTER_VALUE") {
626
+ processAfterArrayValue(char, i);
627
+ }
628
+ } else {
629
+ lastValidIndex = i;
630
+ }
631
+ break;
632
+ }
633
+ }
634
+ }
635
+ let result = input.slice(0, lastValidIndex + 1);
636
+ for (let i = stack.length - 1; i >= 0; i--) {
637
+ const state = stack[i];
638
+ switch (state) {
639
+ case "INSIDE_STRING": {
640
+ result += '"';
641
+ break;
642
+ }
643
+ case "INSIDE_OBJECT_KEY":
644
+ case "INSIDE_OBJECT_AFTER_KEY":
645
+ case "INSIDE_OBJECT_AFTER_COMMA":
646
+ case "INSIDE_OBJECT_START":
647
+ case "INSIDE_OBJECT_BEFORE_VALUE":
648
+ case "INSIDE_OBJECT_AFTER_VALUE": {
649
+ result += "}";
650
+ break;
651
+ }
652
+ case "INSIDE_ARRAY_START":
653
+ case "INSIDE_ARRAY_AFTER_COMMA":
654
+ case "INSIDE_ARRAY_AFTER_VALUE": {
655
+ result += "]";
656
+ break;
657
+ }
658
+ case "INSIDE_LITERAL": {
659
+ const partialLiteral = input.substring(literalStart, input.length);
660
+ if ("true".startsWith(partialLiteral)) {
661
+ result += "true".slice(partialLiteral.length);
662
+ } else if ("false".startsWith(partialLiteral)) {
663
+ result += "false".slice(partialLiteral.length);
664
+ } else if ("null".startsWith(partialLiteral)) {
665
+ result += "null".slice(partialLiteral.length);
666
+ }
667
+ }
668
+ }
669
+ }
670
+ return result;
671
+ }
672
+
673
+ // src/runtimes/edge/partial-json/parse-partial-json.ts
674
+ var parsePartialJson = (json) => {
675
+ try {
676
+ return sjson2.parse(json);
677
+ } catch {
678
+ try {
679
+ return sjson2.parse(fixJson(json));
680
+ } catch {
681
+ return void 0;
682
+ }
683
+ }
684
+ };
685
+
686
+ // src/runtimes/edge/streams/runResultStream.ts
687
+ function runResultStream(initialContent) {
688
+ let message = {
689
+ content: initialContent
690
+ };
691
+ const currentToolCall = { toolCallId: "", argsText: "" };
692
+ return new TransformStream({
693
+ transform(chunk, controller) {
694
+ const chunkType = chunk.type;
695
+ switch (chunkType) {
696
+ case "text-delta": {
697
+ message = appendOrUpdateText(message, chunk.textDelta);
698
+ controller.enqueue(message);
699
+ break;
700
+ }
701
+ case "tool-call-delta": {
702
+ const { toolCallId, toolName, argsTextDelta } = chunk;
703
+ if (currentToolCall.toolCallId !== toolCallId) {
704
+ currentToolCall.toolCallId = toolCallId;
705
+ currentToolCall.argsText = argsTextDelta;
706
+ } else {
707
+ currentToolCall.argsText += argsTextDelta;
708
+ }
709
+ message = appendOrUpdateToolCall(
710
+ message,
711
+ toolCallId,
712
+ toolName,
713
+ currentToolCall.argsText
714
+ );
715
+ controller.enqueue(message);
716
+ break;
717
+ }
718
+ case "tool-call": {
719
+ break;
720
+ }
721
+ case "tool-result": {
722
+ message = appendOrUpdateToolResult(
723
+ message,
724
+ chunk.toolCallId,
725
+ chunk.toolName,
726
+ chunk.result
727
+ );
728
+ controller.enqueue(message);
729
+ break;
730
+ }
731
+ case "finish": {
732
+ message = appendOrUpdateFinish(message, chunk);
733
+ controller.enqueue(message);
734
+ break;
735
+ }
736
+ case "error": {
737
+ throw chunk.error;
738
+ }
739
+ default: {
740
+ const unhandledType = chunkType;
741
+ throw new Error(`Unhandled chunk type: ${unhandledType}`);
742
+ }
743
+ }
744
+ }
745
+ });
746
+ }
747
+ var appendOrUpdateText = (message, textDelta) => {
748
+ let contentParts = message.content;
749
+ let contentPart = message.content.at(-1);
750
+ if (contentPart?.type !== "text") {
751
+ contentPart = { type: "text", text: textDelta };
752
+ } else {
753
+ contentParts = contentParts.slice(0, -1);
754
+ contentPart = { type: "text", text: contentPart.text + textDelta };
755
+ }
756
+ return {
757
+ ...message,
758
+ content: contentParts.concat([contentPart])
759
+ };
760
+ };
761
+ var appendOrUpdateToolCall = (message, toolCallId, toolName, argsText) => {
762
+ let contentParts = message.content;
763
+ let contentPart = message.content.at(-1);
764
+ if (contentPart?.type !== "tool-call" || contentPart.toolCallId !== toolCallId) {
765
+ contentPart = {
766
+ type: "tool-call",
767
+ toolCallId,
768
+ toolName,
769
+ argsText,
770
+ args: parsePartialJson(argsText)
771
+ };
772
+ } else {
773
+ contentParts = contentParts.slice(0, -1);
774
+ contentPart = {
775
+ ...contentPart,
776
+ argsText,
777
+ args: parsePartialJson(argsText)
778
+ };
779
+ }
780
+ return {
781
+ ...message,
782
+ content: contentParts.concat([contentPart])
783
+ };
784
+ };
785
+ var appendOrUpdateToolResult = (message, toolCallId, toolName, result) => {
786
+ let found = false;
787
+ const newContentParts = message.content.map((part) => {
788
+ if (part.type !== "tool-call" || part.toolCallId !== toolCallId)
789
+ return part;
790
+ found = true;
791
+ if (part.toolName !== toolName)
792
+ throw new Error(
793
+ `Tool call ${toolCallId} found with tool name ${part.toolName}, but expected ${toolName}`
794
+ );
795
+ return {
796
+ ...part,
797
+ result
798
+ };
799
+ });
800
+ if (!found)
801
+ throw new Error(
802
+ `Received tool result for unknown tool call "${toolName}" / "${toolCallId}". This is likely an internal bug in assistant-ui.`
803
+ );
804
+ return {
805
+ ...message,
806
+ content: newContentParts
807
+ };
808
+ };
809
+ var appendOrUpdateFinish = (message, chunk) => {
810
+ const { type, ...rest } = chunk;
811
+ return {
812
+ ...message,
813
+ status: {
814
+ type: "done",
815
+ ...rest
816
+ }
817
+ };
818
+ };
819
+
179
820
  // src/runtimes/edge/createEdgeRuntimeAPI.ts
180
- var createEdgeRuntimeAPI = ({ model }) => {
821
+ var voidStream = () => {
822
+ return new WritableStream({
823
+ abort(reason) {
824
+ console.error("Server stream processing aborted:", reason);
825
+ }
826
+ });
827
+ };
828
+ var createEdgeRuntimeAPI = ({
829
+ model: modelOrCreator,
830
+ system: serverSystem,
831
+ tools: serverTools = {},
832
+ toolChoice,
833
+ onFinish,
834
+ ...unsafeSettings
835
+ }) => {
836
+ const settings = LanguageModelV1CallSettingsSchema.parse(unsafeSettings);
837
+ const lmServerTools = toLanguageModelTools(serverTools);
838
+ const hasServerTools = Object.values(serverTools).some((v) => !!v.execute);
181
839
  const POST = async (request) => {
182
- const { system, messages, tools } = await request.json();
183
- const { stream } = await streamMessage({
840
+ const {
841
+ system: clientSystem,
842
+ tools: clientTools,
843
+ messages,
844
+ apiKey,
845
+ baseUrl,
846
+ modelName,
847
+ ...callSettings
848
+ } = EdgeRuntimeRequestOptionsSchema.parse(await request.json());
849
+ const systemMessages = [];
850
+ if (serverSystem) systemMessages.push(serverSystem);
851
+ if (clientSystem) systemMessages.push(clientSystem);
852
+ const system = systemMessages.join("\n\n");
853
+ for (const clientTool of clientTools) {
854
+ if (serverTools?.[clientTool.name]) {
855
+ throw new Error(
856
+ `Tool ${clientTool.name} was defined in both the client and server tools. This is not allowed.`
857
+ );
858
+ }
859
+ }
860
+ const model = typeof modelOrCreator === "function" ? await modelOrCreator({ apiKey, baseUrl, modelName }) : modelOrCreator;
861
+ let stream;
862
+ const streamResult = await streamMessage({
863
+ ...settings,
864
+ ...callSettings,
184
865
  model,
185
866
  abortSignal: request.signal,
186
- ...system ? { system } : void 0,
867
+ ...!!system ? { system } : void 0,
187
868
  messages,
188
- tools
869
+ tools: lmServerTools.concat(clientTools),
870
+ ...toolChoice ? { toolChoice } : void 0
189
871
  });
190
- return new Response(stream, {
191
- headers: {
192
- contentType: "text/plain; charset=utf-8"
872
+ stream = streamResult.stream;
873
+ const canExecuteTools = hasServerTools && toolChoice?.type !== "none";
874
+ if (canExecuteTools) {
875
+ stream = stream.pipeThrough(toolResultStream(serverTools));
876
+ }
877
+ if (canExecuteTools || onFinish) {
878
+ const tees = stream.tee();
879
+ stream = tees[0];
880
+ let serverStream = tees[1];
881
+ if (onFinish) {
882
+ serverStream = serverStream.pipeThrough(runResultStream([])).pipeThrough(
883
+ new TransformStream({
884
+ transform(chunk) {
885
+ if (chunk.status?.type !== "done") return;
886
+ const resultingMessages = [
887
+ ...messages,
888
+ {
889
+ role: "assistant",
890
+ content: chunk.content
891
+ }
892
+ ];
893
+ onFinish({
894
+ finishReason: chunk.status.finishReason,
895
+ usage: chunk.status.usage,
896
+ messages: resultingMessages,
897
+ logProbs: chunk.status.logprops,
898
+ warnings: streamResult.warnings,
899
+ rawCall: streamResult.rawCall,
900
+ rawResponse: streamResult.rawResponse
901
+ });
902
+ }
903
+ })
904
+ );
193
905
  }
194
- });
906
+ serverStream.pipeTo(voidStream()).catch((e) => {
907
+ console.error("Server stream processing error:", e);
908
+ });
909
+ }
910
+ return new Response(
911
+ stream.pipeThrough(assistantEncoderStream()).pipeThrough(new TextEncoderStream()),
912
+ {
913
+ headers: {
914
+ contentType: "text/plain; charset=utf-8"
915
+ }
916
+ }
917
+ );
195
918
  };
196
919
  return { POST };
197
920
  };
@@ -203,7 +926,7 @@ async function streamMessage({
203
926
  toolChoice,
204
927
  ...options
205
928
  }) {
206
- const { stream, warnings, rawResponse } = await model.doStream({
929
+ return model.doStream({
207
930
  inputFormat: "messages",
208
931
  mode: {
209
932
  type: "regular",
@@ -213,11 +936,6 @@ async function streamMessage({
213
936
  prompt: convertToLanguageModelPrompt(system, messages),
214
937
  ...options
215
938
  });
216
- return {
217
- stream: stream.pipeThrough(assistantEncoderStream()).pipeThrough(new TextEncoderStream()),
218
- warnings,
219
- rawResponse
220
- };
221
939
  }
222
940
  function convertToLanguageModelPrompt(system, messages) {
223
941
  const languageModelMessages = [];