@providerprotocol/ai 0.0.38 → 0.0.40

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 (136) hide show
  1. package/README.md +363 -37
  2. package/dist/anthropic/index.d.ts +3 -2
  3. package/dist/anthropic/index.js +7 -5
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/cerebras/index.d.ts +3 -2
  6. package/dist/cerebras/index.js +7 -5
  7. package/dist/cerebras/index.js.map +1 -1
  8. package/dist/chunk-3Q5VELKG.js +124 -0
  9. package/dist/chunk-3Q5VELKG.js.map +1 -0
  10. package/dist/{chunk-WU4U6IHF.js → chunk-6QCV4WXF.js} +4 -13
  11. package/dist/chunk-6QCV4WXF.js.map +1 -0
  12. package/dist/{chunk-LTEMH3CI.js → chunk-AC3VHSZJ.js} +6 -4
  13. package/dist/{chunk-LTEMH3CI.js.map → chunk-AC3VHSZJ.js.map} +1 -1
  14. package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
  15. package/dist/chunk-BIBMNP7Y.js.map +1 -0
  16. package/dist/{chunk-CRP6Y7NF.js → chunk-CWGTARDE.js} +2 -2
  17. package/dist/{chunk-ZRVNAET3.js → chunk-DI47UY2H.js} +6 -3
  18. package/dist/chunk-DI47UY2H.js.map +1 -0
  19. package/dist/{chunk-7GTWHZY2.js → chunk-EHR3LIPS.js} +5 -3
  20. package/dist/{chunk-7GTWHZY2.js.map → chunk-EHR3LIPS.js.map} +1 -1
  21. package/dist/chunk-EY2LLDGY.js +94 -0
  22. package/dist/chunk-EY2LLDGY.js.map +1 -0
  23. package/dist/{chunk-MJI74VEJ.js → chunk-F5ENANMJ.js} +18 -2
  24. package/dist/chunk-F5ENANMJ.js.map +1 -0
  25. package/dist/chunk-IKJH5ZSJ.js +1 -0
  26. package/dist/chunk-IKJH5ZSJ.js.map +1 -0
  27. package/dist/{chunk-4RX4VQCB.js → chunk-KBI45OXI.js} +2 -2
  28. package/dist/{chunk-5IWHCXKN.js → chunk-KVUOTFYZ.js} +2 -2
  29. package/dist/{chunk-EPB3GQNL.js → chunk-L6QWKFGE.js} +13 -3
  30. package/dist/chunk-L6QWKFGE.js.map +1 -0
  31. package/dist/{chunk-BDXH6NQS.js → chunk-N4LAFGLX.js} +7 -7
  32. package/dist/{chunk-ZKNPQBIE.js → chunk-R3T2IYOU.js} +5 -3
  33. package/dist/{chunk-ZKNPQBIE.js.map → chunk-R3T2IYOU.js.map} +1 -1
  34. package/dist/chunk-U2G5PHHL.js +25 -0
  35. package/dist/chunk-U2G5PHHL.js.map +1 -0
  36. package/dist/{chunk-SBGZJVTJ.js → chunk-VQZPADW6.js} +100 -33
  37. package/dist/chunk-VQZPADW6.js.map +1 -0
  38. package/dist/{chunk-FYSZFIZS.js → chunk-XTWBAL42.js} +5 -3
  39. package/dist/{chunk-FYSZFIZS.js.map → chunk-XTWBAL42.js.map} +1 -1
  40. package/dist/{chunk-2YXFLRQ6.js → chunk-ZMESKGUY.js} +2 -2
  41. package/dist/chunk-ZSZVWLGE.js +83 -0
  42. package/dist/chunk-ZSZVWLGE.js.map +1 -0
  43. package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-ts1npsDg.d.ts} +1 -1
  44. package/dist/google/index.d.ts +38 -3
  45. package/dist/google/index.js +5 -4
  46. package/dist/google/index.js.map +1 -1
  47. package/dist/groq/index.d.ts +3 -2
  48. package/dist/groq/index.js +7 -5
  49. package/dist/groq/index.js.map +1 -1
  50. package/dist/http/index.d.ts +5 -4
  51. package/dist/http/index.js +19 -22
  52. package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-BPml2YZZ.d.ts} +1 -1
  53. package/dist/index.d.ts +8 -7
  54. package/dist/index.js +316 -113
  55. package/dist/index.js.map +1 -1
  56. package/dist/{llm-DS_-l71X.d.ts → llm-BWLaTzzY.d.ts} +89 -36
  57. package/dist/middleware/logging/index.d.ts +3 -2
  58. package/dist/middleware/logging/index.js +3 -0
  59. package/dist/middleware/logging/index.js.map +1 -1
  60. package/dist/middleware/parsed-object/index.d.ts +3 -2
  61. package/dist/middleware/parsed-object/index.js +5 -1
  62. package/dist/middleware/parsed-object/index.js.map +1 -1
  63. package/dist/middleware/persistence/index.d.ts +3 -2
  64. package/dist/middleware/persistence/index.js +3 -2
  65. package/dist/middleware/persistence/index.js.map +1 -1
  66. package/dist/middleware/pipeline/index.d.ts +195 -0
  67. package/dist/middleware/pipeline/index.js +61 -0
  68. package/dist/middleware/pipeline/index.js.map +1 -0
  69. package/dist/middleware/pubsub/index.d.ts +13 -10
  70. package/dist/middleware/pubsub/index.js +78 -6
  71. package/dist/middleware/pubsub/index.js.map +1 -1
  72. package/dist/middleware/pubsub/server/express/index.d.ts +3 -2
  73. package/dist/middleware/pubsub/server/express/index.js +2 -2
  74. package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -2
  75. package/dist/middleware/pubsub/server/fastify/index.js +2 -2
  76. package/dist/middleware/pubsub/server/h3/index.d.ts +3 -2
  77. package/dist/middleware/pubsub/server/h3/index.js +2 -2
  78. package/dist/middleware/pubsub/server/index.d.ts +50 -8
  79. package/dist/middleware/pubsub/server/index.js +5 -5
  80. package/dist/middleware/pubsub/server/index.js.map +1 -1
  81. package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -2
  82. package/dist/middleware/pubsub/server/webapi/index.js +2 -2
  83. package/dist/moonshot/index.d.ts +3 -2
  84. package/dist/moonshot/index.js +7 -5
  85. package/dist/moonshot/index.js.map +1 -1
  86. package/dist/ollama/index.d.ts +24 -3
  87. package/dist/ollama/index.js +5 -4
  88. package/dist/ollama/index.js.map +1 -1
  89. package/dist/openai/index.d.ts +65 -3
  90. package/dist/openai/index.js +7 -5
  91. package/dist/openai/index.js.map +1 -1
  92. package/dist/openrouter/index.d.ts +4 -3
  93. package/dist/openrouter/index.js +7 -5
  94. package/dist/openrouter/index.js.map +1 -1
  95. package/dist/proxy/index.d.ts +5 -4
  96. package/dist/proxy/index.js +20 -17
  97. package/dist/proxy/index.js.map +1 -1
  98. package/dist/proxy/server/express/index.d.ts +8 -8
  99. package/dist/proxy/server/express/index.js +5 -3
  100. package/dist/proxy/server/fastify/index.d.ts +8 -8
  101. package/dist/proxy/server/fastify/index.js +5 -3
  102. package/dist/proxy/server/h3/index.d.ts +22 -21
  103. package/dist/proxy/server/h3/index.js +5 -3
  104. package/dist/proxy/server/index.d.ts +5 -4
  105. package/dist/proxy/server/index.js +15 -13
  106. package/dist/proxy/server/webapi/index.d.ts +8 -8
  107. package/dist/proxy/server/webapi/index.js +5 -3
  108. package/dist/responses/index.d.ts +3 -2
  109. package/dist/responses/index.js +7 -5
  110. package/dist/responses/index.js.map +1 -1
  111. package/dist/retry-DVfdPLIB.d.ts +322 -0
  112. package/dist/{stream-sXhBtWjl.d.ts → stream-bBd_4Ipu.d.ts} +29 -419
  113. package/dist/tool-BmAfKNBq.d.ts +507 -0
  114. package/dist/{types-Cr4F0tVy.d.ts → types-nTwlpyJE.d.ts} +28 -3
  115. package/dist/utils/index.d.ts +129 -1
  116. package/dist/utils/index.js +28 -1
  117. package/dist/xai/index.d.ts +3 -2
  118. package/dist/xai/index.js +7 -5
  119. package/dist/xai/index.js.map +1 -1
  120. package/package.json +20 -3
  121. package/dist/chunk-ARVM24K2.js +0 -128
  122. package/dist/chunk-ARVM24K2.js.map +0 -1
  123. package/dist/chunk-EPB3GQNL.js.map +0 -1
  124. package/dist/chunk-MJI74VEJ.js.map +0 -1
  125. package/dist/chunk-SBGZJVTJ.js.map +0 -1
  126. package/dist/chunk-WU4U6IHF.js.map +0 -1
  127. package/dist/chunk-Y5H7C5J4.js +0 -263
  128. package/dist/chunk-Y5H7C5J4.js.map +0 -1
  129. package/dist/chunk-YQLR3XOA.js.map +0 -1
  130. package/dist/chunk-ZRVNAET3.js.map +0 -1
  131. package/dist/retry-CgoBNa51.d.ts +0 -531
  132. /package/dist/{chunk-CRP6Y7NF.js.map → chunk-CWGTARDE.js.map} +0 -0
  133. /package/dist/{chunk-4RX4VQCB.js.map → chunk-KBI45OXI.js.map} +0 -0
  134. /package/dist/{chunk-5IWHCXKN.js.map → chunk-KVUOTFYZ.js.map} +0 -0
  135. /package/dist/{chunk-BDXH6NQS.js.map → chunk-N4LAFGLX.js.map} +0 -0
  136. /package/dist/{chunk-2YXFLRQ6.js.map → chunk-ZMESKGUY.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,10 +1,8 @@
1
1
  import {
2
- ExponentialBackoff,
3
- LinearBackoff,
4
- NoRetry,
5
- RetryAfterStrategy,
6
- TokenBucket
7
- } from "./chunk-Y5H7C5J4.js";
2
+ resolveStructure,
3
+ resolveTools
4
+ } from "./chunk-3Q5VELKG.js";
5
+ import "./chunk-IKJH5ZSJ.js";
8
6
  import {
9
7
  aggregateUsage,
10
8
  createTurn,
@@ -12,23 +10,28 @@ import {
12
10
  } from "./chunk-NSE7QN3P.js";
13
11
  import {
14
12
  Thread
15
- } from "./chunk-ZKNPQBIE.js";
13
+ } from "./chunk-R3T2IYOU.js";
16
14
  import {
17
15
  Image
18
16
  } from "./chunk-N5DX5JW3.js";
