veryfront 0.1.263 → 0.1.265
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/esm/deno.js +1 -1
- package/esm/src/agent/hosted-child-mirror.d.ts +91 -0
- package/esm/src/agent/hosted-child-mirror.d.ts.map +1 -0
- package/esm/src/agent/hosted-child-mirror.js +118 -0
- package/esm/src/agent/index.d.ts +2 -0
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +2 -0
- package/esm/src/chat/hosted-ui-chunk-mapping.d.ts +111 -0
- package/esm/src/chat/hosted-ui-chunk-mapping.d.ts.map +1 -0
- package/esm/src/chat/hosted-ui-chunk-mapping.js +123 -0
- package/esm/src/chat/index.d.ts +1 -0
- package/esm/src/chat/index.d.ts.map +1 -1
- package/esm/src/chat/index.js +1 -0
- package/esm/src/provider/runtime-loader/provider-embedding-responses.d.ts +5 -0
- package/esm/src/provider/runtime-loader/provider-embedding-responses.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-embedding-responses.js +50 -0
- package/esm/src/provider/runtime-loader/provider-finish-reasons.d.ts +9 -0
- package/esm/src/provider/runtime-loader/provider-finish-reasons.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-finish-reasons.js +60 -0
- package/esm/src/provider/runtime-loader/provider-sse.d.ts +5 -0
- package/esm/src/provider/runtime-loader/provider-sse.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-sse.js +23 -0
- package/esm/src/provider/runtime-loader/provider-usage.d.ts +19 -0
- package/esm/src/provider/runtime-loader/provider-usage.d.ts.map +1 -0
- package/esm/src/provider/runtime-loader/provider-usage.js +109 -0
- package/esm/src/provider/runtime-loader.d.ts.map +1 -1
- package/esm/src/provider/runtime-loader.js +4 -240
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/agent/hosted-child-mirror.ts +208 -0
- package/src/src/agent/index.ts +15 -0
- package/src/src/chat/hosted-ui-chunk-mapping.ts +303 -0
- package/src/src/chat/index.ts +5 -0
- package/src/src/provider/runtime-loader/provider-embedding-responses.ts +61 -0
- package/src/src/provider/runtime-loader/provider-finish-reasons.ts +69 -0
- package/src/src/provider/runtime-loader/provider-sse.ts +29 -0
- package/src/src/provider/runtime-loader/provider-usage.ts +135 -0
- package/src/src/provider/runtime-loader.ts +21 -300
- package/src/src/utils/version-constant.ts +1 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import type { ChatMessageMetadata, ChatUiMessageChunk } from "../chat/protocol.js";
|
|
2
|
+
import type { HostedStreamPartForUiChunkMapping } from "../chat/hosted-ui-chunk-mapping.js";
|
|
3
|
+
|
|
4
|
+
export interface HostedChildChunkMirror {
|
|
5
|
+
handleChunk(chunk: ChatUiMessageChunk<ChatMessageMetadata>): Promise<void> | void;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface HostedChildMirrorState {
|
|
9
|
+
reasoningStarted: boolean;
|
|
10
|
+
textStarted: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type CoreMirroredPartType =
|
|
14
|
+
| "reasoning-delta"
|
|
15
|
+
| "text-delta"
|
|
16
|
+
| "tool-input-start"
|
|
17
|
+
| "tool-input-delta"
|
|
18
|
+
| "tool-call"
|
|
19
|
+
| "tool-result";
|
|
20
|
+
|
|
21
|
+
type MirroredPartType = CoreMirroredPartType | "tool-error" | "error";
|
|
22
|
+
|
|
23
|
+
type DurableMirrorChunkType = ChatUiMessageChunk<ChatMessageMetadata>["type"];
|
|
24
|
+
|
|
25
|
+
const ALREADY_MIRRORED_CHUNK_TYPES_BY_PART_TYPE: Readonly<
|
|
26
|
+
Partial<Record<MirroredPartType, readonly DurableMirrorChunkType[]>>
|
|
27
|
+
> = {
|
|
28
|
+
"reasoning-delta": ["reasoning-delta"],
|
|
29
|
+
"text-delta": ["text-delta"],
|
|
30
|
+
"tool-input-start": ["tool-input-start"],
|
|
31
|
+
"tool-call": ["tool-input-start", "tool-input-available", "tool-input-error"],
|
|
32
|
+
"tool-result": ["tool-output-available"],
|
|
33
|
+
"tool-error": ["tool-input-start", "tool-input-error"],
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export function isAlreadyMirroredHostedChunk(
|
|
37
|
+
partType: MirroredPartType,
|
|
38
|
+
mirroredChunkType: DurableMirrorChunkType,
|
|
39
|
+
): boolean {
|
|
40
|
+
return ALREADY_MIRRORED_CHUNK_TYPES_BY_PART_TYPE[partType]?.includes(mirroredChunkType) ?? false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type MirroredHostedStreamPart = Extract<
|
|
44
|
+
HostedStreamPartForUiChunkMapping,
|
|
45
|
+
| { type: "reasoning-delta" }
|
|
46
|
+
| { type: "text-delta" }
|
|
47
|
+
| { type: "source" }
|
|
48
|
+
| { type: "tool-input-start" }
|
|
49
|
+
| { type: "tool-call" }
|
|
50
|
+
| { type: "tool-input-delta" }
|
|
51
|
+
| { type: "tool-result" }
|
|
52
|
+
| { type: "tool-error" }
|
|
53
|
+
| { type: "error" }
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
type HostedMirrorBasePart =
|
|
57
|
+
| { type: "reasoning-delta"; text: string }
|
|
58
|
+
| { type: "text-delta"; text: string }
|
|
59
|
+
| { type: "tool-input-start"; toolCallId: string; toolName: string }
|
|
60
|
+
| { type: "tool-input-delta"; toolCallId: string; delta: string }
|
|
61
|
+
| { type: "tool-call"; toolCallId: string; toolName: string; input: unknown }
|
|
62
|
+
| { type: "tool-result"; toolCallId: string; toolName: string; input: unknown; output: unknown }
|
|
63
|
+
| { type: "tool-error"; toolCallId: string; toolName: string; input: unknown; error: Error }
|
|
64
|
+
| { type: "error"; error: Error };
|
|
65
|
+
|
|
66
|
+
type ExtraMirroredHostedStreamPart = Extract<HostedStreamPartForUiChunkMapping, { type: "source" }>;
|
|
67
|
+
|
|
68
|
+
export type HostedChildMirrorPart = HostedMirrorBasePart | ExtraMirroredHostedStreamPart;
|
|
69
|
+
|
|
70
|
+
export function toMirroredHostedStreamPart(
|
|
71
|
+
part: HostedChildMirrorPart,
|
|
72
|
+
ids: {
|
|
73
|
+
messageId: string | null;
|
|
74
|
+
reasoningMessageId: string | null;
|
|
75
|
+
},
|
|
76
|
+
): MirroredHostedStreamPart {
|
|
77
|
+
switch (part.type) {
|
|
78
|
+
case "reasoning-delta":
|
|
79
|
+
return {
|
|
80
|
+
type: "reasoning-delta",
|
|
81
|
+
id: ids.reasoningMessageId ?? "fork-reasoning",
|
|
82
|
+
text: part.text,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
case "text-delta":
|
|
86
|
+
return {
|
|
87
|
+
type: "text-delta",
|
|
88
|
+
id: ids.messageId ?? "fork-message",
|
|
89
|
+
text: part.text,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
case "tool-input-start":
|
|
93
|
+
return {
|
|
94
|
+
type: "tool-input-start",
|
|
95
|
+
id: part.toolCallId,
|
|
96
|
+
toolName: part.toolName,
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
case "source":
|
|
100
|
+
if (part.sourceType === "url") {
|
|
101
|
+
return {
|
|
102
|
+
type: "source",
|
|
103
|
+
id: part.id,
|
|
104
|
+
sourceType: "url",
|
|
105
|
+
url: part.url,
|
|
106
|
+
...(part.title ? { title: part.title } : {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
type: "source",
|
|
112
|
+
id: part.id,
|
|
113
|
+
sourceType: "document",
|
|
114
|
+
mediaType: part.mediaType,
|
|
115
|
+
title: part.title ?? part.filename ?? part.id,
|
|
116
|
+
...(part.filename ? { filename: part.filename } : {}),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
case "tool-call":
|
|
120
|
+
return {
|
|
121
|
+
type: "tool-call",
|
|
122
|
+
toolCallId: part.toolCallId,
|
|
123
|
+
toolName: part.toolName,
|
|
124
|
+
input: part.input,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
case "tool-input-delta":
|
|
128
|
+
return {
|
|
129
|
+
type: "tool-input-delta",
|
|
130
|
+
id: part.toolCallId,
|
|
131
|
+
delta: part.delta,
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
case "tool-result":
|
|
135
|
+
return {
|
|
136
|
+
type: "tool-result",
|
|
137
|
+
toolCallId: part.toolCallId,
|
|
138
|
+
toolName: part.toolName,
|
|
139
|
+
input: part.input,
|
|
140
|
+
output: part.output,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
case "tool-error":
|
|
144
|
+
return {
|
|
145
|
+
type: "tool-error",
|
|
146
|
+
toolCallId: part.toolCallId,
|
|
147
|
+
toolName: part.toolName,
|
|
148
|
+
input: part.input,
|
|
149
|
+
error: part.error,
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
case "error":
|
|
153
|
+
return {
|
|
154
|
+
type: "error",
|
|
155
|
+
error: part.error,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function appendHostedChildMirrorChunk(input: {
|
|
161
|
+
mirror: HostedChildChunkMirror | null;
|
|
162
|
+
chunk: ChatUiMessageChunk<ChatMessageMetadata>;
|
|
163
|
+
}): Promise<boolean> {
|
|
164
|
+
if (!input.mirror) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
await input.mirror.handleChunk(input.chunk);
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export async function closeHostedChildReasoningSegment(input: {
|
|
173
|
+
mirror: HostedChildChunkMirror | null;
|
|
174
|
+
reasoningMessageId: string | null;
|
|
175
|
+
state: HostedChildMirrorState;
|
|
176
|
+
}): Promise<void> {
|
|
177
|
+
if (!input.state.reasoningStarted || !input.reasoningMessageId) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
input.state.reasoningStarted = false;
|
|
182
|
+
await appendHostedChildMirrorChunk({
|
|
183
|
+
mirror: input.mirror,
|
|
184
|
+
chunk: {
|
|
185
|
+
type: "reasoning-end",
|
|
186
|
+
id: input.reasoningMessageId,
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export async function closeHostedChildTextSegment(input: {
|
|
192
|
+
mirror: HostedChildChunkMirror | null;
|
|
193
|
+
messageId: string | null;
|
|
194
|
+
state: HostedChildMirrorState;
|
|
195
|
+
}): Promise<void> {
|
|
196
|
+
if (!input.state.textStarted || !input.messageId) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
input.state.textStarted = false;
|
|
201
|
+
await appendHostedChildMirrorChunk({
|
|
202
|
+
mirror: input.mirror,
|
|
203
|
+
chunk: {
|
|
204
|
+
type: "text-end",
|
|
205
|
+
id: input.messageId,
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
package/src/src/agent/index.ts
CHANGED
|
@@ -359,6 +359,16 @@ export {
|
|
|
359
359
|
type HostedChildLifecycleTerminalState,
|
|
360
360
|
runHostedChildLifecycle,
|
|
361
361
|
} from "./hosted-child-lifecycle.js";
|
|
362
|
+
export {
|
|
363
|
+
appendHostedChildMirrorChunk,
|
|
364
|
+
closeHostedChildReasoningSegment,
|
|
365
|
+
closeHostedChildTextSegment,
|
|
366
|
+
type HostedChildChunkMirror,
|
|
367
|
+
type HostedChildMirrorPart,
|
|
368
|
+
type HostedChildMirrorState,
|
|
369
|
+
isAlreadyMirroredHostedChunk,
|
|
370
|
+
toMirroredHostedStreamPart,
|
|
371
|
+
} from "./hosted-child-mirror.js";
|
|
362
372
|
export {
|
|
363
373
|
type HostedLifecycleAdapter,
|
|
364
374
|
type HostedLifecycleExecution,
|
|
@@ -398,6 +408,11 @@ export {
|
|
|
398
408
|
normalizeChatUiMessageChunk,
|
|
399
409
|
normalizeChatUiMessageStream,
|
|
400
410
|
} from "../chat/chat-ui-message-helpers.js";
|
|
411
|
+
export {
|
|
412
|
+
type HostedStreamPartForUiChunkMapping,
|
|
413
|
+
type HostedUiChunkMappingOptions,
|
|
414
|
+
mapHostedStreamPartToChatUiChunks,
|
|
415
|
+
} from "../chat/hosted-ui-chunk-mapping.js";
|
|
401
416
|
export {
|
|
402
417
|
expandAllowedRemoteToolNames,
|
|
403
418
|
getProviderNativeToolNames,
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import type { ChatMessageMetadata, ChatUiMessageChunk } from "./protocol.js";
|
|
2
|
+
|
|
3
|
+
export type HostedUiChunkMappingOptions = {
|
|
4
|
+
messageId?: string | null;
|
|
5
|
+
reasoningMessageId?: string | null;
|
|
6
|
+
sendReasoning?: boolean;
|
|
7
|
+
sendSources?: boolean;
|
|
8
|
+
onError?: (error: unknown) => string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type HostedStreamSourcePart =
|
|
12
|
+
| {
|
|
13
|
+
type: "source";
|
|
14
|
+
id: string;
|
|
15
|
+
sourceType: "url";
|
|
16
|
+
url: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
}
|
|
19
|
+
| {
|
|
20
|
+
type: "source";
|
|
21
|
+
id: string;
|
|
22
|
+
sourceType: "document";
|
|
23
|
+
mediaType: string;
|
|
24
|
+
title?: string;
|
|
25
|
+
filename?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type HostedStreamPartForUiChunkMapping =
|
|
29
|
+
| {
|
|
30
|
+
type: "start";
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
type: "start-step";
|
|
34
|
+
}
|
|
35
|
+
| {
|
|
36
|
+
type: "finish-step";
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
type: "finish";
|
|
40
|
+
finishReason?: string;
|
|
41
|
+
}
|
|
42
|
+
| {
|
|
43
|
+
type: "abort";
|
|
44
|
+
}
|
|
45
|
+
| {
|
|
46
|
+
type: "reasoning-start";
|
|
47
|
+
id: string;
|
|
48
|
+
}
|
|
49
|
+
| {
|
|
50
|
+
type: "reasoning-delta";
|
|
51
|
+
id: string;
|
|
52
|
+
text: string;
|
|
53
|
+
}
|
|
54
|
+
| {
|
|
55
|
+
type: "reasoning-end";
|
|
56
|
+
id: string;
|
|
57
|
+
}
|
|
58
|
+
| {
|
|
59
|
+
type: "text-start";
|
|
60
|
+
id: string;
|
|
61
|
+
}
|
|
62
|
+
| {
|
|
63
|
+
type: "text-delta";
|
|
64
|
+
id: string;
|
|
65
|
+
text: string;
|
|
66
|
+
}
|
|
67
|
+
| {
|
|
68
|
+
type: "text-end";
|
|
69
|
+
id: string;
|
|
70
|
+
}
|
|
71
|
+
| HostedStreamSourcePart
|
|
72
|
+
| {
|
|
73
|
+
type: "file";
|
|
74
|
+
file: {
|
|
75
|
+
mediaType: string;
|
|
76
|
+
base64: string;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
type: "tool-input-start";
|
|
81
|
+
id: string;
|
|
82
|
+
toolName: string;
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
type: "tool-input-delta";
|
|
86
|
+
id: string;
|
|
87
|
+
delta: string;
|
|
88
|
+
}
|
|
89
|
+
| {
|
|
90
|
+
type: "tool-call";
|
|
91
|
+
toolCallId: string;
|
|
92
|
+
toolName: string;
|
|
93
|
+
input: unknown;
|
|
94
|
+
invalid: true;
|
|
95
|
+
error: unknown;
|
|
96
|
+
}
|
|
97
|
+
| {
|
|
98
|
+
type: "tool-call";
|
|
99
|
+
toolCallId: string;
|
|
100
|
+
toolName: string;
|
|
101
|
+
input: unknown;
|
|
102
|
+
invalid?: false;
|
|
103
|
+
}
|
|
104
|
+
| {
|
|
105
|
+
type: "tool-approval-request";
|
|
106
|
+
approvalId: string;
|
|
107
|
+
toolCall: {
|
|
108
|
+
toolCallId: string;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
| {
|
|
112
|
+
type: "tool-result";
|
|
113
|
+
toolCallId: string;
|
|
114
|
+
toolName: string;
|
|
115
|
+
input: unknown;
|
|
116
|
+
output: unknown;
|
|
117
|
+
}
|
|
118
|
+
| {
|
|
119
|
+
type: "tool-error";
|
|
120
|
+
toolCallId: string;
|
|
121
|
+
toolName: string;
|
|
122
|
+
input: unknown;
|
|
123
|
+
error: unknown;
|
|
124
|
+
}
|
|
125
|
+
| {
|
|
126
|
+
type: "tool-output-denied";
|
|
127
|
+
toolCallId: string;
|
|
128
|
+
}
|
|
129
|
+
| {
|
|
130
|
+
type: "error";
|
|
131
|
+
error: unknown;
|
|
132
|
+
}
|
|
133
|
+
| {
|
|
134
|
+
type: "tool-input-end";
|
|
135
|
+
}
|
|
136
|
+
| {
|
|
137
|
+
type: "raw";
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
function defaultOnError(error: unknown): string {
|
|
141
|
+
return error instanceof Error ? error.message : String(error);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function mapHostedStreamSourceToUiChunks(
|
|
145
|
+
part: HostedStreamSourcePart,
|
|
146
|
+
sendSources: boolean,
|
|
147
|
+
): ChatUiMessageChunk<ChatMessageMetadata>[] {
|
|
148
|
+
if (!sendSources) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (part.sourceType === "url") {
|
|
153
|
+
return [{
|
|
154
|
+
type: "source-url",
|
|
155
|
+
sourceId: part.id,
|
|
156
|
+
url: part.url,
|
|
157
|
+
...(part.title ? { title: part.title } : {}),
|
|
158
|
+
}];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return [
|
|
162
|
+
{
|
|
163
|
+
type: "source-document",
|
|
164
|
+
sourceId: part.id,
|
|
165
|
+
mediaType: part.mediaType,
|
|
166
|
+
title: part.title ?? part.filename ?? part.id,
|
|
167
|
+
...(part.filename ? { filename: part.filename } : {}),
|
|
168
|
+
},
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function mapToolCallPartToUiChunks(
|
|
173
|
+
part: Extract<HostedStreamPartForUiChunkMapping, { type: "tool-call" }>,
|
|
174
|
+
onError: (error: unknown) => string,
|
|
175
|
+
): ChatUiMessageChunk<ChatMessageMetadata>[] {
|
|
176
|
+
if (part.invalid) {
|
|
177
|
+
return [{
|
|
178
|
+
type: "tool-input-error",
|
|
179
|
+
toolCallId: part.toolCallId,
|
|
180
|
+
toolName: part.toolName,
|
|
181
|
+
input: part.input,
|
|
182
|
+
errorText: onError(part.error),
|
|
183
|
+
}];
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return [{
|
|
187
|
+
type: "tool-input-available",
|
|
188
|
+
toolCallId: part.toolCallId,
|
|
189
|
+
toolName: part.toolName,
|
|
190
|
+
input: part.input,
|
|
191
|
+
}];
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function mapToolErrorPartToUiChunks(
|
|
195
|
+
part: Extract<HostedStreamPartForUiChunkMapping, { type: "tool-error" }>,
|
|
196
|
+
onError: (error: unknown) => string,
|
|
197
|
+
): ChatUiMessageChunk<ChatMessageMetadata>[] {
|
|
198
|
+
return [
|
|
199
|
+
{
|
|
200
|
+
type: "tool-input-start",
|
|
201
|
+
toolCallId: part.toolCallId,
|
|
202
|
+
toolName: part.toolName,
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
type: "tool-input-error",
|
|
206
|
+
toolCallId: part.toolCallId,
|
|
207
|
+
toolName: part.toolName,
|
|
208
|
+
input: part.input,
|
|
209
|
+
errorText: onError(part.error),
|
|
210
|
+
},
|
|
211
|
+
];
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export function mapHostedStreamPartToChatUiChunks(
|
|
215
|
+
part: HostedStreamPartForUiChunkMapping,
|
|
216
|
+
options: HostedUiChunkMappingOptions = {},
|
|
217
|
+
): ChatUiMessageChunk<ChatMessageMetadata>[] {
|
|
218
|
+
const onError = options.onError ?? defaultOnError;
|
|
219
|
+
const sendReasoning = options.sendReasoning ?? true;
|
|
220
|
+
const sendSources = options.sendSources ?? true;
|
|
221
|
+
|
|
222
|
+
switch (part.type) {
|
|
223
|
+
case "start":
|
|
224
|
+
return [{ type: "start", ...(options.messageId ? { messageId: options.messageId } : {}) }];
|
|
225
|
+
|
|
226
|
+
case "start-step":
|
|
227
|
+
return [{ type: "start-step" }];
|
|
228
|
+
|
|
229
|
+
case "finish-step":
|
|
230
|
+
return [{ type: "finish-step" }];
|
|
231
|
+
|
|
232
|
+
case "finish":
|
|
233
|
+
return [{
|
|
234
|
+
type: "finish",
|
|
235
|
+
...(part.finishReason ? { finishReason: part.finishReason } : {}),
|
|
236
|
+
}];
|
|
237
|
+
|
|
238
|
+
case "abort":
|
|
239
|
+
return [{ type: "abort" }];
|
|
240
|
+
|
|
241
|
+
case "reasoning-start":
|
|
242
|
+
return [{ type: "reasoning-start", id: options.reasoningMessageId ?? part.id }];
|
|
243
|
+
|
|
244
|
+
case "reasoning-delta":
|
|
245
|
+
return sendReasoning
|
|
246
|
+
? [{ type: "reasoning-delta", id: options.reasoningMessageId ?? part.id, delta: part.text }]
|
|
247
|
+
: [];
|
|
248
|
+
|
|
249
|
+
case "reasoning-end":
|
|
250
|
+
return [{ type: "reasoning-end", id: options.reasoningMessageId ?? part.id }];
|
|
251
|
+
|
|
252
|
+
case "text-start":
|
|
253
|
+
return [{ type: "text-start", id: options.messageId ?? part.id }];
|
|
254
|
+
|
|
255
|
+
case "text-delta":
|
|
256
|
+
return [{ type: "text-delta", id: options.messageId ?? part.id, delta: part.text }];
|
|
257
|
+
|
|
258
|
+
case "text-end":
|
|
259
|
+
return [{ type: "text-end", id: options.messageId ?? part.id }];
|
|
260
|
+
|
|
261
|
+
case "source":
|
|
262
|
+
return mapHostedStreamSourceToUiChunks(part, sendSources);
|
|
263
|
+
|
|
264
|
+
case "file":
|
|
265
|
+
return [{
|
|
266
|
+
type: "file",
|
|
267
|
+
mediaType: part.file.mediaType,
|
|
268
|
+
url: `data:${part.file.mediaType};base64,${part.file.base64}`,
|
|
269
|
+
}];
|
|
270
|
+
|
|
271
|
+
case "tool-input-start":
|
|
272
|
+
return [{ type: "tool-input-start", toolCallId: part.id, toolName: part.toolName }];
|
|
273
|
+
|
|
274
|
+
case "tool-input-delta":
|
|
275
|
+
return [{ type: "tool-input-delta", toolCallId: part.id, inputTextDelta: part.delta }];
|
|
276
|
+
|
|
277
|
+
case "tool-call":
|
|
278
|
+
return mapToolCallPartToUiChunks(part, onError);
|
|
279
|
+
|
|
280
|
+
case "tool-approval-request":
|
|
281
|
+
return [{
|
|
282
|
+
type: "tool-approval-request",
|
|
283
|
+
approvalId: part.approvalId,
|
|
284
|
+
toolCallId: part.toolCall.toolCallId,
|
|
285
|
+
}];
|
|
286
|
+
|
|
287
|
+
case "tool-result":
|
|
288
|
+
return [{ type: "tool-output-available", toolCallId: part.toolCallId, output: part.output }];
|
|
289
|
+
|
|
290
|
+
case "tool-error":
|
|
291
|
+
return mapToolErrorPartToUiChunks(part, onError);
|
|
292
|
+
|
|
293
|
+
case "tool-output-denied":
|
|
294
|
+
return [{ type: "tool-output-denied", toolCallId: part.toolCallId }];
|
|
295
|
+
|
|
296
|
+
case "error":
|
|
297
|
+
return [{ type: "error", errorText: onError(part.error) }];
|
|
298
|
+
|
|
299
|
+
case "tool-input-end":
|
|
300
|
+
case "raw":
|
|
301
|
+
return [];
|
|
302
|
+
}
|
|
303
|
+
}
|
package/src/src/chat/index.ts
CHANGED
|
@@ -236,6 +236,11 @@ export {
|
|
|
236
236
|
normalizeChatUiMessageChunk,
|
|
237
237
|
normalizeChatUiMessageStream,
|
|
238
238
|
} from "./chat-ui-message-helpers.js";
|
|
239
|
+
export {
|
|
240
|
+
type HostedStreamPartForUiChunkMapping,
|
|
241
|
+
type HostedUiChunkMappingOptions,
|
|
242
|
+
mapHostedStreamPartToChatUiChunks,
|
|
243
|
+
} from "./hosted-ui-chunk-mapping.js";
|
|
239
244
|
|
|
240
245
|
export {
|
|
241
246
|
useCompletion,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { readRecord } from "./provider-records.js";
|
|
2
|
+
|
|
3
|
+
function isNumberArray(value: unknown): value is number[] {
|
|
4
|
+
return Array.isArray(value) && value.every((entry) => typeof entry === "number");
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function extractOpenAIEmbeddings(payload: unknown): number[][] {
|
|
8
|
+
const record = readRecord(payload);
|
|
9
|
+
const data = record?.data;
|
|
10
|
+
if (!Array.isArray(data)) {
|
|
11
|
+
throw new Error("Invalid OpenAI embedding response: data array missing");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const embeddings: number[][] = [];
|
|
15
|
+
|
|
16
|
+
for (const item of data) {
|
|
17
|
+
const itemRecord = readRecord(item);
|
|
18
|
+
const embedding = itemRecord?.embedding;
|
|
19
|
+
if (!isNumberArray(embedding)) {
|
|
20
|
+
throw new Error("Invalid OpenAI embedding response: embedding vector missing");
|
|
21
|
+
}
|
|
22
|
+
embeddings.push(embedding);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return embeddings;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function extractOpenAIUsageTokens(payload: unknown): number | undefined {
|
|
29
|
+
const record = readRecord(payload);
|
|
30
|
+
const usage = readRecord(record?.usage);
|
|
31
|
+
const totalTokens = usage?.total_tokens;
|
|
32
|
+
return typeof totalTokens === "number" ? totalTokens : undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function extractGoogleEmbedding(payload: unknown): number[] {
|
|
36
|
+
const record = readRecord(payload);
|
|
37
|
+
const embeddings = record?.embeddings;
|
|
38
|
+
|
|
39
|
+
if (Array.isArray(embeddings) && embeddings.length > 0) {
|
|
40
|
+
const firstEmbedding = readRecord(embeddings[0]);
|
|
41
|
+
const values = firstEmbedding?.values;
|
|
42
|
+
if (isNumberArray(values)) {
|
|
43
|
+
return values;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const embedding = readRecord(record?.embedding);
|
|
48
|
+
const values = embedding?.values;
|
|
49
|
+
if (isNumberArray(values)) {
|
|
50
|
+
return values;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
throw new Error("Invalid Google embedding response: embedding vector missing");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function extractGoogleUsageTokens(payload: unknown): number | undefined {
|
|
57
|
+
const record = readRecord(payload);
|
|
58
|
+
const usageMetadata = readRecord(record?.usageMetadata);
|
|
59
|
+
const promptTokenCount = usageMetadata?.promptTokenCount;
|
|
60
|
+
return typeof promptTokenCount === "number" ? promptTokenCount : undefined;
|
|
61
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export type NormalizedFinishReason = string | { unified: string; raw: string } | null;
|
|
2
|
+
|
|
3
|
+
export function normalizeAnthropicFinishReason(raw: unknown): NormalizedFinishReason {
|
|
4
|
+
if (typeof raw !== "string") {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
switch (raw) {
|
|
9
|
+
case "tool_use":
|
|
10
|
+
return { unified: "tool-calls", raw };
|
|
11
|
+
case "end_turn":
|
|
12
|
+
case "stop_sequence":
|
|
13
|
+
return { unified: "stop", raw };
|
|
14
|
+
case "max_tokens":
|
|
15
|
+
return { unified: "length", raw };
|
|
16
|
+
default:
|
|
17
|
+
return raw;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function normalizeGoogleFinishReason(raw: unknown): NormalizedFinishReason {
|
|
22
|
+
if (typeof raw !== "string") {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
switch (raw) {
|
|
27
|
+
case "STOP":
|
|
28
|
+
return { unified: "stop", raw };
|
|
29
|
+
case "MAX_TOKENS":
|
|
30
|
+
return { unified: "length", raw };
|
|
31
|
+
case "SAFETY":
|
|
32
|
+
case "RECITATION":
|
|
33
|
+
return { unified: "content-filter", raw };
|
|
34
|
+
default:
|
|
35
|
+
return raw.toLowerCase();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function normalizeOpenAIFinishReason(raw: unknown): NormalizedFinishReason {
|
|
40
|
+
if (typeof raw !== "string") {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (raw === "tool_calls") {
|
|
45
|
+
return { unified: "tool-calls", raw };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (raw === "content_filter") {
|
|
49
|
+
return { unified: "content-filter", raw };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return raw;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function normalizeOpenAIResponsesFinishReason(raw: unknown): NormalizedFinishReason {
|
|
56
|
+
if (typeof raw !== "string") return null;
|
|
57
|
+
switch (raw) {
|
|
58
|
+
case "completed":
|
|
59
|
+
return { unified: "stop", raw };
|
|
60
|
+
case "incomplete":
|
|
61
|
+
return { unified: "length", raw };
|
|
62
|
+
case "failed":
|
|
63
|
+
return { unified: "error", raw };
|
|
64
|
+
case "in_progress":
|
|
65
|
+
return null;
|
|
66
|
+
default:
|
|
67
|
+
return raw;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function parseSseChunk(chunk: string): {
|
|
2
|
+
events: Array<unknown | "[DONE]">;
|
|
3
|
+
remainder: string;
|
|
4
|
+
} {
|
|
5
|
+
const blocks = chunk.split(/\r?\n\r?\n/);
|
|
6
|
+
const remainder = blocks.pop() ?? "";
|
|
7
|
+
const events = blocks.flatMap((block) => {
|
|
8
|
+
const dataLines = block.split(/\r?\n/)
|
|
9
|
+
.filter((line) => line.startsWith("data:"))
|
|
10
|
+
.map((line) => line.slice(5).trimStart());
|
|
11
|
+
|
|
12
|
+
if (!dataLines.length) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const payload = dataLines.join("\n").trim();
|
|
17
|
+
if (payload === "[DONE]") {
|
|
18
|
+
return ["[DONE]" as const];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
return [JSON.parse(payload) as unknown];
|
|
23
|
+
} catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
return { events, remainder };
|
|
29
|
+
}
|