assistant-stream 0.3.25 → 0.3.27
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/README.md +4 -1
- package/dist/core/AssistantStream.d.ts +0 -1
- package/dist/core/AssistantStream.d.ts.map +1 -1
- package/dist/core/AssistantStreamChunk.d.ts +26 -14
- package/dist/core/AssistantStreamChunk.d.ts.map +1 -1
- package/dist/core/accumulators/AssistantMessageStream.d.ts +0 -1
- package/dist/core/accumulators/AssistantMessageStream.d.ts.map +1 -1
- package/dist/core/accumulators/TimingTracker.d.ts +0 -1
- package/dist/core/accumulators/TimingTracker.d.ts.map +1 -1
- package/dist/core/accumulators/assistant-message-accumulator.d.ts +3 -9
- package/dist/core/accumulators/assistant-message-accumulator.d.ts.map +1 -1
- package/dist/core/accumulators/assistant-message-accumulator.js +70 -28
- package/dist/core/accumulators/assistant-message-accumulator.js.map +1 -1
- package/dist/core/converters/toGenericMessages.d.ts.map +1 -1
- package/dist/core/converters/toGenericMessages.js +2 -1
- package/dist/core/converters/toGenericMessages.js.map +1 -1
- package/dist/core/gorp/GorpStreamAccumulator.d.ts +15 -0
- package/dist/core/gorp/GorpStreamAccumulator.d.ts.map +1 -0
- package/dist/core/{object/ObjectStreamAccumulator.js → gorp/GorpStreamAccumulator.js} +11 -9
- package/dist/core/gorp/GorpStreamAccumulator.js.map +1 -0
- package/dist/core/gorp/GorpStreamDeltaTracker.d.ts +17 -0
- package/dist/core/gorp/GorpStreamDeltaTracker.d.ts.map +1 -0
- package/dist/core/gorp/GorpStreamDeltaTracker.js +38 -0
- package/dist/core/gorp/GorpStreamDeltaTracker.js.map +1 -0
- package/dist/core/gorp/GorpStreamResponse.d.ts +16 -0
- package/dist/core/gorp/GorpStreamResponse.d.ts.map +1 -0
- package/dist/core/gorp/GorpStreamResponse.js +51 -0
- package/dist/core/gorp/GorpStreamResponse.js.map +1 -0
- package/dist/core/gorp/changeTree.d.ts +16 -0
- package/dist/core/gorp/changeTree.d.ts.map +1 -0
- package/dist/core/gorp/changeTree.js +77 -0
- package/dist/core/gorp/changeTree.js.map +1 -0
- package/dist/core/gorp/createGorpStream.d.ts +16 -0
- package/dist/core/gorp/createGorpStream.d.ts.map +1 -0
- package/dist/core/{object/createObjectStream.js → gorp/createGorpStream.js} +13 -8
- package/dist/core/gorp/createGorpStream.js.map +1 -0
- package/dist/core/gorp/types.d.ts +20 -0
- package/dist/core/gorp/types.d.ts.map +1 -0
- package/dist/core/modules/assistant-stream.d.ts +18 -11
- package/dist/core/modules/assistant-stream.d.ts.map +1 -1
- package/dist/core/modules/assistant-stream.js +10 -6
- package/dist/core/modules/assistant-stream.js.map +1 -1
- package/dist/core/modules/text.d.ts +0 -1
- package/dist/core/modules/text.d.ts.map +1 -1
- package/dist/core/modules/tool-call.d.ts +0 -1
- package/dist/core/modules/tool-call.d.ts.map +1 -1
- package/dist/core/modules/tool-call.js +2 -2
- package/dist/core/modules/tool-call.js.map +1 -1
- package/dist/core/serialization/PlainText.d.ts +0 -1
- package/dist/core/serialization/PlainText.d.ts.map +1 -1
- package/dist/core/serialization/assistant-transport/AssistantTransport.d.ts +0 -1
- package/dist/core/serialization/assistant-transport/AssistantTransport.d.ts.map +1 -1
- package/dist/core/serialization/assistant-transport/AssistantTransport.js +93 -53
- package/dist/core/serialization/assistant-transport/AssistantTransport.js.map +1 -1
- package/dist/core/serialization/data-stream/DataStream.d.ts +0 -1
- package/dist/core/serialization/data-stream/DataStream.d.ts.map +1 -1
- package/dist/core/serialization/data-stream/chunk-types.d.ts +3 -4
- package/dist/core/serialization/data-stream/chunk-types.d.ts.map +1 -1
- package/dist/core/serialization/data-stream/chunk-types.js.map +1 -1
- package/dist/core/serialization/data-stream/serialization.d.ts +0 -1
- package/dist/core/serialization/data-stream/serialization.d.ts.map +1 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts +0 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.d.ts.map +1 -1
- package/dist/core/serialization/ui-message-stream/UIMessageStream.js +76 -53
- package/dist/core/serialization/ui-message-stream/UIMessageStream.js.map +1 -1
- package/dist/core/serialization/ui-message-stream/chunk-types.d.ts +0 -1
- package/dist/core/serialization/ui-message-stream/chunk-types.d.ts.map +1 -1
- package/dist/core/tool/ToolCallReader.d.ts +1 -0
- package/dist/core/tool/ToolCallReader.d.ts.map +1 -1
- package/dist/core/tool/ToolCallReader.js.map +1 -1
- package/dist/core/tool/ToolExecutionStream.d.ts +0 -1
- package/dist/core/tool/ToolExecutionStream.d.ts.map +1 -1
- package/dist/core/tool/ToolExecutionStream.js +9 -1
- package/dist/core/tool/ToolExecutionStream.js.map +1 -1
- package/dist/core/tool/ToolResponse.d.ts +6 -4
- package/dist/core/tool/ToolResponse.d.ts.map +1 -1
- package/dist/core/tool/schema-utils.d.ts +0 -1
- package/dist/core/tool/schema-utils.d.ts.map +1 -1
- package/dist/core/tool/tool-types.d.ts +71 -33
- package/dist/core/tool/tool-types.d.ts.map +1 -1
- package/dist/core/tool/toolResultStream.d.ts +3 -2
- package/dist/core/tool/toolResultStream.d.ts.map +1 -1
- package/dist/core/tool/toolResultStream.js +7 -2
- package/dist/core/tool/toolResultStream.js.map +1 -1
- package/dist/core/tool/type-path-utils.d.ts +2 -2
- package/dist/core/tool/type-path-utils.d.ts.map +1 -1
- package/dist/core/utils/Counter.d.ts.map +1 -1
- package/dist/core/utils/generateId.d.ts.map +1 -1
- package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts +0 -1
- package/dist/core/utils/stream/AssistantMetaTransformStream.d.ts.map +1 -1
- package/dist/core/utils/stream/AssistantTransformStream.d.ts +0 -1
- package/dist/core/utils/stream/AssistantTransformStream.d.ts.map +1 -1
- package/dist/core/utils/stream/LineDecoderStream.d.ts +1 -0
- package/dist/core/utils/stream/LineDecoderStream.d.ts.map +1 -1
- package/dist/core/utils/stream/LineDecoderStream.js +19 -6
- package/dist/core/utils/stream/LineDecoderStream.js.map +1 -1
- package/dist/core/utils/stream/PipeableTransformStream.d.ts.map +1 -1
- package/dist/core/utils/stream/SSE.d.ts +0 -1
- package/dist/core/utils/stream/SSE.d.ts.map +1 -1
- package/dist/core/utils/stream/SSE.js +2 -52
- package/dist/core/utils/stream/SSE.js.map +1 -1
- package/dist/core/utils/stream/SSEEventDecoder.d.ts +27 -0
- package/dist/core/utils/stream/SSEEventDecoder.d.ts.map +1 -0
- package/dist/core/utils/stream/SSEEventDecoder.js +84 -0
- package/dist/core/utils/stream/SSEEventDecoder.js.map +1 -0
- package/dist/core/utils/stream/SSEEventDecoderStream.d.ts +13 -0
- package/dist/core/utils/stream/SSEEventDecoderStream.d.ts.map +1 -0
- package/dist/core/utils/stream/SSEEventDecoderStream.js +24 -0
- package/dist/core/utils/stream/SSEEventDecoderStream.js.map +1 -0
- package/dist/core/utils/stream/UnderlyingReadable.d.ts.map +1 -1
- package/dist/core/utils/stream/merge.d.ts +2 -1
- package/dist/core/utils/stream/merge.d.ts.map +1 -1
- package/dist/core/utils/stream/merge.js +27 -8
- package/dist/core/utils/stream/merge.js.map +1 -1
- package/dist/core/utils/stream/path-utils.d.ts +0 -1
- package/dist/core/utils/stream/path-utils.d.ts.map +1 -1
- package/dist/core/utils/types.d.ts +16 -8
- package/dist/core/utils/types.d.ts.map +1 -1
- package/dist/core/utils/withPromiseOrValue.d.ts.map +1 -1
- package/dist/index.d.ts +25 -4
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -0
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts +3 -3
- package/dist/node_modules/.pnpm/@types_json-schema@7.0.15/node_modules/@types/json-schema/index.d.ts.map +1 -1
- package/dist/resumable/ResumableStreamContext.d.ts +0 -1
- package/dist/resumable/ResumableStreamContext.d.ts.map +1 -1
- package/dist/resumable/ResumableStreamContext.js +12 -5
- package/dist/resumable/ResumableStreamContext.js.map +1 -1
- package/dist/resumable/constants.d.ts.map +1 -1
- package/dist/resumable/createResumableAssistantStreamResponse.d.ts +6 -4
- package/dist/resumable/createResumableAssistantStreamResponse.d.ts.map +1 -1
- package/dist/resumable/errors.d.ts.map +1 -1
- package/dist/resumable/stores/InMemoryResumableStreamStore.d.ts +0 -1
- package/dist/resumable/stores/InMemoryResumableStreamStore.d.ts.map +1 -1
- package/dist/resumable/stores/InMemoryResumableStreamStore.js +2 -1
- package/dist/resumable/stores/InMemoryResumableStreamStore.js.map +1 -1
- package/dist/resumable/stores/ioredis.d.ts +0 -1
- package/dist/resumable/stores/ioredis.d.ts.map +1 -1
- package/dist/resumable/stores/redis-impl.d.ts +2 -2
- package/dist/resumable/stores/redis-impl.d.ts.map +1 -1
- package/dist/resumable/stores/redis.d.ts +0 -1
- package/dist/resumable/stores/redis.d.ts.map +1 -1
- package/dist/resumable/types.d.ts.map +1 -1
- package/dist/utils/AsyncIterableStream.d.ts.map +1 -1
- package/dist/utils/AsyncIterableStream.js +18 -3
- package/dist/utils/AsyncIterableStream.js.map +1 -1
- package/dist/utils/json/fix-json.d.ts.map +1 -1
- package/dist/utils/json/json-value.d.ts.map +1 -1
- package/dist/utils/json/parse-partial-json-object.d.ts +0 -1
- package/dist/utils/json/parse-partial-json-object.d.ts.map +1 -1
- package/dist/utils/promiseWithResolvers.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +2 -1
- package/package.json +5 -5
- package/src/core/AssistantStreamChunk.ts +5 -3
- package/src/core/accumulators/assistant-message-accumulator.test.ts +437 -1
- package/src/core/accumulators/assistant-message-accumulator.ts +89 -26
- package/src/core/{object/ObjectStream.test.ts → gorp/GorpStream.test.ts} +104 -23
- package/src/core/gorp/GorpStreamAccumulator.test.ts +28 -0
- package/src/core/{object/ObjectStreamAccumulator.ts → gorp/GorpStreamAccumulator.ts} +13 -15
- package/src/core/gorp/GorpStreamDeltaTracker.test.ts +182 -0
- package/src/core/gorp/GorpStreamDeltaTracker.ts +55 -0
- package/src/core/gorp/GorpStreamResponse.test.ts +32 -0
- package/src/core/gorp/GorpStreamResponse.ts +88 -0
- package/src/core/gorp/changeTree.test.ts +168 -0
- package/src/core/gorp/changeTree.ts +96 -0
- package/src/core/{object/createObjectStream.ts → gorp/createGorpStream.ts} +23 -17
- package/src/core/{object → gorp}/types.ts +5 -3
- package/src/core/modules/assistant-stream.test.ts +154 -2
- package/src/core/modules/assistant-stream.ts +16 -6
- package/src/core/modules/tool-call.test.ts +67 -0
- package/src/core/modules/tool-call.ts +3 -3
- package/src/core/serialization/assistant-transport/AssistantTransport.test.ts +215 -1
- package/src/core/serialization/assistant-transport/AssistantTransport.ts +83 -71
- package/src/core/serialization/data-stream/chunk-types.ts +2 -2
- package/src/core/serialization/ui-message-stream/UIMessageStream.test.ts +323 -4
- package/src/core/serialization/ui-message-stream/UIMessageStream.ts +81 -71
- package/src/core/tool/ToolExecutionStream.ts +10 -0
- package/src/core/tool/toolResultStream.test.ts +50 -0
- package/src/core/tool/toolResultStream.ts +7 -2
- package/src/core/utils/stream/LineDecoderStream.test.ts +26 -2
- package/src/core/utils/stream/LineDecoderStream.ts +21 -11
- package/src/core/utils/stream/SSE.ts +6 -70
- package/src/core/utils/stream/SSEEventDecoder.test.ts +146 -0
- package/src/core/utils/stream/SSEEventDecoder.ts +109 -0
- package/src/core/utils/stream/SSEEventDecoderStream.test.ts +42 -0
- package/src/core/utils/stream/SSEEventDecoderStream.ts +34 -0
- package/src/core/utils/stream/merge.ts +31 -9
- package/src/gorp.test.ts +42 -0
- package/src/index.ts +21 -6
- package/src/resumable/ResumableStreamContext.test.ts +116 -1
- package/src/resumable/ResumableStreamContext.ts +32 -5
- package/src/resumable/createResumableAssistantStreamResponse.test.ts +1 -25
- package/src/utils/AsyncIterableStream.test.ts +61 -0
- package/src/utils/AsyncIterableStream.ts +18 -3
- package/src/utils.ts +4 -0
- package/dist/core/object/ObjectStreamAccumulator.d.ts +0 -15
- package/dist/core/object/ObjectStreamAccumulator.d.ts.map +0 -1
- package/dist/core/object/ObjectStreamAccumulator.js.map +0 -1
- package/dist/core/object/ObjectStreamResponse.d.ts +0 -17
- package/dist/core/object/ObjectStreamResponse.d.ts.map +0 -1
- package/dist/core/object/ObjectStreamResponse.js +0 -57
- package/dist/core/object/ObjectStreamResponse.js.map +0 -1
- package/dist/core/object/createObjectStream.d.ts +0 -19
- package/dist/core/object/createObjectStream.d.ts.map +0 -1
- package/dist/core/object/createObjectStream.js.map +0 -1
- package/dist/core/object/types.d.ts +0 -18
- package/dist/core/object/types.d.ts.map +0 -1
- package/dist/utils/json/is-json.d.ts +0 -9
- package/dist/utils/json/is-json.d.ts.map +0 -1
- package/dist/utils/json/is-json.js +0 -17
- package/dist/utils/json/is-json.js.map +0 -1
- package/src/core/object/ObjectStreamResponse.ts +0 -109
- package/src/utils/json/is-json.ts +0 -43
- /package/dist/core/{object → gorp}/types.js +0 -0
package/README.md
CHANGED
|
@@ -30,7 +30,10 @@ export async function POST(request: Request) {
|
|
|
30
30
|
|
|
31
31
|
`createAssistantStreamResponse` returns a standard Web `Response`, so it works out of the box with any Fetch-style route (Next.js App Router, Hono, Bun.serve, Deno, Cloudflare Workers). Frameworks that use their own response objects (Express, Fastify) need a small adapter: copy `status` and `headers`, then pipe `response.body` into the framework's writable stream. Avoid sending the `Response` body into a `res` object whose lifecycle is already controlled by the framework (that is the `ERR_INVALID_STATE: Controller is already closed` failure mode).
|
|
32
32
|
|
|
33
|
-
`createAssistantStreamResponse` emits the data stream wire format
|
|
33
|
+
`createAssistantStreamResponse` emits the data stream wire format and sets the
|
|
34
|
+
`x-vercel-ai-data-stream: v1` response header. On the frontend,
|
|
35
|
+
`useDataStreamRuntime({ api })` detects that marker automatically; pass
|
|
36
|
+
`protocol: "data-stream"` only if a custom proxy strips or hides the header.
|
|
34
37
|
|
|
35
38
|
For tool execution, pipe through `ToolExecutionStream`; for resumable streams (clients can reconnect and replay), import from the `assistant-stream/resumable` sub-path with a `redis` or `ioredis` adapter.
|
|
36
39
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantStream.d.ts","names":[],"sources":["../../src/core/AssistantStream.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"AssistantStream.d.ts","names":[],"sources":["../../src/core/AssistantStream.ts"],"mappings":";;;;;;;;;;KAUY,kBAAkB,eAAe;;;;;;;;KASjC,yBAAyB,qBACnC,WAAW,cACX;EAEA,UAAU;;cAGC;;;;;;;;EAQQ,WAAA,QAAA,iBAAe,aAAe,yBAAsB;;;;;;;;EAc3D,aAAA,UAAA,UAAQ,aACL,qBACX,sBACA,WAAW,gBACZ,eAAA;;;;;EAUO,aAAA,QAAA,iBAAe,aACV,qBACX,WAAW,cACX,wBACD,eAAA,WAAA;;;;;EAUS,eAAA,UAAA,eAAe,WAAW,eAAa,aACpC,qBACX,sBACA,WAAW,gBACZ,eAAA"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ReadonlyJSONValue } from "../utils/json/json-value.js";
|
|
2
2
|
import { ToolModelContentPart } from "./tool/tool-types.js";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { AssistantTransportStateOperation } from "./gorp/types.js";
|
|
5
4
|
//#region src/core/AssistantStreamChunk.d.ts
|
|
6
5
|
/**
|
|
7
6
|
* Initial metadata for a stream part.
|
|
@@ -45,26 +44,34 @@ type PartInit = {
|
|
|
45
44
|
type AssistantStreamChunk = {
|
|
46
45
|
readonly path: readonly number[];
|
|
47
46
|
} & ({
|
|
48
|
-
/** Opens a new content part at `path`. */
|
|
47
|
+
/** Opens a new content part at `path`. */
|
|
48
|
+
readonly type: "part-start";
|
|
49
49
|
readonly part: PartInit;
|
|
50
50
|
} | {
|
|
51
|
-
/** Closes the current part at `path`. */
|
|
51
|
+
/** Closes the current part at `path`. */
|
|
52
|
+
readonly type: "part-finish";
|
|
52
53
|
} | {
|
|
53
|
-
/** Marks streamed tool-call argument text as complete. */
|
|
54
|
+
/** Marks streamed tool-call argument text as complete. */
|
|
55
|
+
readonly type: "tool-call-args-text-finish";
|
|
54
56
|
} | {
|
|
55
|
-
/** Appends text to a text, reasoning, or tool-call argument part. */
|
|
57
|
+
/** Appends text to a text, reasoning, or tool-call argument part. */
|
|
58
|
+
readonly type: "text-delta";
|
|
56
59
|
readonly textDelta: string;
|
|
57
60
|
} | {
|
|
58
|
-
/** Appends provider or application annotations to the current message. */
|
|
61
|
+
/** Appends provider or application annotations to the current message. */
|
|
62
|
+
readonly type: "annotations";
|
|
59
63
|
readonly annotations: ReadonlyJSONValue[];
|
|
60
64
|
} | {
|
|
61
|
-
/** Emits application data chunks associated with the current message. */
|
|
65
|
+
/** Emits application data chunks associated with the current message. */
|
|
66
|
+
readonly type: "data";
|
|
62
67
|
readonly data: ReadonlyJSONValue[];
|
|
63
68
|
} | {
|
|
64
|
-
/** Starts a model generation step. */
|
|
69
|
+
/** Starts a model generation step. */
|
|
70
|
+
readonly type: "step-start";
|
|
65
71
|
readonly messageId: string;
|
|
66
72
|
} | {
|
|
67
|
-
/** Finishes a model generation step and reports usage for that step. */
|
|
73
|
+
/** Finishes a model generation step and reports usage for that step. */
|
|
74
|
+
readonly type: "step-finish";
|
|
68
75
|
readonly finishReason: "stop" | "length" | "content-filter" | "tool-calls" | "error" | "other" | "unknown";
|
|
69
76
|
readonly usage: {
|
|
70
77
|
readonly inputTokens: number;
|
|
@@ -72,7 +79,8 @@ type AssistantStreamChunk = {
|
|
|
72
79
|
};
|
|
73
80
|
readonly isContinued: boolean;
|
|
74
81
|
} | {
|
|
75
|
-
/** Finishes the assistant message and reports final usage. */
|
|
82
|
+
/** Finishes the assistant message and reports final usage. */
|
|
83
|
+
readonly type: "message-finish";
|
|
76
84
|
readonly finishReason: "stop" | "length" | "content-filter" | "tool-calls" | "error" | "other" | "unknown";
|
|
77
85
|
readonly usage: {
|
|
78
86
|
readonly inputTokens: number;
|
|
@@ -92,11 +100,15 @@ type AssistantStreamChunk = {
|
|
|
92
100
|
readonly modelContent?: readonly ToolModelContentPart[];
|
|
93
101
|
readonly messages?: ReadonlyJSONValue;
|
|
94
102
|
} | {
|
|
95
|
-
/** Emits a stream-level error message. */
|
|
103
|
+
/** Emits a stream-level error message. */
|
|
104
|
+
readonly type: "error";
|
|
96
105
|
readonly error: string;
|
|
106
|
+
readonly code?: string;
|
|
107
|
+
readonly severity?: "critical" | "warning" | "info";
|
|
97
108
|
} | {
|
|
98
|
-
/** Applies
|
|
99
|
-
readonly
|
|
109
|
+
/** Applies gorp-stream operations to state carried by this stream. */
|
|
110
|
+
readonly type: "update-state";
|
|
111
|
+
readonly operations: AssistantTransportStateOperation[];
|
|
100
112
|
});
|
|
101
113
|
//#endregion
|
|
102
114
|
export { AssistantStreamChunk, PartInit };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantStreamChunk.d.ts","names":[],"sources":["../../src/core/AssistantStreamChunk.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"AssistantStreamChunk.d.ts","names":[],"sources":["../../src/core/AssistantStreamChunk.ts"],"mappings":";;;;;;;;;;KAUY;WAEG;WACA;;WAGA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA;WACA;WACA;;WAGA;WACA;WACA;WACA;;WAGA;WACA;WACA,MAAM;WACN;;;;;;;;;KAUH;WAAkC;;;WAG/B;WACA,MAAM;;;WAIN;;;WAIA;;;WAIA;WACA;;;WAIA;WACA,aAAa;;;WAIb;WACA,MAAM;;;WAIN;WACA;;;WAIA;WACA;WAQA;aACE;aACA;;WAEF;;;WAIA;WACA;WAQA;aACE;aACA;;;;;;;;;WAUF;WACA,WAAW;WACX,QAAQ;WACR;WACA,wBAAwB;WACxB,WAAW;;;WAIX;WACA;WACA;WACA;;;WAIA;WACA,YAAY"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { AssistantMessage } from "../utils/types.js";
|
|
2
2
|
import { AssistantStream } from "../AssistantStream.js";
|
|
3
|
-
|
|
4
3
|
//#region src/core/accumulators/AssistantMessageStream.d.ts
|
|
5
4
|
declare class AssistantMessageStream {
|
|
6
5
|
readonly readable: ReadableStream<AssistantMessage>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssistantMessageStream.d.ts","names":[],"sources":["../../../src/core/accumulators/AssistantMessageStream.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"AssistantMessageStream.d.ts","names":[],"sources":["../../../src/core/accumulators/AssistantMessageStream.ts"],"mappings":";;;cAIa;WACiB,UAAU,eAAe;EAAzB,YAAA,UAAU,eAAe;SAI9C,oBAAoB,QAAQ,kBAAe;EAM5C,mBAAmB,QAAQ;GAwBhC,OAAO;IAGU,QAAA,QAAQ,eAAe;;EAOzC,QAAQ,wBAAwB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TimingTracker.d.ts","names":[],"sources":["../../../src/core/accumulators/TimingTracker.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"TimingTracker.d.ts","names":[],"sources":["../../../src/core/accumulators/TimingTracker.ts"],"mappings":";;cAEa;UACH;UACA;UACA;UACA;;EAMR;EAIA;EAMA,oBAAoB;EAIpB,UAAU,uBAAuB,qBAAqB"}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { ReadonlyJSONValue } from "../../utils/json/json-value.js";
|
|
2
2
|
import { AssistantMessage } from "../utils/types.js";
|
|
3
|
+
import "../../utils.js";
|
|
3
4
|
import { AssistantStreamChunk } from "../AssistantStreamChunk.js";
|
|
4
|
-
|
|
5
5
|
//#region src/core/accumulators/assistant-message-accumulator.d.ts
|
|
6
|
-
declare const createInitialMessage: ({
|
|
7
|
-
unstable_state
|
|
8
|
-
}?: {
|
|
6
|
+
declare const createInitialMessage: ({ unstable_state }?: {
|
|
9
7
|
unstable_state?: ReadonlyJSONValue;
|
|
10
8
|
}) => AssistantMessage;
|
|
11
9
|
declare class AssistantMessageAccumulator extends TransformStream<AssistantStreamChunk, AssistantMessage> {
|
|
12
|
-
constructor({
|
|
13
|
-
initialMessage,
|
|
14
|
-
throttle,
|
|
15
|
-
onError
|
|
16
|
-
}?: {
|
|
10
|
+
constructor({ initialMessage, throttle, onError }?: {
|
|
17
11
|
initialMessage?: AssistantMessage;
|
|
18
12
|
throttle?: boolean;
|
|
19
13
|
onError?: (error: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-message-accumulator.d.ts","names":[],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"mappings":";;;;;cAmBa,
|
|
1
|
+
{"version":3,"file":"assistant-message-accumulator.d.ts","names":[],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"mappings":";;;;;cAmBa,yBAAwB;EAGnC,iBAAiB;MACV;cAwcI,oCAAoC,gBAC/C,sBACA;EAEY,cACV,gBACA,UACA;IAEA,iBAAiB;IACjB;IACA,WAAW"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { generateId } from "../utils/generateId.js";
|
|
2
2
|
import { parsePartialJsonObject } from "../../utils/json/parse-partial-json-object.js";
|
|
3
|
-
import {
|
|
3
|
+
import { GorpStreamAccumulator } from "../gorp/GorpStreamAccumulator.js";
|
|
4
4
|
import { TimingTracker } from "./TimingTracker.js";
|
|
5
5
|
//#region src/core/accumulators/assistant-message-accumulator.ts
|
|
6
6
|
const createInitialMessage = ({ unstable_state = null } = {}) => ({
|
|
@@ -18,11 +18,16 @@ const createInitialMessage = ({ unstable_state = null } = {}) => ({
|
|
|
18
18
|
custom: {}
|
|
19
19
|
}
|
|
20
20
|
});
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
const MAX_WARNED_KEYS = 16;
|
|
22
|
+
const updatePartForPath = (message, chunk, warnOnce, updater) => {
|
|
23
|
+
const part = chunk.path.length === 1 ? message.parts[chunk.path[0]] : void 0;
|
|
24
|
+
if (part === void 0) {
|
|
25
|
+
warnOnce(`no-part:${chunk.type}`, `Dropped ${chunk.type} chunk: no part at path [${chunk.path.join(", ")}]`);
|
|
26
|
+
return message;
|
|
27
|
+
}
|
|
24
28
|
const partIndex = chunk.path[0];
|
|
25
|
-
const updatedPart = updater(
|
|
29
|
+
const updatedPart = updater(part);
|
|
30
|
+
if (updatedPart === part) return message;
|
|
26
31
|
return {
|
|
27
32
|
...message,
|
|
28
33
|
parts: [
|
|
@@ -35,7 +40,7 @@ const updatePartForPath = (message, chunk, updater) => {
|
|
|
35
40
|
}
|
|
36
41
|
};
|
|
37
42
|
};
|
|
38
|
-
const handlePartStart = (message, chunk) => {
|
|
43
|
+
const handlePartStart = (message, chunk, warnOnce) => {
|
|
39
44
|
const partInit = chunk.part;
|
|
40
45
|
if (partInit.type === "text" || partInit.type === "reasoning") {
|
|
41
46
|
const newTextPart = {
|
|
@@ -117,20 +122,38 @@ const handlePartStart = (message, chunk) => {
|
|
|
117
122
|
return this.parts;
|
|
118
123
|
}
|
|
119
124
|
};
|
|
120
|
-
} else
|
|
125
|
+
} else {
|
|
126
|
+
const unsupportedType = String(partInit.type);
|
|
127
|
+
warnOnce(`unsupported-part-start:${unsupportedType}`, `Unsupported part-start type ${unsupportedType}: inserting an empty reasoning part to preserve part indices`);
|
|
128
|
+
const placeholderPart = {
|
|
129
|
+
type: "reasoning",
|
|
130
|
+
text: "",
|
|
131
|
+
status: { type: "running" }
|
|
132
|
+
};
|
|
133
|
+
return {
|
|
134
|
+
...message,
|
|
135
|
+
parts: [...message.parts, placeholderPart],
|
|
136
|
+
get content() {
|
|
137
|
+
return this.parts;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
121
141
|
};
|
|
122
|
-
const handleToolCallArgsTextFinish = (message, chunk) => {
|
|
123
|
-
return updatePartForPath(message, chunk, (part) => {
|
|
124
|
-
if (part.type !== "tool-call")
|
|
125
|
-
|
|
142
|
+
const handleToolCallArgsTextFinish = (message, chunk, warnOnce) => {
|
|
143
|
+
return updatePartForPath(message, chunk, warnOnce, (part) => {
|
|
144
|
+
if (part.type !== "tool-call") {
|
|
145
|
+
warnOnce("wrong-part:tool-call-args-text-finish", "Dropped tool-call-args-text-finish chunk: part is not a tool-call");
|
|
146
|
+
return part;
|
|
147
|
+
}
|
|
148
|
+
if (part.state !== "partial-call") return { ...part };
|
|
126
149
|
return {
|
|
127
150
|
...part,
|
|
128
151
|
state: "call"
|
|
129
152
|
};
|
|
130
153
|
});
|
|
131
154
|
};
|
|
132
|
-
const handlePartFinish = (message, chunk) => {
|
|
133
|
-
return updatePartForPath(message, chunk, (part) => ({
|
|
155
|
+
const handlePartFinish = (message, chunk, warnOnce) => {
|
|
156
|
+
return updatePartForPath(message, chunk, warnOnce, (part) => ({
|
|
134
157
|
...part,
|
|
135
158
|
status: {
|
|
136
159
|
type: "complete",
|
|
@@ -138,8 +161,8 @@ const handlePartFinish = (message, chunk) => {
|
|
|
138
161
|
}
|
|
139
162
|
}));
|
|
140
163
|
};
|
|
141
|
-
const handleTextDelta = (message, chunk) => {
|
|
142
|
-
return updatePartForPath(message, chunk, (part) => {
|
|
164
|
+
const handleTextDelta = (message, chunk, warnOnce) => {
|
|
165
|
+
return updatePartForPath(message, chunk, warnOnce, (part) => {
|
|
143
166
|
if (part.type === "text" || part.type === "reasoning") return {
|
|
144
167
|
...part,
|
|
145
168
|
text: part.text + chunk.textDelta
|
|
@@ -152,11 +175,14 @@ const handleTextDelta = (message, chunk) => {
|
|
|
152
175
|
argsText: newArgsText,
|
|
153
176
|
args: newArgs
|
|
154
177
|
};
|
|
155
|
-
} else
|
|
178
|
+
} else {
|
|
179
|
+
warnOnce("wrong-part:text-delta", "Dropped text-delta chunk: part is neither text nor tool-call");
|
|
180
|
+
return part;
|
|
181
|
+
}
|
|
156
182
|
});
|
|
157
183
|
};
|
|
158
|
-
const handleResult = (message, chunk) => {
|
|
159
|
-
return updatePartForPath(message, chunk, (part) => {
|
|
184
|
+
const handleResult = (message, chunk, warnOnce) => {
|
|
185
|
+
return updatePartForPath(message, chunk, warnOnce, (part) => {
|
|
160
186
|
if (part.type === "tool-call") return {
|
|
161
187
|
...part,
|
|
162
188
|
state: "result",
|
|
@@ -174,7 +200,10 @@ const handleResult = (message, chunk) => {
|
|
|
174
200
|
reason: "stop"
|
|
175
201
|
}
|
|
176
202
|
};
|
|
177
|
-
else
|
|
203
|
+
else {
|
|
204
|
+
warnOnce("wrong-part:result", "Dropped result chunk: part is not a tool-call");
|
|
205
|
+
return part;
|
|
206
|
+
}
|
|
178
207
|
});
|
|
179
208
|
};
|
|
180
209
|
const handleMessageFinish = (message, chunk) => {
|
|
@@ -255,17 +284,22 @@ const handleStepFinish = (message, chunk) => {
|
|
|
255
284
|
};
|
|
256
285
|
};
|
|
257
286
|
const handleErrorChunk = (message, chunk) => {
|
|
287
|
+
const severity = chunk.severity === "critical" || chunk.severity === "warning" || chunk.severity === "info" ? chunk.severity : void 0;
|
|
258
288
|
return {
|
|
259
289
|
...message,
|
|
260
290
|
status: {
|
|
261
291
|
type: "incomplete",
|
|
262
292
|
reason: "error",
|
|
263
|
-
error:
|
|
293
|
+
error: {
|
|
294
|
+
code: chunk.code ?? "unknown",
|
|
295
|
+
message: chunk.error ?? "unknown error",
|
|
296
|
+
...severity !== void 0 && { severity }
|
|
297
|
+
}
|
|
264
298
|
}
|
|
265
299
|
};
|
|
266
300
|
};
|
|
267
301
|
const handleUpdateState = (message, chunk) => {
|
|
268
|
-
const acc = new
|
|
302
|
+
const acc = new GorpStreamAccumulator(message.metadata.unstable_state);
|
|
269
303
|
acc.append(chunk.operations);
|
|
270
304
|
return {
|
|
271
305
|
...message,
|
|
@@ -297,6 +331,12 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
297
331
|
constructor({ initialMessage, throttle, onError } = {}) {
|
|
298
332
|
let message = initialMessage ?? createInitialMessage();
|
|
299
333
|
const tracker = new TimingTracker();
|
|
334
|
+
const warnedKeys = /* @__PURE__ */ new Set();
|
|
335
|
+
const warnOnce = (key, warning) => {
|
|
336
|
+
if (warnedKeys.has(key) || warnedKeys.size >= MAX_WARNED_KEYS) return;
|
|
337
|
+
warnedKeys.add(key);
|
|
338
|
+
console.warn(warning);
|
|
339
|
+
};
|
|
300
340
|
let controller;
|
|
301
341
|
const emitChunk = throttle ? throttleCallback(() => {
|
|
302
342
|
controller?.enqueue(message);
|
|
@@ -312,21 +352,23 @@ var AssistantMessageAccumulator = class extends TransformStream {
|
|
|
312
352
|
const type = chunk.type;
|
|
313
353
|
switch (type) {
|
|
314
354
|
case "part-start":
|
|
315
|
-
message = handlePartStart(message, chunk);
|
|
355
|
+
message = handlePartStart(message, chunk, warnOnce);
|
|
316
356
|
if (chunk.part.type === "tool-call") tracker.recordToolCallStart(chunk.part.toolCallId);
|
|
317
357
|
break;
|
|
318
358
|
case "tool-call-args-text-finish":
|
|
319
|
-
message = handleToolCallArgsTextFinish(message, chunk);
|
|
359
|
+
message = handleToolCallArgsTextFinish(message, chunk, warnOnce);
|
|
320
360
|
break;
|
|
321
361
|
case "part-finish":
|
|
322
|
-
message = handlePartFinish(message, chunk);
|
|
362
|
+
message = handlePartFinish(message, chunk, warnOnce);
|
|
323
363
|
break;
|
|
324
|
-
case "text-delta":
|
|
325
|
-
|
|
326
|
-
tracker.recordFirstToken();
|
|
364
|
+
case "text-delta": {
|
|
365
|
+
const next = handleTextDelta(message, chunk, warnOnce);
|
|
366
|
+
if (next !== message) tracker.recordFirstToken();
|
|
367
|
+
message = next;
|
|
327
368
|
break;
|
|
369
|
+
}
|
|
328
370
|
case "result":
|
|
329
|
-
message = handleResult(message, chunk);
|
|
371
|
+
message = handleResult(message, chunk, warnOnce);
|
|
330
372
|
break;
|
|
331
373
|
case "message-finish":
|
|
332
374
|
message = handleMessageFinish(message, chunk);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assistant-message-accumulator.js","names":["unhandledType"],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import type { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport type {\n AssistantMessage,\n AssistantMessageStatus,\n AssistantMessageTiming,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n DataPart,\n} from \"../utils/types\";\nimport { ObjectStreamAccumulator } from \"../object/ObjectStreamAccumulator\";\nimport type { ReadonlyJSONValue } from \"../../utils\";\nimport { TimingTracker } from \"./TimingTracker\";\n\nexport const createInitialMessage = ({\n unstable_state = null,\n}: {\n unstable_state?: ReadonlyJSONValue;\n} = {}): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state,\n unstable_data: [],\n unstable_annotations: [],\n steps: [],\n custom: {},\n },\n});\n\nconst updatePartForPath = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk,\n updater: (part: AssistantMessagePart) => AssistantMessagePart,\n): AssistantMessage => {\n if (message.parts.length === 0) {\n throw new Error(\"No parts available to update.\");\n }\n\n if (chunk.path.length !== 1)\n throw new Error(\"Nested paths are not supported yet.\");\n\n const partIndex = chunk.path[0]!;\n const updatedPart = updater(message.parts[partIndex]!);\n return {\n ...message,\n parts: [\n ...message.parts.slice(0, partIndex),\n updatedPart,\n ...message.parts.slice(partIndex + 1),\n ],\n get content() {\n return this.parts;\n },\n };\n};\n\nconst handlePartStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-start\" },\n): AssistantMessage => {\n const partInit = chunk.part;\n if (partInit.type === \"text\" || partInit.type === \"reasoning\") {\n const newTextPart: TextPart | ReasoningPart = {\n type: partInit.type,\n text: \"\",\n status: { type: \"running\" },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newTextPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"tool-call\") {\n const newToolCallPart: ToolCallPart = {\n type: \"tool-call\",\n state: \"partial-call\",\n status: { type: \"running\", isArgsComplete: false },\n toolCallId: partInit.toolCallId,\n toolName: partInit.toolName,\n argsText: \"\",\n args: {},\n timing: { startedAt: Date.now() },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newToolCallPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"source\") {\n const newSourcePart: SourcePart = {\n type: \"source\",\n sourceType: partInit.sourceType,\n id: partInit.id,\n url: partInit.url,\n ...(partInit.title ? { title: partInit.title } : undefined),\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newSourcePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"file\") {\n const newFilePart: FilePart = {\n type: \"file\",\n mimeType: partInit.mimeType,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"data\") {\n const newDataPart: DataPart = {\n type: \"data\",\n name: partInit.name,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newDataPart],\n get content() {\n return this.parts;\n },\n };\n } else {\n throw new Error(`Unsupported part type: ${partInit.type}`);\n }\n};\n\nconst handleToolCallArgsTextFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & {\n readonly type: \"tool-call-args-text-finish\";\n },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type !== \"tool-call\") {\n throw new Error(\"Last is not a tool call\");\n }\n\n // TODO this should never be hit; this happens if args-text-finish is emitted after result\n if (part.state !== \"partial-call\") return part;\n // throw new Error(\"Last is not a partial call\");\n\n return {\n ...part,\n state: \"call\",\n };\n });\n};\n\nconst handlePartFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-finish\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => ({\n ...part,\n status: { type: \"complete\", reason: \"unknown\" },\n }));\n};\n\nconst handleTextDelta = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"text-delta\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n return { ...part, text: part.text + chunk.textDelta };\n } else if (part.type === \"tool-call\") {\n const newArgsText = part.argsText + chunk.textDelta;\n\n // Fall back to existing args if parsing fails\n const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;\n\n return { ...part, argsText: newArgsText, args: newArgs };\n } else {\n throw new Error(\n \"text-delta received but part is neither text nor tool-call\",\n );\n }\n });\n};\n\nconst handleResult = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"result\" },\n): AssistantMessage => {\n return updatePartForPath(message, chunk, (part) => {\n if (part.type === \"tool-call\") {\n return {\n ...part,\n state: \"result\",\n ...(part.timing !== undefined\n ? {\n timing: {\n ...part.timing,\n completedAt: part.timing.completedAt ?? Date.now(),\n },\n }\n : {}),\n ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),\n result: chunk.result,\n isError: chunk.isError ?? false,\n ...(chunk.modelContent !== undefined\n ? { modelContent: chunk.modelContent }\n : {}),\n ...(chunk.messages !== undefined ? { messages: chunk.messages } : {}),\n status: { type: \"complete\", reason: \"stop\" },\n };\n } else {\n throw new Error(\"Result chunk received but part is not a tool-call\");\n }\n });\n};\n\nconst handleMessageFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"message-finish\" },\n): AssistantMessage => {\n // avoid edge case where providers send finish chunks that overwrite message error status (issue #2181)\n if (\n message.status?.type === \"incomplete\" &&\n message.status?.reason === \"error\"\n ) {\n return message;\n }\n\n const newStatus = getStatus(chunk);\n return { ...message, status: newStatus };\n};\n\nconst getStatus = (\n chunk:\n | (AssistantStreamChunk & { type: \"message-finish\" })\n | (AssistantStreamChunk & { type: \"step-finish\" }),\n): AssistantMessageStatus => {\n if (chunk.finishReason === \"tool-calls\") {\n return {\n type: \"requires-action\",\n reason: \"tool-calls\",\n };\n } else if (\n chunk.finishReason === \"stop\" ||\n chunk.finishReason === \"unknown\"\n ) {\n return {\n type: \"complete\",\n reason: chunk.finishReason,\n };\n } else {\n return {\n type: \"incomplete\",\n reason: chunk.finishReason,\n };\n }\n};\n\nconst handleAnnotations = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"annotations\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_annotations: [\n ...message.metadata.unstable_annotations,\n ...chunk.annotations,\n ],\n },\n };\n};\n\nconst handleData = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"data\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_data: [...message.metadata.unstable_data, ...chunk.data],\n },\n };\n};\n\nconst handleStepStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-start\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps: [\n ...message.metadata.steps,\n { state: \"started\", messageId: chunk.messageId },\n ],\n },\n };\n};\n\nconst handleStepFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-finish\" },\n): AssistantMessage => {\n const steps = message.metadata.steps.slice();\n const lastIndex = steps.length - 1;\n\n // Check if the previous step is a step-start (has state \"started\")\n if (steps.length > 0 && steps[lastIndex]?.state === \"started\") {\n steps[lastIndex] = {\n ...steps[lastIndex],\n state: \"finished\",\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n };\n } else {\n // If no previous step-start exists, append a finished step\n steps.push({\n state: \"finished\",\n messageId: generateId(),\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n });\n }\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps,\n },\n };\n};\n\nconst handleErrorChunk = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"error\" },\n): AssistantMessage => {\n return {\n ...message,\n status: { type: \"incomplete\", reason: \"error\", error: chunk.error },\n };\n};\n\nconst handleUpdateState = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"update-state\" },\n): AssistantMessage => {\n const acc = new ObjectStreamAccumulator(message.metadata.unstable_state);\n acc.append(chunk.operations);\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_state: acc.state,\n },\n };\n};\n\nconst computeTiming = (\n tracker: TimingTracker,\n message: AssistantMessage,\n): AssistantMessageTiming => {\n let outputTokens = 0;\n for (const step of message.metadata.steps) {\n if (step.state === \"finished\" && step.usage) {\n outputTokens += step.usage.outputTokens;\n }\n }\n\n let totalText = \"\";\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n totalText += part.text;\n }\n }\n\n return tracker.getTiming(\n outputTokens > 0 ? outputTokens : undefined,\n totalText || undefined,\n );\n};\n\nconst throttleCallback = (callback: () => void) => {\n let hasScheduled = false;\n return () => {\n if (hasScheduled) return;\n hasScheduled = true;\n queueMicrotask(() => {\n hasScheduled = false;\n callback();\n });\n };\n};\n\nexport class AssistantMessageAccumulator extends TransformStream<\n AssistantStreamChunk,\n AssistantMessage\n> {\n constructor({\n initialMessage,\n throttle,\n onError,\n }: {\n initialMessage?: AssistantMessage;\n throttle?: boolean;\n onError?: (error: string) => void;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n const tracker = new TimingTracker();\n let controller:\n | TransformStreamDefaultController<AssistantMessage>\n | undefined;\n const emitChunk = throttle\n ? throttleCallback(() => {\n controller?.enqueue(message);\n })\n : () => {\n controller?.enqueue(message);\n };\n super({\n start(c) {\n controller = c;\n },\n transform(chunk) {\n tracker.recordChunk();\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk);\n if (chunk.part.type === \"tool-call\") {\n tracker.recordToolCallStart(chunk.part.toolCallId);\n }\n break;\n\n case \"tool-call-args-text-finish\":\n message = handleToolCallArgsTextFinish(message, chunk);\n break;\n\n case \"part-finish\":\n message = handlePartFinish(message, chunk);\n break;\n\n case \"text-delta\":\n message = handleTextDelta(message, chunk);\n tracker.recordFirstToken();\n break;\n case \"result\":\n message = handleResult(message, chunk);\n break;\n case \"message-finish\":\n message = handleMessageFinish(message, chunk);\n break;\n case \"annotations\":\n message = handleAnnotations(message, chunk);\n break;\n case \"data\":\n message = handleData(message, chunk);\n break;\n case \"step-start\":\n message = handleStepStart(message, chunk);\n break;\n case \"step-finish\":\n message = handleStepFinish(message, chunk);\n break;\n case \"error\":\n message = handleErrorChunk(message, chunk);\n onError?.(chunk.error);\n break;\n case \"update-state\":\n message = handleUpdateState(message, chunk);\n break;\n default: {\n const unhandledType: never = type;\n throw new Error(`Unsupported chunk type: ${unhandledType}`);\n }\n }\n\n if (message.status.type !== \"running\") {\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n }\n\n emitChunk();\n },\n flush(controller) {\n if (message.status?.type === \"running\") {\n // Check if there are any tool calls that require action\n const requiresAction =\n message.parts?.some(\n (part) =>\n part.type === \"tool-call\" &&\n (part.state === \"call\" || part.state === \"partial-call\") &&\n part.result === undefined,\n ) ?? false;\n message = handleMessageFinish(message, {\n type: \"message-finish\",\n path: [],\n finishReason: requiresAction ? \"tool-calls\" : \"unknown\",\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n });\n\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"assistant-message-accumulator.js","names":["unhandledType"],"sources":["../../../src/core/accumulators/assistant-message-accumulator.ts"],"sourcesContent":["import type { AssistantStreamChunk } from \"../AssistantStreamChunk\";\nimport { generateId } from \"../utils/generateId\";\nimport { parsePartialJsonObject } from \"../../utils/json/parse-partial-json-object\";\nimport type {\n AssistantMessage,\n AssistantMessageStatus,\n AssistantMessageTiming,\n TextPart,\n ToolCallPart,\n SourcePart,\n AssistantMessagePart,\n ReasoningPart,\n FilePart,\n DataPart,\n} from \"../utils/types\";\nimport { GorpStreamAccumulator } from \"../gorp/GorpStreamAccumulator\";\nimport type { ReadonlyJSONValue } from \"../../utils\";\nimport { TimingTracker } from \"./TimingTracker\";\n\nexport const createInitialMessage = ({\n unstable_state = null,\n}: {\n unstable_state?: ReadonlyJSONValue;\n} = {}): AssistantMessage => ({\n role: \"assistant\",\n status: { type: \"running\" },\n parts: [],\n get content() {\n return this.parts;\n },\n metadata: {\n unstable_state,\n unstable_data: [],\n unstable_annotations: [],\n steps: [],\n custom: {},\n },\n});\n\ntype WarnOnce = (key: string, message: string) => void;\n\nconst MAX_WARNED_KEYS = 16;\n\nconst updatePartForPath = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk,\n warnOnce: WarnOnce,\n updater: (part: AssistantMessagePart) => AssistantMessagePart,\n): AssistantMessage => {\n const part =\n chunk.path.length === 1 ? message.parts[chunk.path[0]!] : undefined;\n if (part === undefined) {\n warnOnce(\n `no-part:${chunk.type}`,\n `Dropped ${chunk.type} chunk: no part at path [${chunk.path.join(\", \")}]`,\n );\n return message;\n }\n\n const partIndex = chunk.path[0]!;\n const updatedPart = updater(part);\n if (updatedPart === part) return message;\n return {\n ...message,\n parts: [\n ...message.parts.slice(0, partIndex),\n updatedPart,\n ...message.parts.slice(partIndex + 1),\n ],\n get content() {\n return this.parts;\n },\n };\n};\n\nconst handlePartStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-start\" },\n warnOnce: WarnOnce,\n): AssistantMessage => {\n const partInit = chunk.part;\n if (partInit.type === \"text\" || partInit.type === \"reasoning\") {\n const newTextPart: TextPart | ReasoningPart = {\n type: partInit.type,\n text: \"\",\n status: { type: \"running\" },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newTextPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"tool-call\") {\n const newToolCallPart: ToolCallPart = {\n type: \"tool-call\",\n state: \"partial-call\",\n status: { type: \"running\", isArgsComplete: false },\n toolCallId: partInit.toolCallId,\n toolName: partInit.toolName,\n argsText: \"\",\n args: {},\n timing: { startedAt: Date.now() },\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newToolCallPart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"source\") {\n const newSourcePart: SourcePart = {\n type: \"source\",\n sourceType: partInit.sourceType,\n id: partInit.id,\n url: partInit.url,\n ...(partInit.title ? { title: partInit.title } : undefined),\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newSourcePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"file\") {\n const newFilePart: FilePart = {\n type: \"file\",\n mimeType: partInit.mimeType,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newFilePart],\n get content() {\n return this.parts;\n },\n };\n } else if (partInit.type === \"data\") {\n const newDataPart: DataPart = {\n type: \"data\",\n name: partInit.name,\n data: partInit.data,\n ...(partInit.parentId && { parentId: partInit.parentId }),\n };\n return {\n ...message,\n parts: [...message.parts, newDataPart],\n get content() {\n return this.parts;\n },\n };\n } else {\n const unsupportedType = String((partInit as { type?: unknown }).type);\n warnOnce(\n `unsupported-part-start:${unsupportedType}`,\n `Unsupported part-start type ${unsupportedType}: inserting an empty reasoning part to preserve part indices`,\n );\n // reasoning rather than a data sentinel: auiV0Encode rejects data parts, so a data placeholder would fail cloud persistence\n const placeholderPart: ReasoningPart = {\n type: \"reasoning\",\n text: \"\",\n status: { type: \"running\" },\n };\n return {\n ...message,\n parts: [...message.parts, placeholderPart],\n get content() {\n return this.parts;\n },\n };\n }\n};\n\nconst handleToolCallArgsTextFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & {\n readonly type: \"tool-call-args-text-finish\";\n },\n warnOnce: WarnOnce,\n): AssistantMessage => {\n return updatePartForPath(message, chunk, warnOnce, (part) => {\n if (part.type !== \"tool-call\") {\n warnOnce(\n \"wrong-part:tool-call-args-text-finish\",\n \"Dropped tool-call-args-text-finish chunk: part is not a tool-call\",\n );\n return part;\n }\n\n // TODO this should never be hit; this happens if args-text-finish is emitted after result\n if (part.state !== \"partial-call\") return { ...part };\n // throw new Error(\"Last is not a partial call\");\n\n return {\n ...part,\n state: \"call\",\n };\n });\n};\n\nconst handlePartFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { readonly type: \"part-finish\" },\n warnOnce: WarnOnce,\n): AssistantMessage => {\n return updatePartForPath(message, chunk, warnOnce, (part) => ({\n ...part,\n status: { type: \"complete\", reason: \"unknown\" },\n }));\n};\n\nconst handleTextDelta = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"text-delta\" },\n warnOnce: WarnOnce,\n): AssistantMessage => {\n return updatePartForPath(message, chunk, warnOnce, (part) => {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n return { ...part, text: part.text + chunk.textDelta };\n } else if (part.type === \"tool-call\") {\n const newArgsText = part.argsText + chunk.textDelta;\n\n // Fall back to existing args if parsing fails\n const newArgs = parsePartialJsonObject(newArgsText) ?? part.args;\n\n return { ...part, argsText: newArgsText, args: newArgs };\n } else {\n warnOnce(\n \"wrong-part:text-delta\",\n \"Dropped text-delta chunk: part is neither text nor tool-call\",\n );\n return part;\n }\n });\n};\n\nconst handleResult = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"result\" },\n warnOnce: WarnOnce,\n): AssistantMessage => {\n return updatePartForPath(message, chunk, warnOnce, (part) => {\n if (part.type === \"tool-call\") {\n return {\n ...part,\n state: \"result\",\n ...(part.timing !== undefined\n ? {\n timing: {\n ...part.timing,\n completedAt: part.timing.completedAt ?? Date.now(),\n },\n }\n : {}),\n ...(chunk.artifact !== undefined ? { artifact: chunk.artifact } : {}),\n result: chunk.result,\n isError: chunk.isError ?? false,\n ...(chunk.modelContent !== undefined\n ? { modelContent: chunk.modelContent }\n : {}),\n ...(chunk.messages !== undefined ? { messages: chunk.messages } : {}),\n status: { type: \"complete\", reason: \"stop\" },\n };\n } else {\n warnOnce(\n \"wrong-part:result\",\n \"Dropped result chunk: part is not a tool-call\",\n );\n return part;\n }\n });\n};\n\nconst handleMessageFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"message-finish\" },\n): AssistantMessage => {\n // avoid edge case where providers send finish chunks that overwrite message error status (issue #2181)\n if (\n message.status?.type === \"incomplete\" &&\n message.status?.reason === \"error\"\n ) {\n return message;\n }\n\n const newStatus = getStatus(chunk);\n return { ...message, status: newStatus };\n};\n\nconst getStatus = (\n chunk:\n | (AssistantStreamChunk & { type: \"message-finish\" })\n | (AssistantStreamChunk & { type: \"step-finish\" }),\n): AssistantMessageStatus => {\n if (chunk.finishReason === \"tool-calls\") {\n return {\n type: \"requires-action\",\n reason: \"tool-calls\",\n };\n } else if (\n chunk.finishReason === \"stop\" ||\n chunk.finishReason === \"unknown\"\n ) {\n return {\n type: \"complete\",\n reason: chunk.finishReason,\n };\n } else {\n return {\n type: \"incomplete\",\n reason: chunk.finishReason,\n };\n }\n};\n\nconst handleAnnotations = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"annotations\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_annotations: [\n ...message.metadata.unstable_annotations,\n ...chunk.annotations,\n ],\n },\n };\n};\n\nconst handleData = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"data\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_data: [...message.metadata.unstable_data, ...chunk.data],\n },\n };\n};\n\nconst handleStepStart = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-start\" },\n): AssistantMessage => {\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps: [\n ...message.metadata.steps,\n { state: \"started\", messageId: chunk.messageId },\n ],\n },\n };\n};\n\nconst handleStepFinish = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"step-finish\" },\n): AssistantMessage => {\n const steps = message.metadata.steps.slice();\n const lastIndex = steps.length - 1;\n\n // Check if the previous step is a step-start (has state \"started\")\n if (steps.length > 0 && steps[lastIndex]?.state === \"started\") {\n steps[lastIndex] = {\n ...steps[lastIndex],\n state: \"finished\",\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n };\n } else {\n // If no previous step-start exists, append a finished step\n steps.push({\n state: \"finished\",\n messageId: generateId(),\n finishReason: chunk.finishReason,\n usage: chunk.usage,\n isContinued: chunk.isContinued,\n });\n }\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n steps,\n },\n };\n};\n\nconst handleErrorChunk = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"error\" },\n): AssistantMessage => {\n const severity =\n chunk.severity === \"critical\" ||\n chunk.severity === \"warning\" ||\n chunk.severity === \"info\"\n ? chunk.severity\n : undefined;\n return {\n ...message,\n status: {\n type: \"incomplete\",\n reason: \"error\",\n error: {\n code: chunk.code ?? \"unknown\",\n message: chunk.error ?? \"unknown error\",\n ...(severity !== undefined && { severity }),\n },\n },\n };\n};\n\nconst handleUpdateState = (\n message: AssistantMessage,\n chunk: AssistantStreamChunk & { type: \"update-state\" },\n): AssistantMessage => {\n const acc = new GorpStreamAccumulator(message.metadata.unstable_state);\n acc.append(chunk.operations);\n\n return {\n ...message,\n metadata: {\n ...message.metadata,\n unstable_state: acc.state,\n },\n };\n};\n\nconst computeTiming = (\n tracker: TimingTracker,\n message: AssistantMessage,\n): AssistantMessageTiming => {\n let outputTokens = 0;\n for (const step of message.metadata.steps) {\n if (step.state === \"finished\" && step.usage) {\n outputTokens += step.usage.outputTokens;\n }\n }\n\n let totalText = \"\";\n for (const part of message.parts) {\n if (part.type === \"text\" || part.type === \"reasoning\") {\n totalText += part.text;\n }\n }\n\n return tracker.getTiming(\n outputTokens > 0 ? outputTokens : undefined,\n totalText || undefined,\n );\n};\n\nconst throttleCallback = (callback: () => void) => {\n let hasScheduled = false;\n return () => {\n if (hasScheduled) return;\n hasScheduled = true;\n queueMicrotask(() => {\n hasScheduled = false;\n callback();\n });\n };\n};\n\nexport class AssistantMessageAccumulator extends TransformStream<\n AssistantStreamChunk,\n AssistantMessage\n> {\n constructor({\n initialMessage,\n throttle,\n onError,\n }: {\n initialMessage?: AssistantMessage;\n throttle?: boolean;\n onError?: (error: string) => void;\n } = {}) {\n let message = initialMessage ?? createInitialMessage();\n const tracker = new TimingTracker();\n const warnedKeys = new Set<string>();\n const warnOnce: WarnOnce = (key, warning) => {\n if (warnedKeys.has(key) || warnedKeys.size >= MAX_WARNED_KEYS) return;\n warnedKeys.add(key);\n console.warn(warning);\n };\n let controller:\n | TransformStreamDefaultController<AssistantMessage>\n | undefined;\n const emitChunk = throttle\n ? throttleCallback(() => {\n controller?.enqueue(message);\n })\n : () => {\n controller?.enqueue(message);\n };\n super({\n start(c) {\n controller = c;\n },\n transform(chunk) {\n tracker.recordChunk();\n const type = chunk.type;\n switch (type) {\n case \"part-start\":\n message = handlePartStart(message, chunk, warnOnce);\n if (chunk.part.type === \"tool-call\") {\n tracker.recordToolCallStart(chunk.part.toolCallId);\n }\n break;\n\n case \"tool-call-args-text-finish\":\n message = handleToolCallArgsTextFinish(message, chunk, warnOnce);\n break;\n\n case \"part-finish\":\n message = handlePartFinish(message, chunk, warnOnce);\n break;\n\n case \"text-delta\": {\n const next = handleTextDelta(message, chunk, warnOnce);\n if (next !== message) tracker.recordFirstToken();\n message = next;\n break;\n }\n case \"result\":\n message = handleResult(message, chunk, warnOnce);\n break;\n case \"message-finish\":\n message = handleMessageFinish(message, chunk);\n break;\n case \"annotations\":\n message = handleAnnotations(message, chunk);\n break;\n case \"data\":\n message = handleData(message, chunk);\n break;\n case \"step-start\":\n message = handleStepStart(message, chunk);\n break;\n case \"step-finish\":\n message = handleStepFinish(message, chunk);\n break;\n case \"error\":\n message = handleErrorChunk(message, chunk);\n onError?.(chunk.error);\n break;\n case \"update-state\":\n message = handleUpdateState(message, chunk);\n break;\n default: {\n const unhandledType: never = type;\n throw new Error(`Unsupported chunk type: ${unhandledType}`);\n }\n }\n\n if (message.status.type !== \"running\") {\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n }\n\n emitChunk();\n },\n flush(controller) {\n if (message.status?.type === \"running\") {\n // Check if there are any tool calls that require action\n const requiresAction =\n message.parts?.some(\n (part) =>\n part.type === \"tool-call\" &&\n (part.state === \"call\" || part.state === \"partial-call\") &&\n part.result === undefined,\n ) ?? false;\n message = handleMessageFinish(message, {\n type: \"message-finish\",\n path: [],\n finishReason: requiresAction ? \"tool-calls\" : \"unknown\",\n usage: {\n inputTokens: 0,\n outputTokens: 0,\n },\n });\n\n message = {\n ...message,\n metadata: {\n ...message.metadata,\n timing: computeTiming(tracker, message),\n },\n };\n\n controller.enqueue(message);\n }\n },\n });\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toGenericMessages.d.ts","names":[],"sources":["../../../src/core/converters/toGenericMessages.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"toGenericMessages.d.ts","names":[],"sources":["../../../src/core/converters/toGenericMessages.ts"],"mappings":";;;;;;KAMY;EACV;EACA;;KAGU;EACV;EACA,eAAe;EACf;;KAGU;EACV;EACA;EACA;EACA,MAAM;;KAGI;EACV;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA;;KAGU;EACV;EACA,UAAU,kBAAkB;;KAGlB;EACV;EACA,UAAU,kBAAkB;;KAGlB;EACV;EACA,SAAS;;KAGC,iBACR,uBACA,qBACA,0BACA;KAEC;EACH;EACA;EACA;EACA;EACA;EACA;EACA;EACA,OAAO;EACP;EACA;;KAGG;EACH,kBAAkB;;KAGf;EACH;EACA,kBAAkB;EAClB,uBAAuB;;;;;;iBAqKT,kBACd,mBAAmB,sBAClB"}
|
|
@@ -20,7 +20,8 @@ function inferImageMediaType(url) {
|
|
|
20
20
|
if (match?.[1]) return match[1];
|
|
21
21
|
}
|
|
22
22
|
const [pathWithoutParams = ""] = url.split(/[?#]/);
|
|
23
|
-
|
|
23
|
+
const ext = pathWithoutParams.split(".").pop()?.toLowerCase() ?? "";
|
|
24
|
+
return IMAGE_MEDIA_TYPES[ext] ?? "image/png";
|
|
24
25
|
}
|
|
25
26
|
function toUrlOrString(value) {
|
|
26
27
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toGenericMessages.js","names":[],"sources":["../../../src/core/converters/toGenericMessages.ts"],"sourcesContent":["/**\n * Generic message types for framework-agnostic LLM message interchange.\n * These types represent a common format that can be converted to/from\n * various LLM provider formats (AI SDK, LangChain, etc.).\n */\n\nexport type GenericTextPart = {\n type: \"text\";\n text: string;\n};\n\nexport type GenericFilePart = {\n type: \"file\";\n data: string | URL;\n mediaType: string;\n};\n\nexport type GenericToolCallPart = {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n};\n\nexport type GenericToolResultPart = {\n type: \"tool-result\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n};\n\nexport type GenericSystemMessage = {\n role: \"system\";\n content: string;\n};\n\nexport type GenericUserMessage = {\n role: \"user\";\n content: (GenericTextPart | GenericFilePart)[];\n};\n\nexport type GenericAssistantMessage = {\n role: \"assistant\";\n content: (GenericTextPart | GenericToolCallPart)[];\n};\n\nexport type GenericToolMessage = {\n role: \"tool\";\n content: GenericToolResultPart[];\n};\n\nexport type GenericMessage =\n | GenericSystemMessage\n | GenericUserMessage\n | GenericAssistantMessage\n | GenericToolMessage;\n\ntype MessagePartLike = {\n type: string;\n text?: string;\n image?: string;\n data?: string;\n mimeType?: string;\n toolCallId?: string;\n toolName?: string;\n args?: Record<string, unknown>;\n result?: unknown;\n isError?: boolean;\n};\n\ntype AttachmentLike = {\n content: readonly MessagePartLike[];\n};\n\ntype ThreadMessageLike = {\n role: \"system\" | \"user\" | \"assistant\";\n content: readonly MessagePartLike[];\n attachments?: readonly AttachmentLike[];\n};\n\nconst IMAGE_MEDIA_TYPES: Record<string, string> = {\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n avif: \"image/avif\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n tiff: \"image/tiff\",\n tif: \"image/tiff\",\n heic: \"image/heic\",\n heif: \"image/heif\",\n};\n\nfunction inferImageMediaType(url: string): string {\n // Handle data URLs: data:[<mediatype>][;base64],<data>\n if (url.startsWith(\"data:\")) {\n const match = url.match(/^data:([^;,]+)/);\n if (match?.[1]) return match[1];\n }\n\n // Extract extension from URL path, ignoring query string and hash\n const [pathWithoutParams = \"\"] = url.split(/[?#]/);\n const ext = pathWithoutParams.split(\".\").pop()?.toLowerCase() ?? \"\";\n return IMAGE_MEDIA_TYPES[ext] ?? \"image/png\";\n}\n\nfunction toUrlOrString(value: string): string | URL {\n try {\n return new URL(value);\n } catch {\n return value;\n }\n}\n\ntype ToolCallAccumulator = {\n textParts: (GenericTextPart | GenericToolCallPart)[];\n toolResults: GenericToolResultPart[];\n};\n\nfunction processToolCall(\n part: MessagePartLike,\n accumulator: ToolCallAccumulator,\n): boolean {\n if (!part.toolCallId || !part.toolName) return false;\n\n accumulator.textParts.push({\n type: \"tool-call\",\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n args: part.args ?? {},\n });\n\n if (part.result !== undefined) {\n const toolResult: GenericToolResultPart = {\n type: \"tool-result\",\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n result: part.result,\n };\n if (part.isError) {\n toolResult.isError = true;\n }\n accumulator.toolResults.push(toolResult);\n return true;\n }\n return false;\n}\n\nfunction flushAccumulator(\n accumulator: ToolCallAccumulator,\n result: GenericMessage[],\n): void {\n if (accumulator.textParts.length > 0) {\n result.push({ role: \"assistant\", content: accumulator.textParts });\n accumulator.textParts = [];\n }\n if (accumulator.toolResults.length > 0) {\n result.push({ role: \"tool\", content: accumulator.toolResults });\n accumulator.toolResults = [];\n }\n}\n\nfunction convertSystemMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const textPart = message.content.find((p) => p.type === \"text\");\n if (textPart?.text) {\n result.push({ role: \"system\", content: textPart.text });\n }\n}\n\nfunction convertUserMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const attachments = message.attachments ?? [];\n const allContent = [\n ...message.content,\n ...attachments.flatMap((a) => a.content),\n ];\n\n const content: (GenericTextPart | GenericFilePart)[] = [];\n\n for (const part of allContent) {\n if (part.type === \"text\" && part.text) {\n content.push({ type: \"text\", text: part.text });\n } else if (part.type === \"image\" && part.image) {\n content.push({\n type: \"file\",\n data: toUrlOrString(part.image),\n mediaType: inferImageMediaType(part.image),\n });\n } else if (part.type === \"file\" && part.data && part.mimeType) {\n content.push({\n type: \"file\",\n data: toUrlOrString(part.data),\n mediaType: part.mimeType,\n });\n }\n }\n\n if (content.length > 0) {\n result.push({ role: \"user\", content });\n }\n}\n\nfunction convertAssistantMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const accumulator: ToolCallAccumulator = {\n textParts: [],\n toolResults: [],\n };\n let hasPendingToolResults = false;\n\n for (const part of message.content) {\n if (part.type === \"text\" && part.text) {\n // Flush pending tool results before adding more text\n if (hasPendingToolResults) {\n flushAccumulator(accumulator, result);\n hasPendingToolResults = false;\n }\n accumulator.textParts.push({ type: \"text\", text: part.text });\n } else if (part.type === \"tool-call\") {\n if (processToolCall(part, accumulator)) {\n hasPendingToolResults = true;\n }\n }\n }\n\n flushAccumulator(accumulator, result);\n}\n\n/**\n * Converts thread messages to generic LLM messages.\n * This format can then be easily converted to provider-specific formats.\n */\nexport function toGenericMessages(\n messages: readonly ThreadMessageLike[],\n): GenericMessage[] {\n const result: GenericMessage[] = [];\n\n for (const message of messages) {\n switch (message.role) {\n case \"system\":\n convertSystemMessage(message, result);\n break;\n case \"user\":\n convertUserMessage(message, result);\n break;\n case \"assistant\":\n convertAssistantMessage(message, result);\n break;\n }\n }\n\n return result;\n}\n"],"mappings":";AAiFA,MAAM,oBAA4C;CAChD,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,KAAK;CACL,KAAK;CACL,MAAM;CACN,KAAK;CACL,MAAM;CACN,MAAM;AACR;AAEA,SAAS,oBAAoB,KAAqB;CAEhD,IAAI,IAAI,WAAW,OAAO,GAAG;EAC3B,MAAM,QAAQ,IAAI,MAAM,gBAAgB;EACxC,IAAI,QAAQ,IAAI,OAAO,MAAM;CAC/B;CAGA,MAAM,CAAC,oBAAoB,MAAM,IAAI,MAAM,MAAM;
|
|
1
|
+
{"version":3,"file":"toGenericMessages.js","names":[],"sources":["../../../src/core/converters/toGenericMessages.ts"],"sourcesContent":["/**\n * Generic message types for framework-agnostic LLM message interchange.\n * These types represent a common format that can be converted to/from\n * various LLM provider formats (AI SDK, LangChain, etc.).\n */\n\nexport type GenericTextPart = {\n type: \"text\";\n text: string;\n};\n\nexport type GenericFilePart = {\n type: \"file\";\n data: string | URL;\n mediaType: string;\n};\n\nexport type GenericToolCallPart = {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n};\n\nexport type GenericToolResultPart = {\n type: \"tool-result\";\n toolCallId: string;\n toolName: string;\n result: unknown;\n isError?: boolean;\n};\n\nexport type GenericSystemMessage = {\n role: \"system\";\n content: string;\n};\n\nexport type GenericUserMessage = {\n role: \"user\";\n content: (GenericTextPart | GenericFilePart)[];\n};\n\nexport type GenericAssistantMessage = {\n role: \"assistant\";\n content: (GenericTextPart | GenericToolCallPart)[];\n};\n\nexport type GenericToolMessage = {\n role: \"tool\";\n content: GenericToolResultPart[];\n};\n\nexport type GenericMessage =\n | GenericSystemMessage\n | GenericUserMessage\n | GenericAssistantMessage\n | GenericToolMessage;\n\ntype MessagePartLike = {\n type: string;\n text?: string;\n image?: string;\n data?: string;\n mimeType?: string;\n toolCallId?: string;\n toolName?: string;\n args?: Record<string, unknown>;\n result?: unknown;\n isError?: boolean;\n};\n\ntype AttachmentLike = {\n content: readonly MessagePartLike[];\n};\n\ntype ThreadMessageLike = {\n role: \"system\" | \"user\" | \"assistant\";\n content: readonly MessagePartLike[];\n attachments?: readonly AttachmentLike[];\n};\n\nconst IMAGE_MEDIA_TYPES: Record<string, string> = {\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n png: \"image/png\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n svg: \"image/svg+xml\",\n avif: \"image/avif\",\n bmp: \"image/bmp\",\n ico: \"image/x-icon\",\n tiff: \"image/tiff\",\n tif: \"image/tiff\",\n heic: \"image/heic\",\n heif: \"image/heif\",\n};\n\nfunction inferImageMediaType(url: string): string {\n // Handle data URLs: data:[<mediatype>][;base64],<data>\n if (url.startsWith(\"data:\")) {\n const match = url.match(/^data:([^;,]+)/);\n if (match?.[1]) return match[1];\n }\n\n // Extract extension from URL path, ignoring query string and hash\n const [pathWithoutParams = \"\"] = url.split(/[?#]/);\n const ext = pathWithoutParams.split(\".\").pop()?.toLowerCase() ?? \"\";\n return IMAGE_MEDIA_TYPES[ext] ?? \"image/png\";\n}\n\nfunction toUrlOrString(value: string): string | URL {\n try {\n return new URL(value);\n } catch {\n return value;\n }\n}\n\ntype ToolCallAccumulator = {\n textParts: (GenericTextPart | GenericToolCallPart)[];\n toolResults: GenericToolResultPart[];\n};\n\nfunction processToolCall(\n part: MessagePartLike,\n accumulator: ToolCallAccumulator,\n): boolean {\n if (!part.toolCallId || !part.toolName) return false;\n\n accumulator.textParts.push({\n type: \"tool-call\",\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n args: part.args ?? {},\n });\n\n if (part.result !== undefined) {\n const toolResult: GenericToolResultPart = {\n type: \"tool-result\",\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n result: part.result,\n };\n if (part.isError) {\n toolResult.isError = true;\n }\n accumulator.toolResults.push(toolResult);\n return true;\n }\n return false;\n}\n\nfunction flushAccumulator(\n accumulator: ToolCallAccumulator,\n result: GenericMessage[],\n): void {\n if (accumulator.textParts.length > 0) {\n result.push({ role: \"assistant\", content: accumulator.textParts });\n accumulator.textParts = [];\n }\n if (accumulator.toolResults.length > 0) {\n result.push({ role: \"tool\", content: accumulator.toolResults });\n accumulator.toolResults = [];\n }\n}\n\nfunction convertSystemMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const textPart = message.content.find((p) => p.type === \"text\");\n if (textPart?.text) {\n result.push({ role: \"system\", content: textPart.text });\n }\n}\n\nfunction convertUserMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const attachments = message.attachments ?? [];\n const allContent = [\n ...message.content,\n ...attachments.flatMap((a) => a.content),\n ];\n\n const content: (GenericTextPart | GenericFilePart)[] = [];\n\n for (const part of allContent) {\n if (part.type === \"text\" && part.text) {\n content.push({ type: \"text\", text: part.text });\n } else if (part.type === \"image\" && part.image) {\n content.push({\n type: \"file\",\n data: toUrlOrString(part.image),\n mediaType: inferImageMediaType(part.image),\n });\n } else if (part.type === \"file\" && part.data && part.mimeType) {\n content.push({\n type: \"file\",\n data: toUrlOrString(part.data),\n mediaType: part.mimeType,\n });\n }\n }\n\n if (content.length > 0) {\n result.push({ role: \"user\", content });\n }\n}\n\nfunction convertAssistantMessage(\n message: ThreadMessageLike,\n result: GenericMessage[],\n): void {\n const accumulator: ToolCallAccumulator = {\n textParts: [],\n toolResults: [],\n };\n let hasPendingToolResults = false;\n\n for (const part of message.content) {\n if (part.type === \"text\" && part.text) {\n // Flush pending tool results before adding more text\n if (hasPendingToolResults) {\n flushAccumulator(accumulator, result);\n hasPendingToolResults = false;\n }\n accumulator.textParts.push({ type: \"text\", text: part.text });\n } else if (part.type === \"tool-call\") {\n if (processToolCall(part, accumulator)) {\n hasPendingToolResults = true;\n }\n }\n }\n\n flushAccumulator(accumulator, result);\n}\n\n/**\n * Converts thread messages to generic LLM messages.\n * This format can then be easily converted to provider-specific formats.\n */\nexport function toGenericMessages(\n messages: readonly ThreadMessageLike[],\n): GenericMessage[] {\n const result: GenericMessage[] = [];\n\n for (const message of messages) {\n switch (message.role) {\n case \"system\":\n convertSystemMessage(message, result);\n break;\n case \"user\":\n convertUserMessage(message, result);\n break;\n case \"assistant\":\n convertAssistantMessage(message, result);\n break;\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ReadonlyJSONValue } from "../../utils/json/json-value.js";
|
|
2
|
+
import "../../utils.js";
|
|
3
|
+
import { GorpStreamOperation } from "./types.js";
|
|
4
|
+
//#region src/core/gorp/GorpStreamAccumulator.d.ts
|
|
5
|
+
declare class GorpStreamAccumulator {
|
|
6
|
+
private _state;
|
|
7
|
+
constructor(initialValue?: ReadonlyJSONValue);
|
|
8
|
+
get state(): ReadonlyJSONValue;
|
|
9
|
+
append(ops: readonly GorpStreamOperation[]): void;
|
|
10
|
+
private static apply;
|
|
11
|
+
private static updatePath;
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { GorpStreamAccumulator };
|
|
15
|
+
//# sourceMappingURL=GorpStreamAccumulator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GorpStreamAccumulator.d.ts","names":[],"sources":["../../../src/core/gorp/GorpStreamAccumulator.ts"],"mappings":";;;;cAIa;UACH;EAEI,YAAA,eAAc;MAItB,SAAK;EAIT,OAAO,cAAc;iBAON;iBAmBA"}
|