@providerprotocol/ai 0.0.33 → 0.0.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +542 -3
- package/dist/anthropic/index.d.ts +2 -1
- package/dist/anthropic/index.js +151 -145
- package/dist/anthropic/index.js.map +1 -1
- package/dist/cerebras/index.d.ts +392 -0
- package/dist/cerebras/index.js +648 -0
- package/dist/cerebras/index.js.map +1 -0
- package/dist/chunk-3GWM5GR3.js +153 -0
- package/dist/chunk-3GWM5GR3.js.map +1 -0
- package/dist/chunk-4OGB7JZA.js +157 -0
- package/dist/chunk-4OGB7JZA.js.map +1 -0
- package/dist/chunk-7DXVRILR.js +49 -0
- package/dist/chunk-7DXVRILR.js.map +1 -0
- package/dist/{chunk-3C7O2RNO.js → chunk-A2IM7PGT.js} +6 -4
- package/dist/{chunk-3C7O2RNO.js.map → chunk-A2IM7PGT.js.map} +1 -1
- package/dist/{chunk-3D6XGGVG.js → chunk-ARVM24K2.js} +2 -2
- package/dist/{chunk-4J6OFUKX.js → chunk-AY55T37A.js} +70 -162
- package/dist/chunk-AY55T37A.js.map +1 -0
- package/dist/{chunk-ILR2D5PN.js → chunk-BRP5XJ6Q.js} +2 -86
- package/dist/chunk-BRP5XJ6Q.js.map +1 -0
- package/dist/chunk-C4JP64VW.js +298 -0
- package/dist/chunk-C4JP64VW.js.map +1 -0
- package/dist/chunk-COS4ON4G.js +111 -0
- package/dist/chunk-COS4ON4G.js.map +1 -0
- package/dist/chunk-ETBFOLQN.js +34 -0
- package/dist/chunk-ETBFOLQN.js.map +1 -0
- package/dist/chunk-HB4ZIH3T.js +31 -0
- package/dist/chunk-HB4ZIH3T.js.map +1 -0
- package/dist/chunk-I53CI6ZZ.js +142 -0
- package/dist/chunk-I53CI6ZZ.js.map +1 -0
- package/dist/chunk-IDZOVWP3.js +29 -0
- package/dist/chunk-IDZOVWP3.js.map +1 -0
- package/dist/chunk-JA3UZALR.js +88 -0
- package/dist/chunk-JA3UZALR.js.map +1 -0
- package/dist/{chunk-WAKD3OO5.js → chunk-N5DX5JW3.js} +31 -31
- package/dist/chunk-N5DX5JW3.js.map +1 -0
- package/dist/chunk-OIEWDFQU.js +97 -0
- package/dist/chunk-OIEWDFQU.js.map +1 -0
- package/dist/{chunk-TOJCZMVU.js → chunk-PMK5LZ5Z.js} +40 -40
- package/dist/chunk-PMK5LZ5Z.js.map +1 -0
- package/dist/chunk-UFFJDYCE.js +94 -0
- package/dist/chunk-UFFJDYCE.js.map +1 -0
- package/dist/chunk-VGKZIGVI.js +222 -0
- package/dist/chunk-VGKZIGVI.js.map +1 -0
- package/dist/chunk-VOEWHQUB.js +31 -0
- package/dist/chunk-VOEWHQUB.js.map +1 -0
- package/dist/{chunk-KUPF5KHT.js → chunk-Y5H7C5J4.js} +2 -2
- package/dist/chunk-ZI67WIQS.js +30 -0
- package/dist/chunk-ZI67WIQS.js.map +1 -0
- package/dist/{embedding-D2BYIehX.d.ts → embedding-CW6SaOOz.d.ts} +1 -1
- package/dist/google/index.d.ts +2 -1
- package/dist/google/index.js +202 -199
- package/dist/google/index.js.map +1 -1
- package/dist/groq/index.d.ts +410 -0
- package/dist/groq/index.js +649 -0
- package/dist/groq/index.js.map +1 -0
- package/dist/http/index.d.ts +3 -2
- package/dist/http/index.js +5 -4
- package/dist/image-stream-C0ciACM2.d.ts +11 -0
- package/dist/index.d.ts +8 -118
- package/dist/index.js +518 -767
- package/dist/index.js.map +1 -1
- package/dist/{llm-BQJZj3cD.d.ts → llm-DwbUK7un.d.ts} +12 -1632
- package/dist/middleware/logging/index.d.ts +76 -0
- package/dist/middleware/logging/index.js +74 -0
- package/dist/middleware/logging/index.js.map +1 -0
- package/dist/middleware/parsed-object/index.d.ts +45 -0
- package/dist/middleware/parsed-object/index.js +73 -0
- package/dist/middleware/parsed-object/index.js.map +1 -0
- package/dist/middleware/pubsub/index.d.ts +104 -0
- package/dist/middleware/pubsub/index.js +230 -0
- package/dist/middleware/pubsub/index.js.map +1 -0
- package/dist/middleware/pubsub/server/express/index.d.ts +52 -0
- package/dist/middleware/pubsub/server/express/index.js +11 -0
- package/dist/middleware/pubsub/server/express/index.js.map +1 -0
- package/dist/middleware/pubsub/server/fastify/index.d.ts +53 -0
- package/dist/middleware/pubsub/server/fastify/index.js +11 -0
- package/dist/middleware/pubsub/server/fastify/index.js.map +1 -0
- package/dist/middleware/pubsub/server/h3/index.d.ts +56 -0
- package/dist/middleware/pubsub/server/h3/index.js +11 -0
- package/dist/middleware/pubsub/server/h3/index.js.map +1 -0
- package/dist/middleware/pubsub/server/index.d.ts +78 -0
- package/dist/middleware/pubsub/server/index.js +34 -0
- package/dist/middleware/pubsub/server/index.js.map +1 -0
- package/dist/middleware/pubsub/server/webapi/index.d.ts +53 -0
- package/dist/middleware/pubsub/server/webapi/index.js +11 -0
- package/dist/middleware/pubsub/server/webapi/index.js.map +1 -0
- package/dist/ollama/index.d.ts +2 -1
- package/dist/ollama/index.js +48 -45
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +2 -1
- package/dist/openai/index.js +319 -313
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +2 -1
- package/dist/openrouter/index.js +379 -383
- package/dist/openrouter/index.js.map +1 -1
- package/dist/proxy/index.d.ts +10 -914
- package/dist/proxy/index.js +275 -1007
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/server/express/index.d.ts +161 -0
- package/dist/proxy/server/express/index.js +24 -0
- package/dist/proxy/server/express/index.js.map +1 -0
- package/dist/proxy/server/fastify/index.d.ts +162 -0
- package/dist/proxy/server/fastify/index.js +24 -0
- package/dist/proxy/server/fastify/index.js.map +1 -0
- package/dist/proxy/server/h3/index.d.ts +189 -0
- package/dist/proxy/server/h3/index.js +28 -0
- package/dist/proxy/server/h3/index.js.map +1 -0
- package/dist/proxy/server/index.d.ts +151 -0
- package/dist/proxy/server/index.js +48 -0
- package/dist/proxy/server/index.js.map +1 -0
- package/dist/proxy/server/webapi/index.d.ts +278 -0
- package/dist/proxy/server/webapi/index.js +32 -0
- package/dist/proxy/server/webapi/index.js.map +1 -0
- package/dist/responses/index.d.ts +650 -0
- package/dist/responses/index.js +930 -0
- package/dist/responses/index.js.map +1 -0
- package/dist/{retry-8Ch-WWgX.d.ts → retry-YayV42GV.d.ts} +1 -1
- package/dist/stream-CecfVCPO.d.ts +1632 -0
- package/dist/types-C8Gciizr.d.ts +168 -0
- package/dist/utils/index.d.ts +53 -0
- package/dist/utils/index.js +7 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/xai/index.d.ts +2 -1
- package/dist/xai/index.js +310 -310
- package/dist/xai/index.js.map +1 -1
- package/package.json +94 -4
- package/dist/chunk-4J6OFUKX.js.map +0 -1
- package/dist/chunk-ILR2D5PN.js.map +0 -1
- package/dist/chunk-TOJCZMVU.js.map +0 -1
- package/dist/chunk-WAKD3OO5.js.map +0 -1
- /package/dist/{chunk-3D6XGGVG.js.map → chunk-ARVM24K2.js.map} +0 -0
- /package/dist/{chunk-KUPF5KHT.js.map → chunk-Y5H7C5J4.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExponentialBackoff,
|
|
3
|
+
LinearBackoff,
|
|
4
|
+
NoRetry,
|
|
5
|
+
RetryAfterStrategy,
|
|
6
|
+
TokenBucket
|
|
7
|
+
} from "./chunk-Y5H7C5J4.js";
|
|
1
8
|
import {
|
|
2
9
|
aggregateUsage,
|
|
3
10
|
createTurn,
|
|
@@ -5,54 +12,52 @@ import {
|
|
|
5
12
|
} from "./chunk-NSE7QN3P.js";
|
|
6
13
|
import {
|
|
7
14
|
Image
|
|
8
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-N5DX5JW3.js";
|
|
16
|
+
import "./chunk-PMK5LZ5Z.js";
|
|
9
17
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
toolExecutionStart
|
|
21
|
-
} from "./chunk-6S222DHN.js";
|
|
18
|
+
DynamicKey,
|
|
19
|
+
RoundRobinKeys,
|
|
20
|
+
WeightedKeys
|
|
21
|
+
} from "./chunk-ARVM24K2.js";
|
|
22
|
+
import {
|
|
23
|
+
createProvider,
|
|
24
|
+
resolveEmbeddingHandler,
|
|
25
|
+
resolveImageHandler,
|
|
26
|
+
resolveLLMHandler
|
|
27
|
+
} from "./chunk-JA3UZALR.js";
|
|
22
28
|
import {
|
|
23
29
|
AssistantMessage,
|
|
24
30
|
Message,
|
|
25
31
|
MessageRole,
|
|
26
32
|
ToolResultMessage,
|
|
27
33
|
UserMessage,
|
|
28
|
-
createProvider,
|
|
29
34
|
generateId,
|
|
30
35
|
isAssistantMessage,
|
|
31
36
|
isToolResultMessage,
|
|
32
|
-
isUserMessage
|
|
33
|
-
|
|
34
|
-
resolveImageHandler,
|
|
35
|
-
resolveLLMHandler
|
|
36
|
-
} from "./chunk-ILR2D5PN.js";
|
|
37
|
-
import {
|
|
38
|
-
ExponentialBackoff,
|
|
39
|
-
LinearBackoff,
|
|
40
|
-
NoRetry,
|
|
41
|
-
RetryAfterStrategy,
|
|
42
|
-
TokenBucket
|
|
43
|
-
} from "./chunk-KUPF5KHT.js";
|
|
44
|
-
import "./chunk-TOJCZMVU.js";
|
|
37
|
+
isUserMessage
|
|
38
|
+
} from "./chunk-BRP5XJ6Q.js";
|
|
45
39
|
import {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
} from "./chunk-3D6XGGVG.js";
|
|
40
|
+
isCancelledError,
|
|
41
|
+
toError
|
|
42
|
+
} from "./chunk-AY55T37A.js";
|
|
50
43
|
import {
|
|
51
44
|
ErrorCode,
|
|
52
45
|
ModalityType,
|
|
53
|
-
UPPError
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
UPPError
|
|
47
|
+
} from "./chunk-COS4ON4G.js";
|
|
48
|
+
import {
|
|
49
|
+
StreamEventType,
|
|
50
|
+
contentBlockStart,
|
|
51
|
+
contentBlockStop,
|
|
52
|
+
createStreamResult,
|
|
53
|
+
messageStart,
|
|
54
|
+
messageStop,
|
|
55
|
+
objectDelta,
|
|
56
|
+
textDelta,
|
|
57
|
+
toolCallDelta,
|
|
58
|
+
toolExecutionEnd,
|
|
59
|
+
toolExecutionStart
|
|
60
|
+
} from "./chunk-6S222DHN.js";
|
|
56
61
|
|
|
57
62
|
// src/types/content.ts
|
|
58
63
|
var ContentBlockType = {
|
|
@@ -136,6 +141,17 @@ async function runErrorHook(middlewares, error, ctx) {
|
|
|
136
141
|
}
|
|
137
142
|
}
|
|
138
143
|
}
|
|
144
|
+
async function runAbortHook(middlewares, error, ctx) {
|
|
145
|
+
for (const mw of middlewares) {
|
|
146
|
+
if (mw.onAbort) {
|
|
147
|
+
try {
|
|
148
|
+
await mw.onAbort(error, ctx);
|
|
149
|
+
} catch (hookError) {
|
|
150
|
+
console.error(`[${mw.name}] Error in onAbort hook:`, hookError);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
139
155
|
async function runToolHook(middlewares, hook, tool, data, ctx) {
|
|
140
156
|
for (const mw of middlewares) {
|
|
141
157
|
const fn = mw[hook];
|
|
@@ -202,99 +218,44 @@ function createStreamContext(state) {
|
|
|
202
218
|
|
|
203
219
|
// src/core/llm.ts
|
|
204
220
|
var DEFAULT_MAX_ITERATIONS = 10;
|
|
205
|
-
function
|
|
206
|
-
const {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
system,
|
|
211
|
-
tools,
|
|
212
|
-
toolStrategy,
|
|
213
|
-
structure,
|
|
214
|
-
middleware = []
|
|
215
|
-
} = options;
|
|
216
|
-
const providerConfig = modelRef.providerConfig ?? {};
|
|
217
|
-
const config = {
|
|
218
|
-
...providerConfig,
|
|
219
|
-
...explicitConfig,
|
|
220
|
-
headers: {
|
|
221
|
-
...providerConfig.headers,
|
|
222
|
-
...explicitConfig.headers
|
|
223
|
-
}
|
|
224
|
-
};
|
|
225
|
-
const provider = modelRef.provider;
|
|
226
|
-
const llmHandler = resolveLLMHandler(provider, modelRef.options);
|
|
227
|
-
if (!llmHandler) {
|
|
228
|
-
throw new UPPError(
|
|
229
|
-
`Provider '${provider.name}' does not support LLM modality`,
|
|
230
|
-
ErrorCode.InvalidRequest,
|
|
231
|
-
provider.name,
|
|
232
|
-
ModalityType.LLM
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
|
-
const boundModel = llmHandler.bind(modelRef.modelId);
|
|
236
|
-
const capabilities = boundModel.capabilities;
|
|
237
|
-
if (structure && !capabilities.structuredOutput) {
|
|
238
|
-
throw new UPPError(
|
|
239
|
-
`Provider '${provider.name}' does not support structured output`,
|
|
240
|
-
ErrorCode.InvalidRequest,
|
|
241
|
-
provider.name,
|
|
242
|
-
ModalityType.LLM
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
if (tools && tools.length > 0 && !capabilities.tools) {
|
|
246
|
-
throw new UPPError(
|
|
247
|
-
`Provider '${provider.name}' does not support tools`,
|
|
248
|
-
ErrorCode.InvalidRequest,
|
|
249
|
-
provider.name,
|
|
250
|
-
ModalityType.LLM
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
const instance = {
|
|
254
|
-
model: boundModel,
|
|
255
|
-
system,
|
|
256
|
-
params,
|
|
257
|
-
capabilities,
|
|
258
|
-
async generate(historyOrInput, ...inputs) {
|
|
259
|
-
const { history, messages } = parseInputs(historyOrInput, inputs);
|
|
260
|
-
return executeGenerate(
|
|
261
|
-
boundModel,
|
|
262
|
-
config,
|
|
263
|
-
system,
|
|
264
|
-
params,
|
|
265
|
-
tools,
|
|
266
|
-
toolStrategy,
|
|
267
|
-
structure,
|
|
268
|
-
history,
|
|
269
|
-
messages,
|
|
270
|
-
middleware
|
|
271
|
-
);
|
|
272
|
-
},
|
|
273
|
-
stream(historyOrInput, ...inputs) {
|
|
274
|
-
if (!capabilities.streaming) {
|
|
221
|
+
function validateMediaCapabilities(messages, capabilities, providerName) {
|
|
222
|
+
for (const msg of messages) {
|
|
223
|
+
if (!isUserMessage(msg)) continue;
|
|
224
|
+
for (const block of msg.content) {
|
|
225
|
+
if (block.type === "image" && !capabilities.imageInput) {
|
|
275
226
|
throw new UPPError(
|
|
276
|
-
`Provider '${
|
|
227
|
+
`Provider '${providerName}' does not support image input`,
|
|
277
228
|
ErrorCode.InvalidRequest,
|
|
278
|
-
|
|
229
|
+
providerName,
|
|
230
|
+
ModalityType.LLM
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
if (block.type === "document" && !capabilities.documentInput) {
|
|
234
|
+
throw new UPPError(
|
|
235
|
+
`Provider '${providerName}' does not support document input`,
|
|
236
|
+
ErrorCode.InvalidRequest,
|
|
237
|
+
providerName,
|
|
238
|
+
ModalityType.LLM
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
if (block.type === "video" && !capabilities.videoInput) {
|
|
242
|
+
throw new UPPError(
|
|
243
|
+
`Provider '${providerName}' does not support video input`,
|
|
244
|
+
ErrorCode.InvalidRequest,
|
|
245
|
+
providerName,
|
|
246
|
+
ModalityType.LLM
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
if (block.type === "audio" && !capabilities.audioInput) {
|
|
250
|
+
throw new UPPError(
|
|
251
|
+
`Provider '${providerName}' does not support audio input`,
|
|
252
|
+
ErrorCode.InvalidRequest,
|
|
253
|
+
providerName,
|
|
279
254
|
ModalityType.LLM
|
|
280
255
|
);
|
|
281
256
|
}
|
|
282
|
-
const { history, messages } = parseInputs(historyOrInput, inputs);
|
|
283
|
-
return executeStream(
|
|
284
|
-
boundModel,
|
|
285
|
-
config,
|
|
286
|
-
system,
|
|
287
|
-
params,
|
|
288
|
-
tools,
|
|
289
|
-
toolStrategy,
|
|
290
|
-
structure,
|
|
291
|
-
history,
|
|
292
|
-
messages,
|
|
293
|
-
middleware
|
|
294
|
-
);
|
|
295
257
|
}
|
|
296
|
-
}
|
|
297
|
-
return instance;
|
|
258
|
+
}
|
|
298
259
|
}
|
|
299
260
|
function isMessageInstance(value) {
|
|
300
261
|
if (value instanceof Message) {
|
|
@@ -318,6 +279,25 @@ function isMessageInstance(value) {
|
|
|
318
279
|
}
|
|
319
280
|
return false;
|
|
320
281
|
}
|
|
282
|
+
function inputToMessage(input) {
|
|
283
|
+
if (typeof input === "string") {
|
|
284
|
+
return new UserMessage(input);
|
|
285
|
+
}
|
|
286
|
+
if ("type" in input && "id" in input && "timestamp" in input) {
|
|
287
|
+
return input;
|
|
288
|
+
}
|
|
289
|
+
if (typeof input !== "object" || input === null || !("type" in input)) {
|
|
290
|
+
throw new Error("Invalid inference input");
|
|
291
|
+
}
|
|
292
|
+
const block = input;
|
|
293
|
+
if (isTextBlock(block)) {
|
|
294
|
+
return new UserMessage(block.text);
|
|
295
|
+
}
|
|
296
|
+
if (isImageBlock(block) || isDocumentBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {
|
|
297
|
+
return new UserMessage([block]);
|
|
298
|
+
}
|
|
299
|
+
throw new Error("Invalid inference input");
|
|
300
|
+
}
|
|
321
301
|
function parseInputs(historyOrInput, inputs) {
|
|
322
302
|
if (typeof historyOrInput === "object" && historyOrInput !== null && "messages" in historyOrInput && Array.isArray(historyOrInput.messages)) {
|
|
323
303
|
const thread = historyOrInput;
|
|
@@ -339,61 +319,185 @@ function parseInputs(historyOrInput, inputs) {
|
|
|
339
319
|
const newMessages = allInputs.map(inputToMessage);
|
|
340
320
|
return { history: [], messages: newMessages };
|
|
341
321
|
}
|
|
342
|
-
function
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
322
|
+
async function executeTools(assistantMessage, tools, toolStrategy, executions, onEvent, middleware = [], ctx) {
|
|
323
|
+
const toolCalls = assistantMessage.toolCalls ?? [];
|
|
324
|
+
const results = [];
|
|
325
|
+
const toolMap = new Map(tools.map((t) => [t.name, t]));
|
|
326
|
+
const promises = toolCalls.map(async (call, index) => {
|
|
327
|
+
const tool = toolMap.get(call.toolName);
|
|
328
|
+
const toolName = tool?.name ?? call.toolName;
|
|
329
|
+
const startTime = Date.now();
|
|
330
|
+
onEvent?.(toolExecutionStart(call.toolCallId, toolName, startTime, index));
|
|
331
|
+
let effectiveParams = call.arguments;
|
|
332
|
+
const endWithError = async (errorMessage, approved2) => {
|
|
333
|
+
const endTime = Date.now();
|
|
334
|
+
if (tool) {
|
|
335
|
+
await toolStrategy?.onError?.(tool, effectiveParams, new Error(errorMessage));
|
|
336
|
+
}
|
|
337
|
+
const execution = {
|
|
338
|
+
toolName,
|
|
339
|
+
toolCallId: call.toolCallId,
|
|
340
|
+
arguments: effectiveParams,
|
|
341
|
+
result: errorMessage,
|
|
342
|
+
isError: true,
|
|
343
|
+
duration: endTime - startTime,
|
|
344
|
+
approved: approved2
|
|
345
|
+
};
|
|
346
|
+
executions.push(execution);
|
|
347
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, errorMessage, true, endTime, index));
|
|
348
|
+
return {
|
|
349
|
+
toolCallId: call.toolCallId,
|
|
350
|
+
result: errorMessage,
|
|
351
|
+
isError: true
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
if (!tool) {
|
|
355
|
+
return endWithError(`Tool '${call.toolName}' not found`);
|
|
356
|
+
}
|
|
357
|
+
try {
|
|
358
|
+
await toolStrategy?.onToolCall?.(tool, effectiveParams);
|
|
359
|
+
if (ctx) {
|
|
360
|
+
await runToolHook(middleware, "onToolCall", tool, effectiveParams, ctx);
|
|
361
|
+
}
|
|
362
|
+
} catch (error) {
|
|
363
|
+
return endWithError(toError(error).message);
|
|
364
|
+
}
|
|
365
|
+
if (toolStrategy?.onBeforeCall) {
|
|
366
|
+
let beforeResult;
|
|
367
|
+
try {
|
|
368
|
+
beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
return endWithError(toError(error).message);
|
|
371
|
+
}
|
|
372
|
+
const isBeforeCallResult = (value) => typeof value === "object" && value !== null && "proceed" in value;
|
|
373
|
+
if (isBeforeCallResult(beforeResult)) {
|
|
374
|
+
if (!beforeResult.proceed) {
|
|
375
|
+
return endWithError("Tool execution skipped");
|
|
376
|
+
}
|
|
377
|
+
if (beforeResult.params !== void 0) {
|
|
378
|
+
effectiveParams = beforeResult.params;
|
|
379
|
+
}
|
|
380
|
+
} else if (!beforeResult) {
|
|
381
|
+
return endWithError("Tool execution skipped");
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
let approved = true;
|
|
385
|
+
if (tool.approval) {
|
|
386
|
+
try {
|
|
387
|
+
approved = await tool.approval(effectiveParams);
|
|
388
|
+
} catch (error) {
|
|
389
|
+
return endWithError(toError(error).message);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (!approved) {
|
|
393
|
+
const endTime = Date.now();
|
|
394
|
+
const execution = {
|
|
395
|
+
toolName,
|
|
396
|
+
toolCallId: call.toolCallId,
|
|
397
|
+
arguments: effectiveParams,
|
|
398
|
+
result: "Tool execution denied",
|
|
399
|
+
isError: true,
|
|
400
|
+
duration: endTime - startTime,
|
|
401
|
+
approved: false
|
|
402
|
+
};
|
|
403
|
+
executions.push(execution);
|
|
404
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, "Tool execution denied by approval handler", true, endTime, index));
|
|
405
|
+
return {
|
|
406
|
+
toolCallId: call.toolCallId,
|
|
407
|
+
result: "Tool execution denied by approval handler",
|
|
408
|
+
isError: true
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
try {
|
|
412
|
+
let result = await tool.run(effectiveParams);
|
|
413
|
+
const endTime = Date.now();
|
|
414
|
+
if (toolStrategy?.onAfterCall) {
|
|
415
|
+
const afterResult = await toolStrategy.onAfterCall(tool, effectiveParams, result);
|
|
416
|
+
const isAfterCallResult = (value) => typeof value === "object" && value !== null && "result" in value;
|
|
417
|
+
if (isAfterCallResult(afterResult)) {
|
|
418
|
+
result = afterResult.result;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (ctx) {
|
|
422
|
+
await runToolHook(middleware, "onToolResult", tool, result, ctx);
|
|
423
|
+
}
|
|
424
|
+
const execution = {
|
|
425
|
+
toolName,
|
|
426
|
+
toolCallId: call.toolCallId,
|
|
427
|
+
arguments: effectiveParams,
|
|
428
|
+
result,
|
|
429
|
+
isError: false,
|
|
430
|
+
duration: endTime - startTime,
|
|
431
|
+
approved
|
|
432
|
+
};
|
|
433
|
+
executions.push(execution);
|
|
434
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, result, false, endTime, index));
|
|
435
|
+
return {
|
|
436
|
+
toolCallId: call.toolCallId,
|
|
437
|
+
result,
|
|
438
|
+
isError: false
|
|
439
|
+
};
|
|
440
|
+
} catch (error) {
|
|
441
|
+
const endTime = Date.now();
|
|
442
|
+
const err = toError(error);
|
|
443
|
+
await toolStrategy?.onError?.(tool, effectiveParams, err);
|
|
444
|
+
const execution = {
|
|
445
|
+
toolName,
|
|
446
|
+
toolCallId: call.toolCallId,
|
|
447
|
+
arguments: effectiveParams,
|
|
448
|
+
result: err.message,
|
|
449
|
+
isError: true,
|
|
450
|
+
duration: endTime - startTime,
|
|
451
|
+
approved
|
|
452
|
+
};
|
|
453
|
+
executions.push(execution);
|
|
454
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));
|
|
455
|
+
return {
|
|
456
|
+
toolCallId: call.toolCallId,
|
|
457
|
+
result: err.message,
|
|
458
|
+
isError: true
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
results.push(...await Promise.all(promises));
|
|
463
|
+
return results;
|
|
464
|
+
}
|
|
465
|
+
async function executeGenerate(model, config, system, params, tools, toolStrategy, structure, history, newMessages, middleware) {
|
|
466
|
+
validateMediaCapabilities(
|
|
467
|
+
[...history, ...newMessages],
|
|
468
|
+
model.capabilities,
|
|
469
|
+
model.provider.name
|
|
470
|
+
);
|
|
471
|
+
const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
472
|
+
const allMessages = [...history, ...newMessages];
|
|
473
|
+
const toolExecutions = [];
|
|
474
|
+
const usages = [];
|
|
475
|
+
let cycles = 0;
|
|
476
|
+
let structuredData;
|
|
477
|
+
const initialRequest = {
|
|
478
|
+
messages: allMessages,
|
|
479
|
+
system,
|
|
480
|
+
params,
|
|
481
|
+
tools,
|
|
482
|
+
structure,
|
|
483
|
+
config
|
|
484
|
+
};
|
|
485
|
+
const ctx = createMiddlewareContext(
|
|
486
|
+
"llm",
|
|
487
|
+
model.modelId,
|
|
488
|
+
model.provider.name,
|
|
489
|
+
false,
|
|
490
|
+
initialRequest
|
|
491
|
+
);
|
|
492
|
+
try {
|
|
493
|
+
await runHook(middleware, "onStart", ctx);
|
|
494
|
+
await runHook(middleware, "onRequest", ctx);
|
|
495
|
+
while (cycles < maxIterations + 1) {
|
|
496
|
+
cycles++;
|
|
497
|
+
const request = {
|
|
498
|
+
messages: allMessages,
|
|
499
|
+
system,
|
|
500
|
+
params,
|
|
397
501
|
tools,
|
|
398
502
|
structure,
|
|
399
503
|
config
|
|
@@ -602,7 +706,11 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
602
706
|
} catch (error) {
|
|
603
707
|
const err = toError(error);
|
|
604
708
|
generatorError = err;
|
|
605
|
-
|
|
709
|
+
if (isCancelledError(err)) {
|
|
710
|
+
await runAbortHook(middleware, err, ctx);
|
|
711
|
+
} else {
|
|
712
|
+
await runErrorHook(middleware, err, ctx);
|
|
713
|
+
}
|
|
606
714
|
rejectGenerator(err);
|
|
607
715
|
throw err;
|
|
608
716
|
} finally {
|
|
@@ -613,6 +721,7 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
613
721
|
if (!abortController.signal.aborted) {
|
|
614
722
|
abortController.abort();
|
|
615
723
|
}
|
|
724
|
+
await runAbortHook(middleware, error, ctx);
|
|
616
725
|
rejectGenerator(error);
|
|
617
726
|
}
|
|
618
727
|
}
|
|
@@ -643,223 +752,143 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
643
752
|
};
|
|
644
753
|
return createStreamResult(generateStream(), createTurnPromise, abortController);
|
|
645
754
|
}
|
|
646
|
-
|
|
647
|
-
const
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
arguments: effectiveParams,
|
|
665
|
-
result: message2,
|
|
666
|
-
isError: true,
|
|
667
|
-
duration: endTime - startTime,
|
|
668
|
-
approved: approved2
|
|
669
|
-
};
|
|
670
|
-
executions.push(execution);
|
|
671
|
-
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, message2, true, endTime, index));
|
|
672
|
-
return {
|
|
673
|
-
toolCallId: call.toolCallId,
|
|
674
|
-
result: message2,
|
|
675
|
-
isError: true
|
|
676
|
-
};
|
|
677
|
-
};
|
|
678
|
-
if (!tool) {
|
|
679
|
-
return endWithError(`Tool '${call.toolName}' not found`);
|
|
680
|
-
}
|
|
681
|
-
try {
|
|
682
|
-
await toolStrategy?.onToolCall?.(tool, effectiveParams);
|
|
683
|
-
if (ctx) {
|
|
684
|
-
await runToolHook(middleware, "onToolCall", tool, effectiveParams, ctx);
|
|
685
|
-
}
|
|
686
|
-
} catch (error) {
|
|
687
|
-
return endWithError(toError(error).message);
|
|
688
|
-
}
|
|
689
|
-
if (toolStrategy?.onBeforeCall) {
|
|
690
|
-
let beforeResult;
|
|
691
|
-
try {
|
|
692
|
-
beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);
|
|
693
|
-
} catch (error) {
|
|
694
|
-
return endWithError(toError(error).message);
|
|
695
|
-
}
|
|
696
|
-
const isBeforeCallResult = (value) => typeof value === "object" && value !== null && "proceed" in value;
|
|
697
|
-
if (isBeforeCallResult(beforeResult)) {
|
|
698
|
-
if (!beforeResult.proceed) {
|
|
699
|
-
return endWithError("Tool execution skipped");
|
|
700
|
-
}
|
|
701
|
-
if (beforeResult.params !== void 0) {
|
|
702
|
-
effectiveParams = beforeResult.params;
|
|
703
|
-
}
|
|
704
|
-
} else if (!beforeResult) {
|
|
705
|
-
return endWithError("Tool execution skipped");
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
let approved = true;
|
|
709
|
-
if (tool.approval) {
|
|
710
|
-
try {
|
|
711
|
-
approved = await tool.approval(effectiveParams);
|
|
712
|
-
} catch (error) {
|
|
713
|
-
return endWithError(toError(error).message);
|
|
714
|
-
}
|
|
755
|
+
function llm(options) {
|
|
756
|
+
const {
|
|
757
|
+
model: modelRef,
|
|
758
|
+
config: explicitConfig = {},
|
|
759
|
+
params,
|
|
760
|
+
system,
|
|
761
|
+
tools,
|
|
762
|
+
toolStrategy,
|
|
763
|
+
structure,
|
|
764
|
+
middleware = []
|
|
765
|
+
} = options;
|
|
766
|
+
const providerConfig = modelRef.providerConfig ?? {};
|
|
767
|
+
const config = {
|
|
768
|
+
...providerConfig,
|
|
769
|
+
...explicitConfig,
|
|
770
|
+
headers: {
|
|
771
|
+
...providerConfig.headers,
|
|
772
|
+
...explicitConfig.headers
|
|
715
773
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
await toolStrategy?.onError?.(tool, effectiveParams, err);
|
|
768
|
-
const execution = {
|
|
769
|
-
toolName,
|
|
770
|
-
toolCallId: call.toolCallId,
|
|
771
|
-
arguments: effectiveParams,
|
|
772
|
-
result: err.message,
|
|
773
|
-
isError: true,
|
|
774
|
-
duration: endTime - startTime,
|
|
775
|
-
approved
|
|
776
|
-
};
|
|
777
|
-
executions.push(execution);
|
|
778
|
-
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));
|
|
779
|
-
return {
|
|
780
|
-
toolCallId: call.toolCallId,
|
|
781
|
-
result: err.message,
|
|
782
|
-
isError: true
|
|
783
|
-
};
|
|
784
|
-
}
|
|
785
|
-
});
|
|
786
|
-
results.push(...await Promise.all(promises));
|
|
787
|
-
return results;
|
|
788
|
-
}
|
|
789
|
-
function validateMediaCapabilities(messages, capabilities, providerName) {
|
|
790
|
-
for (const msg of messages) {
|
|
791
|
-
if (!isUserMessage(msg)) continue;
|
|
792
|
-
for (const block of msg.content) {
|
|
793
|
-
if (block.type === "image" && !capabilities.imageInput) {
|
|
794
|
-
throw new UPPError(
|
|
795
|
-
`Provider '${providerName}' does not support image input`,
|
|
796
|
-
ErrorCode.InvalidRequest,
|
|
797
|
-
providerName,
|
|
798
|
-
ModalityType.LLM
|
|
799
|
-
);
|
|
800
|
-
}
|
|
801
|
-
if (block.type === "document" && !capabilities.documentInput) {
|
|
802
|
-
throw new UPPError(
|
|
803
|
-
`Provider '${providerName}' does not support document input`,
|
|
804
|
-
ErrorCode.InvalidRequest,
|
|
805
|
-
providerName,
|
|
806
|
-
ModalityType.LLM
|
|
807
|
-
);
|
|
808
|
-
}
|
|
809
|
-
if (block.type === "video" && !capabilities.videoInput) {
|
|
810
|
-
throw new UPPError(
|
|
811
|
-
`Provider '${providerName}' does not support video input`,
|
|
812
|
-
ErrorCode.InvalidRequest,
|
|
813
|
-
providerName,
|
|
814
|
-
ModalityType.LLM
|
|
815
|
-
);
|
|
816
|
-
}
|
|
817
|
-
if (block.type === "audio" && !capabilities.audioInput) {
|
|
774
|
+
};
|
|
775
|
+
const provider = modelRef.provider;
|
|
776
|
+
const llmHandler = resolveLLMHandler(provider, modelRef.options);
|
|
777
|
+
if (!llmHandler) {
|
|
778
|
+
throw new UPPError(
|
|
779
|
+
`Provider '${provider.name}' does not support LLM modality`,
|
|
780
|
+
ErrorCode.InvalidRequest,
|
|
781
|
+
provider.name,
|
|
782
|
+
ModalityType.LLM
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
const boundModel = llmHandler.bind(modelRef.modelId);
|
|
786
|
+
const capabilities = boundModel.capabilities;
|
|
787
|
+
if (structure && !capabilities.structuredOutput) {
|
|
788
|
+
throw new UPPError(
|
|
789
|
+
`Provider '${provider.name}' does not support structured output`,
|
|
790
|
+
ErrorCode.InvalidRequest,
|
|
791
|
+
provider.name,
|
|
792
|
+
ModalityType.LLM
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
if (tools && tools.length > 0 && !capabilities.tools) {
|
|
796
|
+
throw new UPPError(
|
|
797
|
+
`Provider '${provider.name}' does not support tools`,
|
|
798
|
+
ErrorCode.InvalidRequest,
|
|
799
|
+
provider.name,
|
|
800
|
+
ModalityType.LLM
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
const instance = {
|
|
804
|
+
model: boundModel,
|
|
805
|
+
system,
|
|
806
|
+
params,
|
|
807
|
+
capabilities,
|
|
808
|
+
async generate(historyOrInput, ...inputs) {
|
|
809
|
+
const { history, messages } = parseInputs(historyOrInput, inputs);
|
|
810
|
+
return executeGenerate(
|
|
811
|
+
boundModel,
|
|
812
|
+
config,
|
|
813
|
+
system,
|
|
814
|
+
params,
|
|
815
|
+
tools,
|
|
816
|
+
toolStrategy,
|
|
817
|
+
structure,
|
|
818
|
+
history,
|
|
819
|
+
messages,
|
|
820
|
+
middleware
|
|
821
|
+
);
|
|
822
|
+
},
|
|
823
|
+
stream(historyOrInput, ...inputs) {
|
|
824
|
+
if (!capabilities.streaming) {
|
|
818
825
|
throw new UPPError(
|
|
819
|
-
`Provider '${
|
|
826
|
+
`Provider '${provider.name}' does not support streaming`,
|
|
820
827
|
ErrorCode.InvalidRequest,
|
|
821
|
-
|
|
828
|
+
provider.name,
|
|
822
829
|
ModalityType.LLM
|
|
823
830
|
);
|
|
824
831
|
}
|
|
832
|
+
const { history, messages } = parseInputs(historyOrInput, inputs);
|
|
833
|
+
return executeStream(
|
|
834
|
+
boundModel,
|
|
835
|
+
config,
|
|
836
|
+
system,
|
|
837
|
+
params,
|
|
838
|
+
tools,
|
|
839
|
+
toolStrategy,
|
|
840
|
+
structure,
|
|
841
|
+
history,
|
|
842
|
+
messages,
|
|
843
|
+
middleware
|
|
844
|
+
);
|
|
825
845
|
}
|
|
826
|
-
}
|
|
846
|
+
};
|
|
847
|
+
return instance;
|
|
827
848
|
}
|
|
828
849
|
|
|
829
850
|
// src/core/embedding.ts
|
|
830
|
-
function
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
headers: {
|
|
837
|
-
...providerConfig.headers,
|
|
838
|
-
...explicitConfig.headers
|
|
851
|
+
function decodeBase64(b64, providerName) {
|
|
852
|
+
try {
|
|
853
|
+
const binary = atob(b64);
|
|
854
|
+
const bytes = new Uint8Array(binary.length);
|
|
855
|
+
for (let i = 0; i < binary.length; i++) {
|
|
856
|
+
bytes[i] = binary.charCodeAt(i);
|
|
839
857
|
}
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
858
|
+
const floats = new Float32Array(bytes.buffer);
|
|
859
|
+
return Array.from(floats);
|
|
860
|
+
} catch (error) {
|
|
861
|
+
const cause = error instanceof Error ? error : new Error("Failed to decode base64 vector");
|
|
844
862
|
throw new UPPError(
|
|
845
|
-
|
|
846
|
-
ErrorCode.
|
|
847
|
-
|
|
848
|
-
ModalityType.Embedding
|
|
863
|
+
"Invalid base64 embedding vector",
|
|
864
|
+
ErrorCode.InvalidResponse,
|
|
865
|
+
providerName,
|
|
866
|
+
ModalityType.Embedding,
|
|
867
|
+
void 0,
|
|
868
|
+
cause
|
|
849
869
|
);
|
|
850
870
|
}
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
return createChunkedStream(boundModel, inputs, params, config, embedOptions, middleware);
|
|
856
|
-
}
|
|
857
|
-
return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal, embedOptions?.inputType, middleware);
|
|
871
|
+
}
|
|
872
|
+
function normalizeVector(vector, providerName) {
|
|
873
|
+
if (Array.isArray(vector)) {
|
|
874
|
+
return vector;
|
|
858
875
|
}
|
|
876
|
+
return decodeBase64(vector, providerName);
|
|
877
|
+
}
|
|
878
|
+
function normalizeResponse(response, providerName) {
|
|
859
879
|
return {
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
880
|
+
embeddings: response.embeddings.map((vec, i) => {
|
|
881
|
+
const vector = normalizeVector(vec.vector, providerName);
|
|
882
|
+
return {
|
|
883
|
+
vector,
|
|
884
|
+
dimensions: vector.length,
|
|
885
|
+
index: vec.index ?? i,
|
|
886
|
+
tokens: vec.tokens,
|
|
887
|
+
metadata: vec.metadata
|
|
888
|
+
};
|
|
889
|
+
}),
|
|
890
|
+
usage: response.usage,
|
|
891
|
+
metadata: response.metadata
|
|
863
892
|
};
|
|
864
893
|
}
|
|
865
894
|
async function executeEmbed(model, inputs, params, config, signal, inputType, middleware = []) {
|
|
@@ -881,59 +910,16 @@ async function executeEmbed(model, inputs, params, config, signal, inputType, mi
|
|
|
881
910
|
await runHook(middleware, "onStart", ctx);
|
|
882
911
|
await runHook(middleware, "onRequest", ctx);
|
|
883
912
|
const response = await model.embed(request);
|
|
884
|
-
const result = normalizeResponse(response, model.provider.name);
|
|
885
|
-
ctx.response = response;
|
|
886
|
-
ctx.endTime = Date.now();
|
|
887
|
-
await runHook(middleware, "onResponse", ctx, true);
|
|
888
|
-
await runHook(middleware, "onEnd", ctx, true);
|
|
889
|
-
return result;
|
|
890
|
-
} catch (error) {
|
|
891
|
-
const err = toError(error);
|
|
892
|
-
await runErrorHook(middleware, err, ctx);
|
|
893
|
-
throw err;
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
function normalizeResponse(response, providerName) {
|
|
897
|
-
return {
|
|
898
|
-
embeddings: response.embeddings.map((vec, i) => {
|
|
899
|
-
const vector = normalizeVector(vec.vector, providerName);
|
|
900
|
-
return {
|
|
901
|
-
vector,
|
|
902
|
-
dimensions: vector.length,
|
|
903
|
-
index: vec.index ?? i,
|
|
904
|
-
tokens: vec.tokens,
|
|
905
|
-
metadata: vec.metadata
|
|
906
|
-
};
|
|
907
|
-
}),
|
|
908
|
-
usage: response.usage,
|
|
909
|
-
metadata: response.metadata
|
|
910
|
-
};
|
|
911
|
-
}
|
|
912
|
-
function normalizeVector(vector, providerName) {
|
|
913
|
-
if (Array.isArray(vector)) {
|
|
914
|
-
return vector;
|
|
915
|
-
}
|
|
916
|
-
return decodeBase64(vector, providerName);
|
|
917
|
-
}
|
|
918
|
-
function decodeBase64(b64, providerName) {
|
|
919
|
-
try {
|
|
920
|
-
const binary = atob(b64);
|
|
921
|
-
const bytes = new Uint8Array(binary.length);
|
|
922
|
-
for (let i = 0; i < binary.length; i++) {
|
|
923
|
-
bytes[i] = binary.charCodeAt(i);
|
|
924
|
-
}
|
|
925
|
-
const floats = new Float32Array(bytes.buffer);
|
|
926
|
-
return Array.from(floats);
|
|
913
|
+
const result = normalizeResponse(response, model.provider.name);
|
|
914
|
+
ctx.response = response;
|
|
915
|
+
ctx.endTime = Date.now();
|
|
916
|
+
await runHook(middleware, "onResponse", ctx, true);
|
|
917
|
+
await runHook(middleware, "onEnd", ctx, true);
|
|
918
|
+
return result;
|
|
927
919
|
} catch (error) {
|
|
928
|
-
const
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
ErrorCode.InvalidResponse,
|
|
932
|
-
providerName,
|
|
933
|
-
ModalityType.Embedding,
|
|
934
|
-
void 0,
|
|
935
|
-
cause
|
|
936
|
-
);
|
|
920
|
+
const err = toError(error);
|
|
921
|
+
await runErrorHook(middleware, err, ctx);
|
|
922
|
+
throw err;
|
|
937
923
|
}
|
|
938
924
|
}
|
|
939
925
|
function createChunkedStream(model, inputs, params, config, options, middleware = []) {
|
|
@@ -1072,8 +1058,49 @@ function createChunkedStream(model, inputs, params, config, options, middleware
|
|
|
1072
1058
|
abort: () => abortController.abort()
|
|
1073
1059
|
};
|
|
1074
1060
|
}
|
|
1061
|
+
function embedding(options) {
|
|
1062
|
+
const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;
|
|
1063
|
+
const providerConfig = modelRef.providerConfig ?? {};
|
|
1064
|
+
const config = {
|
|
1065
|
+
...providerConfig,
|
|
1066
|
+
...explicitConfig,
|
|
1067
|
+
headers: {
|
|
1068
|
+
...providerConfig.headers,
|
|
1069
|
+
...explicitConfig.headers
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
const provider = modelRef.provider;
|
|
1073
|
+
const handler = resolveEmbeddingHandler(provider);
|
|
1074
|
+
if (!handler) {
|
|
1075
|
+
throw new UPPError(
|
|
1076
|
+
`Provider '${provider.name}' does not support embedding modality`,
|
|
1077
|
+
ErrorCode.InvalidRequest,
|
|
1078
|
+
provider.name,
|
|
1079
|
+
ModalityType.Embedding
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
const boundModel = handler.bind(modelRef.modelId);
|
|
1083
|
+
function embed(input, embedOptions) {
|
|
1084
|
+
const inputs = Array.isArray(input) ? input : [input];
|
|
1085
|
+
if (embedOptions?.chunked) {
|
|
1086
|
+
return createChunkedStream(boundModel, inputs, params, config, embedOptions, middleware);
|
|
1087
|
+
}
|
|
1088
|
+
return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal, embedOptions?.inputType, middleware);
|
|
1089
|
+
}
|
|
1090
|
+
return {
|
|
1091
|
+
model: boundModel,
|
|
1092
|
+
params,
|
|
1093
|
+
embed
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1075
1096
|
|
|
1076
1097
|
// src/core/image.ts
|
|
1098
|
+
function normalizeInput(input) {
|
|
1099
|
+
if (typeof input === "string") {
|
|
1100
|
+
return input;
|
|
1101
|
+
}
|
|
1102
|
+
return input.prompt;
|
|
1103
|
+
}
|
|
1077
1104
|
function image(options) {
|
|
1078
1105
|
const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;
|
|
1079
1106
|
const providerConfig = modelRef.providerConfig ?? {};
|
|
@@ -1108,13 +1135,13 @@ function image(options) {
|
|
|
1108
1135
|
model: boundModel,
|
|
1109
1136
|
params,
|
|
1110
1137
|
capabilities,
|
|
1111
|
-
async generate(input,
|
|
1138
|
+
async generate(input, generateOptions) {
|
|
1112
1139
|
const prompt = normalizeInput(input);
|
|
1113
1140
|
const request = {
|
|
1114
1141
|
prompt,
|
|
1115
1142
|
params,
|
|
1116
1143
|
config,
|
|
1117
|
-
signal:
|
|
1144
|
+
signal: generateOptions?.signal
|
|
1118
1145
|
};
|
|
1119
1146
|
const ctx = createMiddlewareContext(
|
|
1120
1147
|
"image",
|
|
@@ -1225,14 +1252,22 @@ function image(options) {
|
|
|
1225
1252
|
}
|
|
1226
1253
|
return instance;
|
|
1227
1254
|
}
|
|
1228
|
-
function normalizeInput(input) {
|
|
1229
|
-
if (typeof input === "string") {
|
|
1230
|
-
return input;
|
|
1231
|
-
}
|
|
1232
|
-
return input.prompt;
|
|
1233
|
-
}
|
|
1234
1255
|
|
|
1235
1256
|
// src/core/media/document.ts
|
|
1257
|
+
function detectMimeType(path) {
|
|
1258
|
+
const ext = path.split(".").pop()?.toLowerCase();
|
|
1259
|
+
switch (ext) {
|
|
1260
|
+
case "pdf":
|
|
1261
|
+
return "application/pdf";
|
|
1262
|
+
case "txt":
|
|
1263
|
+
case "text":
|
|
1264
|
+
case "md":
|
|
1265
|
+
case "markdown":
|
|
1266
|
+
return "text/plain";
|
|
1267
|
+
default:
|
|
1268
|
+
return "application/octet-stream";
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1236
1271
|
var Document = class _Document {
|
|
1237
1272
|
/** The underlying document source (base64, url, or text) */
|
|
1238
1273
|
source;
|
|
@@ -1443,22 +1478,33 @@ var Document = class _Document {
|
|
|
1443
1478
|
);
|
|
1444
1479
|
}
|
|
1445
1480
|
};
|
|
1446
|
-
|
|
1481
|
+
|
|
1482
|
+
// src/core/media/Audio.ts
|
|
1483
|
+
function detectMimeType2(path) {
|
|
1447
1484
|
const ext = path.split(".").pop()?.toLowerCase();
|
|
1448
1485
|
switch (ext) {
|
|
1449
|
-
case "
|
|
1450
|
-
return "
|
|
1451
|
-
case "
|
|
1452
|
-
|
|
1453
|
-
case "
|
|
1454
|
-
case "
|
|
1455
|
-
return "
|
|
1486
|
+
case "mp3":
|
|
1487
|
+
return "audio/mp3";
|
|
1488
|
+
case "wav":
|
|
1489
|
+
return "audio/wav";
|
|
1490
|
+
case "ogg":
|
|
1491
|
+
case "oga":
|
|
1492
|
+
return "audio/ogg";
|
|
1493
|
+
case "flac":
|
|
1494
|
+
return "audio/flac";
|
|
1495
|
+
case "aac":
|
|
1496
|
+
return "audio/aac";
|
|
1497
|
+
case "m4a":
|
|
1498
|
+
return "audio/mp4";
|
|
1499
|
+
case "webm":
|
|
1500
|
+
return "audio/webm";
|
|
1501
|
+
case "aiff":
|
|
1502
|
+
case "aif":
|
|
1503
|
+
return "audio/aiff";
|
|
1456
1504
|
default:
|
|
1457
1505
|
return "application/octet-stream";
|
|
1458
1506
|
}
|
|
1459
1507
|
}
|
|
1460
|
-
|
|
1461
|
-
// src/core/media/Audio.ts
|
|
1462
1508
|
var Audio = class _Audio {
|
|
1463
1509
|
/** The audio data as raw bytes */
|
|
1464
1510
|
data;
|
|
@@ -1609,33 +1655,37 @@ var Audio = class _Audio {
|
|
|
1609
1655
|
);
|
|
1610
1656
|
}
|
|
1611
1657
|
};
|
|
1612
|
-
|
|
1658
|
+
|
|
1659
|
+
// src/core/media/Video.ts
|
|
1660
|
+
function detectMimeType3(path) {
|
|
1613
1661
|
const ext = path.split(".").pop()?.toLowerCase();
|
|
1614
1662
|
switch (ext) {
|
|
1615
|
-
case "
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
return "audio/wav";
|
|
1619
|
-
case "ogg":
|
|
1620
|
-
case "oga":
|
|
1621
|
-
return "audio/ogg";
|
|
1622
|
-
case "flac":
|
|
1623
|
-
return "audio/flac";
|
|
1624
|
-
case "aac":
|
|
1625
|
-
return "audio/aac";
|
|
1626
|
-
case "m4a":
|
|
1627
|
-
return "audio/mp4";
|
|
1663
|
+
case "mp4":
|
|
1664
|
+
case "m4v":
|
|
1665
|
+
return "video/mp4";
|
|
1628
1666
|
case "webm":
|
|
1629
|
-
return "
|
|
1630
|
-
case "
|
|
1631
|
-
case "
|
|
1632
|
-
return "
|
|
1667
|
+
return "video/webm";
|
|
1668
|
+
case "ogv":
|
|
1669
|
+
case "ogg":
|
|
1670
|
+
return "video/ogg";
|
|
1671
|
+
case "mov":
|
|
1672
|
+
return "video/quicktime";
|
|
1673
|
+
case "avi":
|
|
1674
|
+
return "video/x-msvideo";
|
|
1675
|
+
case "mpeg":
|
|
1676
|
+
case "mpg":
|
|
1677
|
+
return "video/mpeg";
|
|
1678
|
+
case "wmv":
|
|
1679
|
+
return "video/x-ms-wmv";
|
|
1680
|
+
case "3gp":
|
|
1681
|
+
case "3gpp":
|
|
1682
|
+
return "video/3gpp";
|
|
1683
|
+
case "flv":
|
|
1684
|
+
return "video/x-flv";
|
|
1633
1685
|
default:
|
|
1634
1686
|
return "application/octet-stream";
|
|
1635
1687
|
}
|
|
1636
1688
|
}
|
|
1637
|
-
|
|
1638
|
-
// src/core/media/Video.ts
|
|
1639
1689
|
var Video = class _Video {
|
|
1640
1690
|
/** The video data as raw bytes */
|
|
1641
1691
|
data;
|
|
@@ -1800,35 +1850,6 @@ var Video = class _Video {
|
|
|
1800
1850
|
);
|
|
1801
1851
|
}
|
|
1802
1852
|
};
|
|
1803
|
-
function detectMimeType3(path) {
|
|
1804
|
-
const ext = path.split(".").pop()?.toLowerCase();
|
|
1805
|
-
switch (ext) {
|
|
1806
|
-
case "mp4":
|
|
1807
|
-
case "m4v":
|
|
1808
|
-
return "video/mp4";
|
|
1809
|
-
case "webm":
|
|
1810
|
-
return "video/webm";
|
|
1811
|
-
case "ogv":
|
|
1812
|
-
case "ogg":
|
|
1813
|
-
return "video/ogg";
|
|
1814
|
-
case "mov":
|
|
1815
|
-
return "video/quicktime";
|
|
1816
|
-
case "avi":
|
|
1817
|
-
return "video/x-msvideo";
|
|
1818
|
-
case "mpeg":
|
|
1819
|
-
case "mpg":
|
|
1820
|
-
return "video/mpeg";
|
|
1821
|
-
case "wmv":
|
|
1822
|
-
return "video/x-ms-wmv";
|
|
1823
|
-
case "3gp":
|
|
1824
|
-
case "3gpp":
|
|
1825
|
-
return "video/3gpp";
|
|
1826
|
-
case "flv":
|
|
1827
|
-
return "video/x-flv";
|
|
1828
|
-
default:
|
|
1829
|
-
return "application/octet-stream";
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
1853
|
|
|
1833
1854
|
// src/types/thread.ts
|
|
1834
1855
|
var Thread = class _Thread {
|
|
@@ -2091,274 +2112,6 @@ var EmbeddingInputType = {
|
|
|
2091
2112
|
Query: "query"
|
|
2092
2113
|
};
|
|
2093
2114
|
|
|
2094
|
-
// src/utils/partial-json.ts
|
|
2095
|
-
function parsePartialJson(json) {
|
|
2096
|
-
const trimmed = json.trim();
|
|
2097
|
-
if (trimmed === "") {
|
|
2098
|
-
return { value: void 0, isComplete: false };
|
|
2099
|
-
}
|
|
2100
|
-
try {
|
|
2101
|
-
const value = JSON.parse(trimmed);
|
|
2102
|
-
return { value, isComplete: true };
|
|
2103
|
-
} catch {
|
|
2104
|
-
}
|
|
2105
|
-
try {
|
|
2106
|
-
const repaired = repairJson(trimmed);
|
|
2107
|
-
const value = JSON.parse(repaired);
|
|
2108
|
-
return { value, isComplete: false };
|
|
2109
|
-
} catch {
|
|
2110
|
-
return { value: void 0, isComplete: false };
|
|
2111
|
-
}
|
|
2112
|
-
}
|
|
2113
|
-
function repairJson(json) {
|
|
2114
|
-
let result = json;
|
|
2115
|
-
const stack = [];
|
|
2116
|
-
let inString = false;
|
|
2117
|
-
let escape = false;
|
|
2118
|
-
for (let i = 0; i < result.length; i++) {
|
|
2119
|
-
const char = result[i];
|
|
2120
|
-
if (escape) {
|
|
2121
|
-
escape = false;
|
|
2122
|
-
continue;
|
|
2123
|
-
}
|
|
2124
|
-
if (char === "\\" && inString) {
|
|
2125
|
-
escape = true;
|
|
2126
|
-
continue;
|
|
2127
|
-
}
|
|
2128
|
-
if (char === '"' && !escape) {
|
|
2129
|
-
inString = !inString;
|
|
2130
|
-
}
|
|
2131
|
-
if (!inString) {
|
|
2132
|
-
if (char === "{") {
|
|
2133
|
-
stack.push("{");
|
|
2134
|
-
} else if (char === "[") {
|
|
2135
|
-
stack.push("[");
|
|
2136
|
-
} else if (char === "}") {
|
|
2137
|
-
if (stack.length > 0 && stack[stack.length - 1] === "{") {
|
|
2138
|
-
stack.pop();
|
|
2139
|
-
}
|
|
2140
|
-
} else if (char === "]") {
|
|
2141
|
-
if (stack.length > 0 && stack[stack.length - 1] === "[") {
|
|
2142
|
-
stack.pop();
|
|
2143
|
-
}
|
|
2144
|
-
}
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
if (inString) {
|
|
2148
|
-
const unicodeMatch = result.match(/\\u[0-9a-fA-F]{0,3}$/);
|
|
2149
|
-
if (unicodeMatch) {
|
|
2150
|
-
result = result.slice(0, -unicodeMatch[0].length);
|
|
2151
|
-
}
|
|
2152
|
-
if (result.endsWith("\\")) {
|
|
2153
|
-
result = result.slice(0, -1);
|
|
2154
|
-
}
|
|
2155
|
-
result += '"';
|
|
2156
|
-
inString = false;
|
|
2157
|
-
}
|
|
2158
|
-
result = cleanupTrailingIncomplete(result);
|
|
2159
|
-
while (stack.length > 0) {
|
|
2160
|
-
const open = stack.pop();
|
|
2161
|
-
if (open === "{") {
|
|
2162
|
-
result += "}";
|
|
2163
|
-
} else {
|
|
2164
|
-
result += "]";
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
return result;
|
|
2168
|
-
}
|
|
2169
|
-
function cleanupTrailingIncomplete(json) {
|
|
2170
|
-
let result = json.trim();
|
|
2171
|
-
let changed = true;
|
|
2172
|
-
while (changed) {
|
|
2173
|
-
changed = false;
|
|
2174
|
-
const trimmed = result.trim();
|
|
2175
|
-
if (trimmed.endsWith(",")) {
|
|
2176
|
-
result = trimmed.slice(0, -1);
|
|
2177
|
-
changed = true;
|
|
2178
|
-
continue;
|
|
2179
|
-
}
|
|
2180
|
-
if (trimmed.endsWith(":")) {
|
|
2181
|
-
const colonIndex = trimmed.length - 1;
|
|
2182
|
-
let keyStart = colonIndex - 1;
|
|
2183
|
-
while (keyStart >= 0 && /\s/.test(trimmed[keyStart])) {
|
|
2184
|
-
keyStart--;
|
|
2185
|
-
}
|
|
2186
|
-
if (keyStart >= 0 && trimmed[keyStart] === '"') {
|
|
2187
|
-
keyStart--;
|
|
2188
|
-
while (keyStart >= 0 && trimmed[keyStart] !== '"') {
|
|
2189
|
-
keyStart--;
|
|
2190
|
-
}
|
|
2191
|
-
keyStart--;
|
|
2192
|
-
while (keyStart >= 0 && /\s/.test(trimmed[keyStart])) {
|
|
2193
|
-
keyStart--;
|
|
2194
|
-
}
|
|
2195
|
-
if (keyStart >= 0 && trimmed[keyStart] === ",") {
|
|
2196
|
-
result = trimmed.slice(0, keyStart);
|
|
2197
|
-
} else {
|
|
2198
|
-
result = trimmed.slice(0, keyStart + 1);
|
|
2199
|
-
}
|
|
2200
|
-
changed = true;
|
|
2201
|
-
continue;
|
|
2202
|
-
}
|
|
2203
|
-
}
|
|
2204
|
-
const literalMatch = trimmed.match(/(,?\s*)(t(?:r(?:ue?)?)?|f(?:a(?:l(?:se?)?)?)?|n(?:u(?:ll?)?)?)$/i);
|
|
2205
|
-
if (literalMatch && literalMatch[2]) {
|
|
2206
|
-
const partial = literalMatch[2].toLowerCase();
|
|
2207
|
-
const literals = ["true", "false", "null"];
|
|
2208
|
-
const match = literals.find((lit) => lit.startsWith(partial) && partial !== lit);
|
|
2209
|
-
if (match) {
|
|
2210
|
-
result = trimmed.slice(0, -literalMatch[2].length) + match;
|
|
2211
|
-
changed = true;
|
|
2212
|
-
continue;
|
|
2213
|
-
}
|
|
2214
|
-
}
|
|
2215
|
-
const numberMatch = trimmed.match(/(,?\s*)(-?(?:\d+\.|\d*\.?\d+[eE][+-]?|\d+[eE]|-))$/);
|
|
2216
|
-
if (numberMatch && numberMatch[2]) {
|
|
2217
|
-
const partial = numberMatch[2];
|
|
2218
|
-
if (/[.eE+-]$/.test(partial)) {
|
|
2219
|
-
if (partial === "-") {
|
|
2220
|
-
result = trimmed.slice(0, -(numberMatch[0]?.length ?? 0)).trimEnd();
|
|
2221
|
-
} else {
|
|
2222
|
-
result = trimmed.slice(0, -1);
|
|
2223
|
-
}
|
|
2224
|
-
changed = true;
|
|
2225
|
-
continue;
|
|
2226
|
-
}
|
|
2227
|
-
}
|
|
2228
|
-
}
|
|
2229
|
-
return result;
|
|
2230
|
-
}
|
|
2231
|
-
|
|
2232
|
-
// src/middleware/parsed-object.ts
|
|
2233
|
-
var ACCUMULATED_TEXT_KEY = "parsedObject:text";
|
|
2234
|
-
var ACCUMULATED_ARGS_KEY = "parsedObject:args";
|
|
2235
|
-
function getAccumulatedText(state) {
|
|
2236
|
-
let map = state.get(ACCUMULATED_TEXT_KEY);
|
|
2237
|
-
if (!map) {
|
|
2238
|
-
map = /* @__PURE__ */ new Map();
|
|
2239
|
-
state.set(ACCUMULATED_TEXT_KEY, map);
|
|
2240
|
-
}
|
|
2241
|
-
return map;
|
|
2242
|
-
}
|
|
2243
|
-
function getAccumulatedArgs(state) {
|
|
2244
|
-
let map = state.get(ACCUMULATED_ARGS_KEY);
|
|
2245
|
-
if (!map) {
|
|
2246
|
-
map = /* @__PURE__ */ new Map();
|
|
2247
|
-
state.set(ACCUMULATED_ARGS_KEY, map);
|
|
2248
|
-
}
|
|
2249
|
-
return map;
|
|
2250
|
-
}
|
|
2251
|
-
function parsedObjectMiddleware(options = {}) {
|
|
2252
|
-
const { parseObjects = true, parseToolCalls = true } = options;
|
|
2253
|
-
return {
|
|
2254
|
-
name: "parsed-object",
|
|
2255
|
-
onStreamEvent(event, ctx) {
|
|
2256
|
-
if (parseObjects && event.type === StreamEventType.ObjectDelta) {
|
|
2257
|
-
const accumulatedText = getAccumulatedText(ctx.state);
|
|
2258
|
-
const current = accumulatedText.get(event.index) ?? "";
|
|
2259
|
-
const newText = current + (event.delta.text ?? "");
|
|
2260
|
-
accumulatedText.set(event.index, newText);
|
|
2261
|
-
const parseResult = parsePartialJson(newText);
|
|
2262
|
-
const parsedEvent = {
|
|
2263
|
-
...event,
|
|
2264
|
-
delta: {
|
|
2265
|
-
...event.delta,
|
|
2266
|
-
parsed: parseResult.value
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
return parsedEvent;
|
|
2270
|
-
}
|
|
2271
|
-
if (parseToolCalls && event.type === StreamEventType.ToolCallDelta) {
|
|
2272
|
-
const accumulatedArgs = getAccumulatedArgs(ctx.state);
|
|
2273
|
-
const current = accumulatedArgs.get(event.index) ?? "";
|
|
2274
|
-
const newJson = current + (event.delta.argumentsJson ?? "");
|
|
2275
|
-
accumulatedArgs.set(event.index, newJson);
|
|
2276
|
-
const parseResult = parsePartialJson(newJson);
|
|
2277
|
-
const parsedEvent = {
|
|
2278
|
-
...event,
|
|
2279
|
-
delta: {
|
|
2280
|
-
...event.delta,
|
|
2281
|
-
parsed: parseResult.value
|
|
2282
|
-
}
|
|
2283
|
-
};
|
|
2284
|
-
return parsedEvent;
|
|
2285
|
-
}
|
|
2286
|
-
return event;
|
|
2287
|
-
},
|
|
2288
|
-
onStreamEnd(ctx) {
|
|
2289
|
-
ctx.state.delete(ACCUMULATED_TEXT_KEY);
|
|
2290
|
-
ctx.state.delete(ACCUMULATED_ARGS_KEY);
|
|
2291
|
-
}
|
|
2292
|
-
};
|
|
2293
|
-
}
|
|
2294
|
-
|
|
2295
|
-
// src/middleware/logging.ts
|
|
2296
|
-
var LOG_LEVELS = {
|
|
2297
|
-
debug: 0,
|
|
2298
|
-
info: 1,
|
|
2299
|
-
warn: 2,
|
|
2300
|
-
error: 3
|
|
2301
|
-
};
|
|
2302
|
-
function loggingMiddleware(options = {}) {
|
|
2303
|
-
const {
|
|
2304
|
-
level = "info",
|
|
2305
|
-
logStreamEvents = false,
|
|
2306
|
-
logToolCalls = true,
|
|
2307
|
-
logger,
|
|
2308
|
-
prefix = "[PP]"
|
|
2309
|
-
} = options;
|
|
2310
|
-
const minLevel = LOG_LEVELS[level];
|
|
2311
|
-
const log = (logLevel, message, data) => {
|
|
2312
|
-
if (LOG_LEVELS[logLevel] < minLevel) {
|
|
2313
|
-
return;
|
|
2314
|
-
}
|
|
2315
|
-
const fullMessage = `${prefix} ${message}`;
|
|
2316
|
-
if (logger) {
|
|
2317
|
-
logger(logLevel, fullMessage, data);
|
|
2318
|
-
} else {
|
|
2319
|
-
const consoleMethod = logLevel === "error" ? console.error : logLevel === "warn" ? console.warn : console.log;
|
|
2320
|
-
if (data) {
|
|
2321
|
-
consoleMethod(fullMessage, data);
|
|
2322
|
-
} else {
|
|
2323
|
-
consoleMethod(fullMessage);
|
|
2324
|
-
}
|
|
2325
|
-
}
|
|
2326
|
-
};
|
|
2327
|
-
return {
|
|
2328
|
-
name: "logging",
|
|
2329
|
-
onStart(ctx) {
|
|
2330
|
-
const streamingLabel = ctx.streaming ? "(streaming)" : "";
|
|
2331
|
-
log("info", `[${ctx.provider}] Starting ${ctx.modality} request ${streamingLabel}`.trim());
|
|
2332
|
-
log("debug", `[${ctx.provider}] Model: ${ctx.modelId}`);
|
|
2333
|
-
},
|
|
2334
|
-
onEnd(ctx) {
|
|
2335
|
-
const duration = ctx.endTime ? ctx.endTime - ctx.startTime : 0;
|
|
2336
|
-
log("info", `[${ctx.provider}] Completed in ${duration}ms`);
|
|
2337
|
-
},
|
|
2338
|
-
onError(error, ctx) {
|
|
2339
|
-
const duration = Date.now() - ctx.startTime;
|
|
2340
|
-
log("error", `[${ctx.provider}] Error after ${duration}ms: ${error.message}`);
|
|
2341
|
-
},
|
|
2342
|
-
onStreamEvent(event, ctx) {
|
|
2343
|
-
if (logStreamEvents) {
|
|
2344
|
-
log("debug", `Stream event: ${event.type}`, { index: event.index });
|
|
2345
|
-
}
|
|
2346
|
-
return event;
|
|
2347
|
-
},
|
|
2348
|
-
onToolCall(tool, params, ctx) {
|
|
2349
|
-
if (logToolCalls) {
|
|
2350
|
-
log("info", `[${ctx.provider}] Tool call: ${tool.name}`);
|
|
2351
|
-
log("debug", `[${ctx.provider}] Tool params:`, { params });
|
|
2352
|
-
}
|
|
2353
|
-
},
|
|
2354
|
-
onToolResult(tool, result, ctx) {
|
|
2355
|
-
if (logToolCalls) {
|
|
2356
|
-
log("debug", `[${ctx.provider}] Tool result: ${tool.name}`, { result });
|
|
2357
|
-
}
|
|
2358
|
-
}
|
|
2359
|
-
};
|
|
2360
|
-
}
|
|
2361
|
-
|
|
2362
2115
|
// src/index.ts
|
|
2363
2116
|
var ai = {
|
|
2364
2117
|
/** LLM instance factory */
|
|
@@ -2416,11 +2169,9 @@ export {
|
|
|
2416
2169
|
isUserMessage,
|
|
2417
2170
|
isVideoBlock,
|
|
2418
2171
|
llm,
|
|
2419
|
-
loggingMiddleware,
|
|
2420
2172
|
messageStart,
|
|
2421
2173
|
messageStop,
|
|
2422
2174
|
objectDelta,
|
|
2423
|
-
parsedObjectMiddleware,
|
|
2424
2175
|
reasoning,
|
|
2425
2176
|
text,
|
|
2426
2177
|
textDelta,
|