convex-durable-agents 0.2.3 → 0.2.4

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 (70) hide show
  1. package/README.md +81 -7
  2. package/dist/client/api.d.ts.map +1 -1
  3. package/dist/client/api.js +23 -4
  4. package/dist/client/api.js.map +1 -1
  5. package/dist/client/handler.d.ts +20 -0
  6. package/dist/client/handler.d.ts.map +1 -1
  7. package/dist/client/handler.js +239 -117
  8. package/dist/client/handler.js.map +1 -1
  9. package/dist/client/streamer.js +1 -1
  10. package/dist/client/streamer.js.map +1 -1
  11. package/dist/client/tools.d.ts +17 -0
  12. package/dist/client/tools.d.ts.map +1 -1
  13. package/dist/client/tools.js +16 -0
  14. package/dist/client/tools.js.map +1 -1
  15. package/dist/client/types.d.ts +75 -1
  16. package/dist/client/types.d.ts.map +1 -1
  17. package/dist/client/types.js +11 -0
  18. package/dist/client/types.js.map +1 -1
  19. package/dist/component/_generated/component.d.ts +89 -0
  20. package/dist/component/_generated/component.d.ts.map +1 -1
  21. package/dist/component/agent.d.ts.map +1 -1
  22. package/dist/component/agent.js +21 -2
  23. package/dist/component/agent.js.map +1 -1
  24. package/dist/component/schema.d.ts +70 -2
  25. package/dist/component/schema.d.ts.map +1 -1
  26. package/dist/component/schema.js +21 -0
  27. package/dist/component/schema.js.map +1 -1
  28. package/dist/component/streams.js +2 -2
  29. package/dist/component/streams.js.map +1 -1
  30. package/dist/component/threads.d.ts +92 -2
  31. package/dist/component/threads.d.ts.map +1 -1
  32. package/dist/component/threads.js +83 -2
  33. package/dist/component/threads.js.map +1 -1
  34. package/dist/component/tool_calls.d.ts +54 -3
  35. package/dist/component/tool_calls.d.ts.map +1 -1
  36. package/dist/component/tool_calls.js +345 -35
  37. package/dist/component/tool_calls.js.map +1 -1
  38. package/dist/utils/logger.d.ts.map +1 -0
  39. package/dist/utils/logger.js.map +1 -0
  40. package/dist/utils/retry.d.ts +69 -0
  41. package/dist/utils/retry.d.ts.map +1 -0
  42. package/dist/utils/retry.js +404 -0
  43. package/dist/utils/retry.js.map +1 -0
  44. package/dist/utils/streaming.d.ts +4 -0
  45. package/dist/utils/streaming.d.ts.map +1 -0
  46. package/dist/utils/streaming.js +4 -0
  47. package/dist/utils/streaming.js.map +1 -0
  48. package/package.json +1 -1
  49. package/src/client/api.ts +24 -4
  50. package/src/client/handler.ts +308 -133
  51. package/src/client/streamer.ts +1 -1
  52. package/src/client/tools.ts +43 -1
  53. package/src/client/types.ts +60 -0
  54. package/src/component/_generated/component.ts +103 -0
  55. package/src/component/agent.ts +24 -2
  56. package/src/component/schema.ts +22 -0
  57. package/src/component/streams.ts +2 -2
  58. package/src/component/threads.ts +92 -3
  59. package/src/component/tool_calls.ts +421 -44
  60. package/src/utils/retry.ts +528 -0
  61. package/src/{streaming.ts → utils/streaming.ts} +2 -3
  62. package/dist/logger.d.ts.map +0 -1
  63. package/dist/logger.js.map +0 -1
  64. package/dist/streaming.d.ts +0 -3
  65. package/dist/streaming.d.ts.map +0 -1
  66. package/dist/streaming.js +0 -4
  67. package/dist/streaming.js.map +0 -1
  68. /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
  69. /package/dist/{logger.js → utils/logger.js} +0 -0
  70. /package/src/{logger.ts → utils/logger.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;aACW,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;IAExC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAM5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG,KAAK,CAAC;AAE5B,MAAM,OAAO,MAAM;IACW;IAA5B,YAA4B,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IAE5C,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACtD,CAAC;CACF"}
@@ -0,0 +1,69 @@
1
+ import type { ActionCtx, RetryBackoffConfig } from "../client/types.js";
2
+ export type RetryErrorKind = "network" | "rate_limited" | "provider_5xx" | "context_window_exceeded" | "insufficient_credits" | "invalid_request" | "auth" | "unknown";
3
+ export type RetryErrorSignal = {
4
+ name?: string;
5
+ code?: string;
6
+ status?: number;
7
+ statusCode?: number;
8
+ isRetryable?: boolean;
9
+ retryErrorReason?: "maxRetriesExceeded" | "errorNotRetryable" | "abort";
10
+ responseHeaders?: Record<string, string>;
11
+ responseBody?: string;
12
+ providerCode?: string;
13
+ providerType?: string;
14
+ };
15
+ export type RetryErrorClassification = {
16
+ kind: RetryErrorKind;
17
+ retryable: boolean;
18
+ requiresExplicitHandling: boolean;
19
+ signal: RetryErrorSignal;
20
+ };
21
+ export type RetryDecision = {
22
+ action: "retry";
23
+ delayMs?: number;
24
+ reason?: string;
25
+ } | {
26
+ action: "fail";
27
+ kind?: RetryErrorKind;
28
+ reason?: string;
29
+ requiresExplicitHandling?: boolean;
30
+ };
31
+ export type RetryContext = {
32
+ threadId: string;
33
+ streamId: string;
34
+ attempt: number;
35
+ maxAttempts: number;
36
+ toolCallsScheduled: number;
37
+ streamPartCount: number;
38
+ error: unknown;
39
+ normalizedError: string;
40
+ defaultClassification: RetryErrorClassification;
41
+ defaultDecision: RetryDecision;
42
+ };
43
+ export type RetryOptions = {
44
+ enabled?: boolean;
45
+ maxAttempts?: number;
46
+ backoff?: RetryBackoffConfig;
47
+ retryAfterToolCalls?: boolean;
48
+ classify?: (ctx: ActionCtx, input: RetryContext) => RetryDecision | Promise<RetryDecision>;
49
+ };
50
+ export type ToolErrorInfo = {
51
+ message: string;
52
+ name?: string;
53
+ code?: string;
54
+ status?: number;
55
+ statusCode?: number;
56
+ causeMessage?: string;
57
+ };
58
+ export declare const DEFAULT_RETRY_MAX_ATTEMPTS = 3;
59
+ export declare const DEFAULT_RETRY_BACKOFF: RetryBackoffConfig;
60
+ export declare function clampDelayMs(delayMs: number): number;
61
+ export declare function computeBackoffDelayMs(attempt: number, backoff: RetryBackoffConfig | undefined): number;
62
+ export declare function normalizeErrorMessage(error: unknown): string;
63
+ export declare function extractRetryErrorSignal(error: unknown): RetryErrorSignal;
64
+ export declare function extractRetryAfterDelayMs(signal: RetryErrorSignal): number | undefined;
65
+ export declare function classifyRetryErrorDefault(error: unknown): RetryErrorClassification;
66
+ export declare function extractToolErrorInfo(error: unknown): ToolErrorInfo;
67
+ export declare function isRetryableToolErrorDefault(error: ToolErrorInfo | string): boolean;
68
+ export declare function isRetryableDecision(value: unknown): boolean;
69
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,404 @@
1
+ export const DEFAULT_RETRY_MAX_ATTEMPTS = 3;
2
+ export const DEFAULT_RETRY_BACKOFF = {
3
+ strategy: "exponential",
4
+ initialDelayMs: 250,
5
+ multiplier: 2,
6
+ maxDelayMs: 4000,
7
+ jitter: true,
8
+ };
9
+ const CONTEXT_OVERFLOW_PATTERNS = [
10
+ /prompt is too long/i,
11
+ /input is too long for requested model/i,
12
+ /exceeds the context window/i,
13
+ /input token count.*exceeds the maximum/i,
14
+ /maximum prompt length is \d+/i,
15
+ /reduce the length of the messages/i,
16
+ /maximum context length is \d+ tokens/i,
17
+ /exceeds the limit of \d+/i,
18
+ /exceeds the available context size/i,
19
+ /greater than the context length/i,
20
+ /context window exceeds limit/i,
21
+ /exceeded model token limit/i,
22
+ /context[_ ]length[_ ]exceeded/i,
23
+ /^4(00|13)\s*(status code)?\s*\(no body\)/i,
24
+ ];
25
+ const INSUFFICIENT_CREDITS_PATTERNS = [
26
+ /insufficient[_ ]quota/i,
27
+ /out of credits/i,
28
+ /quota exceeded/i,
29
+ /credit balance/i,
30
+ /freeusagelimiterror/i,
31
+ /usage limit reached/i,
32
+ ];
33
+ const AUTH_PATTERNS = [/unauthorized/i, /forbidden/i, /invalid api key/i, /authentication/i];
34
+ const RATE_LIMIT_PATTERNS = [/too many requests/i, /rate.?limit/i, /resource.?exhausted/i];
35
+ const INVALID_REQUEST_PATTERNS = [/invalid request/i, /invalid argument/i, /validation error/i, /invalid prompt/i];
36
+ const NETWORK_PATTERNS = [
37
+ /network/i,
38
+ /econnreset/i,
39
+ /econnrefused/i,
40
+ /etimedout/i,
41
+ /ehostunreach/i,
42
+ /connection reset/i,
43
+ /connection refused/i,
44
+ /fetch failed/i,
45
+ /socket hang up/i,
46
+ /upstream.?connect/i,
47
+ /other.?side.?closed/i,
48
+ /cannot connect to api/i,
49
+ /(?:connection|stream|socket)\s+terminated/i,
50
+ ];
51
+ const NETWORK_CODES = new Set([
52
+ "ECONNRESET",
53
+ "ECONNREFUSED",
54
+ "ETIMEDOUT",
55
+ "EHOSTUNREACH",
56
+ "EPIPE",
57
+ "ENOTFOUND",
58
+ "CONNECTIONREFUSED",
59
+ "CONNECTIONCLOSED",
60
+ "FAILEDTOOPENSOCKET",
61
+ ]);
62
+ const CONTEXT_OVERFLOW_CODES = new Set([
63
+ "context_length_exceeded",
64
+ "context_window_exceeded",
65
+ "prompt_too_long",
66
+ "token_limit_exceeded",
67
+ ]);
68
+ const INSUFFICIENT_CREDITS_CODES = new Set([
69
+ "insufficient_quota",
70
+ "usage_limit_reached",
71
+ "usage_not_included",
72
+ "credit_balance_too_low",
73
+ "quota_exceeded",
74
+ ]);
75
+ const RATE_LIMIT_CODES = new Set(["rate_limit_exceeded", "too_many_requests", "resource_exhausted"]);
76
+ const AUTH_CODES = new Set(["invalid_api_key", "authentication_error", "unauthorized", "forbidden"]);
77
+ const INVALID_REQUEST_CODES = new Set(["invalid_request_error", "invalid_prompt", "bad_request"]);
78
+ function asRecord(value) {
79
+ if (typeof value !== "object" || value === null) {
80
+ return undefined;
81
+ }
82
+ return value;
83
+ }
84
+ function asString(value) {
85
+ return typeof value === "string" ? value : undefined;
86
+ }
87
+ function asNumber(value) {
88
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
89
+ }
90
+ function parseStatusCodeFromMessage(message) {
91
+ const patterns = [/status(?: code)?[:=\s]+(\d{3})/i, /\b(\d{3})\s*(?:status code)/i, /^\s*(\d{3})\b/];
92
+ for (const pattern of patterns) {
93
+ const match = message.match(pattern);
94
+ if (!match?.[1])
95
+ continue;
96
+ const status = Number.parseInt(match[1], 10);
97
+ if (!Number.isNaN(status))
98
+ return status;
99
+ }
100
+ return undefined;
101
+ }
102
+ function parseJsonRecord(value) {
103
+ if (typeof value === "string") {
104
+ try {
105
+ const parsed = JSON.parse(value);
106
+ return asRecord(parsed);
107
+ }
108
+ catch {
109
+ return undefined;
110
+ }
111
+ }
112
+ return asRecord(value);
113
+ }
114
+ function normalizeHeaderRecord(value) {
115
+ const record = asRecord(value);
116
+ if (!record) {
117
+ return undefined;
118
+ }
119
+ const normalized = {};
120
+ for (const [key, headerValue] of Object.entries(record)) {
121
+ if (typeof headerValue === "string") {
122
+ normalized[key.toLowerCase()] = headerValue;
123
+ }
124
+ else if (typeof headerValue === "number" || typeof headerValue === "boolean") {
125
+ normalized[key.toLowerCase()] = String(headerValue);
126
+ }
127
+ }
128
+ return Object.keys(normalized).length > 0 ? normalized : undefined;
129
+ }
130
+ function parseRetryErrorReason(value) {
131
+ if (value === "maxRetriesExceeded" || value === "errorNotRetryable" || value === "abort") {
132
+ return value;
133
+ }
134
+ return undefined;
135
+ }
136
+ function getNestedErrorFields(payload) {
137
+ const nestedError = asRecord(payload.error);
138
+ const code = asString(nestedError?.code) ?? asString(payload.code);
139
+ const type = asString(nestedError?.type) ?? asString(payload.type);
140
+ return { code, type };
141
+ }
142
+ function includesAnyPattern(message, patterns) {
143
+ return patterns.some((pattern) => pattern.test(message));
144
+ }
145
+ export function clampDelayMs(delayMs) {
146
+ if (!Number.isFinite(delayMs) || delayMs < 0) {
147
+ return 0;
148
+ }
149
+ return Math.floor(delayMs);
150
+ }
151
+ export function computeBackoffDelayMs(attempt, backoff) {
152
+ const policy = backoff ?? DEFAULT_RETRY_BACKOFF;
153
+ if ("delayMs" in policy) {
154
+ const delayMs = clampDelayMs(policy.delayMs);
155
+ if (!policy.jitter)
156
+ return delayMs;
157
+ return Math.floor(Math.random() * (delayMs + 1));
158
+ }
159
+ const initialDelayMs = clampDelayMs(policy.initialDelayMs);
160
+ const multiplier = Number.isFinite(policy.multiplier ?? 2) ? (policy.multiplier ?? 2) : 2;
161
+ const unbounded = initialDelayMs * multiplier ** Math.max(0, attempt - 1);
162
+ const maxDelayMs = policy.maxDelayMs == null ? unbounded : clampDelayMs(policy.maxDelayMs);
163
+ const delayMs = Math.min(unbounded, maxDelayMs);
164
+ if (!policy.jitter)
165
+ return delayMs;
166
+ return Math.floor(Math.random() * (delayMs + 1));
167
+ }
168
+ export function normalizeErrorMessage(error) {
169
+ const errorMessage = error instanceof Error ? error.message : String(error);
170
+ return errorMessage || "Unknown error";
171
+ }
172
+ export function extractRetryErrorSignal(error) {
173
+ const signal = {};
174
+ const queue = [error];
175
+ const seen = new Set();
176
+ let inspected = 0;
177
+ while (queue.length > 0 && inspected < 16) {
178
+ const current = queue.shift();
179
+ inspected += 1;
180
+ if (!current)
181
+ continue;
182
+ if (typeof current === "object") {
183
+ if (seen.has(current))
184
+ continue;
185
+ seen.add(current);
186
+ }
187
+ const record = asRecord(current);
188
+ if (!record)
189
+ continue;
190
+ signal.name ??= asString(record.name);
191
+ signal.code ??= asString(record.code);
192
+ signal.status ??= asNumber(record.status);
193
+ signal.statusCode ??= asNumber(record.statusCode);
194
+ signal.responseBody ??= asString(record.responseBody);
195
+ signal.responseHeaders ??= normalizeHeaderRecord(record.responseHeaders);
196
+ signal.retryErrorReason ??= parseRetryErrorReason(record.reason);
197
+ if (typeof record.isRetryable === "boolean" && signal.isRetryable == null) {
198
+ signal.isRetryable = record.isRetryable;
199
+ }
200
+ const dataPayload = parseJsonRecord(record.data);
201
+ if (dataPayload) {
202
+ const nested = getNestedErrorFields(dataPayload);
203
+ signal.providerCode ??= nested.code;
204
+ signal.providerType ??= nested.type;
205
+ }
206
+ const bodyPayload = parseJsonRecord(signal.responseBody);
207
+ if (bodyPayload) {
208
+ const nested = getNestedErrorFields(bodyPayload);
209
+ signal.providerCode ??= nested.code;
210
+ signal.providerType ??= nested.type;
211
+ }
212
+ if ("cause" in record)
213
+ queue.push(record.cause);
214
+ if ("lastError" in record)
215
+ queue.push(record.lastError);
216
+ if (Array.isArray(record.errors)) {
217
+ queue.push(...record.errors.slice(0, 4));
218
+ }
219
+ }
220
+ if (signal.providerCode)
221
+ signal.providerCode = signal.providerCode.toLowerCase();
222
+ if (signal.providerType)
223
+ signal.providerType = signal.providerType.toLowerCase();
224
+ if (signal.code)
225
+ signal.code = signal.code.toUpperCase();
226
+ if (signal.name)
227
+ signal.name = signal.name.toLowerCase();
228
+ return signal;
229
+ }
230
+ export function extractRetryAfterDelayMs(signal) {
231
+ const headers = signal.responseHeaders;
232
+ if (!headers)
233
+ return undefined;
234
+ const retryAfterMs = headers["retry-after-ms"];
235
+ if (retryAfterMs) {
236
+ const parsedMs = Number.parseFloat(retryAfterMs);
237
+ if (Number.isFinite(parsedMs) && parsedMs >= 0 && parsedMs <= 60_000) {
238
+ return Math.ceil(parsedMs);
239
+ }
240
+ }
241
+ const retryAfter = headers["retry-after"];
242
+ if (retryAfter) {
243
+ const parsedSeconds = Number.parseFloat(retryAfter);
244
+ if (Number.isFinite(parsedSeconds)) {
245
+ const delayMs = parsedSeconds * 1000;
246
+ if (delayMs >= 0 && delayMs <= 60_000) {
247
+ return Math.ceil(delayMs);
248
+ }
249
+ }
250
+ const retryAfterDate = Date.parse(retryAfter);
251
+ if (!Number.isNaN(retryAfterDate)) {
252
+ const delayMs = retryAfterDate - Date.now();
253
+ if (delayMs >= 0 && delayMs <= 60_000) {
254
+ return Math.ceil(delayMs);
255
+ }
256
+ }
257
+ }
258
+ return undefined;
259
+ }
260
+ export function classifyRetryErrorDefault(error) {
261
+ const signal = extractRetryErrorSignal(error);
262
+ const message = normalizeErrorMessage(error);
263
+ const msg = message.toLowerCase();
264
+ const status = signal.statusCode ?? signal.status ?? parseStatusCodeFromMessage(msg);
265
+ const providerCode = signal.providerCode;
266
+ const isAbortError = signal.retryErrorReason === "abort" ||
267
+ signal.name === "aborterror" ||
268
+ signal.name === "responseaborted" ||
269
+ signal.name === "timeouterror" ||
270
+ msg.includes("request was aborted");
271
+ if (isAbortError) {
272
+ return { kind: "unknown", retryable: false, requiresExplicitHandling: false, signal };
273
+ }
274
+ if (providerCode && CONTEXT_OVERFLOW_CODES.has(providerCode)) {
275
+ return { kind: "context_window_exceeded", retryable: false, requiresExplicitHandling: true, signal };
276
+ }
277
+ if (includesAnyPattern(msg, CONTEXT_OVERFLOW_PATTERNS)) {
278
+ return { kind: "context_window_exceeded", retryable: false, requiresExplicitHandling: true, signal };
279
+ }
280
+ if (providerCode && INSUFFICIENT_CREDITS_CODES.has(providerCode)) {
281
+ return { kind: "insufficient_credits", retryable: false, requiresExplicitHandling: true, signal };
282
+ }
283
+ if (includesAnyPattern(msg, INSUFFICIENT_CREDITS_PATTERNS)) {
284
+ return { kind: "insufficient_credits", retryable: false, requiresExplicitHandling: true, signal };
285
+ }
286
+ if (status === 401 ||
287
+ status === 403 ||
288
+ (providerCode && AUTH_CODES.has(providerCode)) ||
289
+ includesAnyPattern(msg, AUTH_PATTERNS)) {
290
+ return { kind: "auth", retryable: false, requiresExplicitHandling: true, signal };
291
+ }
292
+ if (status === 429 ||
293
+ (providerCode && RATE_LIMIT_CODES.has(providerCode)) ||
294
+ includesAnyPattern(msg, RATE_LIMIT_PATTERNS)) {
295
+ return { kind: "rate_limited", retryable: true, requiresExplicitHandling: false, signal };
296
+ }
297
+ if (status != null && status >= 500 && status <= 599) {
298
+ return { kind: "provider_5xx", retryable: true, requiresExplicitHandling: false, signal };
299
+ }
300
+ if (status === 408 || status === 409) {
301
+ return { kind: "network", retryable: true, requiresExplicitHandling: false, signal };
302
+ }
303
+ if ((signal.code && NETWORK_CODES.has(signal.code)) ||
304
+ includesAnyPattern(msg, NETWORK_PATTERNS) ||
305
+ (signal.isRetryable === true && status == null)) {
306
+ return { kind: "network", retryable: true, requiresExplicitHandling: false, signal };
307
+ }
308
+ if (status === 400 ||
309
+ status === 422 ||
310
+ (providerCode && INVALID_REQUEST_CODES.has(providerCode)) ||
311
+ includesAnyPattern(msg, INVALID_REQUEST_PATTERNS)) {
312
+ return { kind: "invalid_request", retryable: false, requiresExplicitHandling: true, signal };
313
+ }
314
+ return { kind: "unknown", retryable: false, requiresExplicitHandling: false, signal };
315
+ }
316
+ export function extractToolErrorInfo(error) {
317
+ const message = error instanceof Error ? error.message : String(error);
318
+ const info = {
319
+ message: message || "Unknown error",
320
+ };
321
+ const root = asRecord(error);
322
+ if (root) {
323
+ info.name = asString(root.name);
324
+ info.code = asString(root.code) ?? asString(root.errno);
325
+ info.status = asNumber(root.status);
326
+ info.statusCode = asNumber(root.statusCode);
327
+ const cause = asRecord(root.cause);
328
+ if (cause) {
329
+ info.causeMessage = asString(cause.message);
330
+ if (!info.code)
331
+ info.code = asString(cause.code) ?? asString(cause.errno);
332
+ if (info.status == null)
333
+ info.status = asNumber(cause.status);
334
+ if (info.statusCode == null)
335
+ info.statusCode = asNumber(cause.statusCode);
336
+ }
337
+ }
338
+ if (info.status == null && info.statusCode == null) {
339
+ const parsedStatus = parseStatusCodeFromMessage(info.message);
340
+ if (parsedStatus != null) {
341
+ info.statusCode = parsedStatus;
342
+ }
343
+ }
344
+ if (info.code)
345
+ info.code = info.code.toUpperCase();
346
+ return info;
347
+ }
348
+ export function isRetryableToolErrorDefault(error) {
349
+ const info = typeof error === "string" ? { message: error } : error;
350
+ const msg = info.message.toLowerCase();
351
+ const status = info.statusCode ?? info.status ?? parseStatusCodeFromMessage(msg);
352
+ const code = info.code?.toUpperCase();
353
+ const hasExplicit5xxStatus = /\bstatus(?:\s+code)?\s*[:=]?\s*5\d{2}\b/.test(msg);
354
+ if (status === 429 || status === 408 || status === 409 || (status != null && status >= 500 && status <= 599)) {
355
+ return true;
356
+ }
357
+ if (status === 401 || status === 403 || (status != null && status >= 400 && status <= 499)) {
358
+ return false;
359
+ }
360
+ if (code === "ECONNRESET" ||
361
+ code === "ECONNREFUSED" ||
362
+ code === "ETIMEDOUT" ||
363
+ code === "EHOSTUNREACH" ||
364
+ code === "EPIPE" ||
365
+ code === "ENOTFOUND" ||
366
+ code === "CONNECTIONREFUSED" ||
367
+ code === "CONNECTIONCLOSED" ||
368
+ code === "FAILEDTOOPENSOCKET") {
369
+ return true;
370
+ }
371
+ if (msg.includes("rate limit") ||
372
+ msg.includes("too many requests") ||
373
+ msg.includes("status: 429") ||
374
+ hasExplicit5xxStatus ||
375
+ msg.includes("internal server error") ||
376
+ msg.includes("bad gateway")) {
377
+ return true;
378
+ }
379
+ if (msg.includes("network") ||
380
+ msg.includes("econnreset") ||
381
+ msg.includes("econnrefused") ||
382
+ msg.includes("etimedout") ||
383
+ msg.includes("ehostunreach") ||
384
+ msg.includes("connection reset") ||
385
+ msg.includes("connection refused") ||
386
+ msg.includes("fetch failed") ||
387
+ msg.includes("socket hang up") ||
388
+ msg.includes("upstream connect") ||
389
+ msg.includes("other side closed") ||
390
+ msg.includes("cannot connect to api")) {
391
+ return true;
392
+ }
393
+ return false;
394
+ }
395
+ export function isRetryableDecision(value) {
396
+ if (value === true)
397
+ return true;
398
+ if (typeof value !== "object" || value === null)
399
+ return false;
400
+ if (!("retryable" in value))
401
+ return false;
402
+ return value.retryable === true;
403
+ }
404
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const STREAM_HEARTBEAT_INTERVAL_MS = 30000;
2
+ export declare const STREAM_HEARTBEAT_JITTER_MS = 10000;
3
+ export declare const STREAM_LIVENESS_THRESHOLD_MS: number;
4
+ //# sourceMappingURL=streaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../../src/utils/streaming.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,QAAS,CAAC;AACnD,eAAO,MAAM,0BAA0B,QAAS,CAAC;AACjD,eAAO,MAAM,4BAA4B,QAA4D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export const STREAM_HEARTBEAT_INTERVAL_MS = 30_000;
2
+ export const STREAM_HEARTBEAT_JITTER_MS = 10_000;
3
+ export const STREAM_LIVENESS_THRESHOLD_MS = STREAM_HEARTBEAT_INTERVAL_MS + STREAM_HEARTBEAT_JITTER_MS;
4
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../../src/utils/streaming.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,4BAA4B,GAAG,MAAM,CAAC;AACnD,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AACjD,MAAM,CAAC,MAAM,4BAA4B,GAAG,4BAA4B,GAAG,0BAA0B,CAAC"}
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "bugs": {
7
7
  "url": "https://github.com/ziegfried/convex-durable-agents/issues"
8
8
  },
9
- "version": "0.2.3",
9
+ "version": "0.2.4",
10
10
  "license": "Apache-2.0",
11
11
  "keywords": [
12
12
  "convex",
package/src/client/api.ts CHANGED
@@ -36,6 +36,9 @@ async function checkThreadIsIdle(component: ComponentApi, ctx: MutationCtx, thre
36
36
  if (!thread) {
37
37
  throw new Error(`Thread ${threadId} not found`);
38
38
  }
39
+ if (thread.retryState) {
40
+ throw new Error(`Thread ${threadId} has retry pending; stop the thread to interrupt the retry flow`);
41
+ }
39
42
  switch (thread.status) {
40
43
  case "awaiting_tool_results":
41
44
  case "streaming":
@@ -43,6 +46,16 @@ async function checkThreadIsIdle(component: ComponentApi, ctx: MutationCtx, thre
43
46
  }
44
47
  }
45
48
 
49
+ async function assertNoRetryPending(component: ComponentApi, ctx: MutationCtx, threadId: Id<"threads">): Promise<void> {
50
+ const thread = await ctx.runQuery(component.threads.get, { threadId });
51
+ if (!thread) {
52
+ throw new Error(`Thread ${threadId} not found`);
53
+ }
54
+ if (thread.retryState) {
55
+ throw new Error(`Thread ${threadId} has retry pending; stop the thread to interrupt the retry flow`);
56
+ }
57
+ }
58
+
46
59
  export type StreamArgs = { kind: "list" } | { kind: "deltas"; cursors: Array<{ streamId: string; cursor: number }> };
47
60
 
48
61
  export type StreamMessage = {
@@ -199,15 +212,17 @@ function createAgentApi(
199
212
  returns: v.null(),
200
213
  handler: async (ctx, args) => {
201
214
  if (authorize) await authorize(ctx, args.threadId);
215
+ const threadId = args.threadId as Id<"threads">;
216
+ await assertNoRetryPending(component, ctx, threadId);
202
217
  await ctx.runMutation(component.messages.add, {
203
- threadId: args.threadId,
218
+ threadId,
204
219
  msg: { role: "user", parts: [{ type: "text", text: args.prompt }] },
205
220
  });
206
221
  await ctx.runMutation(component.threads.resume, {
207
- threadId: args.threadId,
222
+ threadId,
208
223
  });
209
224
  await ctx.scheduler.runAfter(0, component.agent.continueStream, {
210
- threadId: args.threadId,
225
+ threadId,
211
226
  });
212
227
  return null;
213
228
  },
@@ -237,6 +252,7 @@ function createAgentApi(
237
252
  handler: async (ctx, args) => {
238
253
  if (authorize) await authorize(ctx, args.threadId);
239
254
  const threadId = args.threadId as Id<"threads">;
255
+ await assertNoRetryPending(component, ctx, threadId);
240
256
  if (args.prompt) {
241
257
  await ctx.runMutation(component.messages.add, {
242
258
  threadId,
@@ -262,10 +278,14 @@ function createAgentApi(
262
278
  returns: v.null(),
263
279
  handler: async (ctx, args) => {
264
280
  if (authorize) await authorize(ctx, args.threadId);
281
+ const threadId = args.threadId as Id<"threads">;
265
282
  await ctx.runMutation(component.threads.setStopSignal, {
266
- threadId: args.threadId as Id<"threads">,
283
+ threadId,
267
284
  stopSignal: true,
268
285
  });
286
+ await ctx.runMutation(component.threads.clearRetryState, {
287
+ threadId,
288
+ });
269
289
  return null;
270
290
  },
271
291
  }),