@providerprotocol/ai 0.0.21 → 0.0.22
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/dist/anthropic/index.d.ts +1 -1
- package/dist/anthropic/index.js +100 -29
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-Y3GBJNA2.js → chunk-7WYBJPJJ.js} +2 -2
- package/dist/chunk-I2VHCGQE.js +49 -0
- package/dist/chunk-I2VHCGQE.js.map +1 -0
- package/dist/{chunk-SKY2JLA7.js → chunk-MKDLXV4O.js} +1 -1
- package/dist/chunk-MKDLXV4O.js.map +1 -0
- package/dist/{chunk-Z7RBRCRN.js → chunk-NWS5IKNR.js} +37 -11
- package/dist/chunk-NWS5IKNR.js.map +1 -0
- package/dist/{chunk-EDENPF3E.js → chunk-RFWLEFAB.js} +96 -42
- package/dist/chunk-RFWLEFAB.js.map +1 -0
- package/dist/{chunk-Z4ILICF5.js → chunk-RS7C25LS.js} +35 -10
- package/dist/chunk-RS7C25LS.js.map +1 -0
- package/dist/google/index.d.ts +20 -6
- package/dist/google/index.js +261 -65
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +3 -3
- package/dist/http/index.js +4 -4
- package/dist/index.d.ts +7 -5
- package/dist/index.js +286 -119
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +1 -1
- package/dist/ollama/index.js +66 -12
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/openai/index.js +183 -43
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +1 -1
- package/dist/openrouter/index.js +161 -31
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-DGQHYE6I.d.ts → provider-DWEAzeM5.d.ts} +11 -1
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.js +171 -12
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-Pcs3hnbu.d.ts → retry-DmPmqZL6.d.ts} +11 -2
- package/dist/{stream-Di9acos2.d.ts → stream-DbkLOIbJ.d.ts} +15 -5
- package/dist/xai/index.d.ts +1 -1
- package/dist/xai/index.js +139 -30
- package/dist/xai/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-EDENPF3E.js.map +0 -1
- package/dist/chunk-SKY2JLA7.js.map +0 -1
- package/dist/chunk-Z4ILICF5.js.map +0 -1
- package/dist/chunk-Z7RBRCRN.js.map +0 -1
- /package/dist/{chunk-Y3GBJNA2.js.map → chunk-7WYBJPJJ.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
aggregateUsage,
|
|
3
3
|
createTurn,
|
|
4
4
|
emptyUsage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MKDLXV4O.js";
|
|
6
6
|
import {
|
|
7
7
|
Image
|
|
8
8
|
} from "./chunk-WAKD3OO5.js";
|
|
@@ -26,24 +26,57 @@ import {
|
|
|
26
26
|
NoRetry,
|
|
27
27
|
RetryAfterStrategy,
|
|
28
28
|
TokenBucket
|
|
29
|
-
} from "./chunk-
|
|
30
|
-
import "./chunk-
|
|
29
|
+
} from "./chunk-RS7C25LS.js";
|
|
30
|
+
import "./chunk-NWS5IKNR.js";
|
|
31
31
|
import {
|
|
32
32
|
DynamicKey,
|
|
33
33
|
RoundRobinKeys,
|
|
34
34
|
WeightedKeys
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-7WYBJPJJ.js";
|
|
36
36
|
import {
|
|
37
|
-
UPPError
|
|
38
|
-
|
|
37
|
+
UPPError,
|
|
38
|
+
toError
|
|
39
|
+
} from "./chunk-RFWLEFAB.js";
|
|
40
|
+
|
|
41
|
+
// src/types/content.ts
|
|
42
|
+
function text(content) {
|
|
43
|
+
return { type: "text", text: content };
|
|
44
|
+
}
|
|
45
|
+
function isTextBlock(block) {
|
|
46
|
+
return block.type === "text";
|
|
47
|
+
}
|
|
48
|
+
function isImageBlock(block) {
|
|
49
|
+
return block.type === "image";
|
|
50
|
+
}
|
|
51
|
+
function isAudioBlock(block) {
|
|
52
|
+
return block.type === "audio";
|
|
53
|
+
}
|
|
54
|
+
function isVideoBlock(block) {
|
|
55
|
+
return block.type === "video";
|
|
56
|
+
}
|
|
57
|
+
function isBinaryBlock(block) {
|
|
58
|
+
return block.type === "binary";
|
|
59
|
+
}
|
|
39
60
|
|
|
40
61
|
// src/types/stream.ts
|
|
41
|
-
function createStreamResult(generator,
|
|
62
|
+
function createStreamResult(generator, turnPromiseOrFactory, abortController) {
|
|
63
|
+
let cachedTurn = null;
|
|
64
|
+
const getTurn = () => {
|
|
65
|
+
if (typeof turnPromiseOrFactory === "function") {
|
|
66
|
+
if (!cachedTurn) {
|
|
67
|
+
cachedTurn = turnPromiseOrFactory();
|
|
68
|
+
}
|
|
69
|
+
return cachedTurn;
|
|
70
|
+
}
|
|
71
|
+
return turnPromiseOrFactory;
|
|
72
|
+
};
|
|
42
73
|
return {
|
|
43
74
|
[Symbol.asyncIterator]() {
|
|
44
75
|
return generator;
|
|
45
76
|
},
|
|
46
|
-
turn
|
|
77
|
+
get turn() {
|
|
78
|
+
return getTurn();
|
|
79
|
+
},
|
|
47
80
|
abort() {
|
|
48
81
|
abortController.abort();
|
|
49
82
|
}
|
|
@@ -195,10 +228,21 @@ function isMessageInstance(value) {
|
|
|
195
228
|
if (value instanceof Message) {
|
|
196
229
|
return true;
|
|
197
230
|
}
|
|
198
|
-
if (typeof value === "object" && value !== null
|
|
231
|
+
if (typeof value === "object" && value !== null) {
|
|
199
232
|
const obj = value;
|
|
200
|
-
const
|
|
201
|
-
|
|
233
|
+
const type = obj.type;
|
|
234
|
+
const id = obj.id;
|
|
235
|
+
const timestamp = obj.timestamp;
|
|
236
|
+
const hasValidTimestamp = timestamp instanceof Date || typeof timestamp === "string" && !Number.isNaN(Date.parse(timestamp));
|
|
237
|
+
if (typeof id !== "string" || id.length === 0 || !hasValidTimestamp) {
|
|
238
|
+
return false;
|
|
239
|
+
}
|
|
240
|
+
if (type === "user" || type === "assistant") {
|
|
241
|
+
return Array.isArray(obj.content);
|
|
242
|
+
}
|
|
243
|
+
if (type === "tool_result") {
|
|
244
|
+
return Array.isArray(obj.results);
|
|
245
|
+
}
|
|
202
246
|
}
|
|
203
247
|
return false;
|
|
204
248
|
}
|
|
@@ -230,11 +274,17 @@ function inputToMessage(input) {
|
|
|
230
274
|
if ("type" in input && "id" in input && "timestamp" in input) {
|
|
231
275
|
return input;
|
|
232
276
|
}
|
|
277
|
+
if (typeof input !== "object" || input === null || !("type" in input)) {
|
|
278
|
+
throw new Error("Invalid inference input");
|
|
279
|
+
}
|
|
233
280
|
const block = input;
|
|
234
|
-
if (block
|
|
281
|
+
if (isTextBlock(block)) {
|
|
235
282
|
return new UserMessage(block.text);
|
|
236
283
|
}
|
|
237
|
-
|
|
284
|
+
if (isImageBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {
|
|
285
|
+
return new UserMessage([block]);
|
|
286
|
+
}
|
|
287
|
+
throw new Error("Invalid inference input");
|
|
238
288
|
}
|
|
239
289
|
async function executeGenerate(model, config, system, params, tools, toolStrategy, structure, history, newMessages) {
|
|
240
290
|
validateMediaCapabilities(
|
|
@@ -310,20 +360,47 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
310
360
|
let cycles = 0;
|
|
311
361
|
let generatorError = null;
|
|
312
362
|
let structuredData;
|
|
363
|
+
let generatorCompleted = false;
|
|
313
364
|
let resolveGenerator;
|
|
314
365
|
let rejectGenerator;
|
|
366
|
+
let generatorSettled = false;
|
|
315
367
|
const generatorDone = new Promise((resolve, reject) => {
|
|
316
|
-
resolveGenerator =
|
|
317
|
-
|
|
368
|
+
resolveGenerator = () => {
|
|
369
|
+
if (!generatorSettled) {
|
|
370
|
+
generatorSettled = true;
|
|
371
|
+
resolve();
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
rejectGenerator = (error) => {
|
|
375
|
+
if (!generatorSettled) {
|
|
376
|
+
generatorSettled = true;
|
|
377
|
+
reject(error);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
});
|
|
381
|
+
void generatorDone.catch((error) => {
|
|
382
|
+
if (!generatorError) {
|
|
383
|
+
generatorError = toError(error);
|
|
384
|
+
}
|
|
318
385
|
});
|
|
319
386
|
const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
|
|
387
|
+
const onAbort = () => {
|
|
388
|
+
const error = new UPPError("Stream cancelled", "CANCELLED", model.provider.name, "llm");
|
|
389
|
+
generatorError = error;
|
|
390
|
+
rejectGenerator(error);
|
|
391
|
+
};
|
|
392
|
+
abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
393
|
+
const ensureNotAborted = () => {
|
|
394
|
+
if (abortController.signal.aborted) {
|
|
395
|
+
throw new UPPError("Stream cancelled", "CANCELLED", model.provider.name, "llm");
|
|
396
|
+
}
|
|
397
|
+
};
|
|
320
398
|
async function* generateStream() {
|
|
321
399
|
try {
|
|
322
|
-
|
|
323
|
-
throw new UPPError("Stream cancelled", "CANCELLED", model.provider.name, "llm");
|
|
324
|
-
}
|
|
400
|
+
ensureNotAborted();
|
|
325
401
|
while (cycles < maxIterations + 1) {
|
|
326
402
|
cycles++;
|
|
403
|
+
ensureNotAborted();
|
|
327
404
|
const request = {
|
|
328
405
|
messages: allMessages,
|
|
329
406
|
system,
|
|
@@ -335,6 +412,7 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
335
412
|
};
|
|
336
413
|
const streamResult = model.stream(request);
|
|
337
414
|
for await (const event of streamResult) {
|
|
415
|
+
ensureNotAborted();
|
|
338
416
|
yield event;
|
|
339
417
|
}
|
|
340
418
|
const response = await streamResult.response;
|
|
@@ -365,6 +443,7 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
365
443
|
(event) => toolEvents.push(event)
|
|
366
444
|
);
|
|
367
445
|
for (const event of toolEvents) {
|
|
446
|
+
ensureNotAborted();
|
|
368
447
|
yield event;
|
|
369
448
|
}
|
|
370
449
|
allMessages.push(new ToolResultMessage(results));
|
|
@@ -372,14 +451,26 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
372
451
|
}
|
|
373
452
|
break;
|
|
374
453
|
}
|
|
454
|
+
generatorCompleted = true;
|
|
375
455
|
resolveGenerator();
|
|
376
456
|
} catch (error) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
457
|
+
const err = toError(error);
|
|
458
|
+
generatorError = err;
|
|
459
|
+
rejectGenerator(err);
|
|
460
|
+
throw err;
|
|
461
|
+
} finally {
|
|
462
|
+
abortController.signal.removeEventListener("abort", onAbort);
|
|
463
|
+
if (!generatorCompleted && !generatorSettled) {
|
|
464
|
+
const error = new UPPError("Stream cancelled", "CANCELLED", model.provider.name, "llm");
|
|
465
|
+
generatorError = error;
|
|
466
|
+
if (!abortController.signal.aborted) {
|
|
467
|
+
abortController.abort();
|
|
468
|
+
}
|
|
469
|
+
rejectGenerator(error);
|
|
470
|
+
}
|
|
380
471
|
}
|
|
381
472
|
}
|
|
382
|
-
const
|
|
473
|
+
const createTurnPromise = async () => {
|
|
383
474
|
await generatorDone;
|
|
384
475
|
if (generatorError) {
|
|
385
476
|
throw generatorError;
|
|
@@ -392,8 +483,8 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
|
|
|
392
483
|
cycles,
|
|
393
484
|
data
|
|
394
485
|
);
|
|
395
|
-
}
|
|
396
|
-
return createStreamResult(generateStream(),
|
|
486
|
+
};
|
|
487
|
+
return createStreamResult(generateStream(), createTurnPromise, abortController);
|
|
397
488
|
}
|
|
398
489
|
async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
399
490
|
const toolCalls = message.toolCalls ?? [];
|
|
@@ -401,41 +492,57 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
401
492
|
const toolMap = new Map(tools.map((t) => [t.name, t]));
|
|
402
493
|
const promises = toolCalls.map(async (call, index) => {
|
|
403
494
|
const tool = toolMap.get(call.toolName);
|
|
404
|
-
|
|
495
|
+
const toolName = tool?.name ?? call.toolName;
|
|
496
|
+
const startTime = Date.now();
|
|
497
|
+
onEvent?.(toolExecutionStart(call.toolCallId, toolName, startTime, index));
|
|
498
|
+
let effectiveParams = call.arguments;
|
|
499
|
+
const endWithError = async (message2, approved2) => {
|
|
500
|
+
const endTime = Date.now();
|
|
501
|
+
if (tool) {
|
|
502
|
+
await toolStrategy?.onError?.(tool, effectiveParams, new Error(message2));
|
|
503
|
+
}
|
|
504
|
+
const execution = {
|
|
505
|
+
toolName,
|
|
506
|
+
toolCallId: call.toolCallId,
|
|
507
|
+
arguments: effectiveParams,
|
|
508
|
+
result: message2,
|
|
509
|
+
isError: true,
|
|
510
|
+
duration: endTime - startTime,
|
|
511
|
+
approved: approved2
|
|
512
|
+
};
|
|
513
|
+
executions.push(execution);
|
|
514
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, message2, true, endTime, index));
|
|
405
515
|
return {
|
|
406
516
|
toolCallId: call.toolCallId,
|
|
407
|
-
result:
|
|
517
|
+
result: message2,
|
|
408
518
|
isError: true
|
|
409
519
|
};
|
|
520
|
+
};
|
|
521
|
+
if (!tool) {
|
|
522
|
+
return endWithError(`Tool '${call.toolName}' not found`);
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
await toolStrategy?.onToolCall?.(tool, effectiveParams);
|
|
526
|
+
} catch (error) {
|
|
527
|
+
return endWithError(toError(error).message);
|
|
410
528
|
}
|
|
411
|
-
const startTime = Date.now();
|
|
412
|
-
onEvent?.(toolExecutionStart(call.toolCallId, tool.name, startTime, index));
|
|
413
|
-
let effectiveParams = call.arguments;
|
|
414
|
-
await toolStrategy?.onToolCall?.(tool, effectiveParams);
|
|
415
529
|
if (toolStrategy?.onBeforeCall) {
|
|
416
|
-
|
|
530
|
+
let beforeResult;
|
|
531
|
+
try {
|
|
532
|
+
beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);
|
|
533
|
+
} catch (error) {
|
|
534
|
+
return endWithError(toError(error).message);
|
|
535
|
+
}
|
|
417
536
|
const isBeforeCallResult = (value) => typeof value === "object" && value !== null && "proceed" in value;
|
|
418
537
|
if (isBeforeCallResult(beforeResult)) {
|
|
419
538
|
if (!beforeResult.proceed) {
|
|
420
|
-
|
|
421
|
-
onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, "Tool execution skipped", true, endTime, index));
|
|
422
|
-
return {
|
|
423
|
-
toolCallId: call.toolCallId,
|
|
424
|
-
result: "Tool execution skipped",
|
|
425
|
-
isError: true
|
|
426
|
-
};
|
|
539
|
+
return endWithError("Tool execution skipped");
|
|
427
540
|
}
|
|
428
541
|
if (beforeResult.params !== void 0) {
|
|
429
542
|
effectiveParams = beforeResult.params;
|
|
430
543
|
}
|
|
431
544
|
} else if (!beforeResult) {
|
|
432
|
-
|
|
433
|
-
onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, "Tool execution skipped", true, endTime, index));
|
|
434
|
-
return {
|
|
435
|
-
toolCallId: call.toolCallId,
|
|
436
|
-
result: "Tool execution skipped",
|
|
437
|
-
isError: true
|
|
438
|
-
};
|
|
545
|
+
return endWithError("Tool execution skipped");
|
|
439
546
|
}
|
|
440
547
|
}
|
|
441
548
|
let approved = true;
|
|
@@ -443,13 +550,13 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
443
550
|
try {
|
|
444
551
|
approved = await tool.approval(effectiveParams);
|
|
445
552
|
} catch (error) {
|
|
446
|
-
|
|
553
|
+
return endWithError(toError(error).message);
|
|
447
554
|
}
|
|
448
555
|
}
|
|
449
556
|
if (!approved) {
|
|
450
557
|
const endTime = Date.now();
|
|
451
558
|
const execution = {
|
|
452
|
-
toolName
|
|
559
|
+
toolName,
|
|
453
560
|
toolCallId: call.toolCallId,
|
|
454
561
|
arguments: effectiveParams,
|
|
455
562
|
result: "Tool execution denied",
|
|
@@ -458,7 +565,7 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
458
565
|
approved: false
|
|
459
566
|
};
|
|
460
567
|
executions.push(execution);
|
|
461
|
-
onEvent?.(toolExecutionEnd(call.toolCallId,
|
|
568
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, "Tool execution denied by approval handler", true, endTime, index));
|
|
462
569
|
return {
|
|
463
570
|
toolCallId: call.toolCallId,
|
|
464
571
|
result: "Tool execution denied by approval handler",
|
|
@@ -476,7 +583,7 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
476
583
|
}
|
|
477
584
|
}
|
|
478
585
|
const execution = {
|
|
479
|
-
toolName
|
|
586
|
+
toolName,
|
|
480
587
|
toolCallId: call.toolCallId,
|
|
481
588
|
arguments: effectiveParams,
|
|
482
589
|
result,
|
|
@@ -485,7 +592,7 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
485
592
|
approved
|
|
486
593
|
};
|
|
487
594
|
executions.push(execution);
|
|
488
|
-
onEvent?.(toolExecutionEnd(call.toolCallId,
|
|
595
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, result, false, endTime, index));
|
|
489
596
|
return {
|
|
490
597
|
toolCallId: call.toolCallId,
|
|
491
598
|
result,
|
|
@@ -493,22 +600,22 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
|
|
|
493
600
|
};
|
|
494
601
|
} catch (error) {
|
|
495
602
|
const endTime = Date.now();
|
|
496
|
-
|
|
497
|
-
|
|
603
|
+
const err = toError(error);
|
|
604
|
+
await toolStrategy?.onError?.(tool, effectiveParams, err);
|
|
498
605
|
const execution = {
|
|
499
|
-
toolName
|
|
606
|
+
toolName,
|
|
500
607
|
toolCallId: call.toolCallId,
|
|
501
608
|
arguments: effectiveParams,
|
|
502
|
-
result:
|
|
609
|
+
result: err.message,
|
|
503
610
|
isError: true,
|
|
504
611
|
duration: endTime - startTime,
|
|
505
612
|
approved
|
|
506
613
|
};
|
|
507
614
|
executions.push(execution);
|
|
508
|
-
onEvent?.(toolExecutionEnd(call.toolCallId,
|
|
615
|
+
onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));
|
|
509
616
|
return {
|
|
510
617
|
toolCallId: call.toolCallId,
|
|
511
|
-
result:
|
|
618
|
+
result: err.message,
|
|
512
619
|
isError: true
|
|
513
620
|
};
|
|
514
621
|
}
|
|
@@ -550,7 +657,16 @@ function validateMediaCapabilities(messages, capabilities, providerName) {
|
|
|
550
657
|
|
|
551
658
|
// src/core/embedding.ts
|
|
552
659
|
function embedding(options) {
|
|
553
|
-
const { model: modelRef, config = {}, params } = options;
|
|
660
|
+
const { model: modelRef, config: explicitConfig = {}, params } = options;
|
|
661
|
+
const providerConfig = modelRef.providerConfig ?? {};
|
|
662
|
+
const config = {
|
|
663
|
+
...providerConfig,
|
|
664
|
+
...explicitConfig,
|
|
665
|
+
headers: {
|
|
666
|
+
...providerConfig.headers,
|
|
667
|
+
...explicitConfig.headers
|
|
668
|
+
}
|
|
669
|
+
};
|
|
554
670
|
const provider = modelRef.provider;
|
|
555
671
|
const handler = resolveEmbeddingHandler(provider);
|
|
556
672
|
if (!handler) {
|
|
@@ -633,33 +749,59 @@ function createChunkedStream(model, inputs, params, config, options) {
|
|
|
633
749
|
const concurrency = options.concurrency ?? 1;
|
|
634
750
|
let resolveResult;
|
|
635
751
|
let rejectResult;
|
|
752
|
+
let settled = false;
|
|
636
753
|
const resultPromise = new Promise((resolve, reject) => {
|
|
637
|
-
resolveResult =
|
|
638
|
-
|
|
754
|
+
resolveResult = (result) => {
|
|
755
|
+
if (!settled) {
|
|
756
|
+
settled = true;
|
|
757
|
+
resolve(result);
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
rejectResult = (error) => {
|
|
761
|
+
if (!settled) {
|
|
762
|
+
settled = true;
|
|
763
|
+
reject(error);
|
|
764
|
+
}
|
|
765
|
+
};
|
|
639
766
|
});
|
|
767
|
+
const cancelError = () => new UPPError(
|
|
768
|
+
"Embedding cancelled",
|
|
769
|
+
"CANCELLED",
|
|
770
|
+
model.provider.name,
|
|
771
|
+
"embedding"
|
|
772
|
+
);
|
|
773
|
+
const onAbort = () => {
|
|
774
|
+
rejectResult(cancelError());
|
|
775
|
+
};
|
|
776
|
+
abortController.signal.addEventListener("abort", onAbort, { once: true });
|
|
777
|
+
const onExternalAbort = () => abortController.abort();
|
|
778
|
+
if (options.signal) {
|
|
779
|
+
options.signal.addEventListener("abort", onExternalAbort, { once: true });
|
|
780
|
+
}
|
|
781
|
+
const cleanupAbortListeners = () => {
|
|
782
|
+
abortController.signal.removeEventListener("abort", onAbort);
|
|
783
|
+
if (options.signal) {
|
|
784
|
+
options.signal.removeEventListener("abort", onExternalAbort);
|
|
785
|
+
}
|
|
786
|
+
};
|
|
640
787
|
async function* generate() {
|
|
641
788
|
const total = inputs.length;
|
|
642
789
|
const allEmbeddings = [];
|
|
643
790
|
let totalTokens = 0;
|
|
644
791
|
const batches = [];
|
|
645
792
|
for (let i = 0; i < inputs.length; i += batchSize) {
|
|
646
|
-
batches.push(inputs.slice(i, i + batchSize));
|
|
793
|
+
batches.push({ inputs: inputs.slice(i, i + batchSize), startIndex: i });
|
|
647
794
|
}
|
|
648
795
|
try {
|
|
649
796
|
for (let i = 0; i < batches.length; i += concurrency) {
|
|
650
797
|
if (abortController.signal.aborted || options.signal?.aborted) {
|
|
651
|
-
throw
|
|
652
|
-
"Embedding cancelled",
|
|
653
|
-
"CANCELLED",
|
|
654
|
-
model.provider.name,
|
|
655
|
-
"embedding"
|
|
656
|
-
);
|
|
798
|
+
throw cancelError();
|
|
657
799
|
}
|
|
658
800
|
const chunk = batches.slice(i, i + concurrency);
|
|
659
801
|
const responses = await Promise.all(
|
|
660
802
|
chunk.map(
|
|
661
803
|
(batch) => model.embed({
|
|
662
|
-
inputs: batch,
|
|
804
|
+
inputs: batch.inputs,
|
|
663
805
|
params,
|
|
664
806
|
config: config ?? {},
|
|
665
807
|
signal: abortController.signal
|
|
@@ -667,13 +809,17 @@ function createChunkedStream(model, inputs, params, config, options) {
|
|
|
667
809
|
)
|
|
668
810
|
);
|
|
669
811
|
const batchEmbeddings = [];
|
|
670
|
-
for (
|
|
671
|
-
|
|
812
|
+
for (let responseIndex = 0; responseIndex < responses.length; responseIndex += 1) {
|
|
813
|
+
const response = responses[responseIndex];
|
|
814
|
+
const batch = chunk[responseIndex];
|
|
815
|
+
for (let vecIndex = 0; vecIndex < response.embeddings.length; vecIndex += 1) {
|
|
816
|
+
const vec = response.embeddings[vecIndex];
|
|
672
817
|
const vector = normalizeVector(vec.vector, model.provider.name);
|
|
818
|
+
const resolvedIndex = batch.startIndex + (vec.index ?? vecIndex);
|
|
673
819
|
const emb = {
|
|
674
820
|
vector,
|
|
675
821
|
dimensions: vector.length,
|
|
676
|
-
index:
|
|
822
|
+
index: resolvedIndex,
|
|
677
823
|
tokens: vec.tokens,
|
|
678
824
|
metadata: vec.metadata
|
|
679
825
|
};
|
|
@@ -689,13 +835,19 @@ function createChunkedStream(model, inputs, params, config, options) {
|
|
|
689
835
|
percent: allEmbeddings.length / total * 100
|
|
690
836
|
};
|
|
691
837
|
}
|
|
838
|
+
const orderedEmbeddings = [...allEmbeddings].sort(
|
|
839
|
+
(left, right) => left.index - right.index
|
|
840
|
+
);
|
|
692
841
|
resolveResult({
|
|
693
|
-
embeddings:
|
|
842
|
+
embeddings: orderedEmbeddings,
|
|
694
843
|
usage: { totalTokens }
|
|
695
844
|
});
|
|
696
845
|
} catch (error) {
|
|
697
|
-
|
|
698
|
-
|
|
846
|
+
const err = toError(error);
|
|
847
|
+
rejectResult(err);
|
|
848
|
+
throw err;
|
|
849
|
+
} finally {
|
|
850
|
+
cleanupAbortListeners();
|
|
699
851
|
}
|
|
700
852
|
}
|
|
701
853
|
const generator = generate();
|
|
@@ -708,7 +860,16 @@ function createChunkedStream(model, inputs, params, config, options) {
|
|
|
708
860
|
|
|
709
861
|
// src/core/image.ts
|
|
710
862
|
function image(options) {
|
|
711
|
-
const { model: modelRef, config = {}, params } = options;
|
|
863
|
+
const { model: modelRef, config: explicitConfig = {}, params } = options;
|
|
864
|
+
const providerConfig = modelRef.providerConfig ?? {};
|
|
865
|
+
const config = {
|
|
866
|
+
...providerConfig,
|
|
867
|
+
...explicitConfig,
|
|
868
|
+
headers: {
|
|
869
|
+
...providerConfig.headers,
|
|
870
|
+
...explicitConfig.headers
|
|
871
|
+
}
|
|
872
|
+
};
|
|
712
873
|
const provider = modelRef.provider;
|
|
713
874
|
const imageHandler = resolveImageHandler(provider);
|
|
714
875
|
if (!imageHandler) {
|
|
@@ -721,23 +882,34 @@ function image(options) {
|
|
|
721
882
|
}
|
|
722
883
|
const boundModel = imageHandler.bind(modelRef.modelId);
|
|
723
884
|
const capabilities = boundModel.capabilities;
|
|
885
|
+
const normalizeImageError = (error) => {
|
|
886
|
+
if (error instanceof UPPError) {
|
|
887
|
+
return error;
|
|
888
|
+
}
|
|
889
|
+
const err = toError(error);
|
|
890
|
+
return new UPPError(err.message, "PROVIDER_ERROR", provider.name, "image", void 0, err);
|
|
891
|
+
};
|
|
724
892
|
const instance = {
|
|
725
893
|
model: boundModel,
|
|
726
894
|
params,
|
|
727
895
|
capabilities,
|
|
728
896
|
async generate(input, options2) {
|
|
729
897
|
const prompt = normalizeInput(input);
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
898
|
+
try {
|
|
899
|
+
const response = await boundModel.generate({
|
|
900
|
+
prompt,
|
|
901
|
+
params,
|
|
902
|
+
config,
|
|
903
|
+
signal: options2?.signal
|
|
904
|
+
});
|
|
905
|
+
return {
|
|
906
|
+
images: response.images,
|
|
907
|
+
metadata: response.metadata,
|
|
908
|
+
usage: response.usage
|
|
909
|
+
};
|
|
910
|
+
} catch (error) {
|
|
911
|
+
throw normalizeImageError(error);
|
|
912
|
+
}
|
|
741
913
|
}
|
|
742
914
|
};
|
|
743
915
|
if (capabilities.streaming && boundModel.stream) {
|
|
@@ -755,9 +927,20 @@ function image(options) {
|
|
|
755
927
|
images: response.images,
|
|
756
928
|
metadata: response.metadata,
|
|
757
929
|
usage: response.usage
|
|
758
|
-
}))
|
|
930
|
+
})).catch((error) => {
|
|
931
|
+
throw normalizeImageError(error);
|
|
932
|
+
});
|
|
933
|
+
async function* wrappedStream() {
|
|
934
|
+
try {
|
|
935
|
+
for await (const event of providerStream) {
|
|
936
|
+
yield event;
|
|
937
|
+
}
|
|
938
|
+
} catch (error) {
|
|
939
|
+
throw normalizeImageError(error);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
759
942
|
return {
|
|
760
|
-
[Symbol.asyncIterator]: () =>
|
|
943
|
+
[Symbol.asyncIterator]: () => wrappedStream(),
|
|
761
944
|
result: resultPromise,
|
|
762
945
|
abort: () => abortController.abort()
|
|
763
946
|
};
|
|
@@ -766,18 +949,22 @@ function image(options) {
|
|
|
766
949
|
if (capabilities.edit && boundModel.edit) {
|
|
767
950
|
const edit = boundModel.edit;
|
|
768
951
|
instance.edit = async function(input) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
952
|
+
try {
|
|
953
|
+
const response = await edit({
|
|
954
|
+
image: input.image,
|
|
955
|
+
mask: input.mask,
|
|
956
|
+
prompt: input.prompt,
|
|
957
|
+
params,
|
|
958
|
+
config
|
|
959
|
+
});
|
|
960
|
+
return {
|
|
961
|
+
images: response.images,
|
|
962
|
+
metadata: response.metadata,
|
|
963
|
+
usage: response.usage
|
|
964
|
+
};
|
|
965
|
+
} catch (error) {
|
|
966
|
+
throw normalizeImageError(error);
|
|
967
|
+
}
|
|
781
968
|
};
|
|
782
969
|
}
|
|
783
970
|
return instance;
|
|
@@ -789,26 +976,6 @@ function normalizeInput(input) {
|
|
|
789
976
|
return input.prompt;
|
|
790
977
|
}
|
|
791
978
|
|
|
792
|
-
// src/types/content.ts
|
|
793
|
-
function text(content) {
|
|
794
|
-
return { type: "text", text: content };
|
|
795
|
-
}
|
|
796
|
-
function isTextBlock(block) {
|
|
797
|
-
return block.type === "text";
|
|
798
|
-
}
|
|
799
|
-
function isImageBlock(block) {
|
|
800
|
-
return block.type === "image";
|
|
801
|
-
}
|
|
802
|
-
function isAudioBlock(block) {
|
|
803
|
-
return block.type === "audio";
|
|
804
|
-
}
|
|
805
|
-
function isVideoBlock(block) {
|
|
806
|
-
return block.type === "video";
|
|
807
|
-
}
|
|
808
|
-
function isBinaryBlock(block) {
|
|
809
|
-
return block.type === "binary";
|
|
810
|
-
}
|
|
811
|
-
|
|
812
979
|
// src/types/thread.ts
|
|
813
980
|
var Thread = class _Thread {
|
|
814
981
|
/** Unique thread identifier */
|