190proof 1.0.101 → 1.0.102

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 CHANGED
@@ -273,6 +273,11 @@ Main function to make requests to any supported AI provider.
273
273
  - `retries`: `number` - Number of retry attempts (default: 5)
274
274
  - `chunkTimeoutMs`: `number` - Timeout for streaming chunks in ms (default: 15000)
275
275
 
276
+ Two optional per-request knobs live on `payload` (`GenericPayload`):
277
+
278
+ - `payload.requestTimeoutMs`: `number` - Per-attempt HTTP timeout in ms (default: 120000), honored by every adapter.
279
+ - `payload.signal`: `AbortSignal` - Caller-supplied cancellation. When it aborts, the in-flight provider request is cancelled and `callWithRetries` **rejects immediately — it does not retry or fall back** (both the retry loop and the fallback branch bail on `signal.aborted`). Threaded to the underlying fetch/axios/SDK call of each provider.
280
+
276
281
  #### Returns
277
282
 
278
283
  `Promise<ParsedResponseMessage>`:
package/dist/index.d.mts CHANGED
@@ -265,6 +265,14 @@ interface GenericPayload {
265
265
  * valid response isn't cut short.
266
266
  */
267
267
  requestTimeoutMs?: number;
268
+ /**
269
+ * Optional caller-supplied cancellation signal. When it aborts, the in-flight
270
+ * provider request is cancelled and `callWithRetries` rejects immediately —
271
+ * it does NOT retry or fall back (both retry loop and fallback branch bail on
272
+ * `signal.aborted`). Threaded through every adapter to the underlying
273
+ * fetch/axios/SDK call, mirroring `requestTimeoutMs`.
274
+ */
275
+ signal?: AbortSignal;
268
276
  }
269
277
 
270
278
  declare function parseModelString(model: string): {
package/dist/index.d.ts CHANGED
@@ -265,6 +265,14 @@ interface GenericPayload {
265
265
  * valid response isn't cut short.
266
266
  */
267
267
  requestTimeoutMs?: number;
268
+ /**
269
+ * Optional caller-supplied cancellation signal. When it aborts, the in-flight
270
+ * provider request is cancelled and `callWithRetries` rejects immediately —
271
+ * it does NOT retry or fall back (both retry loop and fallback branch bail on
272
+ * `signal.aborted`). Threaded through every adapter to the underlying
273
+ * fetch/axios/SDK call, mirroring `requestTimeoutMs`.
274
+ */
275
+ signal?: AbortSignal;
268
276
  }
269
277
 
270
278
  declare function parseModelString(model: string): {
package/dist/index.js CHANGED
@@ -141,8 +141,13 @@ function isHeicImage(name, mime) {
141
141
  // index.ts
142
142
  var sharp = require("sharp");
143
143
  var decode = require("heic-decode");
144
+ function anySignal(signals) {
145
+ return AbortSignal.any(
146
+ signals
147
+ );
148
+ }
144
149
  async function withRetries(identifier, apiName, fn, options = {}) {
145
- var _a, _b, _c, _d;
150
+ var _a, _b, _c, _d, _e;
146
151
  const { retries = 5, baseDelayMs = 125, onError } = options;
147
152
  logger_default.log(identifier, `Calling ${apiName} API with retries`);
148
153
  let lastError;
@@ -151,19 +156,21 @@ async function withRetries(identifier, apiName, fn, options = {}) {
151
156
  return await fn();
152
157
  } catch (error3) {
153
158
  lastError = error3;
159
+ if ((_a = options.signal) == null ? void 0 : _a.aborted)
160
+ throw error3;
154
161
  if (onError) {
155
162
  onError(error3, attempt);
156
163
  } else {
157
164
  logger_default.error(
158
165
  identifier,
159
166
  `Retry #${attempt} error: ${error3.message}`,
160
- ((_a = error3.response) == null ? void 0 : _a.data) || error3
167
+ ((_b = error3.response) == null ? void 0 : _b.data) || error3
161
168
  );
162
169
  }
163
170
  await timeout(baseDelayMs * attempt);
164
171
  }
165
172
  }
166
- const detail = ((_d = (_c = (_b = lastError == null ? void 0 : lastError.response) == null ? void 0 : _b.data) == null ? void 0 : _c.error) == null ? void 0 : _d.message) || (lastError == null ? void 0 : lastError.message) || String(lastError);
173
+ const detail = ((_e = (_d = (_c = lastError == null ? void 0 : lastError.response) == null ? void 0 : _c.data) == null ? void 0 : _d.error) == null ? void 0 : _e.message) || (lastError == null ? void 0 : lastError.message) || String(lastError);
167
174
  const error2 = new Error(
168
175
  `Failed to call ${apiName} API after ${retries} attempts: ${detail}`
169
176
  );
@@ -386,7 +393,7 @@ async function prepareOpenAIPayload(identifier, payload) {
386
393
  }
387
394
  return preparedPayload;
388
395
  }
389
- async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs, requestTimeoutMs = 12e4) {
396
+ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs, requestTimeoutMs = 12e4, signal) {
390
397
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
391
398
  const functionNames = openAiPayload.tools ? new Set(openAiPayload.tools.map((fn) => fn.function.name)) : null;
392
399
  const { endpoint, headers } = buildOpenAIRequestConfig(
@@ -406,7 +413,10 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs,
406
413
  method: "POST",
407
414
  headers,
408
415
  body: JSON.stringify({ ...openAiPayload, stream: true }),
409
- signal: controller.signal
416
+ // Merge (don't overwrite) the internal timeout controller with the caller's
417
+ // cancellation signal so both an internal timeout and an external abort stop
418
+ // the stream.
419
+ signal: signal ? anySignal([controller.signal, signal]) : controller.signal
410
420
  });
411
421
  if (!response.body) {
412
422
  throw new Error("Stream error: no response body");
@@ -496,7 +506,7 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs,
496
506
  }
497
507
  }
