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