@prestyj/agent 5.11.0 → 5.13.0

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.cjs CHANGED
@@ -83,7 +83,13 @@ function isContextOverflow(err) {
83
83
  if (overflowStatus === 402) return false;
84
84
  if (isBillingError(err)) return false;
85
85
  const msg = err.message.toLowerCase();
86
- return msg.includes("prompt is too long") || msg.includes("prompt too long") || msg.includes("input is too long") || msg.includes("context_length_exceeded") || msg.includes("context_window_exceeded") || msg.includes("maximum context length") || msg.includes("exceeds model context window") || msg.includes("exceeds the context window") || msg.includes("content_too_large") || msg.includes("request_too_large") || msg.includes("reduce the length") || msg.includes("please shorten") || msg.includes("token") && msg.includes("exceed");
86
+ if (msg.includes("prompt is too long") || msg.includes("prompt too long") || msg.includes("input is too long") || msg.includes("context_length_exceeded") || msg.includes("context_window_exceeded") || msg.includes("maximum context length") || msg.includes("exceeds model context window") || msg.includes("exceeds the context window") || msg.includes("content_too_large") || msg.includes("request_too_large") || msg.includes("reduce the length") || msg.includes("please shorten")) {
87
+ return true;
88
+ }
89
+ const rateLimited = overflowStatus === 429 || msg.includes("rate limit") || msg.includes("rate_limit") || msg.includes("too many requests");
90
+ const perUnitTime = msg.includes("per min") || msg.includes("/min") || msg.includes("per minute") || msg.includes("per hour") || msg.includes("per day") || msg.includes("tpm") || msg.includes("rpm");
91
+ if (rateLimited && perUnitTime) return false;
92
+ return msg.includes("token") && msg.includes("exceed");
87
93
  }
