190proof 1.0.98 → 1.0.100

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/index.mjs CHANGED
@@ -111,7 +111,7 @@ function isHeicImage(name, mime) {
111
111
  var sharp = __require("sharp");
112
112
  var decode = __require("heic-decode");
113
113
  async function withRetries(identifier, apiName, fn, options = {}) {
114
- var _a;
114
+ var _a, _b, _c, _d;
115
115
  const { retries = 5, baseDelayMs = 125, onError } = options;
116
116
  logger_default.log(identifier, `Calling ${apiName} API with retries`);
117
117
  let lastError;
@@ -132,8 +132,9 @@ async function withRetries(identifier, apiName, fn, options = {}) {
132
132
  await timeout(baseDelayMs * attempt);
133
133
  }
134
134
  }
135
+ 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);
135
136
  const error2 = new Error(
136
- `Failed to call ${apiName} API after ${retries} attempts`
137
+ `Failed to call ${apiName} API after ${retries} attempts: ${detail}`
137
138
  );
138
139
  error2.cause = lastError;
139
140
  throw error2;
@@ -354,7 +355,7 @@ async function prepareOpenAIPayload(identifier, payload) {
354
355
  }
355
356
  return preparedPayload;
356
357
  }
357
- async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs) {
358
+ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs, requestTimeoutMs = 12e4) {
358
359
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
359
360
  const functionNames = openAiPayload.tools ? new Set(openAiPayload.tools.map((fn) => fn.function.name)) : null;
360
361
  const { endpoint, headers } = buildOpenAIRequestConfig(
@@ -363,6 +364,13 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
363
364
  openAiConfig
364
365
  );
365
366
  const controller = new AbortController();
367
+ const overallTimeout = setTimeout(() => {
368
+ logger_default.error(id, `Request timeout after ${requestTimeoutMs}ms`);
369
+ controller.abort();
370
+ }, requestTimeoutMs);
371
+ if (typeof overallTimeout === "object" && "unref" in overallTimeout) {
372
+ overallTimeout.unref();
373
+ }
366
374
  const response = await fetch(endpoint, {
367
375
  method: "POST",
368
376
  headers,
@@ -404,6 +412,7 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
404
412
  if (!jsonString)
405
413
  continue;
406
414
  if (jsonString.includes("[DONE]")) {
415
+ clearTimeout(overallTimeout);
407
416
  return parseStreamedResponse(
408
417
  id,
409
418
  paragraph,
@@ -456,24 +465,32 @@ async function callOpenAIStream(id, openAiPayload, openAiConfig, chunkTimeoutMs)
456
465
  }
457
466
  }
458
467
  }
459
- async function callOpenAI(id, openAiPayload, openAiConfig) {
468
+ async function callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs = 12e4) {
460
469
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
461
470
  const { endpoint, headers } = buildOpenAIRequestConfig(
462
471
  id,
463
472
  openAiPayload.model,
464
473
  openAiConfig
465
474
  );
466
- const response = await fetch(endpoint, {
467
- method: "POST",
468
- headers,
469
- body: JSON.stringify({ ...openAiPayload, stream: false })
470
- });
471
- if (!response.ok) {
472
- const errorData = await response.json();
473
- logger_default.error(id, "OpenAI API error:", errorData);
474
- throw new Error(`OpenAI API Error: ${errorData.error.message}`);
475
+ const controller = new AbortController();
476
+ const timer = setTimeout(() => controller.abort(), requestTimeoutMs);
477
+ let data;
478
+ try {
479
+ const response = await fetch(endpoint, {
480
+ method: "POST",
481
+ headers,
482
+ body: JSON.stringify({ ...openAiPayload, stream: false }),
483
+ signal: controller.signal
484
+ });
485
+ if (!response.ok) {
486
+ const errorData = await response.json();
487
+ logger_default.error(id, "OpenAI API error:", errorData);
488
+ throw new Error(`OpenAI API Error: ${errorData.error.message}`);
489
+ }
490
+ data = await response.json();
491
+ } finally {
492
+ clearTimeout(timer);
475
493
  }
476
- const data = await response.json();
477
494
  if (!((_a = data.choices) == null ? void 0 : _a.length)) {
478
495
  if (data.error) {
479
496
  logger_default.error(id, "OpenAI error:", data.error);
@@ -526,7 +543,7 @@ async function callOpenAI(id, openAiPayload, openAiConfig) {
526
543
  } : null
527
544
  };
528
545
  }
529
- async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries = 5, chunkTimeoutMs = 15e3) {
546
+ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries = 5, chunkTimeoutMs = 15e3, requestTimeoutMs = 12e4) {
530
547
  logger_default.log(
531
548
  id,
532
549
  "Calling OpenAI API with retries:",
@@ -544,10 +561,11 @@ async function callOpenAiWithRetries(id, openAiPayload, openAiConfig, retries =
544
561
  id,
545
562
  openAiPayload,
546
563
  openAiConfig,
547
- chunkTimeoutMs
564
+ chunkTimeoutMs,
565
+ requestTimeoutMs
548
566
  );
549
567
  } else {
550
- return callOpenAI(id, openAiPayload, openAiConfig);
568
+ return callOpenAI(id, openAiPayload, openAiConfig, requestTimeoutMs);
551
569
  }
552
570
  },
553
571
  {
@@ -683,7 +701,7 @@ async function prepareAnthropicPayload(_identifier, payload) {
683
701
  }
684
702
  return preparedPayload;
685
703
  }
686
- async function callAnthropic(id, payload, config) {
704
+ async function callAnthropic(id, payload, config, requestTimeoutMs = 12e4) {
687
705
  var _a, _b, _c;
688
706
  const anthropicMessages = jigAnthropicMessages(payload.messages);
689
707
  const tools = (_a = payload.functions) == null ? void 0 : _a.map((f) => ({
@@ -733,7 +751,7 @@ async function callAnthropic(id, payload, config) {
733
751
  "anthropic-version": "2023-06-01",
734
752
  "anthropic-beta": "tools-2024-04-04"
735
753
  },
736
- timeout: 6e4
754
+ timeout: requestTimeoutMs
737
755
  }
738
756
  );
739
757
  data = response.data;
@@ -803,11 +821,11 @@ ${text}` : text;
803
821
  usage
804
822
  };
805
823
  }
806
- async function callAnthropicWithRetries(id, payload, config, retries = 5) {
824
+ async function callAnthropicWithRetries(id, payload, config, retries = 5, requestTimeoutMs = 12e4) {
807
825
  return withRetries(
808
826
  id,
809
827
  "Anthropic",
810
- () => callAnthropic(id, payload, config),
828
+ () => callAnthropic(id, payload, config, requestTimeoutMs),
811
829
  {
812
830
  retries
813
831
  }
@@ -843,7 +861,6 @@ async function prepareGoogleAIPayload(_identifier, payload) {
843
861
  const preparedPayload = {
844
862
  model: payload.model,
845
863
  messages: [],
846
- requestTimeoutMs: payload.requestTimeoutMs,
847
864
  tools: payload.functions ? {
848
865
  functionDeclarations: payload.functions.map((fn) => ({
849
866
  name: fn.name,
@@ -928,8 +945,8 @@ async function prepareGoogleAIPayload(_identifier, payload) {
928
945
  }
929
946
  return preparedPayload;
930
947
  }
931
- async function callGoogleAI(id, payload) {
932
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
948
+ async function callGoogleAI(id, payload, requestTimeoutMs = 12e4) {
949
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
933
950
  const contents = jigGoogleMessages(payload.messages);
934
951
  const requestBody = {
935
952
  contents,
@@ -952,50 +969,47 @@ async function callGoogleAI(id, payload) {
952
969
  "content-type": "application/json",
953
970
  "x-goog-api-key": process.env.GEMINI_API_KEY
954
971
  },
955
- // Per-attempt timeout. Defaults to 60s; callers pass a larger value via
956
- // payload.requestTimeoutMs for slow, large generations (e.g. single-file
957
- // app codegen) so a long-but-valid response isn't cut short.
958
- timeout: (_a = payload.requestTimeoutMs) != null ? _a : 6e4
972
+ timeout: requestTimeoutMs
959
973
  }
960
974
  );
961
975
  response = httpResponse.data;
962
976
  } catch (err) {
963
- const apiError = (_c = (_b = err == null ? void 0 : err.response) == null ? void 0 : _b.data) == null ? void 0 : _c.error;
977
+ const apiError = (_b = (_a = err == null ? void 0 : err.response) == null ? void 0 : _a.data) == null ? void 0 : _b.error;
964
978
  const wrapped = new Error(
965
979
  (apiError == null ? void 0 : apiError.message) || (err == null ? void 0 : err.message) || "Google AI API request failed"
966
980
  );
967
- wrapped.status = (_e = apiError == null ? void 0 : apiError.status) != null ? _e : (_d = err == null ? void 0 : err.response) == null ? void 0 : _d.status;
981
+ wrapped.status = (_d = apiError == null ? void 0 : apiError.status) != null ? _d : (_c = err == null ? void 0 : err.response) == null ? void 0 : _c.status;
968
982
  wrapped.code = apiError == null ? void 0 : apiError.code;
969
983
  wrapped.details = apiError == null ? void 0 : apiError.details;
970
- wrapped.promptFeedback = (_g = (_f = err == null ? void 0 : err.response) == null ? void 0 : _f.data) == null ? void 0 : _g.promptFeedback;
984
+ wrapped.promptFeedback = (_f = (_e = err == null ? void 0 : err.response) == null ? void 0 : _e.data) == null ? void 0 : _f.promptFeedback;
971
985
  throw wrapped;
972
986
  }
973
987
  let text = "";
974
988
  const files = [];
975
989
  const reasoningParts = [];
976
990
  const functionCalls = [];
977
- for (const part of ((_j = (_i = (_h = response.candidates) == null ? void 0 : _h[0]) == null ? void 0 : _i.content) == null ? void 0 : _j.parts) || []) {
991
+ for (const part of ((_i = (_h = (_g = response.candidates) == null ? void 0 : _g[0]) == null ? void 0 : _h.content) == null ? void 0 : _i.parts) || []) {
978
992
  if (part.thought) {
979
993
  reasoningParts.push(part);
980
994
  continue;
981
995
  }
982
996
  if (part.functionCall) {
983
997
  functionCalls.push({
984
- id: (_k = part.functionCall.id) != null ? _k : `call_${functionCalls.length}`,
985
- name: (_l = part.functionCall.name) != null ? _l : "",
986
- arguments: (_m = part.functionCall.args) != null ? _m : {},
998
+ id: (_j = part.functionCall.id) != null ? _j : `call_${functionCalls.length}`,
999
+ name: (_k = part.functionCall.name) != null ? _k : "",
1000
+ arguments: (_l = part.functionCall.args) != null ? _l : {},
987
1001
  thoughtSignature: part.thoughtSignature
988
1002
  });
989
1003
  continue;
990
1004
  }
991
1005
  if (part.text)
992
1006
  text += part.text;
993
- if ((_n = part.inlineData) == null ? void 0 : _n.data) {
1007
+ if ((_m = part.inlineData) == null ? void 0 : _m.data) {
994
1008
  files.push({ mimeType: "image/png", data: part.inlineData.data });
995
1009
  }
996
1010
  }
997
1011
  if (!text && !functionCalls.length && !files.length) {
998
- const candidate = (_o = response.candidates) == null ? void 0 : _o[0];
1012
+ const candidate = (_n = response.candidates) == null ? void 0 : _n[0];
999
1013
  const finishReason = candidate == null ? void 0 : candidate.finishReason;
1000
1014
  logger_default.error(id, "Missing text & functions in Google AI API response:", {
1001
1015
  finishReason,
@@ -1030,10 +1044,10 @@ async function callGoogleAI(id, payload) {
1030
1044
  function_calls: functionCalls,
1031
1045
  reasoningDetails: reasoningParts.length ? reasoningParts : void 0,
1032
1046
  usage: response.usageMetadata ? {
1033
- prompt_tokens: (_p = response.usageMetadata.promptTokenCount) != null ? _p : 0,
1034
- completion_tokens: (_q = response.usageMetadata.candidatesTokenCount) != null ? _q : 0,
1035
- total_tokens: (_r = response.usageMetadata.totalTokenCount) != null ? _r : 0,
1036
- cached_tokens: (_s = response.usageMetadata.cachedContentTokenCount) != null ? _s : 0
1047
+ prompt_tokens: (_o = response.usageMetadata.promptTokenCount) != null ? _o : 0,
1048
+ completion_tokens: (_p = response.usageMetadata.candidatesTokenCount) != null ? _p : 0,
1049
+ total_tokens: (_q = response.usageMetadata.totalTokenCount) != null ? _q : 0,
1050
+ cached_tokens: (_r = response.usageMetadata.cachedContentTokenCount) != null ? _r : 0
1037
1051
  } : null
1038
1052
  };
1039
1053
  }
@@ -1054,9 +1068,9 @@ function removeImagesFromGooglePayload(payload) {
1054
1068
  }
1055
1069
  return removedImages;
1056
1070
  }
1057
- async function callGoogleAIWithRetries(id, payload, retries = 5) {
1071
+ async function callGoogleAIWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1058
1072
  let hasTriedWithoutImages = false;
1059
- return withRetries(id, "Google AI", () => callGoogleAI(id, payload), {
1073
+ return withRetries(id, "Google AI", () => callGoogleAI(id, payload, requestTimeoutMs), {
1060
1074
  retries,
1061
1075
  onError: (error2, attempt) => {
1062
1076
  var _a, _b;
@@ -1183,7 +1197,7 @@ function prepareGroqPayload(payload) {
1183
1197
  temperature: payload.temperature
1184
1198
  };
1185
1199
  }
1186
- async function callGroq(id, payload) {
1200
+ async function callGroq(id, payload, requestTimeoutMs = 12e4) {
1187
1201
  var _a, _b, _c, _d, _e, _f, _g;
1188
1202
  const response = await axios.post(
1189
1203
  "https://api.groq.com/openai/v1/chat/completions",
@@ -1192,7 +1206,8 @@ async function callGroq(id, payload) {
1192
1206
  headers: {
1193
1207
  "content-type": "application/json",
1194
1208
  Authorization: `Bearer ${process.env.GROQ_API_KEY}`
1195
- }
1209
+ },
1210
+ timeout: requestTimeoutMs
1196
1211
  }
1197
1212
  );
1198
1213
  if (response.data.error) {
@@ -1240,8 +1255,10 @@ async function callGroq(id, payload) {
1240
1255
  } : null
1241
1256
  };
1242
1257
  }
1243
- async function callGroqWithRetries(id, payload, retries = 5) {
1244
- return withRetries(id, "Groq", () => callGroq(id, payload), { retries });
1258
+ async function callGroqWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1259
+ return withRetries(id, "Groq", () => callGroq(id, payload, requestTimeoutMs), {
1260
+ retries
1261
+ });
1245
1262
  }
1246
1263
  function prepareOpenRouterPayload(payload) {
1247
1264
  var _a;
@@ -1257,7 +1274,7 @@ function prepareOpenRouterPayload(payload) {
1257
1274
  provider: payload.provider
1258
1275
  };
1259
1276
  }
1260
- async function callOpenRouter(id, payload) {
1277
+ async function callOpenRouter(id, payload, requestTimeoutMs = 12e4) {
1261
1278
  var _a, _b, _c, _d, _e, _f, _g, _h;
1262
1279
  const response = await axios.post(
1263
1280
  "https://openrouter.ai/api/v1/chat/completions",
@@ -1266,7 +1283,8 @@ async function callOpenRouter(id, payload) {
1266
1283
  headers: {
1267
1284
  "content-type": "application/json",
1268
1285
  Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`
1269
- }
1286
+ },
1287
+ timeout: requestTimeoutMs
1270
1288
  }
1271
1289
  );
1272
1290
  if (response.data.error) {
@@ -1315,8 +1333,13 @@ async function callOpenRouter(id, payload) {
1315
1333
  } : null
1316
1334
  };
1317
1335
  }
1318
- async function callOpenRouterWithRetries(id, payload, retries = 5) {
1319
- return withRetries(id, "OpenRouter", () => callOpenRouter(id, payload), { retries });
1336
+ async function callOpenRouterWithRetries(id, payload, retries = 5, requestTimeoutMs = 12e4) {
1337
+ return withRetries(
1338
+ id,
1339
+ "OpenRouter",
1340
+ () => callOpenRouter(id, payload, requestTimeoutMs),
1341
+ { retries }
1342
+ );
1320
1343
  }
1321
1344
  var VALID_PROVIDERS = ["openai", "anthropic", "google", "groq", "openrouter"];
1322
1345
  var ENUM_PROVIDER_MAP = [
@@ -1356,16 +1379,19 @@ function parseModelString(model) {
1356
1379
  );
1357
1380
  }
1358
1381
  async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeoutMs = 15e3) {
1382
+ var _a;
1359
1383
  try {
1360
1384
  const { provider, modelId } = parseModelString(aiPayload.model);
1361
1385
  const routingPayload = { ...aiPayload, model: modelId };
1386
+ const requestTimeoutMs = (_a = aiPayload.requestTimeoutMs) != null ? _a : 12e4;
1362
1387
  switch (provider) {
1363
1388
  case "anthropic":
1364
1389
  return await callAnthropicWithRetries(
1365
1390
  id,
1366
1391
  await prepareAnthropicPayload(id, routingPayload),
1367
1392
  aiConfig,
1368
- retries
1393
+ retries,
1394
+ requestTimeoutMs
1369
1395
  );
1370
1396
  case "openai":
1371
1397
  return await callOpenAiWithRetries(
@@ -1373,25 +1399,29 @@ async function callWithRetries(id, aiPayload, aiConfig, retries = 5, chunkTimeou
1373
1399
  await prepareOpenAIPayload(id, routingPayload),
1374
1400
  aiConfig,
1375
1401
  retries,
1376
- chunkTimeoutMs
1402
+ chunkTimeoutMs,
1403
+ requestTimeoutMs
1377
1404
  );
1378
1405
  case "groq":
1379
1406
  return await callGroqWithRetries(
1380
1407
  id,
1381
1408
  prepareGroqPayload(routingPayload),
1382
- retries
1409
+ retries,
1410
+ requestTimeoutMs
1383
1411
  );
1384
1412
  case "google":
1385
1413
  return await callGoogleAIWithRetries(
1386
1414
  id,
1387
1415
  await prepareGoogleAIPayload(id, routingPayload),
1388
- retries
1416
+ retries,
1417
+ requestTimeoutMs
1389
1418
  );
1390
1419
  case "openrouter":
1391
1420
  return await callOpenRouterWithRetries(
1392
1421
  id,
1393
1422
  prepareOpenRouterPayload(routingPayload),
1394
- retries
1423
+ retries,
1424
+ requestTimeoutMs
1395
1425
  );
1396
1426
  }
1397
1427
  } catch (error2) {