19
17
  import "./chunk-PMK5LZ5Z.js";
20
18
  import {
21
- DynamicKey,
22
- RoundRobinKeys,
23
- WeightedKeys
24
- } from "./chunk-ARVM24K2.js";
19
+ dynamicKey,
20
+ roundRobinKeys,
21
+ weightedKeys
22
+ } from "./chunk-EY2LLDGY.js";
25
23
  import {
26
24
  createProvider,
27
25
  resolveEmbeddingHandler,
28
26
  resolveImageHandler,
29
27
  resolveLLMHandler
30
28
  } from "./chunk-JA3UZALR.js";
31
- import "./chunk-SBGZJVTJ.js";
29
+ import {
30
+ exponentialBackoff,
31
+ linearBackoff,
32
+ noRetry,
33
+ retryAfterStrategy
34
+ } from "./chunk-VQZPADW6.js";
32
35
  import {
33
36
  StreamEventType,
34
37
  contentBlockStart,
@@ -37,11 +40,12 @@ import {
37
40
  messageStart,
38
41
  messageStop,
39
42
  objectDelta,
43
+ streamRetry,
40
44
  textDelta,
41
45
  toolCallDelta,
42
46
  toolExecutionEnd,
43
47
  toolExecutionStart
44
- } from "./chunk-MJI74VEJ.js";
48
+ } from "./chunk-F5ENANMJ.js";
45
49
  import {
46
50
  AssistantMessage,
47
51
  Message,
@@ -51,7 +55,8 @@ import {
51
55
  isAssistantMessage,
52
56
  isToolResultMessage,
53
57
  isUserMessage
54
- } from "./chunk-WU4U6IHF.js";
58
+ } from "./chunk-6QCV4WXF.js";
59
+ import "./chunk-U2G5PHHL.js";
55
60
  import {
56
61
  isCancelledError,
57
62
  toError
@@ -155,6 +160,17 @@ async function runAbortHook(middlewares, error, ctx) {
155
160
  }
156
161
  }
