assistant-stream 0.1.8 → 0.2.1
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/ai-sdk/package.json +2 -2
- package/dist/ai-sdk/index.js +7 -34
- package/dist/ai-sdk/index.js.map +1 -1
- package/dist/ai-sdk/language-model.js +5 -31
- package/dist/ai-sdk/language-model.js.map +1 -1
- package/dist/ai-sdk.js +4 -32
- package/dist/ai-sdk.js.map +1 -1
- package/dist/core/AssistantStream.js +3 -29
- package/dist/core/AssistantStream.js.map +1 -1
- package/dist/core/AssistantStreamChunk.js +0 -18
- package/dist/core/AssistantStreamChunk.js.map +1 -1
- package/dist/core/accumulators/AssistantMessageStream.js +9 -35
- package/dist/core/accumulators/AssistantMessageStream.js.map +1 -1
- package/dist/core/accumulators/assistant-message-accumulator.js +22 -48
- package/dist/core/accumulators/assistant-message-accumulator.js.map +1 -1
- package/dist/core/index.js +16 -46
- package/dist/core/index.js.map +1 -1
- package/dist/core/modules/assistant-stream.js +29 -52
- package/dist/core/modules/assistant-stream.js.map +1 -1
- package/dist/core/modules/text.js +6 -33
- package/dist/core/modules/text.js.map +1 -1
- package/dist/core/modules/tool-call.js +8 -35
- package/dist/core/modules/tool-call.js.map +1 -1
- package/dist/core/serialization/PlainText.js +9 -36
- package/dist/core/serialization/PlainText.js.map +1 -1
- package/dist/core/serialization/data-stream/DataStream.js +57 -79
- package/dist/core/serialization/data-stream/DataStream.js.map +1 -1
- package/dist/core/serialization/data-stream/chunk-types.js +2 -28
- package/dist/core/serialization/data-stream/chunk-types.js.map +1 -1
- package/dist/core/serialization/data-stream/serialization.js +6 -33
- package/dist/core/serialization/data-stream/serialization.js.map +1 -1
- package/dist/core/tool/ToolCallReader.js +30 -55
- package/dist/core/tool/ToolCallReader.js.map +1 -1
- package/dist/core/tool/ToolExecutionStream.js +18 -52
- package/dist/core/tool/ToolExecutionStream.js.map +1 -1
- package/dist/core/tool/ToolResponse.js +5 -31
- package/dist/core/tool/ToolResponse.js.map +1 -1
- package/dist/core/tool/index.js +9 -35
- package/dist/core/tool/index.js.map +1 -1
- package/dist/core/tool/tool-types.js +0 -18
- package/dist/core/tool/tool-types.js.map +1 -1
- package/dist/core/tool/toolResultStream.js +8 -35
- package/dist/core/tool/toolResultStream.js.map +1 -1
- package/dist/core/tool/type-path-utils.js +0 -18
- package/dist/core/tool/type-path-utils.js.map +1 -1
- package/dist/core/utils/Counter.js +4 -30
- package/dist/core/utils/Counter.js.map +1 -1
- package/dist/core/utils/generateId.js +4 -30
- package/dist/core/utils/generateId.js.map +1 -1
- package/dist/core/utils/stream/AssistantMetaTransformStream.js +4 -30
- package/dist/core/utils/stream/AssistantMetaTransformStream.js.map +1 -1
- package/dist/core/utils/stream/AssistantTransformStream.js +8 -32
- package/dist/core/utils/stream/AssistantTransformStream.js.map +1 -1
- package/dist/core/utils/stream/LineDecoderStream.js +4 -30
- package/dist/core/utils/stream/LineDecoderStream.js.map +1 -1
- package/dist/core/utils/stream/PipeableTransformStream.js +4 -30
- package/dist/core/utils/stream/PipeableTransformStream.js.map +1 -1
- package/dist/core/utils/stream/UnderlyingReadable.js +0 -18
- package/dist/core/utils/stream/UnderlyingReadable.js.map +1 -1
- package/dist/core/utils/stream/merge.js +5 -31
- package/dist/core/utils/stream/merge.js.map +1 -1
- package/dist/core/utils/stream/path-utils.js +10 -38
- package/dist/core/utils/stream/path-utils.js.map +1 -1
- package/dist/core/utils/types.js +0 -18
- package/dist/core/utils/types.js.map +1 -1
- package/dist/core/utils/withPromiseOrValue.js +2 -28
- package/dist/core/utils/withPromiseOrValue.js.map +1 -1
- package/dist/index.js +1 -24
- package/dist/index.js.map +1 -1
- package/dist/utils/AsyncIterableStream.js +2 -28
- package/dist/utils/AsyncIterableStream.js.map +1 -1
- package/dist/utils/json/fix-json.js +2 -28
- package/dist/utils/json/fix-json.js.map +1 -1
- package/dist/utils/json/is-json.js +2 -30
- package/dist/utils/json/is-json.js.map +1 -1
- package/dist/utils/json/json-value.js +0 -18
- package/dist/utils/json/json-value.js.map +1 -1
- package/dist/utils/json/parse-partial-json-object.js +12 -50
- package/dist/utils/json/parse-partial-json-object.js.map +1 -1
- package/dist/utils/promiseWithResolvers.js +3 -29
- package/dist/utils/promiseWithResolvers.js.map +1 -1
- package/dist/utils.js +9 -32
- package/dist/utils.js.map +1 -1
- package/package.json +7 -9
- package/{dist/ai-sdk/index.mjs → src/ai-sdk/index.ts} +64 -33
- package/{dist/ai-sdk/language-model.mjs → src/ai-sdk/language-model.ts} +35 -19
- package/src/ai-sdk.ts +2 -0
- package/src/core/AssistantStream.ts +39 -0
- package/src/core/AssistantStreamChunk.ts +93 -0
- package/src/core/accumulators/AssistantMessageStream.ts +56 -0
- package/{dist/core/accumulators/assistant-message-accumulator.mjs → src/core/accumulators/assistant-message-accumulator.ts} +152 -67
- package/src/core/index.ts +17 -0
- package/{dist/core/modules/assistant-stream.mjs → src/core/modules/assistant-stream.ts} +122 -60
- package/src/core/modules/text.ts +64 -0
- package/{dist/core/modules/tool-call.mjs → src/core/modules/tool-call.ts} +48 -27
- package/src/core/serialization/PlainText.ts +68 -0
- package/{dist/core/serialization/data-stream/DataStream.mjs → src/core/serialization/data-stream/DataStream.ts} +111 -67
- package/src/core/serialization/data-stream/chunk-types.ts +93 -0
- package/src/core/serialization/data-stream/serialization.ts +32 -0
- package/src/core/tool/ToolCallReader.ts +432 -0
- package/{dist/core/tool/ToolExecutionStream.mjs → src/core/tool/ToolExecutionStream.ts} +83 -35
- package/src/core/tool/ToolResponse.ts +31 -0
- package/src/core/tool/index.ts +8 -0
- package/src/core/tool/tool-types.ts +107 -0
- package/src/core/tool/toolResultStream.ts +119 -0
- package/src/core/tool/type-path-utils.ts +36 -0
- package/src/core/utils/Counter.ts +7 -0
- package/src/core/utils/generateId.tsx +6 -0
- package/src/core/utils/stream/AssistantMetaTransformStream.ts +74 -0
- package/src/core/utils/stream/AssistantTransformStream.ts +74 -0
- package/{dist/core/utils/stream/LineDecoderStream.mjs → src/core/utils/stream/LineDecoderStream.ts} +12 -10
- package/src/core/utils/stream/PipeableTransformStream.ts +10 -0
- package/src/core/utils/stream/UnderlyingReadable.ts +5 -0
- package/src/core/utils/stream/merge.ts +212 -0
- package/src/core/utils/stream/path-utils.ts +71 -0
- package/src/core/utils/types.ts +150 -0
- package/src/core/utils/withPromiseOrValue.ts +20 -0
- package/src/index.ts +1 -0
- package/src/utils/AsyncIterableStream.ts +24 -0
- package/{dist/utils/json/fix-json.mjs → src/utils/json/fix-json.ts} +146 -20
- package/src/utils/json/is-json.ts +43 -0
- package/src/utils/json/json-value.ts +13 -0
- package/src/utils/json/parse-partial-json-object.test.ts +225 -0
- package/src/utils/json/parse-partial-json-object.ts +103 -0
- package/src/utils/promiseWithResolvers.ts +10 -0
- package/src/utils.ts +13 -0
- package/dist/ai-sdk/index.mjs.map +0 -1
- package/dist/ai-sdk/language-model.mjs.map +0 -1
- package/dist/ai-sdk.mjs +0 -7
- package/dist/ai-sdk.mjs.map +0 -1
- package/dist/core/AssistantStream.mjs +0 -21
- package/dist/core/AssistantStream.mjs.map +0 -1
- package/dist/core/AssistantStreamChunk.mjs +0 -1
- package/dist/core/AssistantStreamChunk.mjs.map +0 -1
- package/dist/core/accumulators/AssistantMessageStream.mjs +0 -54
- package/dist/core/accumulators/AssistantMessageStream.mjs.map +0 -1
- package/dist/core/accumulators/assistant-message-accumulator.mjs.map +0 -1
- package/dist/core/index.mjs +0 -26
- package/dist/core/index.mjs.map +0 -1
- package/dist/core/modules/assistant-stream.mjs.map +0 -1
- package/dist/core/modules/text.mjs +0 -52
- package/dist/core/modules/text.mjs.map +0 -1
- package/dist/core/modules/tool-call.mjs.map +0 -1
- package/dist/core/serialization/PlainText.mjs +0 -44
- package/dist/core/serialization/PlainText.mjs.map +0 -1
- package/dist/core/serialization/data-stream/DataStream.mjs.map +0 -1
- package/dist/core/serialization/data-stream/chunk-types.mjs +0 -24
- package/dist/core/serialization/data-stream/chunk-types.mjs.map +0 -1
- package/dist/core/serialization/data-stream/serialization.mjs +0 -30
- package/dist/core/serialization/data-stream/serialization.mjs.map +0 -1
- package/dist/core/tool/ToolCallReader.mjs +0 -315
- package/dist/core/tool/ToolCallReader.mjs.map +0 -1
- package/dist/core/tool/ToolExecutionStream.mjs.map +0 -1
- package/dist/core/tool/ToolResponse.mjs +0 -22
- package/dist/core/tool/ToolResponse.mjs.map +0 -1
- package/dist/core/tool/index.mjs +0 -14
- package/dist/core/tool/index.mjs.map +0 -1
- package/dist/core/tool/tool-types.mjs +0 -1
- package/dist/core/tool/tool-types.mjs.map +0 -1
- package/dist/core/tool/toolResultStream.mjs +0 -78
- package/dist/core/tool/toolResultStream.mjs.map +0 -1
- package/dist/core/tool/type-path-utils.mjs +0 -1
- package/dist/core/tool/type-path-utils.mjs.map +0 -1
- package/dist/core/utils/Counter.mjs +0 -11
- package/dist/core/utils/Counter.mjs.map +0 -1
- package/dist/core/utils/generateId.mjs +0 -10
- package/dist/core/utils/generateId.mjs.map +0 -1
- package/dist/core/utils/stream/AssistantMetaTransformStream.mjs +0 -44
- package/dist/core/utils/stream/AssistantMetaTransformStream.mjs.map +0 -1
- package/dist/core/utils/stream/AssistantTransformStream.mjs +0 -46
- package/dist/core/utils/stream/AssistantTransformStream.mjs.map +0 -1
- package/dist/core/utils/stream/LineDecoderStream.mjs.map +0 -1
- package/dist/core/utils/stream/PipeableTransformStream.mjs +0 -15
- package/dist/core/utils/stream/PipeableTransformStream.mjs.map +0 -1
- package/dist/core/utils/stream/UnderlyingReadable.mjs +0 -1
- package/dist/core/utils/stream/UnderlyingReadable.mjs.map +0 -1
- package/dist/core/utils/stream/merge.mjs +0 -85
- package/dist/core/utils/stream/merge.mjs.map +0 -1
- package/dist/core/utils/stream/path-utils.mjs +0 -61
- package/dist/core/utils/stream/path-utils.mjs.map +0 -1
- package/dist/core/utils/types.mjs +0 -1
- package/dist/core/utils/types.mjs.map +0 -1
- package/dist/core/utils/withPromiseOrValue.mjs +0 -17
- package/dist/core/utils/withPromiseOrValue.mjs.map +0 -1
- package/dist/index.mjs +0 -3
- package/dist/index.mjs.map +0 -1
- package/dist/utils/AsyncIterableStream.mjs +0 -21
- package/dist/utils/AsyncIterableStream.mjs.map +0 -1
- package/dist/utils/json/fix-json.mjs.map +0 -1
- package/dist/utils/json/is-json.mjs +0 -29
- package/dist/utils/json/is-json.mjs.map +0 -1
- package/dist/utils/json/json-value.mjs +0 -1
- package/dist/utils/json/json-value.mjs.map +0 -1
- package/dist/utils/json/parse-partial-json-object.mjs +0 -65
- package/dist/utils/json/parse-partial-json-object.mjs.map +0 -1
- package/dist/utils/promiseWithResolvers.mjs +0 -15
- package/dist/utils/promiseWithResolvers.mjs.map +0 -1
- package/dist/utils.mjs +0 -14
- package/dist/utils.mjs.map +0 -1
- package/utils/README.md +0 -1
- package/utils/package.json +0 -5
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { AssistantStream } from "../AssistantStream";
|
|
2
|
+
import { AssistantMessage } from "../utils/types";
|
|
3
|
+
import { AssistantMessageAccumulator } from "./assistant-message-accumulator";
|
|
4
|
+
|
|
5
|
+
export class AssistantMessageStream {
|
|
6
|
+
constructor(public readonly readable: ReadableStream<AssistantMessage>) {
|
|
7
|
+
this.readable = readable;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static fromAssistantStream(stream: AssistantStream) {
|
|
11
|
+
return new AssistantMessageStream(
|
|
12
|
+
stream.pipeThrough(new AssistantMessageAccumulator()),
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async unstable_result(): Promise<AssistantMessage> {
|
|
17
|
+
let last: AssistantMessage | undefined;
|
|
18
|
+
for await (const chunk of this) {
|
|
19
|
+
last = chunk;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!last) {
|
|
23
|
+
return {
|
|
24
|
+
role: "assistant",
|
|
25
|
+
status: { type: "complete", reason: "unknown" },
|
|
26
|
+
parts: [],
|
|
27
|
+
content: [],
|
|
28
|
+
metadata: {
|
|
29
|
+
unstable_data: [],
|
|
30
|
+
unstable_annotations: [],
|
|
31
|
+
steps: [],
|
|
32
|
+
custom: {},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return last;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[Symbol.asyncIterator]() {
|
|
40
|
+
const reader = this.readable.getReader();
|
|
41
|
+
return {
|
|
42
|
+
async next(): Promise<IteratorResult<AssistantMessage, undefined>> {
|
|
43
|
+
const { done, value } = await reader.read();
|
|
44
|
+
return done ? { done: true, value: undefined } : { done: false, value };
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
tee(): [AssistantMessageStream, AssistantMessageStream] {
|
|
50
|
+
const [readable1, readable2] = this.readable.tee();
|
|
51
|
+
return [
|
|
52
|
+
new AssistantMessageStream(readable1),
|
|
53
|
+
new AssistantMessageStream(readable2),
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
import { generateId } from "../utils/generateId
|
|
3
|
-
import { parsePartialJsonObject } from "../../utils/json/parse-partial-json-object
|
|
4
|
-
|
|
1
|
+
import { AssistantStreamChunk } from "../AssistantStreamChunk";
|
|
2
|
+
import { generateId } from "../utils/generateId";
|
|
3
|
+
import { parsePartialJsonObject } from "../../utils/json/parse-partial-json-object";
|
|
4
|
+
import {
|
|
5
|
+
AssistantMessage,
|
|
6
|
+
AssistantMessageStatus,
|
|
7
|
+
TextPart,
|
|
8
|
+
ToolCallPart,
|
|
9
|
+
SourcePart,
|
|
10
|
+
AssistantMessagePart,
|
|
11
|
+
ReasoningPart,
|
|
12
|
+
FilePart,
|
|
13
|
+
} from "../utils/types";
|
|
14
|
+
|
|
15
|
+
const createInitialMessage = (): AssistantMessage => ({
|
|
5
16
|
role: "assistant",
|
|
6
17
|
status: { type: "running" },
|
|
7
18
|
parts: [],
|
|
@@ -12,126 +23,158 @@ var createInitialMessage = () => ({
|
|
|
12
23
|
unstable_data: [],
|
|
13
24
|
unstable_annotations: [],
|
|
14
25
|
steps: [],
|
|
15
|
-
custom: {}
|
|
16
|
-
}
|
|
26
|
+
custom: {},
|
|
27
|
+
},
|
|
17
28
|
});
|
|
18
|
-
|
|
29
|
+
|
|
30
|
+
const updatePartForPath = (
|
|
31
|
+
message: AssistantMessage,
|
|
32
|
+
chunk: AssistantStreamChunk,
|
|
33
|
+
updater: (part: AssistantMessagePart) => AssistantMessagePart,
|
|
34
|
+
): AssistantMessage => {
|
|
19
35
|
if (message.parts.length === 0) {
|
|
20
36
|
throw new Error("No parts available to update.");
|
|
21
37
|
}
|
|
38
|
+
|
|
22
39
|
if (chunk.path.length !== 1)
|
|
23
40
|
throw new Error("Nested paths are not supported yet.");
|
|
24
|
-
|
|
25
|
-
const
|
|
41
|
+
|
|
42
|
+
const partIndex = chunk.path[0]!;
|
|
43
|
+
const updatedPart = updater(message.parts[partIndex]!);
|
|
26
44
|
return {
|
|
27
45
|
...message,
|
|
28
46
|
parts: [
|
|
29
47
|
...message.parts.slice(0, partIndex),
|
|
30
48
|
updatedPart,
|
|
31
|
-
...message.parts.slice(partIndex + 1)
|
|
49
|
+
...message.parts.slice(partIndex + 1),
|
|
32
50
|
],
|
|
33
51
|
get content() {
|
|
34
52
|
return this.parts;
|
|
35
|
-
}
|
|
53
|
+
},
|
|
36
54
|
};
|
|
37
55
|
};
|
|
38
|
-
|
|
56
|
+
|
|
57
|
+
const handlePartStart = (
|
|
58
|
+
message: AssistantMessage,
|
|
59
|
+
chunk: AssistantStreamChunk & { readonly type: "part-start" },
|
|
60
|
+
): AssistantMessage => {
|
|
39
61
|
const partInit = chunk.part;
|
|
40
62
|
if (partInit.type === "text" || partInit.type === "reasoning") {
|
|
41
|
-
const newTextPart = {
|
|
63
|
+
const newTextPart: TextPart | ReasoningPart = {
|
|
42
64
|
type: partInit.type,
|
|
43
65
|
text: "",
|
|
44
|
-
status: { type: "running" }
|
|
66
|
+
status: { type: "running" },
|
|
45
67
|
};
|
|
46
68
|
return {
|
|
47
69
|
...message,
|
|
48
70
|
parts: [...message.parts, newTextPart],
|
|
49
71
|
get content() {
|
|
50
72
|
return this.parts;
|
|
51
|
-
}
|
|
73
|
+
},
|
|
52
74
|
};
|
|
53
75
|
} else if (partInit.type === "tool-call") {
|
|
54
|
-
const newToolCallPart = {
|
|
76
|
+
const newToolCallPart: ToolCallPart = {
|
|
55
77
|
type: "tool-call",
|
|
56
78
|
state: "partial-call",
|
|
57
79
|
status: { type: "running", isArgsComplete: false },
|
|
58
80
|
toolCallId: partInit.toolCallId,
|
|
59
81
|
toolName: partInit.toolName,
|
|
60
82
|
argsText: "",
|
|
61
|
-
args: {}
|
|
83
|
+
args: {},
|
|
62
84
|
};
|
|
63
85
|
return {
|
|
64
86
|
...message,
|
|
65
87
|
parts: [...message.parts, newToolCallPart],
|
|
66
88
|
get content() {
|
|
67
89
|
return this.parts;
|
|
68
|
-
}
|
|
90
|
+
},
|
|
69
91
|
};
|
|
70
92
|
} else if (partInit.type === "source") {
|
|
71
|
-
const newSourcePart = {
|
|
93
|
+
const newSourcePart: SourcePart = {
|
|
72
94
|
type: "source",
|
|
73
95
|
sourceType: partInit.sourceType,
|
|
74
96
|
id: partInit.id,
|
|
75
97
|
url: partInit.url,
|
|
76
|
-
...partInit.title ? { title: partInit.title } :
|
|
98
|
+
...(partInit.title ? { title: partInit.title } : undefined),
|
|
77
99
|
};
|
|
78
100
|
return {
|
|
79
101
|
...message,
|
|
80
102
|
parts: [...message.parts, newSourcePart],
|
|
81
103
|
get content() {
|
|
82
104
|
return this.parts;
|
|
83
|
-
}
|
|
105
|
+
},
|
|
84
106
|
};
|
|
85
107
|
} else if (partInit.type === "file") {
|
|
86
|
-
const newFilePart = {
|
|
108
|
+
const newFilePart: FilePart = {
|
|
87
109
|
type: "file",
|
|
88
110
|
mimeType: partInit.mimeType,
|
|
89
|
-
data: partInit.data
|
|
111
|
+
data: partInit.data,
|
|
90
112
|
};
|
|
91
113
|
return {
|
|
92
114
|
...message,
|
|
93
115
|
parts: [...message.parts, newFilePart],
|
|
94
116
|
get content() {
|
|
95
117
|
return this.parts;
|
|
96
|
-
}
|
|
118
|
+
},
|
|
97
119
|
};
|
|
98
120
|
} else {
|
|
99
121
|
throw new Error(`Unsupported part type: ${partInit.type}`);
|
|
100
122
|
}
|
|
101
123
|
};
|
|
102
|
-
|
|
124
|
+
|
|
125
|
+
const handleToolCallArgsTextFinish = (
|
|
126
|
+
message: AssistantMessage,
|
|
127
|
+
chunk: AssistantStreamChunk & {
|
|
128
|
+
readonly type: "tool-call-args-text-finish";
|
|
129
|
+
},
|
|
130
|
+
): AssistantMessage => {
|
|
103
131
|
return updatePartForPath(message, chunk, (part) => {
|
|
104
132
|
if (part.type !== "tool-call") {
|
|
105
133
|
throw new Error("Last is not a tool call");
|
|
106
134
|
}
|
|
107
135
|
return {
|
|
108
136
|
...part,
|
|
109
|
-
state: "call"
|
|
137
|
+
state: "call",
|
|
110
138
|
};
|
|
111
139
|
});
|
|
112
140
|
};
|
|
113
|
-
|
|
141
|
+
|
|
142
|
+
const handlePartFinish = (
|
|
143
|
+
message: AssistantMessage,
|
|
144
|
+
chunk: AssistantStreamChunk & { readonly type: "part-finish" },
|
|
145
|
+
): AssistantMessage => {
|
|
114
146
|
return updatePartForPath(message, chunk, (part) => ({
|
|
115
147
|
...part,
|
|
116
|
-
status: { type: "complete", reason: "unknown" }
|
|
148
|
+
status: { type: "complete", reason: "unknown" },
|
|
117
149
|
}));
|
|
118
150
|
};
|
|
119
|
-
|
|
151
|
+
|
|
152
|
+
const handleTextDelta = (
|
|
153
|
+
message: AssistantMessage,
|
|
154
|
+
chunk: AssistantStreamChunk & { type: "text-delta" },
|
|
155
|
+
): AssistantMessage => {
|
|
120
156
|
return updatePartForPath(message, chunk, (part) => {
|
|
121
157
|
if (part.type === "text" || part.type === "reasoning") {
|
|
122
158
|
return { ...part, text: part.text + chunk.textDelta };
|
|
123
159
|
} else if (part.type === "tool-call") {
|
|
124
160
|
const newArgsText = part.argsText + chunk.textDelta;
|
|
161
|
+
|
|
162
|
+
// Fall back to existing args if parsing fails
|
|
125
163
|
const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;
|
|
164
|
+
|
|
126
165
|
return { ...part, argsText: newArgsText, args: newArgs };
|
|
127
166
|
} else {
|
|
128
167
|
throw new Error(
|
|
129
|
-
"text-delta received but part is neither text nor tool-call"
|
|
168
|
+
"text-delta received but part is neither text nor tool-call",
|
|
130
169
|
);
|
|
131
170
|
}
|
|
132
171
|
});
|
|
133
172
|
};
|
|
134
|
-
|
|
173
|
+
|
|
174
|
+
const handleResult = (
|
|
175
|
+
message: AssistantMessage,
|
|
176
|
+
chunk: AssistantStreamChunk & { type: "result" },
|
|
177
|
+
): AssistantMessage => {
|
|
135
178
|
return updatePartForPath(message, chunk, (part) => {
|
|
136
179
|
if (part.type === "tool-call") {
|
|
137
180
|
return {
|
|
@@ -140,105 +183,147 @@ var handleResult = (message, chunk) => {
|
|
|
140
183
|
artifact: chunk.artifact,
|
|
141
184
|
result: chunk.result,
|
|
142
185
|
isError: chunk.isError ?? false,
|
|
143
|
-
status: { type: "complete", reason: "stop" }
|
|
186
|
+
status: { type: "complete", reason: "stop" },
|
|
144
187
|
};
|
|
145
188
|
} else {
|
|
146
189
|
throw new Error("Result chunk received but part is not a tool-call");
|
|
147
190
|
}
|
|
148
191
|
});
|
|
149
192
|
};
|
|
150
|
-
|
|
193
|
+
|
|
194
|
+
const handleMessageFinish = (
|
|
195
|
+
message: AssistantMessage,
|
|
196
|
+
chunk: AssistantStreamChunk & { type: "message-finish" },
|
|
197
|
+
): AssistantMessage => {
|
|
151
198
|
const newStatus = getStatus(chunk);
|
|
152
199
|
return { ...message, status: newStatus };
|
|
153
200
|
};
|
|
154
|
-
|
|
201
|
+
|
|
202
|
+
const getStatus = (
|
|
203
|
+
chunk:
|
|
204
|
+
| (AssistantStreamChunk & { type: "message-finish" })
|
|
205
|
+
| (AssistantStreamChunk & { type: "step-finish" }),
|
|
206
|
+
): AssistantMessageStatus => {
|
|
155
207
|
if (chunk.finishReason === "tool-calls") {
|
|
156
208
|
return {
|
|
157
209
|
type: "requires-action",
|
|
158
|
-
reason: "tool-calls"
|
|
210
|
+
reason: "tool-calls",
|
|
159
211
|
};
|
|
160
|
-
} else if (
|
|
212
|
+
} else if (
|
|
213
|
+
chunk.finishReason === "stop" ||
|
|
214
|
+
chunk.finishReason === "unknown"
|
|
215
|
+
) {
|
|
161
216
|
return {
|
|
162
217
|
type: "complete",
|
|
163
|
-
reason: chunk.finishReason
|
|
218
|
+
reason: chunk.finishReason,
|
|
164
219
|
};
|
|
165
220
|
} else {
|
|
166
221
|
return {
|
|
167
222
|
type: "incomplete",
|
|
168
|
-
reason: chunk.finishReason
|
|
223
|
+
reason: chunk.finishReason,
|
|
169
224
|
};
|
|
170
225
|
}
|
|
171
226
|
};
|
|
172
|
-
|
|
227
|
+
|
|
228
|
+
const handleAnnotations = (
|
|
229
|
+
message: AssistantMessage,
|
|
230
|
+
chunk: AssistantStreamChunk & { type: "annotations" },
|
|
231
|
+
): AssistantMessage => {
|
|
173
232
|
return {
|
|
174
233
|
...message,
|
|
175
234
|
metadata: {
|
|
176
235
|
...message.metadata,
|
|
177
236
|
unstable_annotations: [
|
|
178
237
|
...message.metadata.unstable_annotations,
|
|
179
|
-
...chunk.annotations
|
|
180
|
-
]
|
|
181
|
-
}
|
|
238
|
+
...chunk.annotations,
|
|
239
|
+
],
|
|
240
|
+
},
|
|
182
241
|
};
|
|
183
242
|
};
|
|
184
|
-
|
|
243
|
+
|
|
244
|
+
const handleData = (
|
|
245
|
+
message: AssistantMessage,
|
|
246
|
+
chunk: AssistantStreamChunk & { type: "data" },
|
|
247
|
+
): AssistantMessage => {
|
|
185
248
|
return {
|
|
186
249
|
...message,
|
|
187
250
|
metadata: {
|
|
188
251
|
...message.metadata,
|
|
189
|
-
unstable_data: [...message.metadata.unstable_data, ...chunk.data]
|
|
190
|
-
}
|
|
252
|
+
unstable_data: [...message.metadata.unstable_data, ...chunk.data],
|
|
253
|
+
},
|
|
191
254
|
};
|
|
192
255
|
};
|
|
193
|
-
|
|
256
|
+
|
|
257
|
+
const handleStepStart = (
|
|
258
|
+
message: AssistantMessage,
|
|
259
|
+
chunk: AssistantStreamChunk & { type: "step-start" },
|
|
260
|
+
): AssistantMessage => {
|
|
194
261
|
return {
|
|
195
262
|
...message,
|
|
196
263
|
metadata: {
|
|
197
264
|
...message.metadata,
|
|
198
265
|
steps: [
|
|
199
266
|
...message.metadata.steps,
|
|
200
|
-
{ state: "started", messageId: chunk.messageId }
|
|
201
|
-
]
|
|
202
|
-
}
|
|
267
|
+
{ state: "started", messageId: chunk.messageId },
|
|
268
|
+
],
|
|
269
|
+
},
|
|
203
270
|
};
|
|
204
271
|
};
|
|
205
|
-
|
|
272
|
+
|
|
273
|
+
const handleStepFinish = (
|
|
274
|
+
message: AssistantMessage,
|
|
275
|
+
chunk: AssistantStreamChunk & { type: "step-finish" },
|
|
276
|
+
): AssistantMessage => {
|
|
206
277
|
const steps = message.metadata.steps.slice();
|
|
207
278
|
const lastIndex = steps.length - 1;
|
|
279
|
+
|
|
280
|
+
// Check if the previous step is a step-start (has state "started")
|
|
208
281
|
if (steps.length > 0 && steps[lastIndex]?.state === "started") {
|
|
209
282
|
steps[lastIndex] = {
|
|
210
283
|
...steps[lastIndex],
|
|
211
284
|
state: "finished",
|
|
212
285
|
finishReason: chunk.finishReason,
|
|
213
286
|
usage: chunk.usage,
|
|
214
|
-
isContinued: chunk.isContinued
|
|
287
|
+
isContinued: chunk.isContinued,
|
|
215
288
|
};
|
|
216
289
|
} else {
|
|
290
|
+
// If no previous step-start exists, append a finished step
|
|
217
291
|
steps.push({
|
|
218
292
|
state: "finished",
|
|
219
293
|
messageId: generateId(),
|
|
220
294
|
finishReason: chunk.finishReason,
|
|
221
295
|
usage: chunk.usage,
|
|
222
|
-
isContinued: chunk.isContinued
|
|
296
|
+
isContinued: chunk.isContinued,
|
|
223
297
|
});
|
|
224
298
|
}
|
|
299
|
+
|
|
225
300
|
return {
|
|
226
301
|
...message,
|
|
227
302
|
metadata: {
|
|
228
303
|
...message.metadata,
|
|
229
|
-
steps
|
|
230
|
-
}
|
|
304
|
+
steps,
|
|
305
|
+
},
|
|
231
306
|
};
|
|
232
307
|
};
|
|
233
|
-
|
|
308
|
+
|
|
309
|
+
const handleErrorChunk = (
|
|
310
|
+
message: AssistantMessage,
|
|
311
|
+
chunk: AssistantStreamChunk & { type: "error" },
|
|
312
|
+
): AssistantMessage => {
|
|
234
313
|
return {
|
|
235
314
|
...message,
|
|
236
|
-
status: { type: "incomplete", reason: "error", error: chunk.error }
|
|
315
|
+
status: { type: "incomplete", reason: "error", error: chunk.error },
|
|
237
316
|
};
|
|
238
317
|
};
|
|
239
|
-
|
|
318
|
+
|
|
319
|
+
export class AssistantMessageAccumulator extends TransformStream<
|
|
320
|
+
AssistantStreamChunk,
|
|
321
|
+
AssistantMessage
|
|
322
|
+
> {
|
|
240
323
|
constructor({
|
|
241
|
-
initialMessage
|
|
324
|
+
initialMessage,
|
|
325
|
+
}: {
|
|
326
|
+
initialMessage?: AssistantMessage;
|
|
242
327
|
} = {}) {
|
|
243
328
|
let message = initialMessage ?? createInitialMessage();
|
|
244
329
|
super({
|
|
@@ -248,12 +333,15 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
248
333
|
case "part-start":
|
|
249
334
|
message = handlePartStart(message, chunk);
|
|
250
335
|
break;
|
|
336
|
+
|
|
251
337
|
case "tool-call-args-text-finish":
|
|
252
338
|
message = handleToolCallArgsTextFinish(message, chunk);
|
|
253
339
|
break;
|
|
340
|
+
|
|
254
341
|
case "part-finish":
|
|
255
342
|
message = handlePartFinish(message, chunk);
|
|
256
343
|
break;
|
|
344
|
+
|
|
257
345
|
case "text-delta":
|
|
258
346
|
message = handleTextDelta(message, chunk);
|
|
259
347
|
break;
|
|
@@ -279,7 +367,7 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
279
367
|
message = handleErrorChunk(message, chunk);
|
|
280
368
|
break;
|
|
281
369
|
default: {
|
|
282
|
-
const unhandledType = type;
|
|
370
|
+
const unhandledType: never = type;
|
|
283
371
|
throw new Error(`Unsupported chunk type: ${unhandledType}`);
|
|
284
372
|
}
|
|
285
373
|
}
|
|
@@ -287,6 +375,7 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
287
375
|
},
|
|
288
376
|
flush(controller) {
|
|
289
377
|
if (message.status?.type === "running") {
|
|
378
|
+
// TODO this test isn't sound
|
|
290
379
|
const requiresAction = message.parts?.at(-1)?.type === "tool-call";
|
|
291
380
|
message = handleMessageFinish(message, {
|
|
292
381
|
type: "message-finish",
|
|
@@ -294,16 +383,12 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
294
383
|
finishReason: requiresAction ? "tool-calls" : "unknown",
|
|
295
384
|
usage: {
|
|
296
385
|
promptTokens: 0,
|
|
297
|
-
completionTokens: 0
|
|
298
|
-
}
|
|
386
|
+
completionTokens: 0,
|
|
387
|
+
},
|
|
299
388
|
});
|
|
300
389
|
controller.enqueue(message);
|
|
301
390
|
}
|
|
302
|
-
}
|
|
391
|
+
},
|
|
303
392
|
});
|
|
304
393
|
}
|
|
305
|
-
}
|
|
306
|
-
export {
|
|
307
|
-
AssistantMessageAccumulator
|
|
308
|
-
};
|
|
309
|
-
//# sourceMappingURL=assistant-message-accumulator.mjs.map
|
|
394
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export {
|
|
2
|
+
createAssistantStream,
|
|
3
|
+
createAssistantStreamResponse,
|
|
4
|
+
} from "./modules/assistant-stream";
|
|
5
|
+
export { AssistantMessageAccumulator } from "./accumulators/assistant-message-accumulator";
|
|
6
|
+
export { AssistantStream } from "./AssistantStream";
|
|
7
|
+
export type { AssistantStreamController } from "./modules/assistant-stream";
|
|
8
|
+
export type { AssistantStreamChunk } from "./AssistantStreamChunk";
|
|
9
|
+
export {
|
|
10
|
+
DataStreamDecoder,
|
|
11
|
+
DataStreamEncoder,
|
|
12
|
+
} from "./serialization/data-stream/DataStream";
|
|
13
|
+
export { PlainTextDecoder, PlainTextEncoder } from "./serialization/PlainText";
|
|
14
|
+
export { AssistantMessageStream } from "./accumulators/AssistantMessageStream";
|
|
15
|
+
export type { AssistantMessage } from "./utils/types";
|
|
16
|
+
|
|
17
|
+
export * from "./tool";
|