88
94
  function parseOverflowNumber(value) {
89
95
  return Number(value.replace(/[,_\s]/g, ""));
@@ -196,6 +202,17 @@ function isMalformedStream(err) {
196
202
  const msg = err.message;
197
203
  return /\bin JSON at position \d+/i.test(msg);
198
204
  }
205
+ var TIMEOUT_NAMES = /* @__PURE__ */ new Set(["TimeoutError", "ConnectTimeoutError", "HeadersTimeoutError"]);
206
+ var TIMEOUT_MESSAGES = [
207
+ /^request timed out\.?$/i,
208
+ /\brequest to [\w .-]+ timed out\b/i,
209
+ /\b(?:connection|socket|headers|stream) timed out\b/i
210
+ ];
211
+ function isBareTimeout(e) {
212
+ if (typeof e.name === "string" && TIMEOUT_NAMES.has(e.name)) return true;
213
+ if (typeof e.message !== "string") return false;
214
+ return TIMEOUT_MESSAGES.some((re) => re.test(e.message));
215
+ }
199
216
  function isTransportFailure(err) {
200
217
  const codes = /* @__PURE__ */ new Set([
201
218
  "ECONNRESET",
@@ -232,6 +249,8 @@ function isTransportFailure(err) {
232
249
  if (typeof e.message === "string") {
233
250
  for (const re of messages) if (re.test(e.message)) return true;
234
251
  }
252
+ const clientError = typeof e.status === "number" && e.status >= 400 && e.status < 500;
253
+ if (!clientError && isBareTimeout(e)) return true;
235
254
  cur = e.cause;
236
255
  }
237
256
  return false;
@@ -457,6 +476,21 @@ async function* agentLoop(messages, options) {
457
476
  diag("stream_call", { nonStreaming: useNonStreamingFallback });
458
477
  streamCallStart = Date.now();
459
478
  providerAttemptStartedAt = streamCallStart;
479
+ let liveApiKey = options.apiKey;
480
+ let liveAccountId = options.accountId;
481
+ let liveProjectId = options.projectId;
482
+ if (options.resolveCredentials) {
483
+ try {
484
+ const fresh = await options.resolveCredentials();
485
+ liveApiKey = fresh.apiKey;
486
+ if (fresh.accountId !== void 0) liveAccountId = fresh.accountId;
487
+ if (fresh.projectId !== void 0) liveProjectId = fresh.projectId;
488
+ } catch (credErr) {
489
+ diag("credential_refresh_failed", {
490
+ error: (credErr instanceof Error ? credErr.message : String(credErr)).slice(0, 200)
491
+ });
492
+ }
493
+ }
460
494
  const result = (0, import_ai.stream)({
461
495
  provider: options.provider,
462
496
  model: options.model,
@@ -468,12 +502,12 @@ async function* agentLoop(messages, options) {
468
502
  maxTokens: options.maxTokens,
469
503
  temperature: options.temperature,
470
504
  thinking: options.thinking,
471
- apiKey: options.apiKey,
505
+ apiKey: liveApiKey,
472
506
  baseUrl: options.baseUrl,
473
507
  signal: streamController.signal,
474
- accountId: options.accountId,
508
+ accountId: liveAccountId,
475
509
  transportSessionId: options.transportSessionId,
476
- projectId: options.projectId,
510
+ projectId: liveProjectId,
477
511
  cacheRetention: options.cacheRetention,
478
512
  promptCacheKey: options.promptCacheKey,
479
513
  serviceTier: options.serviceTier,
@@ -917,6 +951,7 @@ async function* agentLoop(messages, options) {
917
951
  continue;
918
952
  }
919
953
  }
954
+ const emptyExhausted = !hasActionableContent;
920
955
  emptyResponseRetries = 0;
921
956
  useNonStreamingFallback = false;
922
957
  totalUsage.inputTokens += response.usage.inputTokens;
@@ -930,9 +965,11 @@ async function* agentLoop(messages, options) {
930
965
  if (response.usage.cacheWrite) {
931
966
  totalUsage.cacheWrite = (totalUsage.cacheWrite ?? 0) + response.usage.cacheWrite;
932
967
  }
933
- messages.push(response.message);
934
- latestProviderUsage = response.usage;
935
- usageAnchorIndex = messages.length - 1;
968
+ if (!emptyExhausted) {
969
+ messages.push(response.message);
970
+ latestProviderUsage = response.usage;
971
+ usageAnchorIndex = messages.length - 1;
972
+ }
936
973
  const completedAt = Date.now();
937
974
  const outputTokensPerSecond = providerDurationMs > 0 && response.usage.outputTokens > 0 ? response.usage.outputTokens / (providerDurationMs / 1e3) : void 0;
938
975
  const timing = {
@@ -964,8 +1001,15 @@ async function* agentLoop(messages, options) {
964
1001
  }
965
1002
  consecutivePauses = 0;
966
1003
  const allToolCalls = extractToolCalls(response.message.content);
967
- if (response.stopReason !== "tool_use" && allToolCalls.length === 0) {
968
- if (response.stopReason === "max_tokens") {
1004
+ if (emptyExhausted || response.stopReason !== "tool_use" && allToolCalls.length === 0) {
1005
+ if (emptyExhausted) {
1006
+ diag("empty_response_exhausted", {
1007
+ provider: options.provider,
1008
+ model: options.model,
1009
+ stopReason: response.stopReason
1010
+ });
1011
+ yield { type: "truncated", reason: "empty_response", continued: false };
1012
+ } else if (response.stopReason === "max_tokens") {
969
1013
  if (maxTokensContinuations < MAX_OUTPUT_CONTINUATIONS) {
970
1014
  maxTokensContinuations++;
971
1015
  diag("max_tokens_continuation", {
@@ -1187,6 +1231,7 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1187
1231
  let resultContent;
1188
1232
  let details;
1189
1233
  let isError = false;
1234
+ let invalidArgAttempt;
1190
1235
  const tool = options.toolMap.get(toolCall.name);
1191
1236
  if (!tool) {
1192
1237
  resultContent = `Unknown tool: ${toolCall.name}`;
@@ -1224,6 +1269,7 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1224
1269
  const failureKey = `${toolCall.name}:${prettyError}`;
1225
1270
  const failureCount = (options.invalidToolArgumentCounts.get(failureKey) ?? 0) + 1;
1226
1271
  options.invalidToolArgumentCounts.set(failureKey, failureCount);
1272
+ invalidArgAttempt = failureCount;
1227
1273
  resultContent = `Invalid arguments for tool \`${toolCall.name}\`:
1228
1274
  ` + prettyError + "\nRe-issue the call with each field as the correct type.";
1229
1275
  if (failureCount >= 3) {
@@ -1254,7 +1300,8 @@ async function executeSingleToolCall(toolCall, options, pushEvent) {
1254
1300
  result: toolResultPreview(resultContent),
1255
1301
  details,
1256
1302
  isError,
1257
- durationMs
1303
+ durationMs,
1304
+ ...invalidArgAttempt === void 0 ? {} : { invalidArgAttempt }
1258
1305
  });
1259
1306
  return { toolCallId: toolCall.id, content: resultContent, isError };
1260
1307
  }