157
162
  }
163
+ async function runRetryHook(middlewares, attempt, error, ctx) {
164
+ for (const mw of middlewares) {
165
+ if (mw.onRetry) {
166
+ try {
167
+ await mw.onRetry(attempt, error, ctx);
168
+ } catch (hookError) {
169
+ console.error(`[${mw.name}] Error in onRetry hook:`, hookError);
170
+ }
171
+ }
172
+ }
173
+ }
158
174
  async function runToolHook(middlewares, hook, tool, data, ctx) {
159
175
  for (const mw of middlewares) {
160
176
  const fn = mw[hook];
@@ -165,11 +181,21 @@ async function runToolHook(middlewares, hook, tool, data, ctx) {
165
181
  }
166
182
  async function runTurnHook(middlewares, turn, ctx) {
167
183
  const ordered = [...middlewares].reverse();
184
+ let firstError = null;
168
185
  for (const mw of ordered) {
169
186
  if (mw.onTurn) {
170
- await mw.onTurn.call(mw, turn, ctx);
187
+ try {
188
+ await mw.onTurn.call(mw, turn, ctx);
189
+ } catch (err) {
190
+ if (!firstError) {
191
+ firstError = err instanceof Error ? err : new Error(String(err));
192
+ }
193
+ }
171
194
  }
172
195
  }
196
+ if (firstError) {
197
+ throw firstError;
198
+ }
173
199
  }
174
200
  function createStreamTransformer(middlewares, ctx) {
175
201
  const streamMiddlewares = middlewares.filter((mw) => mw.onStreamEvent);
@@ -210,7 +236,12 @@ async function runStreamEndHook(middlewares, ctx) {
210
236
  }
211
237
  }
212
238
  }
213
- function createMiddlewareContext(modality, modelId, provider, streaming, request) {
239
+ var noopEmit = () => {
240
+ };
241
+ function createEmitHolder() {
242
+ return { fn: noopEmit };
243
+ }
244
+ function createMiddlewareContext(modality, modelId, provider, streaming, request, emitHolder = { fn: noopEmit }) {
214
245
  return {
215
246
  modality,
216
247
  modelId,
@@ -220,7 +251,8 @@ function createMiddlewareContext(modality, modelId, provider, streaming, request
220
251
  response: void 0,
221
252
  state: /* @__PURE__ */ new Map(),
222
253
  startTime: Date.now(),
223
- endTime: void 0
254
+ endTime: void 0,
255
+ emit: (event) => emitHolder.fn(event)
224
256
  };
225
257
  }
226
258
  function createStreamContext(state) {
@@ -311,6 +343,9 @@ function inputToMessage(input) {
311
343
  throw new Error("Invalid inference input");
312
344
  }
313
345
  function parseInputs(historyOrInput, inputs) {
346
+ if (historyOrInput === void 0 && inputs.length === 0) {
347
+ return { history: [], messages: [] };
348
+ }
314
349
  if (typeof historyOrInput === "object" && historyOrInput !== null && "messages" in historyOrInput && Array.isArray(historyOrInput.messages)) {
315
350
  const thread = historyOrInput;
316
351
  const newMessages2 = inputs.map(inputToMessage);
@@ -625,23 +660,79 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
625
660
  structure,
626
661
  config
627
662
  };
663
+ const emitHolder = createEmitHolder();
628
664
  const ctx = createMiddlewareContext(
629
665
  "llm",
630
666
  model.modelId,
631
667
  model.provider.name,
632
668
  true,
633
- initialRequest
669
+ initialRequest,
670
+ emitHolder
634
671
  );
635
672
  const streamCtx = createStreamContext(ctx.state);
636
673
  const transformer = createStreamTransformer(middleware, streamCtx);
674
+ const lateEventQueue = [];
675
+ let lateEventResolver = null;
676
+ let lateEventsActive = false;
677
+ let lateEventsClosed = false;
678
+ const pushLateEvent = (event) => {
679
+ if (lateEventsClosed) return;
680
+ lateEventQueue.push(event);
681
+ if (lateEventResolver) {
682
+ const resolver = lateEventResolver;
683
+ lateEventResolver = null;
684
+ resolver(false);
685
+ }
686
+ };
687
+ const closeLateEvents = () => {
688
+ lateEventsClosed = true;
689
+ if (lateEventResolver) {
690
+ lateEventResolver(true);
691
+ lateEventResolver = null;
692
+ }
693
+ };
694
+ const waitForLateEvent = () => {
695
+ if (lateEventQueue.length > 0) {
696
+ return Promise.resolve(false);
697
+ }
698
+ if (lateEventsClosed) {
699
+ return Promise.resolve(true);
700
+ }
701
+ return new Promise((resolve) => {
702
+ lateEventResolver = resolve;
703
+ });
704
+ };
705
+ const inlineEventQueue = [];
706
+ emitHolder.fn = (event) => {
707
+ const result = transformer(event);
708
+ if (result === null) return;
709
+ if (lateEventsActive) {
710
+ if (Array.isArray(result)) {
711
+ for (const e of result) pushLateEvent(e);
712
+ } else {
713
+ pushLateEvent(result);
714
+ }
715
+ } else {
716
+ if (Array.isArray(result)) {
717
+ inlineEventQueue.push(...result);
718
+ } else {
719
+ inlineEventQueue.push(result);
720
+ }
721
+ }
722
+ };
723
+ function* drainInlineEvents() {
724
+ while (inlineEventQueue.length > 0) {
725
+ yield inlineEventQueue.shift();
726
+ }
727
+ }
637
728
  let resolveGenerator;
638
729
  let rejectGenerator;
639
730
  let generatorSettled = false;
640
731
  const generatorDone = new Promise((resolve, reject) => {
641
- resolveGenerator = () => {
732
+ resolveGenerator = (turn) => {
642
733
  if (!generatorSettled) {
643
734
  generatorSettled = true;
644
- resolve();
735
+ resolve(turn);
645
736
  }
646
737
  };
647
738
  rejectGenerator = (error) => {
@@ -657,6 +748,10 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
657
748
  }
658
749
  });
659
750
  const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;
751
+ const strategy = (config.retryStrategy ?? noRetry())();
752
+ const strategyMaxAttempts = strategy.maxAttempts ?? 0;
753
+ let attempt = 1;
754
+ let retryMessages = [];
660
755
  const onAbort = () => {
661
756
  const error = new UPPError("Stream cancelled", ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);
662
757
  generatorError = error;
@@ -672,7 +767,9 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
672
767
  try {
673
768
  ensureNotAborted();
674
769
  await runHook(middleware, "onStart", ctx);
770
+ yield* drainInlineEvents();
675
771
  await runHook(middleware, "onRequest", ctx);
772
+ yield* drainInlineEvents();
676
773
  allMessages = ctx.request.messages;
677
774
  const requestMessageCount = allMessages.length;
678
775
  const overrideIndex = ctx.state.get(TURN_START_INDEX_KEY);
@@ -684,64 +781,121 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
684
781
  typeof overrideIndex === "number" ? overrideIndex : void 0
685
782
  );
686
783
  validateMediaCapabilities(allMessages, model.capabilities, model.provider.name);
687
- while (cycles < maxIterations + 1) {
688
- cycles++;
689
- ensureNotAborted();
690
- const request = {
691
- messages: allMessages,
692
- system,
693
- params,
694
- tools,
695
- structure,
696
- config,
697
- signal: abortController.signal
698
- };
699
- const streamResult = model.stream(request);
700
- for await (const event of streamResult) {
701
- ensureNotAborted();
702
- const transformed = transformer(event);
703
- if (transformed === null) continue;
704
- if (Array.isArray(transformed)) {
705
- for (const e of transformed) {
706
- yield e;
784
+ const retryTurnStartIndex = turnStartIndex;
785
+ let lastStreamResult;
786
+ retryLoop: while (true) {
787
+ try {
788
+ while (cycles < maxIterations + 1) {
789
+ cycles++;
790
+ ensureNotAborted();
791
+ retryMessages = [...allMessages];
792
+ if (strategy.beforeRequest) {
793
+ const beforeDelay = await strategy.beforeRequest();
794
+ if (beforeDelay > 0) {
795
+ await new Promise((resolve, reject) => {
796
+ const timeoutId = setTimeout(resolve, beforeDelay);
797
+ const handleBeforeAbort = () => {
798
+ clearTimeout(timeoutId);
799
+ reject(new UPPError("Stream cancelled", ErrorCode.Cancelled, model.provider.name, ModalityType.LLM));
800
+ };
801
+ if (abortController.signal.aborted) {
802
+ clearTimeout(timeoutId);
803
+ reject(new UPPError("Stream cancelled", ErrorCode.Cancelled, model.provider.name, ModalityType.LLM));
804
+ } else {
805
+ abortController.signal.addEventListener("abort", handleBeforeAbort, { once: true });
806
+ }
807
+ });
808
+ }
809
+ }
810
+ const request = {
811
+ messages: allMessages,
812
+ system,
813
+ params,
814
+ tools,
815
+ structure,
816
+ config,
817
+ signal: abortController.signal
818
+ };
819
+ const streamResult = model.stream(request);
820
+ lastStreamResult = streamResult;
821
+ for await (const event of streamResult) {
822
+ ensureNotAborted();
823
+ const transformed = transformer(event);
824
+ if (transformed === null) continue;
825
+ if (Array.isArray(transformed)) {
826
+ for (const e of transformed) {
827
+ yield e;
828
+ }
829
+ } else {
830
+ yield transformed;
831
+ }
832
+ yield* drainInlineEvents();
833
+ }
834
+ const response = await streamResult.response;
835
+ attempt = 1;
836
+ strategy.reset?.();
837
+ usages.push(response.usage);
838
+ allMessages.push(response.message);
839
+ if (response.data !== void 0) {
840
+ structuredData = response.data;
841
+ }
842
+ if (response.message.hasToolCalls && tools && tools.length > 0) {
843
+ if (response.data !== void 0) {
844
+ break;
845
+ }
846
+ if (cycles >= maxIterations) {
847
+ await toolStrategy?.onMaxIterations?.(maxIterations);
848
+ throw new UPPError(
849
+ `Tool execution exceeded maximum iterations (${maxIterations})`,
850
+ ErrorCode.InvalidRequest,
851
+ model.provider.name,
852
+ ModalityType.LLM
853
+ );
854
+ }
855
+ const toolEvents = [];
856
+ const results = await executeTools(
857
+ response.message,
858
+ tools,
859
+ toolStrategy,
860
+ toolExecutions,
861
+ (event) => toolEvents.push(event),
862
+ middleware,
863
+ ctx
864
+ );
865
+ for (const event of toolEvents) {
866
+ ensureNotAborted();
867
+ const transformed = transformer(event);
868
+ if (transformed === null) continue;
869
+ if (Array.isArray(transformed)) {
870
+ for (const e of transformed) {
871
+ yield e;
872
+ }
873
+ } else {
874
+ yield transformed;
875
+ }
876
+ yield* drainInlineEvents();
877
+ }
878
+ allMessages.push(new ToolResultMessage(results));
879
+ continue;
707
880
  }
708
- } else {
709
- yield transformed;
710
- }
711
- }
712
- const response = await streamResult.response;
713
- usages.push(response.usage);
714
- allMessages.push(response.message);
715
- if (response.data !== void 0) {
716
- structuredData = response.data;
717
- }
718
- if (response.message.hasToolCalls && tools && tools.length > 0) {
719
- if (response.data !== void 0) {
720
881
  break;
721
882
  }
722
- if (cycles >= maxIterations) {
723
- await toolStrategy?.onMaxIterations?.(maxIterations);
724
- throw new UPPError(
725
- `Tool execution exceeded maximum iterations (${maxIterations})`,
726
- ErrorCode.InvalidRequest,
727
- model.provider.name,
728
- ModalityType.LLM
729
- );
883
+ break retryLoop;
884
+ } catch (streamError) {
885
+ const err = toError(streamError);
886
+ const uppErr = err instanceof UPPError ? err : null;
887
+ if (!uppErr || isCancelledError(err)) {
888
+ throw err;
730
889
  }
731
- const toolEvents = [];
732
- const results = await executeTools(
733
- response.message,
734
- tools,
735
- toolStrategy,
736
- toolExecutions,
737
- (event) => toolEvents.push(event),
738
- middleware,
739
- ctx
740
- );
741
- for (const event of toolEvents) {
742
- ensureNotAborted();
743
- const transformed = transformer(event);
744
- if (transformed === null) continue;
890
+ const delay = await strategy.onRetry(uppErr, attempt);
891
+ if (delay === null) {
892
+ throw err;
893
+ }
894
+ lastStreamResult?.response.catch(() => {
895
+ });
896
+ const retryEvent = streamRetry(attempt, strategyMaxAttempts, err, Date.now());
897
+ const transformed = transformer(retryEvent);
898
+ if (transformed !== null) {
745
899
  if (Array.isArray(transformed)) {
746
900
  for (const e of transformed) {
747
901
  yield e;
@@ -750,14 +904,84 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
750
904
  yield transformed;
751
905
  }
752
906
  }
753
- allMessages.push(new ToolResultMessage(results));
754
- continue;
907
+ await runRetryHook(middleware, attempt, err, ctx);
908
+ yield* drainInlineEvents();
909
+ allMessages = [...retryMessages];
910
+ turnStartIndex = retryTurnStartIndex;
911
+ cycles--;
912
+ structuredData = void 0;
913
+ ctx.request = {
914
+ messages: allMessages,
915
+ system,
916
+ params,
917
+ tools,
918
+ structure,
919
+ config
920
+ };
921
+ attempt += 1;
922
+ if (delay > 0) {
923
+ await new Promise((resolve, reject) => {
924
+ const timeoutId = setTimeout(resolve, delay);
925
+ const handleDelayAbort = () => {
926
+ clearTimeout(timeoutId);
927
+ reject(new UPPError("Stream cancelled", ErrorCode.Cancelled, model.provider.name, ModalityType.LLM));
928
+ };
929
+ if (abortController.signal.aborted) {
930
+ clearTimeout(timeoutId);
931
+ reject(new UPPError("Stream cancelled", ErrorCode.Cancelled, model.provider.name, ModalityType.LLM));
932
+ } else {
933
+ abortController.signal.addEventListener("abort", handleDelayAbort, { once: true });
934
+ }
935
+ });
936
+ }
937
+ continue retryLoop;
938
+ }
939
+ }
940
+ lateEventsActive = true;
941
+ let hooksTurn = null;
942
+ let hooksError = null;
943
+ const hooksPromise = (async () => {
944
+ try {
945
+ await runStreamEndHook(middleware, streamCtx);
946
+ const data = structure ? structuredData : void 0;
947
+ const turn = createTurn(
948
+ allMessages.slice(turnStartIndex),
949
+ toolExecutions,
950
+ aggregateUsage(usages),
951
+ cycles,
952
+ data
953
+ );
954
+ ctx.response = {
955
+ message: turn.response,
956
+ usage: turn.usage,
957
+ stopReason: "end_turn",
958
+ data
959
+ };
960
+ ctx.endTime = Date.now();
961
+ await runHook(middleware, "onResponse", ctx, true);
962
+ await runTurnHook(middleware, turn, ctx);
963
+ await runHook(middleware, "onEnd", ctx, true);
964
+ hooksTurn = turn;
965
+ } catch (err) {
966
+ hooksError = err instanceof Error ? err : new Error(String(err));
967
+ } finally {
968
+ lateEventsActive = false;
969
+ closeLateEvents();
970
+ }
971
+ })();
972
+ while (true) {
973
+ const done = await waitForLateEvent();
974
+ if (done) break;
975
+ while (lateEventQueue.length > 0) {
976
+ yield lateEventQueue.shift();
755
977
  }
756
- break;
757
978
  }
758
- await runStreamEndHook(middleware, streamCtx);
979
+ await hooksPromise;
980
+ if (hooksError !== null) {
981
+ throw toError(hooksError);
982
+ }
759
983
  generatorCompleted = true;
760
- resolveGenerator();
984
+ resolveGenerator(hooksTurn);
761
985
  } catch (error) {
762
986
  const err = toError(error);
763
987
  generatorError = err;
@@ -782,29 +1006,7 @@ function executeStream(model, config, system, params, tools, toolStrategy, struc
782
1006
  }
783
1007
  }
784
1008
  const createTurnPromise = async () => {
785
- await generatorDone;
786
- if (generatorError) {
787
- throw generatorError;
788
- }
789
- const data = structure ? structuredData : void 0;
790
- const turn = createTurn(
791
- allMessages.slice(turnStartIndex),
792
- toolExecutions,
793
- aggregateUsage(usages),
794
- cycles,
795
- data
796
- );
797
- ctx.response = {
798
- message: turn.response,
799
- usage: turn.usage,
800
- stopReason: "end_turn",
801
- data
802
- };
803
- ctx.endTime = Date.now();
804
- await runHook(middleware, "onResponse", ctx, true);
805
- await runTurnHook(middleware, turn, ctx);
806
- await runHook(middleware, "onEnd", ctx, true);
807
- return turn;
1009
+ return generatorDone;
808
1010
  };
809
1011
  return createStreamResult(generateStream(), createTurnPromise, abortController);
810
1012
  }
@@ -814,11 +1016,13 @@ function llm(options) {
814
1016
  config: explicitConfig = {},
815
1017
  params,
816
1018
  system,
817
- tools,
1019
+ tools: toolsInput,
818
1020
  toolStrategy,
819
- structure,
1021
+ structure: structureInput,
820
1022
  middleware = []
821
1023
  } = options;
1024
+ const structure = structureInput ? resolveStructure(structureInput) : void 0;
1025
+ const tools = toolsInput ? resolveTools(toolsInput) : void 0;
822
1026
  const providerConfig = modelRef.providerConfig ?? {};
823
1027
  const config = {
824
1028
  ...providerConfig,
@@ -1930,27 +2134,19 @@ export {
1930
2134
  ContentBlockType,
1931
2135
  Document,
1932
2136
  DocumentSourceType,
1933
- DynamicKey,
1934
2137
  EmbeddingInputType,
1935
2138
  ErrorCode,
1936
- ExponentialBackoff,
1937
2139
  Image,
1938
2140
  ImageSourceType,
1939
- LinearBackoff,
1940
2141
  Message,
1941
2142
  MessageRole,
1942
2143
  ModalityType,
1943
- NoRetry,
1944
- RetryAfterStrategy,
1945
- RoundRobinKeys,
1946
2144
  StreamEventType,
1947
2145
  Thread,
1948
- TokenBucket,
1949
2146
  ToolResultMessage,
1950
2147
  UPPError,
1951
2148
  UserMessage,
1952
2149
  Video,
1953
- WeightedKeys,
1954
2150
  aggregateUsage,
1955
2151
  ai,
1956
2152
  contentBlockStart,
@@ -1958,8 +2154,10 @@ export {
1958
2154
  createProvider,
1959
2155
  createStreamResult,
1960
2156
  createTurn,
2157
+ dynamicKey,
1961
2158
  embedding,
1962
2159
  emptyUsage,
2160
+ exponentialBackoff,
1963
2161
  image,
1964
2162
  isAssistantMessage,
1965
2163
  isAudioBlock,
@@ -1971,15 +2169,20 @@ export {
1971
2169
  isToolResultMessage,
1972
2170
  isUserMessage,
1973
2171
  isVideoBlock,
2172
+ linearBackoff,
1974
2173
  llm,
1975
2174
  messageStart,
1976
2175
  messageStop,
2176
+ noRetry,
1977
2177
  objectDelta,
1978
2178
  reasoning,
2179
+ retryAfterStrategy,
2180
+ roundRobinKeys,
1979
2181
  text,
1980
2182
  textDelta,
1981
2183
  toolCallDelta,
1982
2184
  toolExecutionEnd,
1983
- toolExecutionStart
2185
+ toolExecutionStart,
2186
+ weightedKeys
1984
2187
  };
1985
2188
  //# sourceMappingURL=index.js.map