@codeworksh/aikit 0.4.0 → 0.4.1-dev.20260530133433
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/LICENSE +21 -0
- package/README.md +109 -137
- package/cli.d.mts +1 -0
- package/cli.mjs +308 -0
- package/cli.mjs.map +1 -0
- package/codex-DfYk740t.mjs +521 -0
- package/codex-DfYk740t.mjs.map +1 -0
- package/index.d.mts +7197 -0
- package/index.mjs +1478 -0
- package/index.mjs.map +1 -0
- package/oauth/openai/codex.d.mts +107 -0
- package/oauth/openai/codex.mjs +2 -0
- package/package.json +28 -33
- package/{dist/pack/index.mjs → registry-CYfzJ6lk.mjs} +210 -3300
- package/registry-CYfzJ6lk.mjs.map +1 -0
- package/dist/pack/agent/codemode/drivers/drivers.d.mts +0 -7
- package/dist/pack/agent/codemode/drivers/drivers.mjs +0 -122
- package/dist/pack/agent/codemode/drivers/drivers.mjs.map +0 -1
- package/dist/pack/codemode-BEDXG7WN.d.mts +0 -8736
- package/dist/pack/index.d.mts +0 -71
- package/dist/pack/index.mjs.map +0 -1
- package/src/agent/agent.ts +0 -790
- package/src/agent/codemode/codemode.ts +0 -561
- package/src/agent/codemode/drivers/drivers.ts +0 -1
- package/src/agent/codemode/drivers/quickjs-wasi-driver.ts +0 -149
- package/src/agent/codemode/index.ts +0 -1
- package/src/agent/loop.ts +0 -903
- package/src/agent.ts +0 -11
- package/src/event/event.ts +0 -277
- package/src/index.ts +0 -6
- package/src/llm.ts +0 -31
- package/src/message/message.ts +0 -311
- package/src/model/catalog.ts +0 -94
- package/src/model/model.ts +0 -250
- package/src/model/transform.ts +0 -59
- package/src/provider/provider.ts +0 -60
- package/src/provider/providers/anthropic/index.ts +0 -792
- package/src/provider/providers/github/github.ts +0 -34
- package/src/provider/providers/openai/completions.ts +0 -953
- package/src/provider/providers/utils.ts +0 -7
- package/src/provider/register.ts +0 -6
- package/src/provider/stream.ts +0 -278
- package/src/stream.ts +0 -72
- package/src/utils/eventstream.ts +0 -95
- package/src/utils/helpers.ts +0 -24
- package/src/utils/jsonparse.ts +0 -32
- package/src/utils/overflow.ts +0 -121
- package/src/utils/sanitize.ts +0 -25
- package/src/utils/validation.ts +0 -87
package/index.mjs
ADDED
|
@@ -0,0 +1,1478 @@
|
|
|
1
|
+
import { d as NamedError, i as packageForModel, o as resolveLanguageModel, r as loadProviderFactory, s as Model } from "./registry-CYfzJ6lk.mjs";
|
|
2
|
+
import Type$1, { Type, Type as Type$2 } from "typebox";
|
|
3
|
+
import { uuidv7 } from "uuidv7";
|
|
4
|
+
import Value from "typebox/value";
|
|
5
|
+
import { jsonSchema, streamText } from "ai";
|
|
6
|
+
import { parse } from "partial-json";
|
|
7
|
+
import Schema from "typebox/schema";
|
|
8
|
+
//#region src/message/message.ts
|
|
9
|
+
let Message;
|
|
10
|
+
(function(_Message) {
|
|
11
|
+
const TextContentSchema = _Message.TextContentSchema = Type$1.Object({
|
|
12
|
+
type: Type$1.Literal("text"),
|
|
13
|
+
text: Type$1.String(),
|
|
14
|
+
textSignature: Type$1.Optional(Type$1.String())
|
|
15
|
+
});
|
|
16
|
+
const ImageContentSchema = _Message.ImageContentSchema = Type$1.Object({
|
|
17
|
+
type: Type$1.Literal("image"),
|
|
18
|
+
data: Type$1.String(),
|
|
19
|
+
mimeType: Type$1.String()
|
|
20
|
+
});
|
|
21
|
+
const ThinkingContentSchema = _Message.ThinkingContentSchema = Type$1.Object({
|
|
22
|
+
type: Type$1.Literal("thinking"),
|
|
23
|
+
thinking: Type$1.String(),
|
|
24
|
+
thinkingSignature: Type$1.Optional(Type$1.String()),
|
|
25
|
+
redacted: Type$1.Optional(Type$1.Boolean())
|
|
26
|
+
});
|
|
27
|
+
const ToolCallBaseSchema = _Message.ToolCallBaseSchema = Type$1.Object({
|
|
28
|
+
type: Type$1.Literal("toolCall"),
|
|
29
|
+
callID: Type$1.String(),
|
|
30
|
+
name: Type$1.String(),
|
|
31
|
+
arguments: Type$1.Record(Type$1.String(), Type$1.Any()),
|
|
32
|
+
thoughtSignature: Type$1.Optional(Type$1.String()),
|
|
33
|
+
time: Type$1.Object({
|
|
34
|
+
start: Type$1.Number(),
|
|
35
|
+
end: Type$1.Number()
|
|
36
|
+
})
|
|
37
|
+
});
|
|
38
|
+
const ToolSuccessResult = _Message.ToolSuccessResult = Type$1.Object({
|
|
39
|
+
content: Type$1.Array(Type$1.Union([TextContentSchema, ImageContentSchema])),
|
|
40
|
+
details: Type$1.Optional(Type$1.Any()),
|
|
41
|
+
isError: Type$1.Literal(false)
|
|
42
|
+
});
|
|
43
|
+
const ToolErrorResult = _Message.ToolErrorResult = Type$1.Object({
|
|
44
|
+
content: Type$1.Array(Type$1.Union([TextContentSchema, ImageContentSchema])),
|
|
45
|
+
details: Type$1.Optional(Type$1.Any()),
|
|
46
|
+
isError: Type$1.Literal(true)
|
|
47
|
+
});
|
|
48
|
+
const ToolRunningPartial = _Message.ToolRunningPartial = Type$1.Object({
|
|
49
|
+
content: Type$1.Optional(Type$1.Array(Type$1.Union([TextContentSchema, ImageContentSchema]))),
|
|
50
|
+
details: Type$1.Optional(Type$1.Any())
|
|
51
|
+
});
|
|
52
|
+
const ToolStatusEnum = _Message.ToolStatusEnum = {
|
|
53
|
+
pending: "pending",
|
|
54
|
+
running: "running",
|
|
55
|
+
completed: "completed",
|
|
56
|
+
error: "error",
|
|
57
|
+
skipped: "skipped",
|
|
58
|
+
aborted: "aborted"
|
|
59
|
+
};
|
|
60
|
+
const ToolRunningSchema = _Message.ToolRunningSchema = Type$1.Object({
|
|
61
|
+
status: Type$1.Literal(ToolStatusEnum.running),
|
|
62
|
+
partial: Type$1.Optional(ToolRunningPartial)
|
|
63
|
+
});
|
|
64
|
+
const ToolCompletedSchema = _Message.ToolCompletedSchema = Type$1.Object({
|
|
65
|
+
status: Type$1.Literal(ToolStatusEnum.completed),
|
|
66
|
+
result: ToolSuccessResult
|
|
67
|
+
});
|
|
68
|
+
const ToolErrorSchema = _Message.ToolErrorSchema = Type$1.Object({
|
|
69
|
+
status: Type$1.Literal(ToolStatusEnum.error),
|
|
70
|
+
result: ToolErrorResult
|
|
71
|
+
});
|
|
72
|
+
const ToolSkippedSchema = _Message.ToolSkippedSchema = Type$1.Object({
|
|
73
|
+
status: Type$1.Literal(ToolStatusEnum.skipped),
|
|
74
|
+
result: ToolErrorResult
|
|
75
|
+
});
|
|
76
|
+
const ToolAbortedSchema = _Message.ToolAbortedSchema = Type$1.Object({
|
|
77
|
+
status: Type$1.Literal(ToolStatusEnum.aborted),
|
|
78
|
+
result: ToolErrorResult
|
|
79
|
+
});
|
|
80
|
+
const ToolCallPendingPart = Type$1.Intersect([ToolCallBaseSchema, Type$1.Object({ status: Type$1.Literal(ToolStatusEnum.pending) })]);
|
|
81
|
+
const ToolCallRunningPart = Type$1.Evaluate(Type$1.Intersect([ToolCallBaseSchema, ToolRunningSchema]));
|
|
82
|
+
const ToolCallCompletedPart = Type$1.Evaluate(Type$1.Intersect([ToolCallBaseSchema, ToolCompletedSchema]));
|
|
83
|
+
const ToolCallErrorPart = Type$1.Evaluate(Type$1.Intersect([ToolCallBaseSchema, ToolErrorSchema]));
|
|
84
|
+
const ToolCallSkippedPart = Type$1.Evaluate(Type$1.Intersect([ToolCallBaseSchema, ToolSkippedSchema]));
|
|
85
|
+
const ToolCallAbortedPart = Type$1.Evaluate(Type$1.Intersect([ToolCallBaseSchema, ToolAbortedSchema]));
|
|
86
|
+
_Message.ToolCallInFlightSchema = Type$1.Object({
|
|
87
|
+
callID: Type$1.String(),
|
|
88
|
+
name: Type$1.String(),
|
|
89
|
+
rawArgs: Type$1.Record(Type$1.String(), Type$1.Unknown()),
|
|
90
|
+
args: Type$1.Optional(Type$1.Unknown())
|
|
91
|
+
});
|
|
92
|
+
const ToolCallSchema = _Message.ToolCallSchema = Type$1.Union([
|
|
93
|
+
ToolCallPendingPart,
|
|
94
|
+
ToolCallRunningPart,
|
|
95
|
+
ToolCallCompletedPart,
|
|
96
|
+
ToolCallErrorPart,
|
|
97
|
+
ToolCallSkippedPart,
|
|
98
|
+
ToolCallAbortedPart
|
|
99
|
+
]);
|
|
100
|
+
const UsageSchema = _Message.UsageSchema = Type$1.Object({
|
|
101
|
+
input: Type$1.Number(),
|
|
102
|
+
output: Type$1.Number(),
|
|
103
|
+
cacheRead: Type$1.Number(),
|
|
104
|
+
cacheWrite: Type$1.Number(),
|
|
105
|
+
totalTokens: Type$1.Number(),
|
|
106
|
+
cost: Type$1.Object({
|
|
107
|
+
input: Type$1.Number(),
|
|
108
|
+
output: Type$1.Number(),
|
|
109
|
+
cacheRead: Type$1.Number(),
|
|
110
|
+
cacheWrite: Type$1.Number(),
|
|
111
|
+
total: Type$1.Number()
|
|
112
|
+
})
|
|
113
|
+
});
|
|
114
|
+
const StopReasonSchema = _Message.StopReasonSchema = Type$1.Union([
|
|
115
|
+
Type$1.Literal("stop"),
|
|
116
|
+
Type$1.Literal("length"),
|
|
117
|
+
Type$1.Literal("toolUse"),
|
|
118
|
+
Type$1.Literal("error"),
|
|
119
|
+
Type$1.Literal("aborted")
|
|
120
|
+
]);
|
|
121
|
+
const UserMessageSchema = _Message.UserMessageSchema = Type$1.Object({
|
|
122
|
+
messageId: Type$1.String(),
|
|
123
|
+
role: Type$1.Literal("user"),
|
|
124
|
+
time: Type$1.Object({ created: Type$1.Number() }),
|
|
125
|
+
parts: Type$1.Array(Type$1.Union([TextContentSchema, ImageContentSchema]))
|
|
126
|
+
});
|
|
127
|
+
const AssistantMessageSchema = _Message.AssistantMessageSchema = Type$1.Object({
|
|
128
|
+
role: Type$1.Literal("assistant"),
|
|
129
|
+
protocol: Model.KnownProviderEnumSchema,
|
|
130
|
+
provider: Model.ProviderInfo,
|
|
131
|
+
model: Type$1.String(),
|
|
132
|
+
usage: UsageSchema,
|
|
133
|
+
stopReason: StopReasonSchema,
|
|
134
|
+
errorMessage: Type$1.Optional(Type$1.String()),
|
|
135
|
+
time: Type$1.Object({
|
|
136
|
+
created: Type$1.Number(),
|
|
137
|
+
completed: Type$1.Number()
|
|
138
|
+
}),
|
|
139
|
+
parts: Type$1.Array(Type$1.Union([
|
|
140
|
+
TextContentSchema,
|
|
141
|
+
ImageContentSchema,
|
|
142
|
+
ThinkingContentSchema,
|
|
143
|
+
ToolCallSchema
|
|
144
|
+
])),
|
|
145
|
+
responseId: Type$1.Optional(Type$1.String()),
|
|
146
|
+
responseModel: Type$1.Optional(Type$1.String()),
|
|
147
|
+
messageId: Type$1.String()
|
|
148
|
+
});
|
|
149
|
+
const MessageSchema = _Message.MessageSchema = Type$1.Union([UserMessageSchema, AssistantMessageSchema]);
|
|
150
|
+
function createMessageId() {
|
|
151
|
+
return uuidv7();
|
|
152
|
+
}
|
|
153
|
+
_Message.createMessageId = createMessageId;
|
|
154
|
+
function createUserMessage(message) {
|
|
155
|
+
const { messageId = createMessageId(), ...rest } = message;
|
|
156
|
+
return {
|
|
157
|
+
messageId,
|
|
158
|
+
...rest
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
_Message.createUserMessage = createUserMessage;
|
|
162
|
+
function createAssistantMessage(message) {
|
|
163
|
+
const { messageId = createMessageId(), ...rest } = message;
|
|
164
|
+
return {
|
|
165
|
+
messageId,
|
|
166
|
+
...rest
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
_Message.createAssistantMessage = createAssistantMessage;
|
|
170
|
+
const ToolSchema = _Message.ToolSchema = Type$1.Object({
|
|
171
|
+
name: Type$1.String(),
|
|
172
|
+
description: Type$1.String(),
|
|
173
|
+
parameters: Type$1.Unsafe({})
|
|
174
|
+
});
|
|
175
|
+
function defineTool(tool) {
|
|
176
|
+
return tool;
|
|
177
|
+
}
|
|
178
|
+
_Message.defineTool = defineTool;
|
|
179
|
+
_Message.ContextSchema = Type$1.Object({
|
|
180
|
+
systemPrompt: Type$1.Optional(Type$1.String()),
|
|
181
|
+
messages: Type$1.Array(MessageSchema),
|
|
182
|
+
tools: Type$1.Optional(Type$1.Array(ToolSchema))
|
|
183
|
+
});
|
|
184
|
+
function isUnresolvedToolCall(toolCall) {
|
|
185
|
+
return toolCall.status === ToolStatusEnum.pending || toolCall.status === ToolStatusEnum.running;
|
|
186
|
+
}
|
|
187
|
+
function syntheticSkippedToolCall(toolCall) {
|
|
188
|
+
const { status: _status, partial: _partial, ...base } = toolCall;
|
|
189
|
+
return {
|
|
190
|
+
...base,
|
|
191
|
+
status: ToolStatusEnum.skipped,
|
|
192
|
+
result: {
|
|
193
|
+
content: [{
|
|
194
|
+
type: "text",
|
|
195
|
+
text: "No result provided"
|
|
196
|
+
}],
|
|
197
|
+
isError: true
|
|
198
|
+
},
|
|
199
|
+
time: {
|
|
200
|
+
...toolCall.time,
|
|
201
|
+
end: Math.max(toolCall.time.end, Date.now())
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function transformMessages(messages, model, normalizeToolCallId) {
|
|
206
|
+
const toolCallIDMap = /* @__PURE__ */ new Map();
|
|
207
|
+
const transformed = [];
|
|
208
|
+
for (const msg of messages) {
|
|
209
|
+
if (msg.role === "user") {
|
|
210
|
+
transformed.push(msg);
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
const assistantMsg = msg;
|
|
214
|
+
const isSameModel = assistantMsg.provider.id === model.provider.id && assistantMsg.protocol === model.protocol && assistantMsg.model === model.id;
|
|
215
|
+
const parts = assistantMsg.parts.flatMap((block) => {
|
|
216
|
+
if (block.type === "thinking") {
|
|
217
|
+
if (isSameModel && block.thinkingSignature) return block;
|
|
218
|
+
if (!block.thinking || block.thinking.trim() === "") return [];
|
|
219
|
+
if (isSameModel) return block;
|
|
220
|
+
return {
|
|
221
|
+
type: "text",
|
|
222
|
+
text: block.thinking
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
if (block.type === "text") {
|
|
226
|
+
if (isSameModel) return block;
|
|
227
|
+
return {
|
|
228
|
+
type: "text",
|
|
229
|
+
text: block.text
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
if (block.type === "toolCall") {
|
|
233
|
+
const toolCall = block;
|
|
234
|
+
let normalizedToolCall = toolCall;
|
|
235
|
+
if (!isSameModel && toolCall.thoughtSignature) {
|
|
236
|
+
normalizedToolCall = { ...toolCall };
|
|
237
|
+
delete normalizedToolCall.thoughtSignature;
|
|
238
|
+
}
|
|
239
|
+
const normalizedID = toolCallIDMap.get(block.callID);
|
|
240
|
+
if (normalizedID && normalizedID !== block.callID) normalizedToolCall = {
|
|
241
|
+
...normalizedToolCall,
|
|
242
|
+
callID: normalizedID
|
|
243
|
+
};
|
|
244
|
+
else if (!isSameModel && normalizeToolCallId) {
|
|
245
|
+
const nextID = normalizeToolCallId(toolCall.callID, model, assistantMsg);
|
|
246
|
+
if (nextID !== toolCall.callID) {
|
|
247
|
+
toolCallIDMap.set(toolCall.callID, nextID);
|
|
248
|
+
normalizedToolCall = {
|
|
249
|
+
...normalizedToolCall,
|
|
250
|
+
callID: nextID
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return normalizedToolCall;
|
|
255
|
+
}
|
|
256
|
+
return block;
|
|
257
|
+
}).map((block) => {
|
|
258
|
+
if (block.type === "toolCall" && isUnresolvedToolCall(block)) return syntheticSkippedToolCall(block);
|
|
259
|
+
return block;
|
|
260
|
+
});
|
|
261
|
+
transformed.push({
|
|
262
|
+
...assistantMsg,
|
|
263
|
+
parts
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
return transformed;
|
|
267
|
+
}
|
|
268
|
+
_Message.transformMessages = transformMessages;
|
|
269
|
+
})(Message || (Message = {}));
|
|
270
|
+
//#endregion
|
|
271
|
+
//#region src/event/event.ts
|
|
272
|
+
let Event;
|
|
273
|
+
(function(_Event) {
|
|
274
|
+
const LLMMessageEventType = _Event.LLMMessageEventType = {
|
|
275
|
+
start: "start",
|
|
276
|
+
textStart: "text.start",
|
|
277
|
+
textDelta: "text.delta",
|
|
278
|
+
textEnd: "text.end",
|
|
279
|
+
thinkingStart: "thinking.start",
|
|
280
|
+
thinkingDelta: "thinking.delta",
|
|
281
|
+
thinkingEnd: "thinking.end",
|
|
282
|
+
toolcallStart: "toolcall.start",
|
|
283
|
+
toolcallDelta: "toolcall.delta",
|
|
284
|
+
toolcallEnd: "toolcall.end",
|
|
285
|
+
toolcallFinal: "toolcall.final",
|
|
286
|
+
done: "done",
|
|
287
|
+
error: "error"
|
|
288
|
+
};
|
|
289
|
+
_Event.LLMMessageEventSchema = Type$1.Union([
|
|
290
|
+
Type$1.Object({
|
|
291
|
+
type: Type$1.Literal(LLMMessageEventType.start),
|
|
292
|
+
partial: Message.AssistantMessageSchema
|
|
293
|
+
}),
|
|
294
|
+
Type$1.Object({
|
|
295
|
+
type: Type$1.Literal(LLMMessageEventType.textStart),
|
|
296
|
+
partIndex: Type$1.Number(),
|
|
297
|
+
partial: Message.AssistantMessageSchema
|
|
298
|
+
}),
|
|
299
|
+
Type$1.Object({
|
|
300
|
+
type: Type$1.Literal(LLMMessageEventType.textDelta),
|
|
301
|
+
partIndex: Type$1.Number(),
|
|
302
|
+
delta: Type$1.String(),
|
|
303
|
+
partial: Message.AssistantMessageSchema
|
|
304
|
+
}),
|
|
305
|
+
Type$1.Object({
|
|
306
|
+
type: Type$1.Literal(LLMMessageEventType.textEnd),
|
|
307
|
+
partIndex: Type$1.Number(),
|
|
308
|
+
content: Type$1.String(),
|
|
309
|
+
partial: Message.AssistantMessageSchema
|
|
310
|
+
}),
|
|
311
|
+
Type$1.Object({
|
|
312
|
+
type: Type$1.Literal(LLMMessageEventType.thinkingStart),
|
|
313
|
+
partIndex: Type$1.Number(),
|
|
314
|
+
partial: Message.AssistantMessageSchema
|
|
315
|
+
}),
|
|
316
|
+
Type$1.Object({
|
|
317
|
+
type: Type$1.Literal(LLMMessageEventType.thinkingDelta),
|
|
318
|
+
partIndex: Type$1.Number(),
|
|
319
|
+
delta: Type$1.String(),
|
|
320
|
+
partial: Message.AssistantMessageSchema
|
|
321
|
+
}),
|
|
322
|
+
Type$1.Object({
|
|
323
|
+
type: Type$1.Literal(LLMMessageEventType.thinkingEnd),
|
|
324
|
+
partIndex: Type$1.Number(),
|
|
325
|
+
content: Type$1.String(),
|
|
326
|
+
partial: Message.AssistantMessageSchema
|
|
327
|
+
}),
|
|
328
|
+
Type$1.Object({
|
|
329
|
+
type: Type$1.Literal(LLMMessageEventType.toolcallStart),
|
|
330
|
+
partIndex: Type$1.Number(),
|
|
331
|
+
partial: Message.AssistantMessageSchema
|
|
332
|
+
}),
|
|
333
|
+
Type$1.Object({
|
|
334
|
+
type: Type$1.Literal(LLMMessageEventType.toolcallDelta),
|
|
335
|
+
partIndex: Type$1.Number(),
|
|
336
|
+
delta: Type$1.String(),
|
|
337
|
+
partial: Message.AssistantMessageSchema
|
|
338
|
+
}),
|
|
339
|
+
Type$1.Object({
|
|
340
|
+
type: Type$1.Literal(LLMMessageEventType.toolcallEnd),
|
|
341
|
+
partIndex: Type$1.Number(),
|
|
342
|
+
toolCall: Message.ToolCallSchema,
|
|
343
|
+
partial: Message.AssistantMessageSchema
|
|
344
|
+
}),
|
|
345
|
+
Type$1.Object({
|
|
346
|
+
type: Type$1.Literal(LLMMessageEventType.toolcallFinal),
|
|
347
|
+
partIndex: Type$1.Number(),
|
|
348
|
+
toolCall: Message.ToolCallSchema,
|
|
349
|
+
partial: Message.AssistantMessageSchema
|
|
350
|
+
}),
|
|
351
|
+
Type$1.Object({
|
|
352
|
+
type: Type$1.Literal(LLMMessageEventType.done),
|
|
353
|
+
reason: Type$1.Union([
|
|
354
|
+
Type$1.Literal("stop"),
|
|
355
|
+
Type$1.Literal("length"),
|
|
356
|
+
Type$1.Literal("toolUse")
|
|
357
|
+
]),
|
|
358
|
+
message: Message.AssistantMessageSchema
|
|
359
|
+
}),
|
|
360
|
+
Type$1.Object({
|
|
361
|
+
type: Type$1.Literal(LLMMessageEventType.error),
|
|
362
|
+
reason: Type$1.Union([Type$1.Literal("aborted"), Type$1.Literal("error")]),
|
|
363
|
+
error: Message.AssistantMessageSchema
|
|
364
|
+
})
|
|
365
|
+
]);
|
|
366
|
+
const AgentEventType = _Event.AgentEventType = {
|
|
367
|
+
agentStart: "agent.start",
|
|
368
|
+
agentEnd: "agent.end",
|
|
369
|
+
turnStart: "turn.start",
|
|
370
|
+
turnEnd: "turn.end",
|
|
371
|
+
messageStart: "message.start",
|
|
372
|
+
messagePartStart: "message.part.start",
|
|
373
|
+
messagePartUpdate: "message.part.update",
|
|
374
|
+
messagePartEnd: "message.part.end",
|
|
375
|
+
messageUpdate: "message.update",
|
|
376
|
+
messageEnd: "message.end",
|
|
377
|
+
toolExecutionStart: "tool.execution.start",
|
|
378
|
+
toolExecutionUpdate: "tool.execution.update",
|
|
379
|
+
toolExecutionEnd: "tool.execution.end"
|
|
380
|
+
};
|
|
381
|
+
const UserMessagePart = Type$1.Union([Message.TextContentSchema, Message.ImageContentSchema]);
|
|
382
|
+
const AssistantMessagePart = Type$1.Union([
|
|
383
|
+
Message.TextContentSchema,
|
|
384
|
+
Message.ImageContentSchema,
|
|
385
|
+
Message.ThinkingContentSchema,
|
|
386
|
+
Message.ToolCallSchema
|
|
387
|
+
]);
|
|
388
|
+
const UserMessagePartStart = Type$1.Object({
|
|
389
|
+
type: Type$1.Literal(AgentEventType.messagePartStart),
|
|
390
|
+
message: Message.UserMessageSchema,
|
|
391
|
+
partIndex: Type$1.Number(),
|
|
392
|
+
part: UserMessagePart
|
|
393
|
+
});
|
|
394
|
+
const UserMessagePartEnd = Type$1.Object({
|
|
395
|
+
type: Type$1.Literal(AgentEventType.messagePartEnd),
|
|
396
|
+
message: Message.UserMessageSchema,
|
|
397
|
+
partIndex: Type$1.Number(),
|
|
398
|
+
part: UserMessagePart
|
|
399
|
+
});
|
|
400
|
+
const AssistantMessagePartStart = Type$1.Object({
|
|
401
|
+
type: Type$1.Literal(AgentEventType.messagePartStart),
|
|
402
|
+
message: Message.AssistantMessageSchema,
|
|
403
|
+
partIndex: Type$1.Number(),
|
|
404
|
+
part: AssistantMessagePart
|
|
405
|
+
});
|
|
406
|
+
const AssistantMessagePartLLMUpdate = Type$1.Object({
|
|
407
|
+
type: Type$1.Literal(AgentEventType.messagePartUpdate),
|
|
408
|
+
message: Message.AssistantMessageSchema,
|
|
409
|
+
partIndex: Type$1.Number(),
|
|
410
|
+
part: AssistantMessagePart,
|
|
411
|
+
source: Type$1.Literal("llm")
|
|
412
|
+
});
|
|
413
|
+
const AssistantMessagePartToolUpdate = Type$1.Object({
|
|
414
|
+
type: Type$1.Literal(AgentEventType.messagePartUpdate),
|
|
415
|
+
message: Message.AssistantMessageSchema,
|
|
416
|
+
partIndex: Type$1.Number(),
|
|
417
|
+
part: AssistantMessagePart,
|
|
418
|
+
source: Type$1.Literal("tool")
|
|
419
|
+
});
|
|
420
|
+
const AssistantMessagePartEnd = Type$1.Object({
|
|
421
|
+
type: Type$1.Literal(AgentEventType.messagePartEnd),
|
|
422
|
+
message: Message.AssistantMessageSchema,
|
|
423
|
+
partIndex: Type$1.Number(),
|
|
424
|
+
part: AssistantMessagePart
|
|
425
|
+
});
|
|
426
|
+
const ToolExecutionStartSchema = Type$1.Evaluate(Type$1.Intersect([Message.ToolCallInFlightSchema, Type$1.Object({ type: Type$1.Literal(AgentEventType.toolExecutionStart) })]));
|
|
427
|
+
const ToolExecutionUpdateSchema = Type$1.Evaluate(Type$1.Intersect([
|
|
428
|
+
Message.ToolCallInFlightSchema,
|
|
429
|
+
Type$1.Object({ type: Type$1.Literal(AgentEventType.toolExecutionUpdate) }),
|
|
430
|
+
Message.ToolRunningSchema
|
|
431
|
+
]));
|
|
432
|
+
const ToolExecutionEndSchema = Type$1.Evaluate(Type$1.Intersect([
|
|
433
|
+
Message.ToolCallInFlightSchema,
|
|
434
|
+
Type$1.Object({ type: Type$1.Literal(AgentEventType.toolExecutionEnd) }),
|
|
435
|
+
Type$1.Union([Message.ToolCompletedSchema, Message.ToolErrorSchema])
|
|
436
|
+
]));
|
|
437
|
+
_Event.AgentEventSchema = Type$1.Union([
|
|
438
|
+
Type$1.Object({ type: Type$1.Literal(AgentEventType.agentStart) }),
|
|
439
|
+
Type$1.Object({
|
|
440
|
+
type: Type$1.Literal(AgentEventType.agentEnd),
|
|
441
|
+
messages: Type$1.Array(Message.MessageSchema)
|
|
442
|
+
}),
|
|
443
|
+
Type$1.Object({ type: Type$1.Literal(AgentEventType.turnStart) }),
|
|
444
|
+
Type$1.Object({
|
|
445
|
+
type: Type$1.Literal(AgentEventType.turnEnd),
|
|
446
|
+
message: Message.AssistantMessageSchema
|
|
447
|
+
}),
|
|
448
|
+
Type$1.Object({
|
|
449
|
+
type: Type$1.Literal(AgentEventType.messageStart),
|
|
450
|
+
message: Message.MessageSchema
|
|
451
|
+
}),
|
|
452
|
+
Type$1.Union([UserMessagePartStart, UserMessagePartEnd]),
|
|
453
|
+
Type$1.Union([
|
|
454
|
+
AssistantMessagePartStart,
|
|
455
|
+
AssistantMessagePartLLMUpdate,
|
|
456
|
+
AssistantMessagePartToolUpdate,
|
|
457
|
+
AssistantMessagePartEnd
|
|
458
|
+
]),
|
|
459
|
+
Type$1.Object({
|
|
460
|
+
type: Type$1.Literal(AgentEventType.messageUpdate),
|
|
461
|
+
message: Message.MessageSchema
|
|
462
|
+
}),
|
|
463
|
+
Type$1.Object({
|
|
464
|
+
type: Type$1.Literal(AgentEventType.messageEnd),
|
|
465
|
+
message: Message.MessageSchema
|
|
466
|
+
}),
|
|
467
|
+
ToolExecutionStartSchema,
|
|
468
|
+
ToolExecutionUpdateSchema,
|
|
469
|
+
ToolExecutionEndSchema
|
|
470
|
+
]);
|
|
471
|
+
})(Event || (Event = {}));
|
|
472
|
+
//#endregion
|
|
473
|
+
//#region src/llm.ts
|
|
474
|
+
const llmImpl = async (provider, model, overrides) => Model.getModel(provider, model, overrides);
|
|
475
|
+
const llm = Object.assign(llmImpl, {
|
|
476
|
+
model: Model.getModel,
|
|
477
|
+
models: Model.getModels,
|
|
478
|
+
providers: Model.getProviders,
|
|
479
|
+
registry: Model.registry,
|
|
480
|
+
modelsAreEqual: Model.modelsAreEqual
|
|
481
|
+
});
|
|
482
|
+
//#endregion
|
|
483
|
+
//#region src/llm/protocol.ts
|
|
484
|
+
let Protocol;
|
|
485
|
+
(function(_Protocol) {
|
|
486
|
+
const ProviderProtocolNotFoundError = _Protocol.ProviderProtocolNotFoundError = NamedError.create("ProviderProtocolNotFoundError", Type$1.Object({ protocol: Model.KnownProviderEnumSchema }));
|
|
487
|
+
const ProtocolMismatchError = _Protocol.ProtocolMismatchError = NamedError.create("ProtocolMismatchError", Type$1.Object({
|
|
488
|
+
actual: Model.KnownProviderEnumSchema,
|
|
489
|
+
expected: Model.KnownProviderEnumSchema
|
|
490
|
+
}));
|
|
491
|
+
_Protocol.ProtocolAuthError = NamedError.create("ProtocolAuthError", Type$1.Object({
|
|
492
|
+
message: Type$1.String(),
|
|
493
|
+
protocol: Type$1.String()
|
|
494
|
+
}));
|
|
495
|
+
const protocolRegistry = /* @__PURE__ */ new Map();
|
|
496
|
+
function wrapStream(protocol, stream) {
|
|
497
|
+
return (model, context, options) => {
|
|
498
|
+
if (model.protocol !== protocol) throw new ProtocolMismatchError({
|
|
499
|
+
actual: model.protocol,
|
|
500
|
+
expected: protocol
|
|
501
|
+
});
|
|
502
|
+
return stream(model, context, options);
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
function registerProtocolProvider(provider, sourceId) {
|
|
506
|
+
const registered = {
|
|
507
|
+
protocol: provider.protocol,
|
|
508
|
+
stream: wrapStream(provider.protocol, provider.stream)
|
|
509
|
+
};
|
|
510
|
+
protocolRegistry.set(provider.protocol, {
|
|
511
|
+
provider: registered,
|
|
512
|
+
sourceId
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
_Protocol.registerProtocolProvider = registerProtocolProvider;
|
|
516
|
+
function getProtocolProvider(protocol) {
|
|
517
|
+
return protocolRegistry.get(protocol)?.provider;
|
|
518
|
+
}
|
|
519
|
+
_Protocol.getProtocolProvider = getProtocolProvider;
|
|
520
|
+
function resolveProtocolProvider(model) {
|
|
521
|
+
const provider = getProtocolProvider(model.protocol);
|
|
522
|
+
if (!provider) throw new ProviderProtocolNotFoundError({ protocol: model.protocol });
|
|
523
|
+
return provider;
|
|
524
|
+
}
|
|
525
|
+
_Protocol.resolveProtocolProvider = resolveProtocolProvider;
|
|
526
|
+
function getProtocolProviders() {
|
|
527
|
+
return Array.from(protocolRegistry.values(), (entry) => entry.provider);
|
|
528
|
+
}
|
|
529
|
+
_Protocol.getProtocolProviders = getProtocolProviders;
|
|
530
|
+
function stream(model, context, options) {
|
|
531
|
+
return resolveProtocolProvider(model).stream(model, context, options);
|
|
532
|
+
}
|
|
533
|
+
_Protocol.stream = stream;
|
|
534
|
+
async function complete(model, context, options) {
|
|
535
|
+
return stream(model, context, options).result();
|
|
536
|
+
}
|
|
537
|
+
_Protocol.complete = complete;
|
|
538
|
+
function unregisterProtocolProviders(sourceId) {
|
|
539
|
+
for (const [protocol, entry] of protocolRegistry.entries()) if (entry.sourceId === sourceId) protocolRegistry.delete(protocol);
|
|
540
|
+
}
|
|
541
|
+
_Protocol.unregisterProtocolProviders = unregisterProtocolProviders;
|
|
542
|
+
function clearProtocolProviders() {
|
|
543
|
+
protocolRegistry.clear();
|
|
544
|
+
}
|
|
545
|
+
_Protocol.clearProtocolProviders = clearProtocolProviders;
|
|
546
|
+
})(Protocol || (Protocol = {}));
|
|
547
|
+
//#endregion
|
|
548
|
+
//#region src/llm/shared.ts
|
|
549
|
+
const CacheRetention = Type$2.Union([
|
|
550
|
+
Type$2.Literal("none"),
|
|
551
|
+
Type$2.Literal("short"),
|
|
552
|
+
Type$2.Literal("long")
|
|
553
|
+
]);
|
|
554
|
+
const GenerationOptions = Type$2.Object({
|
|
555
|
+
maxTokens: Type$2.Optional(Type$2.Number()),
|
|
556
|
+
temperature: Type$2.Optional(Type$2.Number()),
|
|
557
|
+
cacheRetention: Type$2.Optional(CacheRetention)
|
|
558
|
+
});
|
|
559
|
+
const HelperOptions = Type$2.Object({
|
|
560
|
+
headers: Type$2.Optional(Type$2.Record(Type$2.String(), Type$2.String())),
|
|
561
|
+
sessionId: Type$2.Optional(Type$2.String()),
|
|
562
|
+
apiKey: Type$2.Optional(Type$2.String()),
|
|
563
|
+
timeoutMs: Type$2.Optional(Type$2.Number()),
|
|
564
|
+
maxRetries: Type$2.Optional(Type$2.Number()),
|
|
565
|
+
signal: Type$2.Optional(Type$2.Unsafe({})),
|
|
566
|
+
onPayload: Type$2.Optional(Type$2.Unsafe({})),
|
|
567
|
+
metadata: Type$2.Optional(Type$2.Record(Type$2.String(), Type$2.Unknown()))
|
|
568
|
+
});
|
|
569
|
+
const ThinkingBudgets = Type$2.Object({
|
|
570
|
+
minimal: Type$2.Optional(Type$2.Number()),
|
|
571
|
+
low: Type$2.Optional(Type$2.Number()),
|
|
572
|
+
medium: Type$2.Optional(Type$2.Number()),
|
|
573
|
+
high: Type$2.Optional(Type$2.Number()),
|
|
574
|
+
xhigh: Type$2.Optional(Type$2.Number())
|
|
575
|
+
});
|
|
576
|
+
const SharedOptions = Type$2.Evaluate(Type$2.Intersect([GenerationOptions, HelperOptions]));
|
|
577
|
+
const DEFAULT_MAX_OUTPUT_TOKENS = 32e3;
|
|
578
|
+
const CONTEXT_WINDOW_OUTPUT_TOLERANCE = 1024;
|
|
579
|
+
function applyDefaultMaxTokens(model, options) {
|
|
580
|
+
const defaultMaxTokens = model.maxTokens > 0 ? model.maxTokens >= model.contextWindow - CONTEXT_WINDOW_OUTPUT_TOLERANCE ? Math.min(model.maxTokens, DEFAULT_MAX_OUTPUT_TOKENS) : model.maxTokens : void 0;
|
|
581
|
+
return {
|
|
582
|
+
...options,
|
|
583
|
+
maxTokens: options?.maxTokens ?? defaultMaxTokens
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
Type$2.Evaluate(Type$2.Intersect([SharedOptions, Type$2.Object({
|
|
587
|
+
baseURL: Type$2.Optional(Type$2.String()),
|
|
588
|
+
method: Type$2.Optional(Model.APIMethodEnumSchema),
|
|
589
|
+
modelId: Type$2.Optional(Type$2.String()),
|
|
590
|
+
reasoning: Type$2.Optional(Model.ActiveThinkingLevel),
|
|
591
|
+
thinkingBudgets: Type$2.Optional(ThinkingBudgets),
|
|
592
|
+
toolChoice: Type$2.Optional(Type$2.Any()),
|
|
593
|
+
activeTools: Type$2.Optional(Type$2.Array(Type$2.String())),
|
|
594
|
+
factoryOptions: Type$2.Optional(Type$2.Record(Type$2.String(), Type$2.Unknown())),
|
|
595
|
+
providerOptions: Type$2.Optional(Type$2.Record(Type$2.String(), Type$2.Record(Type$2.String(), Type$2.Unknown())))
|
|
596
|
+
})]));
|
|
597
|
+
//#endregion
|
|
598
|
+
//#region src/utils/eventstream.ts
|
|
599
|
+
var EventStream = class {
|
|
600
|
+
queue = [];
|
|
601
|
+
waiting = [];
|
|
602
|
+
done = false;
|
|
603
|
+
finalResultPromise;
|
|
604
|
+
resolveFinalResult;
|
|
605
|
+
constructor(isComplete, extractResult) {
|
|
606
|
+
this.isComplete = isComplete;
|
|
607
|
+
this.extractResult = extractResult;
|
|
608
|
+
this.finalResultPromise = new Promise((resolve) => {
|
|
609
|
+
this.resolveFinalResult = resolve;
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
push(event) {
|
|
613
|
+
if (this.done) return;
|
|
614
|
+
if (this.isComplete(event)) {
|
|
615
|
+
this.done = true;
|
|
616
|
+
this.resolveFinalResult(this.extractResult(event));
|
|
617
|
+
}
|
|
618
|
+
const waiter = this.waiting.shift();
|
|
619
|
+
if (waiter) waiter({
|
|
620
|
+
value: event,
|
|
621
|
+
done: false
|
|
622
|
+
});
|
|
623
|
+
else this.queue.push(event);
|
|
624
|
+
}
|
|
625
|
+
end(result) {
|
|
626
|
+
this.done = true;
|
|
627
|
+
if (result !== void 0) this.resolveFinalResult(result);
|
|
628
|
+
while (this.waiting.length > 0) this.waiting.shift()({
|
|
629
|
+
value: void 0,
|
|
630
|
+
done: true
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
async *[Symbol.asyncIterator]() {
|
|
634
|
+
while (true) if (this.queue.length > 0) yield this.queue.shift();
|
|
635
|
+
else if (this.done) return;
|
|
636
|
+
else {
|
|
637
|
+
const result = await new Promise((resolve) => this.waiting.push(resolve));
|
|
638
|
+
if (result.done) return;
|
|
639
|
+
yield result.value;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
result() {
|
|
643
|
+
return this.finalResultPromise;
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
var AssistantMessageEventStream = class extends EventStream {
|
|
647
|
+
constructor() {
|
|
648
|
+
super((event) => event.type === "done" || event.type === "error", (event) => {
|
|
649
|
+
if (event.type === "done") return event.message;
|
|
650
|
+
else if (event.type === "error") return event.error;
|
|
651
|
+
throw new Error("Unexpected event type for final result");
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
/** Factory function for AssistantMessageEventStream (for use in extensions) */
|
|
656
|
+
function createAssistantMessageEventStream() {
|
|
657
|
+
return new AssistantMessageEventStream();
|
|
658
|
+
}
|
|
659
|
+
//#endregion
|
|
660
|
+
//#region src/llm/runtime.ts
|
|
661
|
+
function mergeHeaders(...headerSources) {
|
|
662
|
+
const merged = {};
|
|
663
|
+
for (const headers of headerSources) if (headers) Object.assign(merged, headers);
|
|
664
|
+
return merged;
|
|
665
|
+
}
|
|
666
|
+
function getEnvApiKey(provider) {
|
|
667
|
+
if (typeof process === "undefined") return;
|
|
668
|
+
const candidates = [provider.key, ...provider.env ?? []].filter((name) => Boolean(name));
|
|
669
|
+
for (const name of candidates) {
|
|
670
|
+
const value = process.env[name];
|
|
671
|
+
if (value) return value;
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
function formatThrownError(error) {
|
|
675
|
+
if (error instanceof Error) return error.stack || error.message || error.name;
|
|
676
|
+
if (typeof error === "string") return error;
|
|
677
|
+
try {
|
|
678
|
+
return JSON.stringify(error);
|
|
679
|
+
} catch {
|
|
680
|
+
return String(error);
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
//#endregion
|
|
684
|
+
//#region src/llm/provider.ts
|
|
685
|
+
function cleanHeaders(headers) {
|
|
686
|
+
const result = {};
|
|
687
|
+
for (const [key, value] of Object.entries(headers)) if (value !== null) result[key] = value;
|
|
688
|
+
return result;
|
|
689
|
+
}
|
|
690
|
+
function resolveBaseURL(model, options) {
|
|
691
|
+
return (options.baseURL ?? model.api?.url ?? model.baseUrl) || void 0;
|
|
692
|
+
}
|
|
693
|
+
async function resolveAISDKLanguageModel(model, options) {
|
|
694
|
+
const npm = packageForModel(model);
|
|
695
|
+
const createProvider = await loadProviderFactory(npm);
|
|
696
|
+
const apiKey = options.apiKey ?? getEnvApiKey(model.provider);
|
|
697
|
+
const headers = cleanHeaders(mergeHeaders(model.headers, options.headers));
|
|
698
|
+
const baseURL = resolveBaseURL(model, options);
|
|
699
|
+
const factoryOptions = {
|
|
700
|
+
...model.options,
|
|
701
|
+
...options.factoryOptions
|
|
702
|
+
};
|
|
703
|
+
if (apiKey) factoryOptions.apiKey = apiKey;
|
|
704
|
+
if (Object.keys(headers).length > 0) factoryOptions.headers = headers;
|
|
705
|
+
if (baseURL) factoryOptions.baseURL = baseURL;
|
|
706
|
+
if (npm === "@ai-sdk/openai-compatible") {
|
|
707
|
+
if (!baseURL) throw new Protocol.ProtocolAuthError({
|
|
708
|
+
protocol: model.protocol,
|
|
709
|
+
message: "AI SDK openai-compatible transport requires model.baseUrl, model.api.url, or options.baseURL"
|
|
710
|
+
});
|
|
711
|
+
factoryOptions.name ??= model.provider.id;
|
|
712
|
+
factoryOptions.includeUsage ??= true;
|
|
713
|
+
}
|
|
714
|
+
return resolveLanguageModel(createProvider(factoryOptions), model, options.method);
|
|
715
|
+
}
|
|
716
|
+
//#endregion
|
|
717
|
+
//#region src/utils/jsonparse.ts
|
|
718
|
+
/**
|
|
719
|
+
* @description Helper function to parse partial jsons during LLM streaming.
|
|
720
|
+
*/
|
|
721
|
+
/**
|
|
722
|
+
* Attempts to parse potentially incomplete JSON during streaming.
|
|
723
|
+
* Always returns a valid object, even if the JSON is incomplete.
|
|
724
|
+
*
|
|
725
|
+
* @param partialJson The partial JSON string from streaming
|
|
726
|
+
* @returns Parsed object or empty object if parsing fails
|
|
727
|
+
*/
|
|
728
|
+
function parseStreamingJson(partialJson) {
|
|
729
|
+
if (!partialJson || partialJson.trim() === "") return {};
|
|
730
|
+
try {
|
|
731
|
+
return JSON.parse(partialJson);
|
|
732
|
+
} catch {
|
|
733
|
+
const repaired = repairInvalidJsonStringContent(partialJson);
|
|
734
|
+
if (repaired !== partialJson) try {
|
|
735
|
+
return JSON.parse(repaired);
|
|
736
|
+
} catch {
|
|
737
|
+
try {
|
|
738
|
+
return parse(repaired) ?? {};
|
|
739
|
+
} catch {}
|
|
740
|
+
}
|
|
741
|
+
try {
|
|
742
|
+
return parse(partialJson) ?? {};
|
|
743
|
+
} catch {
|
|
744
|
+
return {};
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
function repairInvalidJsonStringContent(input) {
|
|
749
|
+
let output = "";
|
|
750
|
+
let inString = false;
|
|
751
|
+
let escaping = false;
|
|
752
|
+
for (const char of input) {
|
|
753
|
+
if (!inString) {
|
|
754
|
+
output += char;
|
|
755
|
+
if (char === "\"") inString = true;
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
if (escaping) {
|
|
759
|
+
if (`"\\/bfnrtu`.includes(char)) output += `\\${char}`;
|
|
760
|
+
else output += `\\\\${char}`;
|
|
761
|
+
escaping = false;
|
|
762
|
+
continue;
|
|
763
|
+
}
|
|
764
|
+
if (char === "\\") {
|
|
765
|
+
escaping = true;
|
|
766
|
+
continue;
|
|
767
|
+
}
|
|
768
|
+
if (char === "\"") {
|
|
769
|
+
inString = false;
|
|
770
|
+
output += char;
|
|
771
|
+
continue;
|
|
772
|
+
}
|
|
773
|
+
switch (char) {
|
|
774
|
+
case "\b":
|
|
775
|
+
output += "\\b";
|
|
776
|
+
break;
|
|
777
|
+
case "\f":
|
|
778
|
+
output += "\\f";
|
|
779
|
+
break;
|
|
780
|
+
case "\n":
|
|
781
|
+
output += "\\n";
|
|
782
|
+
break;
|
|
783
|
+
case "\r":
|
|
784
|
+
output += "\\r";
|
|
785
|
+
break;
|
|
786
|
+
case " ":
|
|
787
|
+
output += "\\t";
|
|
788
|
+
break;
|
|
789
|
+
default:
|
|
790
|
+
output += char;
|
|
791
|
+
break;
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
if (escaping) output += "\\\\";
|
|
795
|
+
return output;
|
|
796
|
+
}
|
|
797
|
+
//#endregion
|
|
798
|
+
//#region src/utils/sanitize.ts
|
|
799
|
+
/**
|
|
800
|
+
* Removes unpaired Unicode surrogate characters from a string.
|
|
801
|
+
*
|
|
802
|
+
* Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
|
|
803
|
+
* or vice versa) cause JSON serialization errors in many API providers.
|
|
804
|
+
*
|
|
805
|
+
* Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
|
|
806
|
+
* surrogates and will NOT be affected by this function.
|
|
807
|
+
*
|
|
808
|
+
* @param text - The text to sanitize
|
|
809
|
+
* @returns The sanitized text with unpaired surrogates removed
|
|
810
|
+
*
|
|
811
|
+
* @example
|
|
812
|
+
* // Valid emoji (properly paired surrogates) are preserved
|
|
813
|
+
* sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
|
|
814
|
+
*
|
|
815
|
+
* // Unpaired high surrogate is removed
|
|
816
|
+
* const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
|
|
817
|
+
* sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
|
|
818
|
+
*/
|
|
819
|
+
function sanitizeSurrogates(text) {
|
|
820
|
+
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
821
|
+
}
|
|
822
|
+
//#endregion
|
|
823
|
+
//#region src/llm/transform.ts
|
|
824
|
+
function createAssistantMessage(model) {
|
|
825
|
+
return Message.createAssistantMessage({
|
|
826
|
+
role: "assistant",
|
|
827
|
+
parts: [],
|
|
828
|
+
protocol: model.protocol,
|
|
829
|
+
provider: model.provider,
|
|
830
|
+
model: model.id,
|
|
831
|
+
usage: {
|
|
832
|
+
input: 0,
|
|
833
|
+
output: 0,
|
|
834
|
+
cacheRead: 0,
|
|
835
|
+
cacheWrite: 0,
|
|
836
|
+
totalTokens: 0,
|
|
837
|
+
cost: {
|
|
838
|
+
input: 0,
|
|
839
|
+
output: 0,
|
|
840
|
+
cacheRead: 0,
|
|
841
|
+
cacheWrite: 0,
|
|
842
|
+
total: 0
|
|
843
|
+
}
|
|
844
|
+
},
|
|
845
|
+
stopReason: "stop",
|
|
846
|
+
time: {
|
|
847
|
+
created: Date.now(),
|
|
848
|
+
completed: Date.now()
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
function userContent(parts, supportsImages) {
|
|
853
|
+
const content = [];
|
|
854
|
+
for (const part of parts) {
|
|
855
|
+
if (part.type === "text") {
|
|
856
|
+
const text = sanitizeSurrogates(part.text);
|
|
857
|
+
if (text.trim().length > 0) content.push({
|
|
858
|
+
type: "text",
|
|
859
|
+
text
|
|
860
|
+
});
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
if (supportsImages) content.push({
|
|
864
|
+
type: "image",
|
|
865
|
+
image: part.data,
|
|
866
|
+
mediaType: part.mimeType
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
if (content.length === 0) return [];
|
|
870
|
+
return [{
|
|
871
|
+
role: "user",
|
|
872
|
+
content
|
|
873
|
+
}];
|
|
874
|
+
}
|
|
875
|
+
function sanitizeValue(value) {
|
|
876
|
+
if (typeof value === "string") return sanitizeSurrogates(value);
|
|
877
|
+
if (Array.isArray(value)) return value.map((item) => sanitizeValue(item));
|
|
878
|
+
if (typeof value === "object" && value !== null) {
|
|
879
|
+
const result = {};
|
|
880
|
+
for (const [key, item] of Object.entries(value)) result[key] = sanitizeValue(item);
|
|
881
|
+
return result;
|
|
882
|
+
}
|
|
883
|
+
return value;
|
|
884
|
+
}
|
|
885
|
+
function sanitizeRecord(value) {
|
|
886
|
+
return sanitizeValue(value);
|
|
887
|
+
}
|
|
888
|
+
function toolResultOutput(toolCall) {
|
|
889
|
+
const text = toolCall.result.content.filter((content) => content.type === "text").map((content) => sanitizeSurrogates(content.text)).join("\n");
|
|
890
|
+
const images = toolCall.result.content.filter((content) => content.type === "image");
|
|
891
|
+
if (toolCall.result.isError) return {
|
|
892
|
+
type: "error-text",
|
|
893
|
+
value: text || "Tool returned an error"
|
|
894
|
+
};
|
|
895
|
+
if (images.length === 0) return {
|
|
896
|
+
type: "text",
|
|
897
|
+
value: text
|
|
898
|
+
};
|
|
899
|
+
return {
|
|
900
|
+
type: "content",
|
|
901
|
+
value: [...text.length > 0 ? [{
|
|
902
|
+
type: "text",
|
|
903
|
+
text
|
|
904
|
+
}] : [], ...images.map((image) => ({
|
|
905
|
+
type: "image-data",
|
|
906
|
+
data: image.data,
|
|
907
|
+
mediaType: image.mimeType
|
|
908
|
+
}))]
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
function assistantMessages(message) {
|
|
912
|
+
if (message.stopReason === "error" || message.stopReason === "aborted") return [];
|
|
913
|
+
const assistantContent = [];
|
|
914
|
+
const toolResults = [];
|
|
915
|
+
for (const part of message.parts) {
|
|
916
|
+
if (part.type === "text") {
|
|
917
|
+
const text = sanitizeSurrogates(part.text);
|
|
918
|
+
if (text.trim().length === 0) continue;
|
|
919
|
+
assistantContent.push({
|
|
920
|
+
type: "text",
|
|
921
|
+
text
|
|
922
|
+
});
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
if (part.type === "thinking") {
|
|
926
|
+
const thinking = sanitizeSurrogates(part.thinking);
|
|
927
|
+
if (thinking.trim().length === 0) continue;
|
|
928
|
+
const reasoning = {
|
|
929
|
+
type: "reasoning",
|
|
930
|
+
text: thinking
|
|
931
|
+
};
|
|
932
|
+
if (part.thinkingSignature) reasoning.providerOptions = { anthropic: { signature: part.thinkingSignature } };
|
|
933
|
+
assistantContent.push(reasoning);
|
|
934
|
+
continue;
|
|
935
|
+
}
|
|
936
|
+
if (part.type !== "toolCall") continue;
|
|
937
|
+
assistantContent.push({
|
|
938
|
+
type: "tool-call",
|
|
939
|
+
toolCallId: part.callID,
|
|
940
|
+
toolName: part.name,
|
|
941
|
+
input: sanitizeRecord(part.arguments ?? {})
|
|
942
|
+
});
|
|
943
|
+
const terminal = part.status === "pending" || part.status === "running" ? void 0 : part;
|
|
944
|
+
toolResults.push({
|
|
945
|
+
type: "tool-result",
|
|
946
|
+
toolCallId: part.callID,
|
|
947
|
+
toolName: part.name,
|
|
948
|
+
output: terminal ? toolResultOutput(terminal) : {
|
|
949
|
+
type: "error-text",
|
|
950
|
+
value: "No result provided"
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
const result = [];
|
|
955
|
+
if (assistantContent.length > 0) result.push({
|
|
956
|
+
role: "assistant",
|
|
957
|
+
content: assistantContent
|
|
958
|
+
});
|
|
959
|
+
if (toolResults.length > 0) result.push({
|
|
960
|
+
role: "tool",
|
|
961
|
+
content: toolResults
|
|
962
|
+
});
|
|
963
|
+
return result;
|
|
964
|
+
}
|
|
965
|
+
function convertMessages(context, model) {
|
|
966
|
+
const messages = [];
|
|
967
|
+
const transformedMessages = Message.transformMessages(context.messages, model);
|
|
968
|
+
for (const msg of transformedMessages) {
|
|
969
|
+
if (msg.role === "user") {
|
|
970
|
+
messages.push(...userContent(msg.parts, model.input.includes("image")));
|
|
971
|
+
continue;
|
|
972
|
+
}
|
|
973
|
+
messages.push(...assistantMessages(msg));
|
|
974
|
+
}
|
|
975
|
+
return messages;
|
|
976
|
+
}
|
|
977
|
+
function convertTools(tools) {
|
|
978
|
+
if (!tools || tools.length === 0) return;
|
|
979
|
+
const result = {};
|
|
980
|
+
for (const tool of tools) result[tool.name] = {
|
|
981
|
+
description: tool.description,
|
|
982
|
+
inputSchema: jsonSchema(tool.parameters)
|
|
983
|
+
};
|
|
984
|
+
return result;
|
|
985
|
+
}
|
|
986
|
+
function mapFinishReason(reason) {
|
|
987
|
+
switch (reason) {
|
|
988
|
+
case "length": return "length";
|
|
989
|
+
case "tool-calls": return "toolUse";
|
|
990
|
+
case "content-filter":
|
|
991
|
+
case "error":
|
|
992
|
+
case "other": return "error";
|
|
993
|
+
default: return "stop";
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
function mapUsage(usage, model) {
|
|
997
|
+
const cacheRead = usage?.inputTokenDetails?.cacheReadTokens ?? usage?.cachedInputTokens ?? 0;
|
|
998
|
+
const cacheWrite = usage?.inputTokenDetails?.cacheWriteTokens ?? 0;
|
|
999
|
+
const input = usage?.inputTokenDetails?.noCacheTokens ?? Math.max((usage?.inputTokens ?? 0) - cacheRead - cacheWrite, 0);
|
|
1000
|
+
const output = usage?.outputTokens ?? 0;
|
|
1001
|
+
const result = {
|
|
1002
|
+
input,
|
|
1003
|
+
output,
|
|
1004
|
+
cacheRead,
|
|
1005
|
+
cacheWrite,
|
|
1006
|
+
totalTokens: usage?.totalTokens ?? input + cacheRead + cacheWrite + output,
|
|
1007
|
+
cost: {
|
|
1008
|
+
input: 0,
|
|
1009
|
+
output: 0,
|
|
1010
|
+
cacheRead: 0,
|
|
1011
|
+
cacheWrite: 0,
|
|
1012
|
+
total: 0
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
Model.calculateCost(model, result);
|
|
1016
|
+
return result;
|
|
1017
|
+
}
|
|
1018
|
+
function toolCallFromPart(part) {
|
|
1019
|
+
return {
|
|
1020
|
+
type: "toolCall",
|
|
1021
|
+
callID: part.toolCallId,
|
|
1022
|
+
name: part.toolName,
|
|
1023
|
+
arguments: typeof part.input === "object" && part.input !== null ? part.input : {},
|
|
1024
|
+
status: "pending",
|
|
1025
|
+
time: {
|
|
1026
|
+
start: Date.now(),
|
|
1027
|
+
end: Date.now()
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
}
|
|
1031
|
+
function updateToolCallFromInput(block, partialJson) {
|
|
1032
|
+
block.partialJson = partialJson;
|
|
1033
|
+
block.arguments = parseStreamingJson(partialJson);
|
|
1034
|
+
block.time.end = Date.now();
|
|
1035
|
+
}
|
|
1036
|
+
//#endregion
|
|
1037
|
+
//#region src/llm/stream.ts
|
|
1038
|
+
function providerOptionsKey(model) {
|
|
1039
|
+
return model.providerOptionsKey ?? model.protocol;
|
|
1040
|
+
}
|
|
1041
|
+
function mergeProviderOptions(...sources) {
|
|
1042
|
+
const result = {};
|
|
1043
|
+
for (const source of sources) {
|
|
1044
|
+
if (!source) continue;
|
|
1045
|
+
for (const [key, value] of Object.entries(source)) {
|
|
1046
|
+
if (!value) continue;
|
|
1047
|
+
result[key] = {
|
|
1048
|
+
...result[key],
|
|
1049
|
+
...value
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
return result;
|
|
1054
|
+
}
|
|
1055
|
+
function configuredCacheRetention(options) {
|
|
1056
|
+
if (options.cacheRetention) return options.cacheRetention;
|
|
1057
|
+
const env = process.env.CODEWORK_CACHE_RETENTION;
|
|
1058
|
+
if (env === "none" || env === "short" || env === "long") return env;
|
|
1059
|
+
}
|
|
1060
|
+
function cacheProviderOptions(model, options) {
|
|
1061
|
+
const retention = configuredCacheRetention(options);
|
|
1062
|
+
const key = providerOptionsKey(model);
|
|
1063
|
+
if (retention === "none") return {};
|
|
1064
|
+
if (key === "openai") {
|
|
1065
|
+
const openai = {};
|
|
1066
|
+
if (options.sessionId) openai.promptCacheKey = options.sessionId;
|
|
1067
|
+
if (retention === "short") openai.promptCacheRetention = "in_memory";
|
|
1068
|
+
if (retention === "long") openai.promptCacheRetention = "24h";
|
|
1069
|
+
return Object.keys(openai).length > 0 ? { [key]: openai } : {};
|
|
1070
|
+
}
|
|
1071
|
+
if ((key === "anthropic" || key === "google-vertex-anthropic") && retention) return { [key]: { cacheControl: {
|
|
1072
|
+
type: "ephemeral",
|
|
1073
|
+
...retention === "long" ? { ttl: "1h" } : {}
|
|
1074
|
+
} } };
|
|
1075
|
+
return {};
|
|
1076
|
+
}
|
|
1077
|
+
const DEFAULT_THINKING_BUDGET_FRACTIONS = {
|
|
1078
|
+
minimal: .05,
|
|
1079
|
+
low: .1,
|
|
1080
|
+
medium: .25,
|
|
1081
|
+
high: .5,
|
|
1082
|
+
xhigh: .8
|
|
1083
|
+
};
|
|
1084
|
+
const MIN_THINKING_BUDGET = 1024;
|
|
1085
|
+
function resolveThinkingBudget(model, options, level) {
|
|
1086
|
+
const explicit = options.thinkingBudgets?.[level];
|
|
1087
|
+
if (explicit !== void 0) return explicit;
|
|
1088
|
+
const key = providerOptionsKey(model);
|
|
1089
|
+
if (key === "anthropic" || key === "google-vertex-anthropic") {
|
|
1090
|
+
const fraction = DEFAULT_THINKING_BUDGET_FRACTIONS[level];
|
|
1091
|
+
return Math.max(Math.floor(model.maxTokens * fraction), MIN_THINKING_BUDGET);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
function reasoningProviderOptions(model, options) {
|
|
1095
|
+
const requestedLevel = options.reasoning;
|
|
1096
|
+
if (!requestedLevel) return {};
|
|
1097
|
+
const level = Model.clampThinkingLevel(model, requestedLevel);
|
|
1098
|
+
if (level === "off") return {};
|
|
1099
|
+
const mapped = model.thinkingLevelMap?.[level] ?? level;
|
|
1100
|
+
if (!mapped) return {};
|
|
1101
|
+
const key = providerOptionsKey(model);
|
|
1102
|
+
const budget = resolveThinkingBudget(model, options, level);
|
|
1103
|
+
if (key === "openai" || key === "xai") return { [key]: { reasoningEffort: mapped } };
|
|
1104
|
+
if (key === "openrouter") return { [key]: { reasoning: { effort: mapped === "off" ? "none" : mapped } } };
|
|
1105
|
+
if (key === "google" || key === "google-vertex") {
|
|
1106
|
+
const thinkingLevel = mapped === "xhigh" ? "high" : mapped;
|
|
1107
|
+
return { [key]: { thinkingConfig: {
|
|
1108
|
+
thinkingLevel,
|
|
1109
|
+
includeThoughts: true,
|
|
1110
|
+
...budget !== void 0 ? { thinkingBudget: budget } : {}
|
|
1111
|
+
} } };
|
|
1112
|
+
}
|
|
1113
|
+
if (key === "anthropic" || key === "google-vertex-anthropic") return { [key]: { thinking: {
|
|
1114
|
+
type: "enabled",
|
|
1115
|
+
budgetTokens: budget ?? MIN_THINKING_BUDGET
|
|
1116
|
+
} } };
|
|
1117
|
+
return {};
|
|
1118
|
+
}
|
|
1119
|
+
function resolveProviderOptions(model, options) {
|
|
1120
|
+
return mergeProviderOptions(model.providerOptions, cacheProviderOptions(model, options), reasoningProviderOptions(model, options), options.providerOptions);
|
|
1121
|
+
}
|
|
1122
|
+
function partIndex(output, block) {
|
|
1123
|
+
return output.parts.indexOf(block);
|
|
1124
|
+
}
|
|
1125
|
+
function ensureTextBlock(output, id, stream) {
|
|
1126
|
+
const existing = output.parts.find((part) => part.type === "text" && part.streamId === id);
|
|
1127
|
+
if (existing) return existing;
|
|
1128
|
+
const block = {
|
|
1129
|
+
type: "text",
|
|
1130
|
+
text: "",
|
|
1131
|
+
streamId: id
|
|
1132
|
+
};
|
|
1133
|
+
output.parts.push(block);
|
|
1134
|
+
stream.push({
|
|
1135
|
+
type: "text.start",
|
|
1136
|
+
partIndex: partIndex(output, block),
|
|
1137
|
+
partial: output
|
|
1138
|
+
});
|
|
1139
|
+
return block;
|
|
1140
|
+
}
|
|
1141
|
+
function ensureThinkingBlock(output, id, stream) {
|
|
1142
|
+
const existing = output.parts.find((part) => part.type === "thinking" && part.streamId === id);
|
|
1143
|
+
if (existing) return existing;
|
|
1144
|
+
const block = {
|
|
1145
|
+
type: "thinking",
|
|
1146
|
+
thinking: "",
|
|
1147
|
+
streamId: id
|
|
1148
|
+
};
|
|
1149
|
+
output.parts.push(block);
|
|
1150
|
+
stream.push({
|
|
1151
|
+
type: "thinking.start",
|
|
1152
|
+
partIndex: partIndex(output, block),
|
|
1153
|
+
partial: output
|
|
1154
|
+
});
|
|
1155
|
+
return block;
|
|
1156
|
+
}
|
|
1157
|
+
function ensureToolCallBlock(output, id, name, stream, emitStart) {
|
|
1158
|
+
const existing = output.parts.find((part) => part.type === "toolCall" && part.callID === id);
|
|
1159
|
+
if (existing) {
|
|
1160
|
+
if (!existing.name && name) existing.name = name;
|
|
1161
|
+
return existing;
|
|
1162
|
+
}
|
|
1163
|
+
const block = {
|
|
1164
|
+
type: "toolCall",
|
|
1165
|
+
callID: id,
|
|
1166
|
+
name,
|
|
1167
|
+
arguments: {},
|
|
1168
|
+
status: "pending",
|
|
1169
|
+
time: {
|
|
1170
|
+
start: Date.now(),
|
|
1171
|
+
end: Date.now()
|
|
1172
|
+
}
|
|
1173
|
+
};
|
|
1174
|
+
output.parts.push(block);
|
|
1175
|
+
if (emitStart) stream.push({
|
|
1176
|
+
type: "toolcall.start",
|
|
1177
|
+
partIndex: partIndex(output, block),
|
|
1178
|
+
partial: output
|
|
1179
|
+
});
|
|
1180
|
+
return block;
|
|
1181
|
+
}
|
|
1182
|
+
function finishTextBlock(output, id, stream) {
|
|
1183
|
+
const block = output.parts.find((part) => part.type === "text" && part.streamId === id);
|
|
1184
|
+
if (!block) return;
|
|
1185
|
+
const index = partIndex(output, block);
|
|
1186
|
+
delete block.streamId;
|
|
1187
|
+
stream.push({
|
|
1188
|
+
type: "text.end",
|
|
1189
|
+
partIndex: index,
|
|
1190
|
+
content: block.text,
|
|
1191
|
+
partial: output
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
function finishThinkingBlock(output, id, stream) {
|
|
1195
|
+
const block = output.parts.find((part) => part.type === "thinking" && part.streamId === id);
|
|
1196
|
+
if (!block) return;
|
|
1197
|
+
const index = partIndex(output, block);
|
|
1198
|
+
delete block.streamId;
|
|
1199
|
+
stream.push({
|
|
1200
|
+
type: "thinking.end",
|
|
1201
|
+
partIndex: index,
|
|
1202
|
+
content: block.thinking,
|
|
1203
|
+
partial: output
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
function finishToolInput(output, id, stream) {
|
|
1207
|
+
const block = output.parts.find((part) => part.type === "toolCall" && part.callID === id);
|
|
1208
|
+
if (!block) return;
|
|
1209
|
+
const index = partIndex(output, block);
|
|
1210
|
+
delete block.partialJson;
|
|
1211
|
+
stream.push({
|
|
1212
|
+
type: "toolcall.end",
|
|
1213
|
+
partIndex: index,
|
|
1214
|
+
toolCall: block,
|
|
1215
|
+
partial: output
|
|
1216
|
+
});
|
|
1217
|
+
}
|
|
1218
|
+
function finalizeToolCall(output, part, stream) {
|
|
1219
|
+
const existing = output.parts.find((item) => item.type === "toolCall" && item.callID === part.toolCallId);
|
|
1220
|
+
const block = existing ?? toolCallFromPart(part);
|
|
1221
|
+
block.callID = part.toolCallId;
|
|
1222
|
+
block.name = part.toolName;
|
|
1223
|
+
block.arguments = typeof part.input === "object" && part.input !== null ? part.input : {};
|
|
1224
|
+
block.time.end = Date.now();
|
|
1225
|
+
delete block.partialJson;
|
|
1226
|
+
if (!existing) output.parts.push(block);
|
|
1227
|
+
const index = partIndex(output, block);
|
|
1228
|
+
stream.push({
|
|
1229
|
+
type: "toolcall.final",
|
|
1230
|
+
partIndex: index,
|
|
1231
|
+
toolCall: block,
|
|
1232
|
+
partial: output
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
function handlePart(part, output, model, stream) {
|
|
1236
|
+
switch (part.type) {
|
|
1237
|
+
case "text-start":
|
|
1238
|
+
ensureTextBlock(output, part.id, stream);
|
|
1239
|
+
break;
|
|
1240
|
+
case "text-delta": {
|
|
1241
|
+
const block = ensureTextBlock(output, part.id, stream);
|
|
1242
|
+
block.text += part.text;
|
|
1243
|
+
stream.push({
|
|
1244
|
+
type: "text.delta",
|
|
1245
|
+
partIndex: partIndex(output, block),
|
|
1246
|
+
delta: part.text,
|
|
1247
|
+
partial: output
|
|
1248
|
+
});
|
|
1249
|
+
break;
|
|
1250
|
+
}
|
|
1251
|
+
case "text-end":
|
|
1252
|
+
finishTextBlock(output, part.id, stream);
|
|
1253
|
+
break;
|
|
1254
|
+
case "reasoning-start":
|
|
1255
|
+
ensureThinkingBlock(output, part.id, stream);
|
|
1256
|
+
break;
|
|
1257
|
+
case "reasoning-delta": {
|
|
1258
|
+
const block = ensureThinkingBlock(output, part.id, stream);
|
|
1259
|
+
block.thinking += part.text;
|
|
1260
|
+
const sig = (part.providerMetadata?.anthropic)?.signature ?? (part.providerMetadata?.["google-vertex-anthropic"])?.signature;
|
|
1261
|
+
if (typeof sig === "string") block.thinkingSignature = sig;
|
|
1262
|
+
stream.push({
|
|
1263
|
+
type: "thinking.delta",
|
|
1264
|
+
partIndex: partIndex(output, block),
|
|
1265
|
+
delta: part.text,
|
|
1266
|
+
partial: output
|
|
1267
|
+
});
|
|
1268
|
+
break;
|
|
1269
|
+
}
|
|
1270
|
+
case "reasoning-end":
|
|
1271
|
+
finishThinkingBlock(output, part.id, stream);
|
|
1272
|
+
break;
|
|
1273
|
+
case "tool-input-start":
|
|
1274
|
+
ensureToolCallBlock(output, part.id, part.toolName, stream, true);
|
|
1275
|
+
break;
|
|
1276
|
+
case "tool-input-delta": {
|
|
1277
|
+
const block = ensureToolCallBlock(output, part.id, "", stream, true);
|
|
1278
|
+
updateToolCallFromInput(block, (block.partialJson ?? "") + part.delta);
|
|
1279
|
+
stream.push({
|
|
1280
|
+
type: "toolcall.delta",
|
|
1281
|
+
partIndex: partIndex(output, block),
|
|
1282
|
+
delta: part.delta,
|
|
1283
|
+
partial: output
|
|
1284
|
+
});
|
|
1285
|
+
break;
|
|
1286
|
+
}
|
|
1287
|
+
case "tool-input-end":
|
|
1288
|
+
finishToolInput(output, part.id, stream);
|
|
1289
|
+
break;
|
|
1290
|
+
case "tool-call":
|
|
1291
|
+
finalizeToolCall(output, part, stream);
|
|
1292
|
+
break;
|
|
1293
|
+
case "finish-step":
|
|
1294
|
+
output.responseId ||= part.response.id;
|
|
1295
|
+
if (part.response.modelId && part.response.modelId !== model.id) output.responseModel ||= part.response.modelId;
|
|
1296
|
+
output.usage = mapUsage(part.usage, model);
|
|
1297
|
+
output.stopReason = mapFinishReason(part.finishReason);
|
|
1298
|
+
break;
|
|
1299
|
+
case "finish":
|
|
1300
|
+
output.usage = mapUsage(part.totalUsage, model);
|
|
1301
|
+
output.stopReason = mapFinishReason(part.finishReason);
|
|
1302
|
+
break;
|
|
1303
|
+
case "abort":
|
|
1304
|
+
output.stopReason = "aborted";
|
|
1305
|
+
output.errorMessage = part.reason;
|
|
1306
|
+
break;
|
|
1307
|
+
case "error": throw part.error instanceof Error ? part.error : new Error(formatThrownError(part.error));
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
/**
|
|
1311
|
+
* Resolve maxOutputTokens so that (maxOutputTokens + thinkingBudget) does not exceed model.maxTokens.
|
|
1312
|
+
* Without this adjustment @ai-sdk/anthropic logs a warning and silently caps the value.
|
|
1313
|
+
*/
|
|
1314
|
+
function resolveMaxOutputTokens(model, options, providerOptions) {
|
|
1315
|
+
const maxTokens = options.maxTokens;
|
|
1316
|
+
if (maxTokens === void 0) return void 0;
|
|
1317
|
+
const key = providerOptionsKey(model);
|
|
1318
|
+
if (key === "anthropic" || key === "google-vertex-anthropic") {
|
|
1319
|
+
const budgetTokens = ((providerOptions?.[key])?.thinking)?.budgetTokens ?? 0;
|
|
1320
|
+
if (budgetTokens > 0 && maxTokens + budgetTokens > model.maxTokens) return Math.max(model.maxTokens - budgetTokens, 1);
|
|
1321
|
+
}
|
|
1322
|
+
return maxTokens;
|
|
1323
|
+
}
|
|
1324
|
+
const stream$1 = (model, context, options) => {
|
|
1325
|
+
const stream = new AssistantMessageEventStream();
|
|
1326
|
+
const runtimeOptions = applyDefaultMaxTokens(model, options ?? {});
|
|
1327
|
+
(async () => {
|
|
1328
|
+
const output = createAssistantMessage(model);
|
|
1329
|
+
try {
|
|
1330
|
+
const languageModel = await resolveAISDKLanguageModel(model, runtimeOptions);
|
|
1331
|
+
const tools = convertTools(context.tools);
|
|
1332
|
+
const messages = convertMessages(context, model);
|
|
1333
|
+
const providerOptions = resolveProviderOptions(model, runtimeOptions);
|
|
1334
|
+
const activeTools = runtimeOptions.activeTools?.filter((name) => !tools || name in tools);
|
|
1335
|
+
let params = {
|
|
1336
|
+
model: languageModel,
|
|
1337
|
+
system: context.systemPrompt,
|
|
1338
|
+
messages,
|
|
1339
|
+
tools,
|
|
1340
|
+
toolChoice: runtimeOptions.toolChoice,
|
|
1341
|
+
activeTools,
|
|
1342
|
+
maxOutputTokens: resolveMaxOutputTokens(model, runtimeOptions, providerOptions),
|
|
1343
|
+
temperature: runtimeOptions.temperature,
|
|
1344
|
+
providerOptions,
|
|
1345
|
+
abortSignal: runtimeOptions.signal,
|
|
1346
|
+
timeout: runtimeOptions.timeoutMs,
|
|
1347
|
+
maxRetries: runtimeOptions.maxRetries,
|
|
1348
|
+
headers: runtimeOptions.headers
|
|
1349
|
+
};
|
|
1350
|
+
const payload = await runtimeOptions.onPayload?.(params, model);
|
|
1351
|
+
if (payload !== void 0) params = payload;
|
|
1352
|
+
const result = streamText(params);
|
|
1353
|
+
stream.push({
|
|
1354
|
+
type: "start",
|
|
1355
|
+
partial: output
|
|
1356
|
+
});
|
|
1357
|
+
for await (const part of result.fullStream) handlePart(part, output, model, stream);
|
|
1358
|
+
if (runtimeOptions.signal?.aborted || output.stopReason === "aborted") throw new Error(output.errorMessage || "Request was aborted");
|
|
1359
|
+
if (output.stopReason === "error") throw new Error(output.errorMessage || "Provider returned an error stop reason");
|
|
1360
|
+
output.time.completed = Date.now();
|
|
1361
|
+
stream.push({
|
|
1362
|
+
type: "done",
|
|
1363
|
+
reason: output.stopReason,
|
|
1364
|
+
message: output
|
|
1365
|
+
});
|
|
1366
|
+
stream.end();
|
|
1367
|
+
} catch (error) {
|
|
1368
|
+
for (const block of output.parts) {
|
|
1369
|
+
delete block.streamId;
|
|
1370
|
+
delete block.streamId;
|
|
1371
|
+
delete block.partialJson;
|
|
1372
|
+
}
|
|
1373
|
+
output.time.completed = Date.now();
|
|
1374
|
+
output.stopReason = runtimeOptions.signal?.aborted || output.stopReason === "aborted" ? "aborted" : "error";
|
|
1375
|
+
output.errorMessage = formatThrownError(error);
|
|
1376
|
+
stream.push({
|
|
1377
|
+
type: "error",
|
|
1378
|
+
reason: output.stopReason,
|
|
1379
|
+
error: output
|
|
1380
|
+
});
|
|
1381
|
+
stream.end();
|
|
1382
|
+
}
|
|
1383
|
+
})();
|
|
1384
|
+
return stream;
|
|
1385
|
+
};
|
|
1386
|
+
//#endregion
|
|
1387
|
+
//#region src/llm/index.ts
|
|
1388
|
+
function createAISDKProtocol(protocol) {
|
|
1389
|
+
return {
|
|
1390
|
+
protocol,
|
|
1391
|
+
stream: stream$1
|
|
1392
|
+
};
|
|
1393
|
+
}
|
|
1394
|
+
function registerAISDKProtocols() {
|
|
1395
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.anthropic));
|
|
1396
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.google));
|
|
1397
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.googleVertex));
|
|
1398
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.googleVertexAnthropic));
|
|
1399
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.openai));
|
|
1400
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.openaiCompatible));
|
|
1401
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.openrouter));
|
|
1402
|
+
Protocol.registerProtocolProvider(createAISDKProtocol(Model.KnownProviderEnum.xai));
|
|
1403
|
+
}
|
|
1404
|
+
//#endregion
|
|
1405
|
+
//#region src/llm/register.ts
|
|
1406
|
+
registerAISDKProtocols();
|
|
1407
|
+
//#endregion
|
|
1408
|
+
//#region src/stream.ts
|
|
1409
|
+
const streamImpl = (model, context, options) => Protocol.stream(model, context, options);
|
|
1410
|
+
/**
|
|
1411
|
+
* Start a streaming assistant response for a model/context pair.
|
|
1412
|
+
*
|
|
1413
|
+
* This is the main streaming entrypoint.
|
|
1414
|
+
* Attached helpers:
|
|
1415
|
+
*
|
|
1416
|
+
* - `stream.complete(...)` resolves the final assistant message without manually iterating events.
|
|
1417
|
+
* - `stream.resolveProtocolProvider(...)` exposes protocol resolution for advanced integrations.
|
|
1418
|
+
*/
|
|
1419
|
+
const stream = Object.assign(streamImpl, {
|
|
1420
|
+
complete: Protocol.complete,
|
|
1421
|
+
resolveProtocolProvider: Protocol.resolveProtocolProvider
|
|
1422
|
+
});
|
|
1423
|
+
Protocol.complete;
|
|
1424
|
+
//#endregion
|
|
1425
|
+
//#region src/utils/validation.ts
|
|
1426
|
+
const validators = /* @__PURE__ */ new WeakMap();
|
|
1427
|
+
function getValidator(schema) {
|
|
1428
|
+
const existing = validators.get(schema);
|
|
1429
|
+
if (existing) return existing;
|
|
1430
|
+
const validator = Schema.Compile(schema);
|
|
1431
|
+
validators.set(schema, validator);
|
|
1432
|
+
return validator;
|
|
1433
|
+
}
|
|
1434
|
+
function errorPath(error) {
|
|
1435
|
+
if (error.instancePath) return error.instancePath.substring(1);
|
|
1436
|
+
const requiredProperties = error.params?.requiredProperties;
|
|
1437
|
+
if (Array.isArray(requiredProperties)) return requiredProperties.join(", ");
|
|
1438
|
+
return "root";
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Validates an arbitrary value against a TypeBox schema and returns the coerced value.
|
|
1442
|
+
*/
|
|
1443
|
+
function validateSchema(schema, value, label) {
|
|
1444
|
+
const validator = getValidator(schema);
|
|
1445
|
+
const input = Value.Convert(schema, structuredClone(value));
|
|
1446
|
+
try {
|
|
1447
|
+
return validator.Parse(input);
|
|
1448
|
+
} catch {
|
|
1449
|
+
const [_result, validationErrors] = validator.Errors(input);
|
|
1450
|
+
const errors = validationErrors.map((err) => {
|
|
1451
|
+
return ` - ${errorPath(err)}: ${err.message}`;
|
|
1452
|
+
}).join("\n") || "Unknown Validation Error";
|
|
1453
|
+
throw new Error([
|
|
1454
|
+
`Validation Failed For ${label}`,
|
|
1455
|
+
`${errors}\n`,
|
|
1456
|
+
"Received Value:",
|
|
1457
|
+
`${JSON.stringify(value, null, 2)}\n`
|
|
1458
|
+
].join("\n"));
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Finds a tool by name and validates the tool call arguments against its TypeBox schema
|
|
1463
|
+
*/
|
|
1464
|
+
function validateToolCall(tools, toolExecution) {
|
|
1465
|
+
const tool = tools.find((t) => t.name === toolExecution.name);
|
|
1466
|
+
if (!tool) throw new Error(`Tool "${toolExecution.name}" not found`);
|
|
1467
|
+
return validateToolArguments(tool, toolExecution);
|
|
1468
|
+
}
|
|
1469
|
+
/**
|
|
1470
|
+
* Validates tool call arguments against the tool's TypeBox schema
|
|
1471
|
+
*/
|
|
1472
|
+
function validateToolArguments(tool, toolExecution) {
|
|
1473
|
+
return validateSchema(tool.parameters, toolExecution.rawArgs, `Tool "${toolExecution.name}"`);
|
|
1474
|
+
}
|
|
1475
|
+
//#endregion
|
|
1476
|
+
export { Event, EventStream, Message, Model, Protocol, ThinkingBudgets, Type, createAssistantMessageEventStream, llm, stream, validateSchema, validateToolArguments, validateToolCall };
|
|
1477
|
+
|
|
1478
|
+
//# sourceMappingURL=index.mjs.map
|