498
508
  }
499
- async function callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs = 12e4) {
509
+ async function callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs = 12e4, signal) {
500
510
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
501
511
  const { endpoint, headers } = buildOpenAIRequestConfig(
502
512
  id,
@@ -511,7 +521,8 @@ async function callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs = 12
511
521
  method: "POST",
512
522
  headers,
513
523
  body: JSON.stringify({ ...openAiPayload, stream: false }),
514
- signal: controller.signal
524
+ // Merge the internal timeout controller with the caller's cancellation signal.
525
+ signal: signal ? anySignal([controller.signal, signal]) : controller.signal
515
526
  });
516
527
  if (!response.ok) {
517
528
  const errorData = await response.json();
@@ -574,7 +585,7 @@ async function callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs = 12
574
585
  } : null
575
586
  };
576
587
  }
577
- async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries = 5, chunkTimeoutMs = 15e3, requestTimeoutMs = 12e4) {
588
+ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries = 5, chunkTimeoutMs = 15e3, requestTimeoutMs = 12e4, signal) {
578
589
  logger_default.log(
579
590
  id,
580
591
  "Calling OpenAI API with retries:",
@@ -593,14 +604,16 @@ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries =
593
604
  openAiPayload,
594
605
  openAiConfig,
595
606
  chunkTimeoutMs,
596
- requestTimeoutMs
607
+ requestTimeoutMs,
608
+ signal
597
609
  );
598
610
  } else {
599
- return callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs);
611
+ return callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs, signal);
600
612
  }
601
613
  },
602
614
  {
603
615
  retries,
616
+ signal,
604
617
  baseDelayMs: 250,
605
618
  onError: (error2, attempt) => {
606
619
  var _a, _b;
@@ -732,7 +745,7 @@ async function prepareAnthropicPayload(_identifier, payload) {
732
745
  }
733
746
  return preparedPayload;
734
747
  }
735
- async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4) {
748
+ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4, signal) {
736
749
  var _a, _b, _c;
737
750
  const anthropicMessages = jigAnthropicMessages(payload.messages);
738
751
  const tools = (_a = payload.functions) == null ? void 0 : _a.map((f) => ({
@@ -756,7 +769,8 @@ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4) {
756
769
  contentType: "application/json",
757
770
  body: JSON.stringify(bedrockPayload),
758
771
  modelId: MODEL_ID
759
- })
772
+ }),
773
+ { abortSignal: signal }
760
774
  );
761
775
  const decodedResponseBody = new TextDecoder().decode(response.body);
762
776
  data = JSON.parse(decodedResponseBody);
