@assistant-ui/react 0.4.3 → 0.4.5

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