@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.
Files changed (46) hide show
  1. package/dist/anthropic/index.d.ts +1 -1
  2. package/dist/anthropic/index.js +100 -29
  3. package/dist/anthropic/index.js.map +1 -1
  4. package/dist/{chunk-Y3GBJNA2.js → chunk-7WYBJPJJ.js} +2 -2
  5. package/dist/chunk-I2VHCGQE.js +49 -0
  6. package/dist/chunk-I2VHCGQE.js.map +1 -0
  7. package/dist/{chunk-SKY2JLA7.js → chunk-MKDLXV4O.js} +1 -1
  8. package/dist/chunk-MKDLXV4O.js.map +1 -0
  9. package/dist/{chunk-Z7RBRCRN.js → chunk-NWS5IKNR.js} +37 -11
  10. package/dist/chunk-NWS5IKNR.js.map +1 -0
  11. package/dist/{chunk-EDENPF3E.js → chunk-RFWLEFAB.js} +96 -42
  12. package/dist/chunk-RFWLEFAB.js.map +1 -0
  13. package/dist/{chunk-Z4ILICF5.js → chunk-RS7C25LS.js} +35 -10
  14. package/dist/chunk-RS7C25LS.js.map +1 -0
  15. package/dist/google/index.d.ts +20 -6
  16. package/dist/google/index.js +261 -65
  17. package/dist/google/index.js.map +1 -1
  18. package/dist/http/index.d.ts +3 -3
  19. package/dist/http/index.js +4 -4
  20. package/dist/index.d.ts +7 -5
  21. package/dist/index.js +286 -119
  22. package/dist/index.js.map +1 -1
  23. package/dist/ollama/index.d.ts +1 -1
  24. package/dist/ollama/index.js +66 -12
  25. package/dist/ollama/index.js.map +1 -1
  26. package/dist/openai/index.d.ts +1 -1
  27. package/dist/openai/index.js +183 -43
  28. package/dist/openai/index.js.map +1 -1
  29. package/dist/openrouter/index.d.ts +1 -1
  30. package/dist/openrouter/index.js +161 -31
  31. package/dist/openrouter/index.js.map +1 -1
  32. package/dist/{provider-DGQHYE6I.d.ts → provider-DWEAzeM5.d.ts} +11 -1
  33. package/dist/proxy/index.d.ts +2 -2
  34. package/dist/proxy/index.js +171 -12
  35. package/dist/proxy/index.js.map +1 -1
  36. package/dist/{retry-Pcs3hnbu.d.ts → retry-DmPmqZL6.d.ts} +11 -2
  37. package/dist/{stream-Di9acos2.d.ts → stream-DbkLOIbJ.d.ts} +15 -5
  38. package/dist/xai/index.d.ts +1 -1
  39. package/dist/xai/index.js +139 -30
  40. package/dist/xai/index.js.map +1 -1
  41. package/package.json +1 -1
  42. package/dist/chunk-EDENPF3E.js.map +0 -1
  43. package/dist/chunk-SKY2JLA7.js.map +0 -1
  44. package/dist/chunk-Z4ILICF5.js.map +0 -1
  45. package/dist/chunk-Z7RBRCRN.js.map +0 -1
  46. /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-SKY2JLA7.js";
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-Z4ILICF5.js";
30
- import "./chunk-Z7RBRCRN.js";
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-Y3GBJNA2.js";
35
+ } from "./chunk-7WYBJPJJ.js";
36
36
  import {
37
- UPPError
38
- } from "./chunk-EDENPF3E.js";
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, turnPromise, abortController) {
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: turnPromise,
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 && "timestamp" in value && "type" in value && "id" in value) {
231
+ if (typeof value === "object" && value !== null) {
199
232
  const obj = value;
200
- const messageTypes = ["user", "assistant", "tool_result"];
201
- return messageTypes.includes(obj.type);
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.type === "text") {
281
+ if (isTextBlock(block)) {
235
282
  return new UserMessage(block.text);
236
283
  }
237
- return new UserMessage([block]);
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 = resolve;
317
- rejectGenerator = reject;
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
- if (abortController.signal.aborted) {
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
- generatorError = error;
378
- rejectGenerator(error);
379
- throw error;
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 turnPromise = (async () => {
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(), turnPromise, abortController);
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
- if (!tool) {
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: `Tool '${call.toolName}' not found`,
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
- const beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);
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
- const endTime = Date.now();
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
- const endTime = Date.now();
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
- throw error;
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: tool.name,
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, tool.name, "Tool execution denied by approval handler", true, endTime, index));
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: tool.name,
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, tool.name, result, false, endTime, index));
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
- await toolStrategy?.onError?.(tool, effectiveParams, error);
497
- const errorMessage = error instanceof Error ? error.message : String(error);
603
+ const err = toError(error);
604
+ await toolStrategy?.onError?.(tool, effectiveParams, err);
498
605
  const execution = {
499
- toolName: tool.name,
606
+ toolName,
500
607
  toolCallId: call.toolCallId,
501
608
  arguments: effectiveParams,
502
- result: errorMessage,
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, tool.name, errorMessage, true, endTime, index));
615
+ onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));
509
616
  return {
510
617
  toolCallId: call.toolCallId,
511
- result: errorMessage,
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 = resolve;
638
- rejectResult = reject;
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 new UPPError(
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 (const response of responses) {
671
- for (const vec of response.embeddings) {
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: allEmbeddings.length + batchEmbeddings.length,
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: allEmbeddings,
842
+ embeddings: orderedEmbeddings,
694
843
  usage: { totalTokens }
695
844
  });
696
845
  } catch (error) {
697
- rejectResult(error);
698
- throw error;
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
- const response = await boundModel.generate({
731
- prompt,
732
- params,
733
- config,
734
- signal: options2?.signal
735
- });
736
- return {
737
- images: response.images,
738
- metadata: response.metadata,
739
- usage: response.usage
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]: () => providerStream[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
- const response = await edit({
770
- image: input.image,
771
- mask: input.mask,
772
- prompt: input.prompt,
773
- params,
774
- config
775
- });
776
- return {
777
- images: response.images,
778
- metadata: response.metadata,
779
- usage: response.usage
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 */