assistant-stream 0.1.2 → 0.1.4
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/AsyncIterableStream-C3C8ZoXv.d.mts +4 -0
- package/dist/AsyncIterableStream-C3C8ZoXv.d.ts +4 -0
- package/dist/ai-sdk.d.mts +2 -1
- package/dist/ai-sdk.d.ts +2 -1
- package/dist/ai-sdk.js +6 -13
- package/dist/ai-sdk.js.map +1 -1
- package/dist/ai-sdk.mjs +1 -1
- package/dist/ai-sdk.mjs.map +1 -1
- package/dist/{assistant-stream-54RSz6y3.d.mts → assistant-stream-ISFjQ0mQ.d.mts} +2 -6
- package/dist/{assistant-stream-54RSz6y3.d.ts → assistant-stream-kAoIMgvk.d.ts} +2 -6
- package/dist/{chunk-OONTWUTM.mjs → chunk-EDE6WQ2R.mjs} +8 -14
- package/dist/chunk-EDE6WQ2R.mjs.map +1 -0
- package/dist/{chunk-C7JS3OBQ.mjs → chunk-PQLDKUPN.mjs} +97 -10
- package/dist/chunk-PQLDKUPN.mjs.map +1 -0
- package/dist/index.d.mts +113 -16
- package/dist/index.d.ts +113 -16
- package/dist/index.js +607 -146
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +510 -128
- package/dist/index.mjs.map +1 -1
- package/dist/json-value-Ch5eKkQ_.d.mts +7 -0
- package/dist/json-value-Ch5eKkQ_.d.ts +7 -0
- package/dist/utils.d.mts +15 -2
- package/dist/utils.d.ts +15 -2
- package/dist/utils.js +118 -10
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +24 -3
- package/dist/utils.mjs.map +1 -1
- package/package.json +9 -4
- package/dist/chunk-C7JS3OBQ.mjs.map +0 -1
- package/dist/chunk-OONTWUTM.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -7,127 +7,13 @@ import {
|
|
|
7
7
|
PipeableTransformStream,
|
|
8
8
|
createAssistantStream,
|
|
9
9
|
createAssistantStreamResponse,
|
|
10
|
-
generateId
|
|
11
|
-
|
|
10
|
+
generateId,
|
|
11
|
+
promiseWithResolvers
|
|
12
|
+
} from "./chunk-EDE6WQ2R.mjs";
|
|
12
13
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// src/core/effects/ToolExecutionStream.ts
|
|
17
|
-
import sjson from "secure-json-parse";
|
|
18
|
-
|
|
19
|
-
// src/core/utils/withPromiseOrValue.ts
|
|
20
|
-
function withPromiseOrValue(callback, thenHandler, catchHandler) {
|
|
21
|
-
try {
|
|
22
|
-
const promiseOrValue = callback();
|
|
23
|
-
if (typeof promiseOrValue === "object" && promiseOrValue !== null && "then" in promiseOrValue) {
|
|
24
|
-
return promiseOrValue.then(thenHandler, catchHandler);
|
|
25
|
-
} else {
|
|
26
|
-
thenHandler(promiseOrValue);
|
|
27
|
-
}
|
|
28
|
-
} catch (e) {
|
|
29
|
-
catchHandler(e);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// src/core/effects/ToolExecutionStream.ts
|
|
34
|
-
var ToolExecutionStream = class extends PipeableTransformStream {
|
|
35
|
-
constructor(toolCallback) {
|
|
36
|
-
const toolCallPromises = /* @__PURE__ */ new Map();
|
|
37
|
-
const toolCallArgsText = {};
|
|
38
|
-
super((readable) => {
|
|
39
|
-
const transform = new TransformStream({
|
|
40
|
-
transform(chunk, controller) {
|
|
41
|
-
if (chunk.type !== "part-finish" || chunk.meta.type !== "tool-call") {
|
|
42
|
-
controller.enqueue(chunk);
|
|
43
|
-
}
|
|
44
|
-
const type = chunk.type;
|
|
45
|
-
switch (type) {
|
|
46
|
-
case "text-delta": {
|
|
47
|
-
if (chunk.meta.type === "tool-call") {
|
|
48
|
-
const toolCallId = chunk.meta.toolCallId;
|
|
49
|
-
if (toolCallArgsText[toolCallId] === void 0) {
|
|
50
|
-
toolCallArgsText[toolCallId] = chunk.textDelta;
|
|
51
|
-
} else {
|
|
52
|
-
toolCallArgsText[toolCallId] += chunk.textDelta;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
break;
|
|
56
|
-
}
|
|
57
|
-
case "tool-call-args-text-finish": {
|
|
58
|
-
if (chunk.meta.type !== "tool-call") break;
|
|
59
|
-
const { toolCallId, toolName } = chunk.meta;
|
|
60
|
-
const argsText = toolCallArgsText[toolCallId];
|
|
61
|
-
const promise = withPromiseOrValue(
|
|
62
|
-
() => {
|
|
63
|
-
if (!argsText) {
|
|
64
|
-
console.log(
|
|
65
|
-
"Encountered tool call without argsText, this should never happen"
|
|
66
|
-
);
|
|
67
|
-
throw new Error(
|
|
68
|
-
"Encountered tool call without argsText, this is unexpected."
|
|
69
|
-
);
|
|
70
|
-
}
|
|
71
|
-
let args;
|
|
72
|
-
try {
|
|
73
|
-
args = sjson.parse(argsText);
|
|
74
|
-
} catch (e) {
|
|
75
|
-
throw new Error(
|
|
76
|
-
`Function parameter parsing failed. ${JSON.stringify(e.message)}`
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
return toolCallback({
|
|
80
|
-
toolCallId,
|
|
81
|
-
toolName,
|
|
82
|
-
args
|
|
83
|
-
});
|
|
84
|
-
},
|
|
85
|
-
(c) => {
|
|
86
|
-
if (c === void 0) return;
|
|
87
|
-
controller.enqueue({
|
|
88
|
-
type: "result",
|
|
89
|
-
path: chunk.path,
|
|
90
|
-
artifact: c.artifact,
|
|
91
|
-
result: c.result,
|
|
92
|
-
isError: c.isError
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
(e) => {
|
|
96
|
-
controller.enqueue({
|
|
97
|
-
type: "result",
|
|
98
|
-
path: chunk.path,
|
|
99
|
-
result: String(e),
|
|
100
|
-
isError: true
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
);
|
|
104
|
-
if (promise) {
|
|
105
|
-
toolCallPromises.set(toolCallId, promise);
|
|
106
|
-
}
|
|
107
|
-
break;
|
|
108
|
-
}
|
|
109
|
-
case "part-finish": {
|
|
110
|
-
if (chunk.meta.type !== "tool-call") break;
|
|
111
|
-
const { toolCallId } = chunk.meta;
|
|
112
|
-
const toolCallPromise = toolCallPromises.get(toolCallId);
|
|
113
|
-
if (toolCallPromise) {
|
|
114
|
-
toolCallPromise.then(() => {
|
|
115
|
-
controller.enqueue(chunk);
|
|
116
|
-
});
|
|
117
|
-
} else {
|
|
118
|
-
controller.enqueue(chunk);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
async flush() {
|
|
124
|
-
await Promise.all(toolCallPromises.values());
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
return readable.pipeThrough(new AssistantMetaTransformStream()).pipeThrough(transform);
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
};
|
|
14
|
+
getPartialJsonObjectFieldState,
|
|
15
|
+
parsePartialJsonObject
|
|
16
|
+
} from "./chunk-PQLDKUPN.mjs";
|
|
131
17
|
|
|
132
18
|
// src/core/accumulators/assistant-message-accumulator.ts
|
|
133
19
|
var createInitialMessage = () => ({
|
|
@@ -251,12 +137,7 @@ var handleTextDelta = (message, chunk) => {
|
|
|
251
137
|
return { ...part, text: part.text + chunk.textDelta };
|
|
252
138
|
} else if (part.type === "tool-call") {
|
|
253
139
|
const newArgsText = part.argsText + chunk.textDelta;
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
newArgs = parsePartialJson(newArgsText);
|
|
257
|
-
} catch (err) {
|
|
258
|
-
newArgs = part.args;
|
|
259
|
-
}
|
|
140
|
+
const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;
|
|
260
141
|
return { ...part, argsText: newArgsText, args: newArgs };
|
|
261
142
|
} else {
|
|
262
143
|
throw new Error(
|
|
@@ -526,7 +407,7 @@ var AssistantMessageStream = class _AssistantMessageStream {
|
|
|
526
407
|
}
|
|
527
408
|
};
|
|
528
409
|
|
|
529
|
-
// src/core/ToolResponse.ts
|
|
410
|
+
// src/core/tool/ToolResponse.ts
|
|
530
411
|
var TOOL_RESPONSE_SYMBOL = Symbol.for("aui.tool-response");
|
|
531
412
|
var ToolResponse = class {
|
|
532
413
|
get [TOOL_RESPONSE_SYMBOL]() {
|
|
@@ -544,6 +425,505 @@ var ToolResponse = class {
|
|
|
544
425
|
return typeof obj === "object" && obj !== null && TOOL_RESPONSE_SYMBOL in obj;
|
|
545
426
|
}
|
|
546
427
|
};
|
|
428
|
+
|
|
429
|
+
// src/core/tool/ToolExecutionStream.ts
|
|
430
|
+
import sjson from "secure-json-parse";
|
|
431
|
+
|
|
432
|
+
// src/core/utils/withPromiseOrValue.ts
|
|
433
|
+
function withPromiseOrValue(callback, thenHandler, catchHandler) {
|
|
434
|
+
try {
|
|
435
|
+
const promiseOrValue = callback();
|
|
436
|
+
if (typeof promiseOrValue === "object" && promiseOrValue !== null && "then" in promiseOrValue) {
|
|
437
|
+
return promiseOrValue.then(thenHandler, catchHandler);
|
|
438
|
+
} else {
|
|
439
|
+
thenHandler(promiseOrValue);
|
|
440
|
+
}
|
|
441
|
+
} catch (e) {
|
|
442
|
+
catchHandler(e);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
// src/core/tool/ToolCallReader.ts
|
|
447
|
+
function getField(obj, fieldPath) {
|
|
448
|
+
let current = obj;
|
|
449
|
+
for (const key of fieldPath) {
|
|
450
|
+
if (current === void 0 || current === null) {
|
|
451
|
+
return void 0;
|
|
452
|
+
}
|
|
453
|
+
current = current[key];
|
|
454
|
+
}
|
|
455
|
+
return current;
|
|
456
|
+
}
|
|
457
|
+
var GetHandle = class {
|
|
458
|
+
resolve;
|
|
459
|
+
reject;
|
|
460
|
+
disposed = false;
|
|
461
|
+
fieldPath;
|
|
462
|
+
constructor(resolve, reject, fieldPath) {
|
|
463
|
+
this.resolve = resolve;
|
|
464
|
+
this.reject = reject;
|
|
465
|
+
this.fieldPath = fieldPath;
|
|
466
|
+
}
|
|
467
|
+
update(args) {
|
|
468
|
+
if (this.disposed) return;
|
|
469
|
+
try {
|
|
470
|
+
if (getPartialJsonObjectFieldState(
|
|
471
|
+
args,
|
|
472
|
+
this.fieldPath
|
|
473
|
+
) === "complete") {
|
|
474
|
+
const value = getField(args, this.fieldPath);
|
|
475
|
+
if (value !== void 0) {
|
|
476
|
+
this.resolve(value);
|
|
477
|
+
this.dispose();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
} catch (e) {
|
|
481
|
+
this.reject(e);
|
|
482
|
+
this.dispose();
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
dispose() {
|
|
486
|
+
this.disposed = true;
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
var StreamValuesHandle = class {
|
|
490
|
+
controller;
|
|
491
|
+
disposed = false;
|
|
492
|
+
fieldPath;
|
|
493
|
+
constructor(controller, fieldPath) {
|
|
494
|
+
this.controller = controller;
|
|
495
|
+
this.fieldPath = fieldPath;
|
|
496
|
+
}
|
|
497
|
+
update(args) {
|
|
498
|
+
if (this.disposed) return;
|
|
499
|
+
try {
|
|
500
|
+
const value = getField(args, this.fieldPath);
|
|
501
|
+
if (value !== void 0) {
|
|
502
|
+
this.controller.enqueue(value);
|
|
503
|
+
}
|
|
504
|
+
if (getPartialJsonObjectFieldState(
|
|
505
|
+
args,
|
|
506
|
+
this.fieldPath
|
|
507
|
+
) === "complete") {
|
|
508
|
+
this.controller.close();
|
|
509
|
+
this.dispose();
|
|
510
|
+
}
|
|
511
|
+
} catch (e) {
|
|
512
|
+
this.controller.error(e);
|
|
513
|
+
this.dispose();
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
dispose() {
|
|
517
|
+
this.disposed = true;
|
|
518
|
+
}
|
|
519
|
+
};
|
|
520
|
+
var StreamTextHandle = class {
|
|
521
|
+
controller;
|
|
522
|
+
disposed = false;
|
|
523
|
+
fieldPath;
|
|
524
|
+
lastValue = void 0;
|
|
525
|
+
constructor(controller, fieldPath) {
|
|
526
|
+
this.controller = controller;
|
|
527
|
+
this.fieldPath = fieldPath;
|
|
528
|
+
}
|
|
529
|
+
update(args) {
|
|
530
|
+
if (this.disposed) return;
|
|
531
|
+
try {
|
|
532
|
+
const value = getField(args, this.fieldPath);
|
|
533
|
+
if (value !== void 0 && typeof value === "string") {
|
|
534
|
+
const delta = value.substring(this.lastValue?.length || 0);
|
|
535
|
+
this.lastValue = value;
|
|
536
|
+
this.controller.enqueue(delta);
|
|
537
|
+
}
|
|
538
|
+
if (getPartialJsonObjectFieldState(
|
|
539
|
+
args,
|
|
540
|
+
this.fieldPath
|
|
541
|
+
) === "complete") {
|
|
542
|
+
this.controller.close();
|
|
543
|
+
this.dispose();
|
|
544
|
+
}
|
|
545
|
+
} catch (e) {
|
|
546
|
+
this.controller.error(e);
|
|
547
|
+
this.dispose();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
dispose() {
|
|
551
|
+
this.disposed = true;
|
|
552
|
+
}
|
|
553
|
+
};
|
|
554
|
+
var ForEachHandle = class {
|
|
555
|
+
controller;
|
|
556
|
+
disposed = false;
|
|
557
|
+
fieldPath;
|
|
558
|
+
processedIndexes = /* @__PURE__ */ new Set();
|
|
559
|
+
constructor(controller, fieldPath) {
|
|
560
|
+
this.controller = controller;
|
|
561
|
+
this.fieldPath = fieldPath;
|
|
562
|
+
}
|
|
563
|
+
update(args) {
|
|
564
|
+
if (this.disposed) return;
|
|
565
|
+
try {
|
|
566
|
+
const array = getField(args, this.fieldPath);
|
|
567
|
+
if (!Array.isArray(array)) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
for (let i = 0; i < array.length; i++) {
|
|
571
|
+
if (!this.processedIndexes.has(i)) {
|
|
572
|
+
const elementPath = [...this.fieldPath, i];
|
|
573
|
+
if (getPartialJsonObjectFieldState(
|
|
574
|
+
args,
|
|
575
|
+
elementPath
|
|
576
|
+
) === "complete") {
|
|
577
|
+
this.controller.enqueue(array[i]);
|
|
578
|
+
this.processedIndexes.add(i);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (getPartialJsonObjectFieldState(
|
|
583
|
+
args,
|
|
584
|
+
this.fieldPath
|
|
585
|
+
) === "complete") {
|
|
586
|
+
this.controller.close();
|
|
587
|
+
this.dispose();
|
|
588
|
+
}
|
|
589
|
+
} catch (e) {
|
|
590
|
+
this.controller.error(e);
|
|
591
|
+
this.dispose();
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
dispose() {
|
|
595
|
+
this.disposed = true;
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
var ToolCallArgsReaderImpl = class {
|
|
599
|
+
argTextDeltas;
|
|
600
|
+
handles = /* @__PURE__ */ new Set();
|
|
601
|
+
args = parsePartialJsonObject("");
|
|
602
|
+
constructor(argTextDeltas) {
|
|
603
|
+
this.argTextDeltas = argTextDeltas;
|
|
604
|
+
this.processStream();
|
|
605
|
+
}
|
|
606
|
+
async processStream() {
|
|
607
|
+
try {
|
|
608
|
+
let accumulatedText = "";
|
|
609
|
+
const reader = this.argTextDeltas.getReader();
|
|
610
|
+
while (true) {
|
|
611
|
+
const { value, done } = await reader.read();
|
|
612
|
+
if (done) break;
|
|
613
|
+
accumulatedText += value;
|
|
614
|
+
const parsedArgs = parsePartialJsonObject(accumulatedText);
|
|
615
|
+
if (parsedArgs !== void 0) {
|
|
616
|
+
this.args = parsedArgs;
|
|
617
|
+
for (const handle of this.handles) {
|
|
618
|
+
handle.update(parsedArgs);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
} catch (error) {
|
|
623
|
+
console.error("Error processing argument stream:", error);
|
|
624
|
+
for (const handle of this.handles) {
|
|
625
|
+
handle.dispose();
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
get(...fieldPath) {
|
|
630
|
+
return new Promise((resolve, reject) => {
|
|
631
|
+
const handle = new GetHandle(resolve, reject, fieldPath);
|
|
632
|
+
if (this.args && getPartialJsonObjectFieldState(
|
|
633
|
+
this.args,
|
|
634
|
+
fieldPath
|
|
635
|
+
) === "complete") {
|
|
636
|
+
const value = getField(this.args, fieldPath);
|
|
637
|
+
if (value !== void 0) {
|
|
638
|
+
resolve(value);
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
this.handles.add(handle);
|
|
643
|
+
handle.update(this.args);
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
streamValues(...fieldPath) {
|
|
647
|
+
const simplePath = fieldPath;
|
|
648
|
+
const stream = new ReadableStream({
|
|
649
|
+
start: (controller) => {
|
|
650
|
+
const handle = new StreamValuesHandle(controller, simplePath);
|
|
651
|
+
this.handles.add(handle);
|
|
652
|
+
handle.update(this.args);
|
|
653
|
+
},
|
|
654
|
+
cancel: () => {
|
|
655
|
+
for (const handle of this.handles) {
|
|
656
|
+
if (handle instanceof StreamValuesHandle) {
|
|
657
|
+
handle.dispose();
|
|
658
|
+
this.handles.delete(handle);
|
|
659
|
+
break;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return stream;
|
|
665
|
+
}
|
|
666
|
+
streamText(...fieldPath) {
|
|
667
|
+
const simplePath = fieldPath;
|
|
668
|
+
const stream = new ReadableStream({
|
|
669
|
+
start: (controller) => {
|
|
670
|
+
const handle = new StreamTextHandle(controller, simplePath);
|
|
671
|
+
this.handles.add(handle);
|
|
672
|
+
handle.update(this.args);
|
|
673
|
+
},
|
|
674
|
+
cancel: () => {
|
|
675
|
+
for (const handle of this.handles) {
|
|
676
|
+
if (handle instanceof StreamTextHandle) {
|
|
677
|
+
handle.dispose();
|
|
678
|
+
this.handles.delete(handle);
|
|
679
|
+
break;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
return stream;
|
|
685
|
+
}
|
|
686
|
+
forEach(...fieldPath) {
|
|
687
|
+
const simplePath = fieldPath;
|
|
688
|
+
const stream = new ReadableStream({
|
|
689
|
+
start: (controller) => {
|
|
690
|
+
const handle = new ForEachHandle(controller, simplePath);
|
|
691
|
+
this.handles.add(handle);
|
|
692
|
+
handle.update(this.args);
|
|
693
|
+
},
|
|
694
|
+
cancel: () => {
|
|
695
|
+
for (const handle of this.handles) {
|
|
696
|
+
if (handle instanceof ForEachHandle) {
|
|
697
|
+
handle.dispose();
|
|
698
|
+
this.handles.delete(handle);
|
|
699
|
+
break;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
return stream;
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
var ToolCallResultReaderImpl = class {
|
|
708
|
+
constructor(resultPromise) {
|
|
709
|
+
this.resultPromise = resultPromise;
|
|
710
|
+
}
|
|
711
|
+
get() {
|
|
712
|
+
return this.resultPromise;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
var ToolCallReaderImpl = class {
|
|
716
|
+
args;
|
|
717
|
+
result;
|
|
718
|
+
writable;
|
|
719
|
+
resolve;
|
|
720
|
+
argsText = "";
|
|
721
|
+
constructor() {
|
|
722
|
+
const stream = new TransformStream();
|
|
723
|
+
this.writable = stream.writable;
|
|
724
|
+
this.args = new ToolCallArgsReaderImpl(stream.readable);
|
|
725
|
+
const { promise, resolve } = promiseWithResolvers();
|
|
726
|
+
this.resolve = resolve;
|
|
727
|
+
this.result = new ToolCallResultReaderImpl(promise);
|
|
728
|
+
}
|
|
729
|
+
async appendArgsTextDelta(text) {
|
|
730
|
+
const writer = this.writable.getWriter();
|
|
731
|
+
try {
|
|
732
|
+
await writer.write(text);
|
|
733
|
+
} catch (err) {
|
|
734
|
+
console.warn(err);
|
|
735
|
+
} finally {
|
|
736
|
+
writer.releaseLock();
|
|
737
|
+
}
|
|
738
|
+
this.argsText += text;
|
|
739
|
+
}
|
|
740
|
+
setResult(value) {
|
|
741
|
+
this.resolve(value);
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
// src/core/tool/ToolExecutionStream.ts
|
|
746
|
+
var ToolExecutionStream = class extends PipeableTransformStream {
|
|
747
|
+
constructor(options) {
|
|
748
|
+
const toolCallPromises = /* @__PURE__ */ new Map();
|
|
749
|
+
const toolCallControllers = /* @__PURE__ */ new Map();
|
|
750
|
+
super((readable) => {
|
|
751
|
+
const transform = new TransformStream({
|
|
752
|
+
transform(chunk, controller) {
|
|
753
|
+
if (chunk.type !== "part-finish" || chunk.meta.type !== "tool-call") {
|
|
754
|
+
controller.enqueue(chunk);
|
|
755
|
+
}
|
|
756
|
+
const type = chunk.type;
|
|
757
|
+
switch (type) {
|
|
758
|
+
case "part-start":
|
|
759
|
+
if (chunk.part.type === "tool-call") {
|
|
760
|
+
const reader = new ToolCallReaderImpl();
|
|
761
|
+
toolCallControllers.set(chunk.part.toolCallId, reader);
|
|
762
|
+
options.streamCall({
|
|
763
|
+
reader,
|
|
764
|
+
toolCallId: chunk.part.toolCallId,
|
|
765
|
+
toolName: chunk.part.toolName
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
break;
|
|
769
|
+
case "text-delta": {
|
|
770
|
+
if (chunk.meta.type === "tool-call") {
|
|
771
|
+
const toolCallId = chunk.meta.toolCallId;
|
|
772
|
+
const controller2 = toolCallControllers.get(toolCallId);
|
|
773
|
+
if (!controller2)
|
|
774
|
+
throw new Error("No controller found for tool call");
|
|
775
|
+
controller2.appendArgsTextDelta(chunk.textDelta);
|
|
776
|
+
}
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
case "tool-call-args-text-finish": {
|
|
780
|
+
if (chunk.meta.type !== "tool-call") break;
|
|
781
|
+
const { toolCallId, toolName } = chunk.meta;
|
|
782
|
+
const promise = withPromiseOrValue(
|
|
783
|
+
() => {
|
|
784
|
+
const controller2 = toolCallControllers.get(toolCallId);
|
|
785
|
+
if (!controller2) {
|
|
786
|
+
console.log(
|
|
787
|
+
"Encountered tool call without controller, this should never happen"
|
|
788
|
+
);
|
|
789
|
+
throw new Error(
|
|
790
|
+
"Encountered tool call without controller, this is unexpected."
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
let args;
|
|
794
|
+
try {
|
|
795
|
+
args = sjson.parse(controller2.argsText);
|
|
796
|
+
} catch (e) {
|
|
797
|
+
throw new Error(
|
|
798
|
+
`Function parameter parsing failed. ${JSON.stringify(e.message)}`
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
return options.execute({
|
|
802
|
+
toolCallId,
|
|
803
|
+
toolName,
|
|
804
|
+
args
|
|
805
|
+
});
|
|
806
|
+
},
|
|
807
|
+
(c) => {
|
|
808
|
+
if (c === void 0) return;
|
|
809
|
+
controller.enqueue({
|
|
810
|
+
type: "result",
|
|
811
|
+
path: chunk.path,
|
|
812
|
+
artifact: c.artifact,
|
|
813
|
+
result: c.result,
|
|
814
|
+
isError: c.isError
|
|
815
|
+
});
|
|
816
|
+
},
|
|
817
|
+
(e) => {
|
|
818
|
+
controller.enqueue({
|
|
819
|
+
type: "result",
|
|
820
|
+
path: chunk.path,
|
|
821
|
+
result: String(e),
|
|
822
|
+
isError: true
|
|
823
|
+
});
|
|
824
|
+
}
|
|
825
|
+
);
|
|
826
|
+
if (promise) {
|
|
827
|
+
toolCallPromises.set(toolCallId, promise);
|
|
828
|
+
}
|
|
829
|
+
break;
|
|
830
|
+
}
|
|
831
|
+
case "part-finish": {
|
|
832
|
+
if (chunk.meta.type !== "tool-call") break;
|
|
833
|
+
const { toolCallId } = chunk.meta;
|
|
834
|
+
const toolCallPromise = toolCallPromises.get(toolCallId);
|
|
835
|
+
if (toolCallPromise) {
|
|
836
|
+
toolCallPromise.then(() => {
|
|
837
|
+
toolCallPromises.delete(toolCallId);
|
|
838
|
+
toolCallControllers.delete(toolCallId);
|
|
839
|
+
controller.enqueue(chunk);
|
|
840
|
+
});
|
|
841
|
+
} else {
|
|
842
|
+
controller.enqueue(chunk);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
},
|
|
847
|
+
async flush() {
|
|
848
|
+
await Promise.all(toolCallPromises.values());
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
return readable.pipeThrough(new AssistantMetaTransformStream()).pipeThrough(transform);
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
};
|
|
855
|
+
|
|
856
|
+
// src/core/tool/toolResultStream.ts
|
|
857
|
+
var isStandardSchemaV1 = (schema) => {
|
|
858
|
+
return typeof schema === "object" && schema !== null && "~standard" in schema && schema["~standard"].version === 1;
|
|
859
|
+
};
|
|
860
|
+
function getToolResponse(tools, abortSignal, toolCall) {
|
|
861
|
+
const tool = tools?.[toolCall.toolName];
|
|
862
|
+
if (!tool || !tool.execute) return void 0;
|
|
863
|
+
const getResult = async (toolExecute) => {
|
|
864
|
+
let executeFn = toolExecute;
|
|
865
|
+
if (isStandardSchemaV1(tool.parameters)) {
|
|
866
|
+
let result2 = tool.parameters["~standard"].validate(toolCall.args);
|
|
867
|
+
if (result2 instanceof Promise) result2 = await result2;
|
|
868
|
+
if (result2.issues) {
|
|
869
|
+
executeFn = tool.experimental_onSchemaValidationError ?? (() => {
|
|
870
|
+
throw new Error(
|
|
871
|
+
`Function parameter validation failed. ${JSON.stringify(result2.issues)}`
|
|
872
|
+
);
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
const result = await executeFn(toolCall.args, {
|
|
877
|
+
toolCallId: toolCall.toolCallId,
|
|
878
|
+
abortSignal
|
|
879
|
+
});
|
|
880
|
+
if (result instanceof ToolResponse) return result;
|
|
881
|
+
return new ToolResponse({
|
|
882
|
+
result: result === void 0 ? "<no result>" : result
|
|
883
|
+
});
|
|
884
|
+
};
|
|
885
|
+
return getResult(tool.execute);
|
|
886
|
+
}
|
|
887
|
+
function getToolStreamResponse(tools, abortSignal, reader, context) {
|
|
888
|
+
tools?.[context.toolName]?.streamCall?.(reader, {
|
|
889
|
+
toolCallId: context.toolCallId,
|
|
890
|
+
abortSignal
|
|
891
|
+
});
|
|
892
|
+
}
|
|
893
|
+
async function unstable_runPendingTools(message, tools, abortSignal) {
|
|
894
|
+
for (const part of message.parts) {
|
|
895
|
+
if (part.type === "tool-call") {
|
|
896
|
+
const promiseOrUndefined = getToolResponse(tools, abortSignal, part);
|
|
897
|
+
if (promiseOrUndefined) {
|
|
898
|
+
const result = await promiseOrUndefined;
|
|
899
|
+
const updatedParts = message.parts.map((p) => {
|
|
900
|
+
if (p.type === "tool-call" && p.toolCallId === part.toolCallId) {
|
|
901
|
+
return {
|
|
902
|
+
...p,
|
|
903
|
+
state: "result",
|
|
904
|
+
artifact: result.artifact,
|
|
905
|
+
result: result.result,
|
|
906
|
+
isError: result.isError
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
return p;
|
|
910
|
+
});
|
|
911
|
+
message = {
|
|
912
|
+
...message,
|
|
913
|
+
parts: updatedParts,
|
|
914
|
+
content: updatedParts
|
|
915
|
+
};
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return message;
|
|
920
|
+
}
|
|
921
|
+
function toolResultStream(tools, abortSignal) {
|
|
922
|
+
return new ToolExecutionStream({
|
|
923
|
+
execute: (toolCall) => getToolResponse(tools, abortSignal, toolCall),
|
|
924
|
+
streamCall: ({ reader, ...context }) => getToolStreamResponse(tools, abortSignal, reader, context)
|
|
925
|
+
});
|
|
926
|
+
}
|
|
547
927
|
export {
|
|
548
928
|
AssistantMessageAccumulator,
|
|
549
929
|
AssistantMessageStream,
|
|
@@ -555,6 +935,8 @@ export {
|
|
|
555
935
|
ToolExecutionStream,
|
|
556
936
|
ToolResponse,
|
|
557
937
|
createAssistantStream,
|
|
558
|
-
createAssistantStreamResponse
|
|
938
|
+
createAssistantStreamResponse,
|
|
939
|
+
unstable_runPendingTools,
|
|
940
|
+
toolResultStream as unstable_toolResultStream
|
|
559
941
|
};
|
|
560
942
|
//# sourceMappingURL=index.mjs.map
|