@@ -782,7 +796,8 @@ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4) {
782
796
  "anthropic-version": "2023-06-01",
783
797
  "anthropic-beta": "tools-2024-04-04"
784
798
  },
785
- timeout: requestTimeoutMs
799
+ timeout: requestTimeoutMs,
800
+ signal
786
801
  }
787
802
  );
788
803
  data = response.data;
@@ -852,13 +867,14 @@ ${text}` : text;
852
867
  usage
853
868
  };
854
869
  }
855
- async function callAnthropicWithRetries(id, payload, config, retries = 5, requestTimeoutMs = 12e4) {
870
+ async function callAnthropicWithRetries(id, payload, config, retries = 5, requestTimeoutMs = 12e4, signal) {
856
871
  return withRetries(
857
872
  id,
858
873
  "Anthropic",
859
- () => callAnthropic(id, payload, config, requestTimeoutMs),
874
+ () => callAnthropic(id, payload, config, requestTimeoutMs, signal),
860
875
  {
861
- retries
876
+ retries,
877
+ signal
862
878
  }
863
879
  );
864
880
  }
@@ -976,7 +992,7 @@ async function prepareGoogleAIPayload(_identifier, payload) {
976
992
  }
977
993
  return preparedPayload;
978
994
  }
979
- async function callGoogleAI(id, payload, requestTimeoutMs = 12e4) {
995
+ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4, signal) {
980
996
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
981
997
  const contents = jigGoogleMessages(payload.messages);
982
998
  const requestBody = {
@@ -1000,7 +1016,8 @@ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4) {
1000
1016
  "content-type": "application/json",
1001
1017
  "x-goog-api-key": process.env.GEMINI_API_KEY
1002
1018
  },
1003
- timeout: requestTimeoutMs
1019
+ timeout: requestTimeoutMs,
1020
+ signal
1004
1021
  }
1005
1022
  );
1006
1023
  response = httpResponse.data;
@@ -1099,10 +1116,11 @@ function removeImagesFromGooglePayload(payload) {
1099
1116
  }
1100
1117
  return removedImages;
1101
1118
  }
1102
- async function callGoogleAIWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1119
+ async function callGoogleAIWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4, signal) {
1103
1120
  let hasTriedWithoutImages = false;
1104
- return withRetries(id, "Google AI", () => callGoogleAI(id, payload, requestTimeoutMs), {
1121
+ return withRetries(id, "Google AI", () => callGoogleAI(id, payload, requestTimeoutMs, signal), {
1105
1122
  retries,
1123
+ signal,
1106
1124
  onError: (error2, attempt) => {
1107
1125
  var _a, _b;
1108
1126
  const errorDetails = {
@@ -1228,7 +1246,7 @@ function prepareGroqPayload(payload) {
1228
1246
  temperature: payload.temperature
1229
1247
  };
1230
1248
  }
1231
- async function callGroq(id, payload, requestTimeoutMs = 12e4) {
1249
+ async function callGroq(id, payload, requestTimeoutMs = 12e4, signal) {
1232
1250
  var _a, _b, _c, _d, _e, _f, _g;
1233
1251
  const response = await import_axios.default.post(
1234
1252
  "https://api.groq.com/openai/v1/chat/completions",
@@ -1238,7 +1256,8 @@ async function callGroq(id, payload, requestTimeoutMs = 12e4) {
1238
1256
  "content-type": "application/json",
1239
1257
  Authorization: `Bearer ${process.env.GROQ_API_KEY}`
1240
1258
  },
1241
- timeout: requestTimeoutMs
1259
+ timeout: requestTimeoutMs,
1260
+ signal
1242
1261
  }
1243
1262
  );
1244
1263
  if (response.data.error) {
@@ -1286,9 +1305,10 @@ async function callGroq(id, payload, requestTimeoutMs = 12e4) {
1286
1305
  } : null
1287
1306
  };
1288
1307
  }
1289
- async function callGroqWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1290
- return withRetries(id, "Groq", () => callGroq(id, payload, requestTimeoutMs), {
1291
- retries
1308
+ async function callGroqWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4, signal) {
1309
+ return withRetries(id, "Groq", () => callGroq(id, payload, requestTimeoutMs, signal), {
1310
+ retries,
1311
+ signal
1292
1312
  });
1293
1313
  }
1294
1314
  function prepareOpenRouterPayload(payload) {
@@ -1353,7 +1373,7 @@ function parseDsmlToolCalls(content) {
1353
1373
  const remaining = first === -1 ? content : (content.slice(0, first) + content.slice(last)).trim();
1354
1374
  return { calls, remainingContent: remaining.length ? remaining : null };
1355
1375
  }
1356
- async function callOpenRouter(id, payload, requestTimeoutMs = 12e4) {
1376
+ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4, signal) {
1357
1377
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1358
1378
  const response = await import_axios.default.post(
1359
1379
  "https://openrouter.ai/api/v1/chat/completions",
@@ -1363,7 +1383,8 @@ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4) {
1363
1383
  "content-type": "application/json",
1364
1384
  Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`
