@lleverage-ai/agent-sdk 0.0.1
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/LICENSE +21 -0
- package/README.md +2321 -0
- package/dist/agent.d.ts +52 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +2122 -0
- package/dist/agent.js.map +1 -0
- package/dist/backend.d.ts +378 -0
- package/dist/backend.d.ts.map +1 -0
- package/dist/backend.js +71 -0
- package/dist/backend.js.map +1 -0
- package/dist/backends/composite.d.ts +258 -0
- package/dist/backends/composite.d.ts.map +1 -0
- package/dist/backends/composite.js +437 -0
- package/dist/backends/composite.js.map +1 -0
- package/dist/backends/filesystem.d.ts +268 -0
- package/dist/backends/filesystem.d.ts.map +1 -0
- package/dist/backends/filesystem.js +623 -0
- package/dist/backends/filesystem.js.map +1 -0
- package/dist/backends/index.d.ts +14 -0
- package/dist/backends/index.d.ts.map +1 -0
- package/dist/backends/index.js +14 -0
- package/dist/backends/index.js.map +1 -0
- package/dist/backends/persistent.d.ts +312 -0
- package/dist/backends/persistent.d.ts.map +1 -0
- package/dist/backends/persistent.js +519 -0
- package/dist/backends/persistent.js.map +1 -0
- package/dist/backends/sandbox.d.ts +315 -0
- package/dist/backends/sandbox.d.ts.map +1 -0
- package/dist/backends/sandbox.js +490 -0
- package/dist/backends/sandbox.js.map +1 -0
- package/dist/backends/state.d.ts +225 -0
- package/dist/backends/state.d.ts.map +1 -0
- package/dist/backends/state.js +396 -0
- package/dist/backends/state.js.map +1 -0
- package/dist/checkpointer/file-saver.d.ts +182 -0
- package/dist/checkpointer/file-saver.d.ts.map +1 -0
- package/dist/checkpointer/file-saver.js +298 -0
- package/dist/checkpointer/file-saver.js.map +1 -0
- package/dist/checkpointer/index.d.ts +40 -0
- package/dist/checkpointer/index.d.ts.map +1 -0
- package/dist/checkpointer/index.js +40 -0
- package/dist/checkpointer/index.js.map +1 -0
- package/dist/checkpointer/kv-saver.d.ts +142 -0
- package/dist/checkpointer/kv-saver.d.ts.map +1 -0
- package/dist/checkpointer/kv-saver.js +176 -0
- package/dist/checkpointer/kv-saver.js.map +1 -0
- package/dist/checkpointer/memory-saver.d.ts +158 -0
- package/dist/checkpointer/memory-saver.d.ts.map +1 -0
- package/dist/checkpointer/memory-saver.js +222 -0
- package/dist/checkpointer/memory-saver.js.map +1 -0
- package/dist/checkpointer/types.d.ts +353 -0
- package/dist/checkpointer/types.d.ts.map +1 -0
- package/dist/checkpointer/types.js +159 -0
- package/dist/checkpointer/types.js.map +1 -0
- package/dist/context-manager.d.ts +627 -0
- package/dist/context-manager.d.ts.map +1 -0
- package/dist/context-manager.js +1039 -0
- package/dist/context-manager.js.map +1 -0
- package/dist/context.d.ts +57 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +76 -0
- package/dist/context.js.map +1 -0
- package/dist/errors/index.d.ts +611 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +1023 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/generation-helpers.d.ts +126 -0
- package/dist/generation-helpers.d.ts.map +1 -0
- package/dist/generation-helpers.js +181 -0
- package/dist/generation-helpers.js.map +1 -0
- package/dist/hooks/audit.d.ts +210 -0
- package/dist/hooks/audit.d.ts.map +1 -0
- package/dist/hooks/audit.js +305 -0
- package/dist/hooks/audit.js.map +1 -0
- package/dist/hooks/cache.d.ts +180 -0
- package/dist/hooks/cache.d.ts.map +1 -0
- package/dist/hooks/cache.js +273 -0
- package/dist/hooks/cache.js.map +1 -0
- package/dist/hooks/guardrails.d.ts +145 -0
- package/dist/hooks/guardrails.d.ts.map +1 -0
- package/dist/hooks/guardrails.js +326 -0
- package/dist/hooks/guardrails.js.map +1 -0
- package/dist/hooks/index.d.ts +18 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +32 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/logging.d.ts +193 -0
- package/dist/hooks/logging.d.ts.map +1 -0
- package/dist/hooks/logging.js +345 -0
- package/dist/hooks/logging.js.map +1 -0
- package/dist/hooks/parallel-guardrails.d.ts +268 -0
- package/dist/hooks/parallel-guardrails.d.ts.map +1 -0
- package/dist/hooks/parallel-guardrails.js +416 -0
- package/dist/hooks/parallel-guardrails.js.map +1 -0
- package/dist/hooks/rate-limit.d.ts +305 -0
- package/dist/hooks/rate-limit.d.ts.map +1 -0
- package/dist/hooks/rate-limit.js +372 -0
- package/dist/hooks/rate-limit.js.map +1 -0
- package/dist/hooks/retry.d.ts +144 -0
- package/dist/hooks/retry.d.ts.map +1 -0
- package/dist/hooks/retry.js +210 -0
- package/dist/hooks/retry.js.map +1 -0
- package/dist/hooks/secrets.d.ts +174 -0
- package/dist/hooks/secrets.d.ts.map +1 -0
- package/dist/hooks/secrets.js +306 -0
- package/dist/hooks/secrets.js.map +1 -0
- package/dist/hooks.d.ts +229 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +352 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +97 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +182 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/env.d.ts +25 -0
- package/dist/mcp/env.d.ts.map +1 -0
- package/dist/mcp/env.js +18 -0
- package/dist/mcp/env.js.map +1 -0
- package/dist/mcp/index.d.ts +16 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +17 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +184 -0
- package/dist/mcp/manager.d.ts.map +1 -0
- package/dist/mcp/manager.js +446 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/types.d.ts +58 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +7 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/mcp/validation.d.ts +119 -0
- package/dist/mcp/validation.d.ts.map +1 -0
- package/dist/mcp/validation.js +407 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/mcp/virtual-server.d.ts +78 -0
- package/dist/mcp/virtual-server.d.ts.map +1 -0
- package/dist/mcp/virtual-server.js +137 -0
- package/dist/mcp/virtual-server.js.map +1 -0
- package/dist/memory/filesystem-store.d.ts +217 -0
- package/dist/memory/filesystem-store.d.ts.map +1 -0
- package/dist/memory/filesystem-store.js +343 -0
- package/dist/memory/filesystem-store.js.map +1 -0
- package/dist/memory/index.d.ts +46 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +46 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/loader.d.ts +396 -0
- package/dist/memory/loader.d.ts.map +1 -0
- package/dist/memory/loader.js +419 -0
- package/dist/memory/loader.js.map +1 -0
- package/dist/memory/permissions.d.ts +282 -0
- package/dist/memory/permissions.d.ts.map +1 -0
- package/dist/memory/permissions.js +297 -0
- package/dist/memory/permissions.js.map +1 -0
- package/dist/memory/rules.d.ts +249 -0
- package/dist/memory/rules.d.ts.map +1 -0
- package/dist/memory/rules.js +362 -0
- package/dist/memory/rules.js.map +1 -0
- package/dist/memory/store.d.ts +286 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +263 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/middleware/apply.d.ts +73 -0
- package/dist/middleware/apply.d.ts.map +1 -0
- package/dist/middleware/apply.js +219 -0
- package/dist/middleware/apply.js.map +1 -0
- package/dist/middleware/context.d.ts +33 -0
- package/dist/middleware/context.d.ts.map +1 -0
- package/dist/middleware/context.js +176 -0
- package/dist/middleware/context.js.map +1 -0
- package/dist/middleware/index.d.ts +31 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +32 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/logging.d.ts +137 -0
- package/dist/middleware/logging.d.ts.map +1 -0
- package/dist/middleware/logging.js +374 -0
- package/dist/middleware/logging.js.map +1 -0
- package/dist/middleware/types.d.ts +183 -0
- package/dist/middleware/types.d.ts.map +1 -0
- package/dist/middleware/types.js +11 -0
- package/dist/middleware/types.js.map +1 -0
- package/dist/observability/events.d.ts +183 -0
- package/dist/observability/events.d.ts.map +1 -0
- package/dist/observability/events.js +305 -0
- package/dist/observability/events.js.map +1 -0
- package/dist/observability/index.d.ts +55 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +87 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/logger.d.ts +318 -0
- package/dist/observability/logger.d.ts.map +1 -0
- package/dist/observability/logger.js +436 -0
- package/dist/observability/logger.js.map +1 -0
- package/dist/observability/metrics.d.ts +341 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +490 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/preset.d.ts +161 -0
- package/dist/observability/preset.d.ts.map +1 -0
- package/dist/observability/preset.js +133 -0
- package/dist/observability/preset.js.map +1 -0
- package/dist/observability/streaming.d.ts +113 -0
- package/dist/observability/streaming.d.ts.map +1 -0
- package/dist/observability/streaming.js +114 -0
- package/dist/observability/streaming.js.map +1 -0
- package/dist/observability/tracing.d.ts +378 -0
- package/dist/observability/tracing.d.ts.map +1 -0
- package/dist/observability/tracing.js +539 -0
- package/dist/observability/tracing.js.map +1 -0
- package/dist/plugins.d.ts +55 -0
- package/dist/plugins.d.ts.map +1 -0
- package/dist/plugins.js +63 -0
- package/dist/plugins.js.map +1 -0
- package/dist/presets/index.d.ts +7 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +7 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/production.d.ts +262 -0
- package/dist/presets/production.d.ts.map +1 -0
- package/dist/presets/production.js +295 -0
- package/dist/presets/production.js.map +1 -0
- package/dist/security/index.d.ts +179 -0
- package/dist/security/index.d.ts.map +1 -0
- package/dist/security/index.js +323 -0
- package/dist/security/index.js.map +1 -0
- package/dist/subagents/advanced.d.ts +413 -0
- package/dist/subagents/advanced.d.ts.map +1 -0
- package/dist/subagents/advanced.js +396 -0
- package/dist/subagents/advanced.js.map +1 -0
- package/dist/subagents/index.d.ts +14 -0
- package/dist/subagents/index.d.ts.map +1 -0
- package/dist/subagents/index.js +15 -0
- package/dist/subagents/index.js.map +1 -0
- package/dist/subagents.d.ts +73 -0
- package/dist/subagents.d.ts.map +1 -0
- package/dist/subagents.js +213 -0
- package/dist/subagents.js.map +1 -0
- package/dist/task-store/file-store.d.ts +76 -0
- package/dist/task-store/file-store.d.ts.map +1 -0
- package/dist/task-store/file-store.js +190 -0
- package/dist/task-store/file-store.js.map +1 -0
- package/dist/task-store/index.d.ts +11 -0
- package/dist/task-store/index.d.ts.map +1 -0
- package/dist/task-store/index.js +10 -0
- package/dist/task-store/index.js.map +1 -0
- package/dist/task-store/kv-store.d.ts +140 -0
- package/dist/task-store/kv-store.d.ts.map +1 -0
- package/dist/task-store/kv-store.js +169 -0
- package/dist/task-store/kv-store.js.map +1 -0
- package/dist/task-store/memory-store.d.ts +66 -0
- package/dist/task-store/memory-store.d.ts.map +1 -0
- package/dist/task-store/memory-store.js +125 -0
- package/dist/task-store/memory-store.js.map +1 -0
- package/dist/task-store/types.d.ts +235 -0
- package/dist/task-store/types.d.ts.map +1 -0
- package/dist/task-store/types.js +110 -0
- package/dist/task-store/types.js.map +1 -0
- package/dist/testing/assertions.d.ts +401 -0
- package/dist/testing/assertions.d.ts.map +1 -0
- package/dist/testing/assertions.js +630 -0
- package/dist/testing/assertions.js.map +1 -0
- package/dist/testing/index.d.ts +343 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +360 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-agent.d.ts +214 -0
- package/dist/testing/mock-agent.d.ts.map +1 -0
- package/dist/testing/mock-agent.js +448 -0
- package/dist/testing/mock-agent.js.map +1 -0
- package/dist/testing/recorder.d.ts +288 -0
- package/dist/testing/recorder.d.ts.map +1 -0
- package/dist/testing/recorder.js +499 -0
- package/dist/testing/recorder.js.map +1 -0
- package/dist/tools/execute.d.ts +104 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +191 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/factory.d.ts +260 -0
- package/dist/tools/factory.d.ts.map +1 -0
- package/dist/tools/factory.js +241 -0
- package/dist/tools/factory.js.map +1 -0
- package/dist/tools/filesystem.d.ts +215 -0
- package/dist/tools/filesystem.d.ts.map +1 -0
- package/dist/tools/filesystem.js +311 -0
- package/dist/tools/filesystem.js.map +1 -0
- package/dist/tools/index.d.ts +33 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +33 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search.d.ts +59 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +94 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/skills.d.ts +354 -0
- package/dist/tools/skills.d.ts.map +1 -0
- package/dist/tools/skills.js +413 -0
- package/dist/tools/skills.js.map +1 -0
- package/dist/tools/task.d.ts +272 -0
- package/dist/tools/task.d.ts.map +1 -0
- package/dist/tools/task.js +521 -0
- package/dist/tools/task.js.map +1 -0
- package/dist/tools/todos.d.ts +131 -0
- package/dist/tools/todos.d.ts.map +1 -0
- package/dist/tools/todos.js +120 -0
- package/dist/tools/todos.js.map +1 -0
- package/dist/tools/tool-registry.d.ts +424 -0
- package/dist/tools/tool-registry.d.ts.map +1 -0
- package/dist/tools/tool-registry.js +607 -0
- package/dist/tools/tool-registry.js.map +1 -0
- package/dist/tools/user-interaction.d.ts +116 -0
- package/dist/tools/user-interaction.d.ts.map +1 -0
- package/dist/tools/user-interaction.js +147 -0
- package/dist/tools/user-interaction.js.map +1 -0
- package/dist/tools/utils.d.ts +124 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +189 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools.d.ts +74 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +73 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +2421 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +55 -0
- package/dist/types.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,1023 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error Handling System.
|
|
3
|
+
*
|
|
4
|
+
* Provides typed error classes, utilities, and patterns for robust error handling
|
|
5
|
+
* across the agent SDK.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Base error class for all agent SDK errors.
|
|
11
|
+
*
|
|
12
|
+
* Provides consistent structure with error codes, user-friendly messages,
|
|
13
|
+
* and metadata support.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* throw new AgentError("Something went wrong", {
|
|
18
|
+
* code: "TOOL_ERROR",
|
|
19
|
+
* userMessage: "The operation failed. Please try again.",
|
|
20
|
+
* cause: originalError,
|
|
21
|
+
* metadata: { toolName: "read_file", path: "/path/to/file" },
|
|
22
|
+
* });
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @category Errors
|
|
26
|
+
*/
|
|
27
|
+
export class AgentError extends Error {
|
|
28
|
+
/**
|
|
29
|
+
* Error code for categorization.
|
|
30
|
+
*/
|
|
31
|
+
code;
|
|
32
|
+
/**
|
|
33
|
+
* User-friendly error message suitable for display.
|
|
34
|
+
*/
|
|
35
|
+
userMessage;
|
|
36
|
+
/**
|
|
37
|
+
* Severity level of the error.
|
|
38
|
+
*/
|
|
39
|
+
severity;
|
|
40
|
+
/**
|
|
41
|
+
* Whether this error can be retried.
|
|
42
|
+
*/
|
|
43
|
+
retryable;
|
|
44
|
+
/**
|
|
45
|
+
* Suggested delay before retry in milliseconds.
|
|
46
|
+
*/
|
|
47
|
+
retryAfterMs;
|
|
48
|
+
/**
|
|
49
|
+
* Additional metadata about the error.
|
|
50
|
+
*/
|
|
51
|
+
metadata;
|
|
52
|
+
/**
|
|
53
|
+
* The original error that caused this error.
|
|
54
|
+
*/
|
|
55
|
+
cause;
|
|
56
|
+
/**
|
|
57
|
+
* Timestamp when the error occurred.
|
|
58
|
+
*/
|
|
59
|
+
timestamp;
|
|
60
|
+
constructor(message, options = {}) {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = "AgentError";
|
|
63
|
+
this.code = options.code ?? "AGENT_ERROR";
|
|
64
|
+
this.userMessage = options.userMessage ?? this.generateUserMessage(message);
|
|
65
|
+
this.severity = options.severity ?? "error";
|
|
66
|
+
this.retryable = options.retryable ?? false;
|
|
67
|
+
this.retryAfterMs = options.retryAfterMs;
|
|
68
|
+
this.metadata = options.metadata ?? {};
|
|
69
|
+
this.cause = options.cause;
|
|
70
|
+
this.timestamp = Date.now();
|
|
71
|
+
// Maintain proper stack trace
|
|
72
|
+
if (Error.captureStackTrace) {
|
|
73
|
+
Error.captureStackTrace(this, this.constructor);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Generate a user-friendly message from the technical message.
|
|
78
|
+
*/
|
|
79
|
+
generateUserMessage(message) {
|
|
80
|
+
// Remove technical details for user display
|
|
81
|
+
return message
|
|
82
|
+
.replace(/\b[A-Z_]+Error\b/g, "An error")
|
|
83
|
+
.replace(/\{[^}]+\}/g, "")
|
|
84
|
+
.replace(/\s+/g, " ")
|
|
85
|
+
.trim();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get a structured representation of the error for logging.
|
|
89
|
+
*/
|
|
90
|
+
toJSON() {
|
|
91
|
+
return {
|
|
92
|
+
name: this.name,
|
|
93
|
+
code: this.code,
|
|
94
|
+
message: this.message,
|
|
95
|
+
userMessage: this.userMessage,
|
|
96
|
+
severity: this.severity,
|
|
97
|
+
retryable: this.retryable,
|
|
98
|
+
retryAfterMs: this.retryAfterMs,
|
|
99
|
+
metadata: this.metadata,
|
|
100
|
+
cause: this.cause?.message,
|
|
101
|
+
timestamp: this.timestamp,
|
|
102
|
+
stack: this.stack,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Check if an error is a specific type of AgentError.
|
|
107
|
+
*/
|
|
108
|
+
static is(error) {
|
|
109
|
+
return error instanceof AgentError;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Check if an error has a specific code.
|
|
113
|
+
*/
|
|
114
|
+
static hasCode(error, code) {
|
|
115
|
+
return AgentError.is(error) && error.code === code;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// Specific Error Classes
|
|
120
|
+
// =============================================================================
|
|
121
|
+
/**
|
|
122
|
+
* Error thrown when agent configuration is invalid.
|
|
123
|
+
*
|
|
124
|
+
* @category Errors
|
|
125
|
+
*/
|
|
126
|
+
export class ConfigurationError extends AgentError {
|
|
127
|
+
constructor(message, options = {}) {
|
|
128
|
+
super(message, {
|
|
129
|
+
code: "CONFIGURATION_ERROR",
|
|
130
|
+
severity: "fatal",
|
|
131
|
+
userMessage: `Configuration error: ${options.configKey ? `Invalid value for '${options.configKey}'` : message}`,
|
|
132
|
+
metadata: {
|
|
133
|
+
configKey: options.configKey,
|
|
134
|
+
expectedType: options.expectedType,
|
|
135
|
+
actualValue: options.actualValue,
|
|
136
|
+
...options.metadata,
|
|
137
|
+
},
|
|
138
|
+
cause: options.cause,
|
|
139
|
+
});
|
|
140
|
+
this.name = "ConfigurationError";
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Error thrown when input validation fails.
|
|
145
|
+
*
|
|
146
|
+
* @category Errors
|
|
147
|
+
*/
|
|
148
|
+
export class ValidationError extends AgentError {
|
|
149
|
+
/**
|
|
150
|
+
* Validation errors for specific fields.
|
|
151
|
+
*/
|
|
152
|
+
fieldErrors;
|
|
153
|
+
constructor(message, options = {}) {
|
|
154
|
+
super(message, {
|
|
155
|
+
code: "VALIDATION_ERROR",
|
|
156
|
+
severity: "error",
|
|
157
|
+
userMessage: "The provided input is invalid. Please check and try again.",
|
|
158
|
+
metadata: {
|
|
159
|
+
fieldErrors: options.fieldErrors,
|
|
160
|
+
...options.metadata,
|
|
161
|
+
},
|
|
162
|
+
cause: options.cause,
|
|
163
|
+
});
|
|
164
|
+
this.name = "ValidationError";
|
|
165
|
+
this.fieldErrors = options.fieldErrors ?? {};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get a formatted list of validation errors.
|
|
169
|
+
*/
|
|
170
|
+
getErrorList() {
|
|
171
|
+
const errors = [];
|
|
172
|
+
for (const [field, messages] of Object.entries(this.fieldErrors)) {
|
|
173
|
+
for (const msg of messages) {
|
|
174
|
+
errors.push(`${field}: ${msg}`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return errors;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Error thrown when a tool execution fails.
|
|
182
|
+
*
|
|
183
|
+
* @category Errors
|
|
184
|
+
*/
|
|
185
|
+
export class ToolExecutionError extends AgentError {
|
|
186
|
+
/**
|
|
187
|
+
* Name of the tool that failed.
|
|
188
|
+
*/
|
|
189
|
+
toolName;
|
|
190
|
+
/**
|
|
191
|
+
* Input that was passed to the tool.
|
|
192
|
+
*/
|
|
193
|
+
toolInput;
|
|
194
|
+
constructor(message, options) {
|
|
195
|
+
super(message, {
|
|
196
|
+
code: "TOOL_ERROR",
|
|
197
|
+
severity: "error",
|
|
198
|
+
userMessage: `The tool '${options.toolName}' encountered an error. Please try again or use a different approach.`,
|
|
199
|
+
retryable: true,
|
|
200
|
+
metadata: {
|
|
201
|
+
toolName: options.toolName,
|
|
202
|
+
toolInput: options.toolInput,
|
|
203
|
+
...options.metadata,
|
|
204
|
+
},
|
|
205
|
+
cause: options.cause,
|
|
206
|
+
});
|
|
207
|
+
this.name = "ToolExecutionError";
|
|
208
|
+
this.toolName = options.toolName;
|
|
209
|
+
this.toolInput = options.toolInput;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Error thrown when a tool execution is denied by a PreToolUse hook.
|
|
214
|
+
*
|
|
215
|
+
* @category Errors
|
|
216
|
+
*/
|
|
217
|
+
export class ToolPermissionDeniedError extends AgentError {
|
|
218
|
+
/**
|
|
219
|
+
* Name of the tool that was denied.
|
|
220
|
+
*/
|
|
221
|
+
toolName;
|
|
222
|
+
/**
|
|
223
|
+
* Input that was attempted.
|
|
224
|
+
*/
|
|
225
|
+
toolInput;
|
|
226
|
+
/**
|
|
227
|
+
* Reason provided by the hook (if any).
|
|
228
|
+
*/
|
|
229
|
+
reason;
|
|
230
|
+
constructor(message, options) {
|
|
231
|
+
super(message, {
|
|
232
|
+
code: "AUTHORIZATION_ERROR",
|
|
233
|
+
severity: "error",
|
|
234
|
+
userMessage: `Tool '${options.toolName}' was blocked: ${options.reason || "Permission denied"}`,
|
|
235
|
+
retryable: false,
|
|
236
|
+
metadata: {
|
|
237
|
+
toolName: options.toolName,
|
|
238
|
+
toolInput: options.toolInput,
|
|
239
|
+
reason: options.reason,
|
|
240
|
+
...options.metadata,
|
|
241
|
+
},
|
|
242
|
+
cause: options.cause,
|
|
243
|
+
});
|
|
244
|
+
this.name = "ToolPermissionDeniedError";
|
|
245
|
+
this.toolName = options.toolName;
|
|
246
|
+
this.toolInput = options.toolInput;
|
|
247
|
+
this.reason = options.reason;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Error thrown when a generation request is denied by a PreGenerate hook.
|
|
252
|
+
*
|
|
253
|
+
* @category Errors
|
|
254
|
+
*/
|
|
255
|
+
export class GeneratePermissionDeniedError extends AgentError {
|
|
256
|
+
/**
|
|
257
|
+
* Reason provided by the hook (if any).
|
|
258
|
+
*/
|
|
259
|
+
reason;
|
|
260
|
+
/**
|
|
261
|
+
* IDs of messages that caused the block (for client-side cleanup).
|
|
262
|
+
*/
|
|
263
|
+
blockedMessageIds;
|
|
264
|
+
constructor(message, options = {}) {
|
|
265
|
+
super(message, {
|
|
266
|
+
code: "AUTHORIZATION_ERROR",
|
|
267
|
+
severity: "error",
|
|
268
|
+
userMessage: options.reason || "Generation blocked by content policy",
|
|
269
|
+
retryable: false,
|
|
270
|
+
metadata: {
|
|
271
|
+
reason: options.reason,
|
|
272
|
+
blockedMessageIds: options.blockedMessageIds,
|
|
273
|
+
...options.metadata,
|
|
274
|
+
},
|
|
275
|
+
cause: options.cause,
|
|
276
|
+
});
|
|
277
|
+
this.name = "GeneratePermissionDeniedError";
|
|
278
|
+
this.reason = options.reason;
|
|
279
|
+
this.blockedMessageIds = options.blockedMessageIds;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Error thrown when the AI model fails or returns an error.
|
|
284
|
+
*
|
|
285
|
+
* @category Errors
|
|
286
|
+
*/
|
|
287
|
+
export class ModelError extends AgentError {
|
|
288
|
+
/**
|
|
289
|
+
* Model identifier that failed.
|
|
290
|
+
*/
|
|
291
|
+
modelId;
|
|
292
|
+
constructor(message, options = {}) {
|
|
293
|
+
const isRateLimit = options.statusCode === 429 || message.toLowerCase().includes("rate limit");
|
|
294
|
+
const isTimeout = message.toLowerCase().includes("timeout") || message.toLowerCase().includes("timed out");
|
|
295
|
+
super(message, {
|
|
296
|
+
code: isRateLimit ? "RATE_LIMIT_ERROR" : isTimeout ? "TIMEOUT_ERROR" : "MODEL_ERROR",
|
|
297
|
+
severity: "error",
|
|
298
|
+
userMessage: isRateLimit
|
|
299
|
+
? "The AI service is busy. Please wait a moment and try again."
|
|
300
|
+
: isTimeout
|
|
301
|
+
? "The request took too long. Please try again."
|
|
302
|
+
: "The AI service encountered an error. Please try again.",
|
|
303
|
+
retryable: isRateLimit || isTimeout,
|
|
304
|
+
retryAfterMs: isRateLimit ? 30000 : isTimeout ? 5000 : undefined,
|
|
305
|
+
metadata: {
|
|
306
|
+
modelId: options.modelId,
|
|
307
|
+
statusCode: options.statusCode,
|
|
308
|
+
...options.metadata,
|
|
309
|
+
},
|
|
310
|
+
cause: options.cause,
|
|
311
|
+
});
|
|
312
|
+
this.name = "ModelError";
|
|
313
|
+
this.modelId = options.modelId;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Error thrown when a network request fails.
|
|
318
|
+
*
|
|
319
|
+
* @category Errors
|
|
320
|
+
*/
|
|
321
|
+
export class NetworkError extends AgentError {
|
|
322
|
+
constructor(message, options = {}) {
|
|
323
|
+
super(message, {
|
|
324
|
+
code: "NETWORK_ERROR",
|
|
325
|
+
severity: "error",
|
|
326
|
+
userMessage: "A network error occurred. Please check your connection and try again.",
|
|
327
|
+
retryable: true,
|
|
328
|
+
retryAfterMs: 2000,
|
|
329
|
+
metadata: {
|
|
330
|
+
url: options.url,
|
|
331
|
+
statusCode: options.statusCode,
|
|
332
|
+
...options.metadata,
|
|
333
|
+
},
|
|
334
|
+
cause: options.cause,
|
|
335
|
+
});
|
|
336
|
+
this.name = "NetworkError";
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Error thrown when an operation times out.
|
|
341
|
+
*
|
|
342
|
+
* @category Errors
|
|
343
|
+
*/
|
|
344
|
+
export class TimeoutError extends AgentError {
|
|
345
|
+
/**
|
|
346
|
+
* Timeout duration in milliseconds.
|
|
347
|
+
*/
|
|
348
|
+
timeoutMs;
|
|
349
|
+
/**
|
|
350
|
+
* Operation that timed out.
|
|
351
|
+
*/
|
|
352
|
+
operation;
|
|
353
|
+
constructor(message, options) {
|
|
354
|
+
super(message, {
|
|
355
|
+
code: "TIMEOUT_ERROR",
|
|
356
|
+
severity: "error",
|
|
357
|
+
userMessage: `The operation '${options.operation}' took too long and was stopped.`,
|
|
358
|
+
retryable: true,
|
|
359
|
+
retryAfterMs: 1000,
|
|
360
|
+
metadata: {
|
|
361
|
+
timeoutMs: options.timeoutMs,
|
|
362
|
+
operation: options.operation,
|
|
363
|
+
...options.metadata,
|
|
364
|
+
},
|
|
365
|
+
cause: options.cause,
|
|
366
|
+
});
|
|
367
|
+
this.name = "TimeoutError";
|
|
368
|
+
this.timeoutMs = options.timeoutMs;
|
|
369
|
+
this.operation = options.operation;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Error thrown when rate limits are exceeded.
|
|
374
|
+
*
|
|
375
|
+
* @category Errors
|
|
376
|
+
*/
|
|
377
|
+
export class RateLimitError extends AgentError {
|
|
378
|
+
/**
|
|
379
|
+
* When to retry after (Date or ms).
|
|
380
|
+
*/
|
|
381
|
+
retryAfter;
|
|
382
|
+
constructor(message, options = {}) {
|
|
383
|
+
const retryMs = options.retryAfter instanceof Date
|
|
384
|
+
? options.retryAfter.getTime() - Date.now()
|
|
385
|
+
: (options.retryAfter ?? 60000);
|
|
386
|
+
super(message, {
|
|
387
|
+
code: "RATE_LIMIT_ERROR",
|
|
388
|
+
severity: "error",
|
|
389
|
+
userMessage: "Rate limit reached. Please wait a moment before trying again.",
|
|
390
|
+
retryable: true,
|
|
391
|
+
retryAfterMs: Math.max(retryMs, 1000),
|
|
392
|
+
metadata: {
|
|
393
|
+
retryAfter: options.retryAfter,
|
|
394
|
+
limit: options.limit,
|
|
395
|
+
remaining: options.remaining,
|
|
396
|
+
...options.metadata,
|
|
397
|
+
},
|
|
398
|
+
cause: options.cause,
|
|
399
|
+
});
|
|
400
|
+
this.name = "RateLimitError";
|
|
401
|
+
this.retryAfter = options.retryAfter;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Error thrown when authentication fails.
|
|
406
|
+
*
|
|
407
|
+
* @category Errors
|
|
408
|
+
*/
|
|
409
|
+
export class AuthenticationError extends AgentError {
|
|
410
|
+
constructor(message, options = {}) {
|
|
411
|
+
super(message, {
|
|
412
|
+
code: "AUTHENTICATION_ERROR",
|
|
413
|
+
severity: "fatal",
|
|
414
|
+
userMessage: "Authentication failed. Please check your credentials.",
|
|
415
|
+
retryable: false,
|
|
416
|
+
metadata: options.metadata,
|
|
417
|
+
cause: options.cause,
|
|
418
|
+
});
|
|
419
|
+
this.name = "AuthenticationError";
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Error thrown when authorization fails.
|
|
424
|
+
*
|
|
425
|
+
* @category Errors
|
|
426
|
+
*/
|
|
427
|
+
export class AuthorizationError extends AgentError {
|
|
428
|
+
constructor(message, options = {}) {
|
|
429
|
+
super(message, {
|
|
430
|
+
code: "AUTHORIZATION_ERROR",
|
|
431
|
+
severity: "error",
|
|
432
|
+
userMessage: "You don't have permission to perform this action.",
|
|
433
|
+
retryable: false,
|
|
434
|
+
metadata: {
|
|
435
|
+
resource: options.resource,
|
|
436
|
+
action: options.action,
|
|
437
|
+
...options.metadata,
|
|
438
|
+
},
|
|
439
|
+
cause: options.cause,
|
|
440
|
+
});
|
|
441
|
+
this.name = "AuthorizationError";
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Error thrown when checkpoint operations fail.
|
|
446
|
+
*
|
|
447
|
+
* @category Errors
|
|
448
|
+
*/
|
|
449
|
+
export class CheckpointError extends AgentError {
|
|
450
|
+
/**
|
|
451
|
+
* Thread ID associated with the checkpoint.
|
|
452
|
+
*/
|
|
453
|
+
threadId;
|
|
454
|
+
/**
|
|
455
|
+
* Operation that failed (save, load, delete, fork).
|
|
456
|
+
*/
|
|
457
|
+
operation;
|
|
458
|
+
constructor(message, options) {
|
|
459
|
+
super(message, {
|
|
460
|
+
code: "CHECKPOINT_ERROR",
|
|
461
|
+
severity: "error",
|
|
462
|
+
userMessage: `Failed to ${options.operation} session state. Your progress may not be saved.`,
|
|
463
|
+
retryable: options.operation === "save" || options.operation === "fork",
|
|
464
|
+
metadata: {
|
|
465
|
+
operation: options.operation,
|
|
466
|
+
threadId: options.threadId,
|
|
467
|
+
...options.metadata,
|
|
468
|
+
},
|
|
469
|
+
cause: options.cause,
|
|
470
|
+
});
|
|
471
|
+
this.name = "CheckpointError";
|
|
472
|
+
this.threadId = options.threadId;
|
|
473
|
+
this.operation = options.operation;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Error thrown when backend operations fail.
|
|
478
|
+
*
|
|
479
|
+
* @category Errors
|
|
480
|
+
*/
|
|
481
|
+
export class BackendError extends AgentError {
|
|
482
|
+
/**
|
|
483
|
+
* Backend operation that failed.
|
|
484
|
+
*/
|
|
485
|
+
operation;
|
|
486
|
+
/**
|
|
487
|
+
* Path involved in the operation.
|
|
488
|
+
*/
|
|
489
|
+
path;
|
|
490
|
+
constructor(message, options) {
|
|
491
|
+
super(message, {
|
|
492
|
+
code: "BACKEND_ERROR",
|
|
493
|
+
severity: "error",
|
|
494
|
+
userMessage: `Failed to ${options.operation}${options.path ? ` for '${options.path}'` : ""}. Please try again.`,
|
|
495
|
+
retryable: true,
|
|
496
|
+
metadata: {
|
|
497
|
+
operation: options.operation,
|
|
498
|
+
path: options.path,
|
|
499
|
+
...options.metadata,
|
|
500
|
+
},
|
|
501
|
+
cause: options.cause,
|
|
502
|
+
});
|
|
503
|
+
this.name = "BackendError";
|
|
504
|
+
this.operation = options.operation;
|
|
505
|
+
this.path = options.path;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Error thrown when context management fails.
|
|
510
|
+
*
|
|
511
|
+
* @category Errors
|
|
512
|
+
*/
|
|
513
|
+
export class ContextError extends AgentError {
|
|
514
|
+
constructor(message, options = {}) {
|
|
515
|
+
super(message, {
|
|
516
|
+
code: "CONTEXT_ERROR",
|
|
517
|
+
severity: "warning",
|
|
518
|
+
userMessage: "Context management encountered an issue. The conversation may be truncated.",
|
|
519
|
+
retryable: false,
|
|
520
|
+
metadata: {
|
|
521
|
+
operation: options.operation,
|
|
522
|
+
currentTokens: options.currentTokens,
|
|
523
|
+
maxTokens: options.maxTokens,
|
|
524
|
+
...options.metadata,
|
|
525
|
+
},
|
|
526
|
+
cause: options.cause,
|
|
527
|
+
});
|
|
528
|
+
this.name = "ContextError";
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Error thrown when subagent operations fail.
|
|
533
|
+
*
|
|
534
|
+
* @category Errors
|
|
535
|
+
*/
|
|
536
|
+
export class SubagentError extends AgentError {
|
|
537
|
+
/**
|
|
538
|
+
* Name of the subagent that failed.
|
|
539
|
+
*/
|
|
540
|
+
subagentName;
|
|
541
|
+
/**
|
|
542
|
+
* Task that was being executed.
|
|
543
|
+
*/
|
|
544
|
+
task;
|
|
545
|
+
constructor(message, options) {
|
|
546
|
+
super(message, {
|
|
547
|
+
code: "SUBAGENT_ERROR",
|
|
548
|
+
severity: "error",
|
|
549
|
+
userMessage: `The assistant '${options.subagentName}' encountered an error while working on your request.`,
|
|
550
|
+
retryable: true,
|
|
551
|
+
metadata: {
|
|
552
|
+
subagentName: options.subagentName,
|
|
553
|
+
task: options.task,
|
|
554
|
+
...options.metadata,
|
|
555
|
+
},
|
|
556
|
+
cause: options.cause,
|
|
557
|
+
});
|
|
558
|
+
this.name = "SubagentError";
|
|
559
|
+
this.subagentName = options.subagentName;
|
|
560
|
+
this.task = options.task;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* Error thrown when memory operations fail.
|
|
565
|
+
*
|
|
566
|
+
* @category Errors
|
|
567
|
+
*/
|
|
568
|
+
export class MemoryError extends AgentError {
|
|
569
|
+
/**
|
|
570
|
+
* Memory path that was being accessed.
|
|
571
|
+
*/
|
|
572
|
+
memoryPath;
|
|
573
|
+
/**
|
|
574
|
+
* Operation that failed.
|
|
575
|
+
*/
|
|
576
|
+
operation;
|
|
577
|
+
constructor(message, options) {
|
|
578
|
+
super(message, {
|
|
579
|
+
code: "MEMORY_ERROR",
|
|
580
|
+
severity: "warning",
|
|
581
|
+
userMessage: `Failed to ${options.operation} memory${options.memoryPath ? ` at '${options.memoryPath}'` : ""}.`,
|
|
582
|
+
retryable: options.operation !== "delete",
|
|
583
|
+
metadata: {
|
|
584
|
+
operation: options.operation,
|
|
585
|
+
memoryPath: options.memoryPath,
|
|
586
|
+
...options.metadata,
|
|
587
|
+
},
|
|
588
|
+
cause: options.cause,
|
|
589
|
+
});
|
|
590
|
+
this.name = "MemoryError";
|
|
591
|
+
this.memoryPath = options.memoryPath;
|
|
592
|
+
this.operation = options.operation;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Error thrown when an operation is aborted.
|
|
597
|
+
*
|
|
598
|
+
* @category Errors
|
|
599
|
+
*/
|
|
600
|
+
export class AbortError extends AgentError {
|
|
601
|
+
/**
|
|
602
|
+
* Reason for the abort.
|
|
603
|
+
*/
|
|
604
|
+
reason;
|
|
605
|
+
constructor(message = "Operation was aborted", options = {}) {
|
|
606
|
+
super(message, {
|
|
607
|
+
code: "ABORT_ERROR",
|
|
608
|
+
severity: "warning",
|
|
609
|
+
userMessage: options.reason ?? "The operation was cancelled.",
|
|
610
|
+
retryable: false,
|
|
611
|
+
metadata: {
|
|
612
|
+
reason: options.reason,
|
|
613
|
+
...options.metadata,
|
|
614
|
+
},
|
|
615
|
+
cause: options.cause,
|
|
616
|
+
});
|
|
617
|
+
this.name = "AbortError";
|
|
618
|
+
this.reason = options.reason;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Wrap any error as an AgentError.
|
|
623
|
+
*
|
|
624
|
+
* Preserves existing AgentErrors while wrapping other errors with additional context.
|
|
625
|
+
*
|
|
626
|
+
* @param error - The error to wrap
|
|
627
|
+
* @param message - Additional context message
|
|
628
|
+
* @param options - Options for the wrapped error
|
|
629
|
+
* @returns An AgentError instance
|
|
630
|
+
*
|
|
631
|
+
* @example
|
|
632
|
+
* ```typescript
|
|
633
|
+
* try {
|
|
634
|
+
* await riskyOperation();
|
|
635
|
+
* } catch (error) {
|
|
636
|
+
* throw wrapError(error, "Failed to perform risky operation", {
|
|
637
|
+
* code: "BACKEND_ERROR",
|
|
638
|
+
* metadata: { operation: "risky" },
|
|
639
|
+
* });
|
|
640
|
+
* }
|
|
641
|
+
* ```
|
|
642
|
+
*
|
|
643
|
+
* @category Errors
|
|
644
|
+
*/
|
|
645
|
+
export function wrapError(error, message, options = {}) {
|
|
646
|
+
// Already an AgentError - preserve it
|
|
647
|
+
if (AgentError.is(error)) {
|
|
648
|
+
return error;
|
|
649
|
+
}
|
|
650
|
+
// Wrap standard Error
|
|
651
|
+
if (error instanceof Error) {
|
|
652
|
+
return new AgentError(message, {
|
|
653
|
+
code: options.code ?? inferErrorCode(error),
|
|
654
|
+
userMessage: options.userMessage,
|
|
655
|
+
severity: options.severity,
|
|
656
|
+
retryable: options.retryable ?? isRetryable(error),
|
|
657
|
+
metadata: options.metadata,
|
|
658
|
+
cause: error,
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
// Wrap unknown error
|
|
662
|
+
return new AgentError(message, {
|
|
663
|
+
code: options.code ?? "UNKNOWN_ERROR",
|
|
664
|
+
userMessage: options.userMessage,
|
|
665
|
+
severity: options.severity,
|
|
666
|
+
retryable: options.retryable ?? false,
|
|
667
|
+
metadata: {
|
|
668
|
+
...options.metadata,
|
|
669
|
+
originalError: String(error),
|
|
670
|
+
},
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
/**
|
|
674
|
+
* Infer error code from an Error instance.
|
|
675
|
+
*/
|
|
676
|
+
function inferErrorCode(error) {
|
|
677
|
+
const message = error.message.toLowerCase();
|
|
678
|
+
const name = error.name.toLowerCase();
|
|
679
|
+
if (name.includes("abort") || message.includes("abort")) {
|
|
680
|
+
return "ABORT_ERROR";
|
|
681
|
+
}
|
|
682
|
+
if (message.includes("timeout") || message.includes("timed out")) {
|
|
683
|
+
return "TIMEOUT_ERROR";
|
|
684
|
+
}
|
|
685
|
+
if (message.includes("rate limit") || message.includes("429")) {
|
|
686
|
+
return "RATE_LIMIT_ERROR";
|
|
687
|
+
}
|
|
688
|
+
if (message.includes("network") ||
|
|
689
|
+
message.includes("fetch") ||
|
|
690
|
+
message.includes("econnrefused") ||
|
|
691
|
+
message.includes("econnreset")) {
|
|
692
|
+
return "NETWORK_ERROR";
|
|
693
|
+
}
|
|
694
|
+
if (message.includes("auth") || message.includes("401")) {
|
|
695
|
+
return "AUTHENTICATION_ERROR";
|
|
696
|
+
}
|
|
697
|
+
if (message.includes("permission") || message.includes("forbidden") || message.includes("403")) {
|
|
698
|
+
return "AUTHORIZATION_ERROR";
|
|
699
|
+
}
|
|
700
|
+
if (message.includes("validation") || message.includes("invalid")) {
|
|
701
|
+
return "VALIDATION_ERROR";
|
|
702
|
+
}
|
|
703
|
+
return "UNKNOWN_ERROR";
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Check if an error is retryable.
|
|
707
|
+
*
|
|
708
|
+
* @param error - The error to check
|
|
709
|
+
* @returns Whether the error is retryable
|
|
710
|
+
*
|
|
711
|
+
* @category Errors
|
|
712
|
+
*/
|
|
713
|
+
export function isRetryable(error) {
|
|
714
|
+
if (AgentError.is(error)) {
|
|
715
|
+
return error.retryable;
|
|
716
|
+
}
|
|
717
|
+
if (error instanceof Error) {
|
|
718
|
+
const message = error.message.toLowerCase();
|
|
719
|
+
// Retryable conditions
|
|
720
|
+
if (message.includes("rate limit") ||
|
|
721
|
+
message.includes("timeout") ||
|
|
722
|
+
message.includes("timed out") ||
|
|
723
|
+
message.includes("network") ||
|
|
724
|
+
message.includes("econnreset") ||
|
|
725
|
+
message.includes("econnrefused") ||
|
|
726
|
+
message.includes("503") ||
|
|
727
|
+
message.includes("502") ||
|
|
728
|
+
message.includes("504")) {
|
|
729
|
+
return true;
|
|
730
|
+
}
|
|
731
|
+
// Non-retryable conditions
|
|
732
|
+
if (message.includes("invalid") ||
|
|
733
|
+
message.includes("validation") ||
|
|
734
|
+
message.includes("auth") ||
|
|
735
|
+
message.includes("permission") ||
|
|
736
|
+
message.includes("not found")) {
|
|
737
|
+
return false;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Get a user-friendly error message from any error.
|
|
744
|
+
*
|
|
745
|
+
* @param error - The error to get a message from
|
|
746
|
+
* @param fallback - Fallback message if extraction fails
|
|
747
|
+
* @returns A user-friendly error message
|
|
748
|
+
*
|
|
749
|
+
* @category Errors
|
|
750
|
+
*/
|
|
751
|
+
export function getUserMessage(error, fallback = "An unexpected error occurred. Please try again.") {
|
|
752
|
+
if (AgentError.is(error)) {
|
|
753
|
+
return error.userMessage;
|
|
754
|
+
}
|
|
755
|
+
if (error instanceof Error) {
|
|
756
|
+
// Try to make the message more user-friendly
|
|
757
|
+
const message = error.message;
|
|
758
|
+
// Common error patterns to user-friendly messages
|
|
759
|
+
if (message.toLowerCase().includes("rate limit")) {
|
|
760
|
+
return "The service is busy. Please wait a moment and try again.";
|
|
761
|
+
}
|
|
762
|
+
if (message.toLowerCase().includes("timeout") || message.toLowerCase().includes("timed out")) {
|
|
763
|
+
return "The request took too long. Please try again.";
|
|
764
|
+
}
|
|
765
|
+
if (message.toLowerCase().includes("network")) {
|
|
766
|
+
return "A network error occurred. Please check your connection.";
|
|
767
|
+
}
|
|
768
|
+
if (message.toLowerCase().includes("auth") || message.toLowerCase().includes("401")) {
|
|
769
|
+
return "Authentication failed. Please check your credentials.";
|
|
770
|
+
}
|
|
771
|
+
if (message.toLowerCase().includes("permission") || message.toLowerCase().includes("403")) {
|
|
772
|
+
return "You don't have permission to perform this action.";
|
|
773
|
+
}
|
|
774
|
+
if (message.toLowerCase().includes("not found") || message.includes("404")) {
|
|
775
|
+
return "The requested resource was not found.";
|
|
776
|
+
}
|
|
777
|
+
// Return the original message if it's reasonably short
|
|
778
|
+
if (message.length < 100 && !message.includes("Error:")) {
|
|
779
|
+
return message;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
return fallback;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Format an error for logging.
|
|
786
|
+
*
|
|
787
|
+
* @param error - The error to format
|
|
788
|
+
* @returns A structured object suitable for logging
|
|
789
|
+
*
|
|
790
|
+
* @category Errors
|
|
791
|
+
*/
|
|
792
|
+
export function formatErrorForLogging(error) {
|
|
793
|
+
if (AgentError.is(error)) {
|
|
794
|
+
return error.toJSON();
|
|
795
|
+
}
|
|
796
|
+
if (error instanceof Error) {
|
|
797
|
+
return {
|
|
798
|
+
name: error.name,
|
|
799
|
+
message: error.message,
|
|
800
|
+
stack: error.stack,
|
|
801
|
+
cause: error.cause instanceof Error ? error.cause.message : error.cause,
|
|
802
|
+
};
|
|
803
|
+
}
|
|
804
|
+
return {
|
|
805
|
+
type: typeof error,
|
|
806
|
+
value: String(error),
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
/**
|
|
810
|
+
* Create an error handler that catches and transforms errors.
|
|
811
|
+
*
|
|
812
|
+
* @param options - Handler options
|
|
813
|
+
* @returns A function that wraps async operations with error handling
|
|
814
|
+
*
|
|
815
|
+
* @example
|
|
816
|
+
* ```typescript
|
|
817
|
+
* const handle = createErrorHandler({
|
|
818
|
+
* onError: (error) => console.error(error),
|
|
819
|
+
* transform: (error) => wrapError(error, "Operation failed"),
|
|
820
|
+
* });
|
|
821
|
+
*
|
|
822
|
+
* const result = await handle(async () => {
|
|
823
|
+
* return await riskyOperation();
|
|
824
|
+
* });
|
|
825
|
+
* ```
|
|
826
|
+
*
|
|
827
|
+
* @category Errors
|
|
828
|
+
*/
|
|
829
|
+
export function createErrorHandler(options) {
|
|
830
|
+
const { onError, transform } = options;
|
|
831
|
+
return async (fn) => {
|
|
832
|
+
try {
|
|
833
|
+
return await fn();
|
|
834
|
+
}
|
|
835
|
+
catch (error) {
|
|
836
|
+
const agentError = transform ? transform(error) : wrapError(error, "An error occurred");
|
|
837
|
+
if (onError) {
|
|
838
|
+
await onError(agentError);
|
|
839
|
+
}
|
|
840
|
+
throw agentError;
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Execute an operation with a fallback value on error.
|
|
846
|
+
*
|
|
847
|
+
* Provides graceful degradation by returning a fallback value when
|
|
848
|
+
* the primary operation fails.
|
|
849
|
+
*
|
|
850
|
+
* @param fn - The operation to execute
|
|
851
|
+
* @param options - Fallback options
|
|
852
|
+
* @returns The result or fallback value
|
|
853
|
+
*
|
|
854
|
+
* @example
|
|
855
|
+
* ```typescript
|
|
856
|
+
* const memory = await withFallback(
|
|
857
|
+
* () => loadAgentMemory("/path/to/memory.md"),
|
|
858
|
+
* { fallback: "", logError: true }
|
|
859
|
+
* );
|
|
860
|
+
* ```
|
|
861
|
+
*
|
|
862
|
+
* @category Errors
|
|
863
|
+
*/
|
|
864
|
+
export async function withFallback(fn, options) {
|
|
865
|
+
const { fallback, logError = true, onError, rethrowFatal = true } = options;
|
|
866
|
+
try {
|
|
867
|
+
return await fn();
|
|
868
|
+
}
|
|
869
|
+
catch (error) {
|
|
870
|
+
const agentError = wrapError(error, "Operation failed");
|
|
871
|
+
// Rethrow fatal errors
|
|
872
|
+
if (rethrowFatal && agentError.severity === "fatal") {
|
|
873
|
+
throw agentError;
|
|
874
|
+
}
|
|
875
|
+
// Log if requested
|
|
876
|
+
if (logError) {
|
|
877
|
+
console.warn(`[withFallback] Using fallback due to error: ${agentError.message}`);
|
|
878
|
+
}
|
|
879
|
+
// Call error handler
|
|
880
|
+
if (onError) {
|
|
881
|
+
await onError(agentError);
|
|
882
|
+
}
|
|
883
|
+
return fallback;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Execute an operation with a fallback function on error.
|
|
888
|
+
*
|
|
889
|
+
* Similar to withFallback but allows computing the fallback value.
|
|
890
|
+
*
|
|
891
|
+
* @param fn - The primary operation
|
|
892
|
+
* @param fallbackFn - Function to compute the fallback
|
|
893
|
+
* @param onError - Optional error callback
|
|
894
|
+
* @returns The result or computed fallback
|
|
895
|
+
*
|
|
896
|
+
* @example
|
|
897
|
+
* ```typescript
|
|
898
|
+
* const data = await withFallbackFn(
|
|
899
|
+
* () => fetchFromPrimary(),
|
|
900
|
+
* (error) => fetchFromBackup(error)
|
|
901
|
+
* );
|
|
902
|
+
* ```
|
|
903
|
+
*
|
|
904
|
+
* @category Errors
|
|
905
|
+
*/
|
|
906
|
+
export async function withFallbackFn(fn, fallbackFn, onError) {
|
|
907
|
+
try {
|
|
908
|
+
return await fn();
|
|
909
|
+
}
|
|
910
|
+
catch (error) {
|
|
911
|
+
const agentError = wrapError(error, "Operation failed");
|
|
912
|
+
if (onError) {
|
|
913
|
+
await onError(agentError);
|
|
914
|
+
}
|
|
915
|
+
return fallbackFn(agentError);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Execute multiple operations until one succeeds.
|
|
920
|
+
*
|
|
921
|
+
* Tries each operation in order and returns the first successful result.
|
|
922
|
+
*
|
|
923
|
+
* @param operations - Array of operations to try
|
|
924
|
+
* @param options - Options including error handling
|
|
925
|
+
* @returns The first successful result
|
|
926
|
+
* @throws The last error if all operations fail
|
|
927
|
+
*
|
|
928
|
+
* @example
|
|
929
|
+
* ```typescript
|
|
930
|
+
* const result = await tryOperations([
|
|
931
|
+
* () => fetchFromPrimaryAPI(),
|
|
932
|
+
* () => fetchFromSecondaryAPI(),
|
|
933
|
+
* () => fetchFromCache(),
|
|
934
|
+
* ]);
|
|
935
|
+
* ```
|
|
936
|
+
*
|
|
937
|
+
* @category Errors
|
|
938
|
+
*/
|
|
939
|
+
export async function tryOperations(operations, options = {}) {
|
|
940
|
+
const { onError } = options;
|
|
941
|
+
let lastError;
|
|
942
|
+
for (let i = 0; i < operations.length; i++) {
|
|
943
|
+
try {
|
|
944
|
+
const operation = operations[i];
|
|
945
|
+
if (!operation)
|
|
946
|
+
continue;
|
|
947
|
+
return await operation();
|
|
948
|
+
}
|
|
949
|
+
catch (error) {
|
|
950
|
+
lastError = wrapError(error, `Operation ${i + 1} failed`);
|
|
951
|
+
if (onError) {
|
|
952
|
+
await onError(lastError, i);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
throw (lastError ??
|
|
957
|
+
new AgentError("All operations failed", {
|
|
958
|
+
code: "UNKNOWN_ERROR",
|
|
959
|
+
}));
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Create a circuit breaker for error protection.
|
|
963
|
+
*
|
|
964
|
+
* Opens the circuit after threshold failures to prevent cascading failures.
|
|
965
|
+
*
|
|
966
|
+
* @param options - Circuit breaker options
|
|
967
|
+
* @returns A function that wraps operations with circuit breaker protection
|
|
968
|
+
*
|
|
969
|
+
* @example
|
|
970
|
+
* ```typescript
|
|
971
|
+
* const breaker = createCircuitBreaker({
|
|
972
|
+
* failureThreshold: 5,
|
|
973
|
+
* resetTimeout: 60000,
|
|
974
|
+
* });
|
|
975
|
+
*
|
|
976
|
+
* const result = await breaker(() => callExternalService());
|
|
977
|
+
* ```
|
|
978
|
+
*
|
|
979
|
+
* @category Errors
|
|
980
|
+
*/
|
|
981
|
+
export function createCircuitBreaker(options) {
|
|
982
|
+
const { failureThreshold = 5, resetTimeout = 60000, onStateChange } = options;
|
|
983
|
+
let failures = 0;
|
|
984
|
+
let state = "closed";
|
|
985
|
+
let lastFailureTime = 0;
|
|
986
|
+
function setState(newState) {
|
|
987
|
+
if (state !== newState) {
|
|
988
|
+
state = newState;
|
|
989
|
+
onStateChange?.(newState);
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
return async (fn) => {
|
|
993
|
+
// Check if circuit should be opened
|
|
994
|
+
if (state === "open") {
|
|
995
|
+
if (Date.now() - lastFailureTime >= resetTimeout) {
|
|
996
|
+
setState("half-open");
|
|
997
|
+
}
|
|
998
|
+
else {
|
|
999
|
+
throw new AgentError("Circuit breaker is open", {
|
|
1000
|
+
code: "NETWORK_ERROR",
|
|
1001
|
+
userMessage: "Service temporarily unavailable. Please try again later.",
|
|
1002
|
+
retryable: true,
|
|
1003
|
+
retryAfterMs: Math.max(1000, resetTimeout - (Date.now() - lastFailureTime)),
|
|
1004
|
+
});
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
try {
|
|
1008
|
+
const result = await fn();
|
|
1009
|
+
failures = 0;
|
|
1010
|
+
setState("closed");
|
|
1011
|
+
return result;
|
|
1012
|
+
}
|
|
1013
|
+
catch (error) {
|
|
1014
|
+
failures++;
|
|
1015
|
+
lastFailureTime = Date.now();
|
|
1016
|
+
if (failures >= failureThreshold) {
|
|
1017
|
+
setState("open");
|
|
1018
|
+
}
|
|
1019
|
+
throw error;
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
//# sourceMappingURL=index.js.map
|