1365
1385
  },
1366
- timeout: requestTimeoutMs
1386
+ timeout: requestTimeoutMs,
1387
+ signal
1367
1388
  }
1368
1389
  );
1369
1390
  if (response.data.error) {
@@ -1421,12 +1442,12 @@ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4) {
1421
1442
  } : null
1422
1443
  };
1423
1444
  }
1424
- async function callOpenRouterWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1445
+ async function callOpenRouterWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4, signal) {
1425
1446
  return withRetries(
1426
1447
  id,
1427
1448
  "OpenRouter",
1428
- () => callOpenRouter(id, payload, requestTimeoutMs),
1429
- { retries }
1449
+ () => callOpenRouter(id, payload, requestTimeoutMs, signal),
1450
+ { retries, signal }
1430
1451
  );
1431
1452
  }
1432
1453
  var VALID_PROVIDERS = ["openai", "anthropic", "google", "groq", "openrouter"];
@@ -1467,11 +1488,12 @@ function parseModelString(model) {
1467
1488
  );
1468
1489
  }
1469
1490
  async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeoutMs = 15e3) {
1470
- var _a;
1491
+ var _a, _b;
1471
1492
  try {
1472
1493
  const { provider, modelId } = parseModelString(aiPayload.model);
1473
1494
  const routingPayload = { ...aiPayload, model: modelId };
1474
1495
  const requestTimeoutMs = (_a = aiPayload.requestTimeoutMs) != null ? _a : 12e4;
1496
+ const signal = aiPayload.signal;
1475
1497
  switch (provider) {
1476
1498
  case "anthropic":
1477
1499
  return await callAnthropicWithRetries(
@@ -1479,7 +1501,8 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1479
1501
  await prepareAnthropicPayload(id, routingPayload),
1480
1502
  aiConfig,
1481
1503
  retries,
1482
- requestTimeoutMs
1504
+ requestTimeoutMs,
1505
+ signal
1483
1506
  );
1484
1507
  case "openai":
1485
1508
  return await callOpenAiWithRetries(
@@ -1488,31 +1511,37 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1488
1511
  aiConfig,
1489
1512
  retries,
1490
1513
  chunkTimeoutMs,
1491
- requestTimeoutMs
1514
+ requestTimeoutMs,
1515
+ signal
1492
1516
  );
1493
1517
  case "groq":
1494
1518
  return await callGroqWithRetries(
1495
1519
  id,
1496
1520
  prepareGroqPayload(routingPayload),
1497
1521
  retries,
1498
- requestTimeoutMs
1522
+ requestTimeoutMs,
1523
+ signal
1499
1524
  );
1500
1525
  case "google":
1501
1526
  return await callGoogleAIWithRetries(
1502
1527
  id,
1503
1528
  await prepareGoogleAIPayload(id, routingPayload),
1504
1529
  retries,
1505
- requestTimeoutMs
1530
+ requestTimeoutMs,
1531
+ signal
1506
1532
  );
1507
1533
  case "openrouter":
1508
1534
  return await callOpenRouterWithRetries(
1509
1535
  id,
1510
1536
  prepareOpenRouterPayload(routingPayload),
1511
1537
  retries,
1512
- requestTimeoutMs
1538
+ requestTimeoutMs,
1539
+ signal
1513
1540
  );
1514
1541
  }
1515
1542
  } catch (error2) {
1543
+ if ((_b = aiPayload.signal) == null ? void 0 : _b.aborted)
1544
+ throw error2;
1516
1545
  if (aiPayload.fallbackModel) {
1517
1546
  logger_default.error(
1518
1547
  id,