@shareai-lab/kode-sdk 1.0.0-beta.8 → 2.7.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/LICENSE +21 -0
- package/README.md +115 -273
- package/README.zh-CN.md +114 -0
- package/dist/core/agent/breakpoint-manager.d.ts +16 -0
- package/dist/core/agent/breakpoint-manager.js +36 -0
- package/dist/core/agent/message-queue.d.ts +26 -0
- package/dist/core/agent/message-queue.js +57 -0
- package/dist/core/agent/permission-manager.d.ts +9 -0
- package/dist/core/agent/permission-manager.js +32 -0
- package/dist/core/agent/todo-manager.d.ts +26 -0
- package/dist/core/agent/todo-manager.js +91 -0
- package/dist/core/agent/tool-runner.d.ts +9 -0
- package/dist/core/agent/tool-runner.js +45 -0
- package/dist/core/agent.d.ts +228 -62
- package/dist/core/agent.js +1890 -615
- package/dist/core/config.d.ts +10 -0
- package/dist/core/config.js +2 -0
- package/dist/core/context-manager.d.ts +82 -0
- package/dist/core/context-manager.js +241 -0
- package/dist/core/errors.d.ts +22 -0
- package/dist/core/errors.js +49 -0
- package/dist/core/events.d.ts +41 -10
- package/dist/core/events.js +270 -68
- package/dist/core/file-pool.d.ts +41 -0
- package/dist/core/file-pool.js +102 -0
- package/dist/core/hooks.d.ts +3 -3
- package/dist/core/hooks.js +1 -1
- package/dist/core/permission-modes.d.ts +31 -0
- package/dist/core/permission-modes.js +61 -0
- package/dist/core/pool.d.ts +56 -13
- package/dist/core/pool.js +244 -34
- package/dist/core/room.d.ts +2 -2
- package/dist/core/room.js +10 -10
- package/dist/core/scheduler.d.ts +30 -23
- package/dist/core/scheduler.js +42 -168
- package/dist/core/skills/index.d.ts +10 -0
- package/dist/core/skills/index.js +20 -0
- package/dist/core/skills/management-manager.d.ts +130 -0
- package/dist/core/skills/management-manager.js +557 -0
- package/dist/core/skills/manager.d.ts +47 -0
- package/dist/core/skills/manager.js +243 -0
- package/dist/core/skills/operation-queue.d.ts +87 -0
- package/dist/core/skills/operation-queue.js +113 -0
- package/dist/core/skills/sandbox-file-manager.d.ts +82 -0
- package/dist/core/skills/sandbox-file-manager.js +183 -0
- package/dist/core/skills/types.d.ts +120 -0
- package/dist/core/skills/types.js +9 -0
- package/dist/core/skills/xml-generator.d.ts +13 -0
- package/dist/core/skills/xml-generator.js +70 -0
- package/dist/core/template.d.ts +57 -0
- package/dist/core/template.js +35 -0
- package/dist/core/time-bridge.d.ts +18 -0
- package/dist/core/time-bridge.js +100 -0
- package/dist/core/todo.d.ts +34 -0
- package/dist/core/todo.js +89 -0
- package/dist/core/types.d.ts +311 -114
- package/dist/core/types.js +1 -12
- package/dist/index.d.ts +47 -9
- package/dist/index.js +108 -15
- package/dist/infra/db/postgres/postgres-store.d.ts +97 -0
- package/dist/infra/db/postgres/postgres-store.js +1073 -0
- package/dist/infra/db/sqlite/sqlite-store.d.ts +84 -0
- package/dist/infra/db/sqlite/sqlite-store.js +800 -0
- package/dist/infra/e2b/e2b-fs.d.ts +29 -0
- package/dist/infra/e2b/e2b-fs.js +128 -0
- package/dist/infra/e2b/e2b-sandbox.d.ts +37 -0
- package/dist/infra/e2b/e2b-sandbox.js +156 -0
- package/dist/infra/e2b/e2b-template.d.ts +24 -0
- package/dist/infra/e2b/e2b-template.js +105 -0
- package/dist/infra/e2b/index.d.ts +4 -0
- package/dist/infra/e2b/index.js +9 -0
- package/dist/infra/e2b/types.d.ts +46 -0
- package/dist/infra/e2b/types.js +2 -0
- package/dist/infra/provider.d.ts +17 -58
- package/dist/infra/provider.js +65 -116
- package/dist/infra/providers/anthropic.d.ts +42 -0
- package/dist/infra/providers/anthropic.js +308 -0
- package/dist/infra/providers/core/errors.d.ts +230 -0
- package/dist/infra/providers/core/errors.js +353 -0
- package/dist/infra/providers/core/fork.d.ts +106 -0
- package/dist/infra/providers/core/fork.js +418 -0
- package/dist/infra/providers/core/index.d.ts +10 -0
- package/dist/infra/providers/core/index.js +76 -0
- package/dist/infra/providers/core/logger.d.ts +186 -0
- package/dist/infra/providers/core/logger.js +191 -0
- package/dist/infra/providers/core/retry.d.ts +62 -0
- package/dist/infra/providers/core/retry.js +189 -0
- package/dist/infra/providers/core/usage.d.ts +151 -0
- package/dist/infra/providers/core/usage.js +376 -0
- package/dist/infra/providers/gemini.d.ts +49 -0
- package/dist/infra/providers/gemini.js +493 -0
- package/dist/infra/providers/index.d.ts +25 -0
- package/dist/infra/providers/index.js +83 -0
- package/dist/infra/providers/openai.d.ts +123 -0
- package/dist/infra/providers/openai.js +662 -0
- package/dist/infra/providers/types.d.ts +334 -0
- package/dist/infra/providers/types.js +20 -0
- package/dist/infra/providers/utils.d.ts +53 -0
- package/dist/infra/providers/utils.js +400 -0
- package/dist/infra/sandbox-factory.d.ts +13 -0
- package/dist/infra/sandbox-factory.js +30 -0
- package/dist/infra/sandbox.d.ts +35 -6
- package/dist/infra/sandbox.js +174 -8
- package/dist/infra/store/factory.d.ts +45 -0
- package/dist/infra/store/factory.js +80 -0
- package/dist/infra/store/index.d.ts +3 -0
- package/dist/infra/store/index.js +26 -0
- package/dist/infra/store/json-store.d.ts +67 -0
- package/dist/infra/store/json-store.js +606 -0
- package/dist/infra/store/types.d.ts +342 -0
- package/dist/infra/store/types.js +2 -0
- package/dist/infra/store.d.ts +12 -32
- package/dist/infra/store.js +27 -130
- package/dist/tools/bash_kill/index.d.ts +1 -0
- package/dist/tools/bash_kill/index.js +35 -0
- package/dist/tools/bash_kill/prompt.d.ts +2 -0
- package/dist/tools/bash_kill/prompt.js +14 -0
- package/dist/tools/bash_logs/index.d.ts +1 -0
- package/dist/tools/bash_logs/index.js +40 -0
- package/dist/tools/bash_logs/prompt.d.ts +2 -0
- package/dist/tools/bash_logs/prompt.js +14 -0
- package/dist/tools/bash_run/index.d.ts +16 -0
- package/dist/tools/bash_run/index.js +61 -0
- package/dist/tools/bash_run/prompt.d.ts +2 -0
- package/dist/tools/bash_run/prompt.js +18 -0
- package/dist/tools/builtin.d.ts +7 -13
- package/dist/tools/builtin.js +19 -90
- package/dist/tools/define.d.ts +101 -0
- package/dist/tools/define.js +214 -0
- package/dist/tools/fs_edit/index.d.ts +1 -0
- package/dist/tools/fs_edit/index.js +62 -0
- package/dist/tools/fs_edit/prompt.d.ts +2 -0
- package/dist/tools/fs_edit/prompt.js +15 -0
- package/dist/tools/fs_glob/index.d.ts +1 -0
- package/dist/tools/fs_glob/index.js +40 -0
- package/dist/tools/fs_glob/prompt.d.ts +2 -0
- package/dist/tools/fs_glob/prompt.js +15 -0
- package/dist/tools/fs_grep/index.d.ts +1 -0
- package/dist/tools/fs_grep/index.js +66 -0
- package/dist/tools/fs_grep/prompt.d.ts +2 -0
- package/dist/tools/fs_grep/prompt.js +16 -0
- package/dist/tools/fs_multi_edit/index.d.ts +1 -0
- package/dist/tools/fs_multi_edit/index.js +106 -0
- package/dist/tools/fs_multi_edit/prompt.d.ts +2 -0
- package/dist/tools/fs_multi_edit/prompt.js +16 -0
- package/dist/tools/fs_read/index.d.ts +1 -0
- package/dist/tools/fs_read/index.js +40 -0
- package/dist/tools/fs_read/prompt.d.ts +2 -0
- package/dist/tools/fs_read/prompt.js +16 -0
- package/dist/tools/fs_write/index.d.ts +1 -0
- package/dist/tools/fs_write/index.js +40 -0
- package/dist/tools/fs_write/prompt.d.ts +2 -0
- package/dist/tools/fs_write/prompt.js +15 -0
- package/dist/tools/index.d.ts +11 -0
- package/dist/tools/index.js +61 -0
- package/dist/tools/mcp.d.ts +69 -0
- package/dist/tools/mcp.js +185 -0
- package/dist/tools/registry.d.ts +29 -0
- package/dist/tools/registry.js +26 -0
- package/dist/tools/scripts.d.ts +22 -0
- package/dist/tools/scripts.js +205 -0
- package/dist/tools/skills.d.ts +20 -0
- package/dist/tools/skills.js +115 -0
- package/dist/tools/task_run/index.d.ts +7 -0
- package/dist/tools/task_run/index.js +58 -0
- package/dist/tools/task_run/prompt.d.ts +5 -0
- package/dist/tools/task_run/prompt.js +25 -0
- package/dist/tools/todo_read/index.d.ts +1 -0
- package/dist/tools/todo_read/index.js +29 -0
- package/dist/tools/todo_read/prompt.d.ts +2 -0
- package/dist/tools/todo_read/prompt.js +18 -0
- package/dist/tools/todo_write/index.d.ts +1 -0
- package/dist/tools/todo_write/index.js +42 -0
- package/dist/tools/todo_write/prompt.d.ts +2 -0
- package/dist/tools/todo_write/prompt.js +23 -0
- package/dist/tools/tool.d.ts +43 -0
- package/dist/tools/tool.js +211 -0
- package/dist/tools/toolkit.d.ts +69 -0
- package/dist/tools/toolkit.js +98 -0
- package/dist/tools/type-inference.d.ts +127 -0
- package/dist/tools/type-inference.js +207 -0
- package/dist/utils/agent-id.d.ts +1 -0
- package/dist/utils/agent-id.js +28 -0
- package/dist/utils/logger.d.ts +15 -0
- package/dist/utils/logger.js +44 -0
- package/dist/utils/session-id.js +16 -16
- package/package.json +35 -11
- package/dist/tools/bash.d.ts +0 -63
- package/dist/tools/bash.js +0 -92
- package/dist/tools/fs.d.ts +0 -96
- package/dist/tools/fs.js +0 -100
- package/dist/tools/task.d.ts +0 -38
- package/dist/tools/task.js +0 -45
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Error Hierarchy
|
|
3
|
+
*
|
|
4
|
+
* Typed error classes for all provider operations with retry support.
|
|
5
|
+
* Each error type has a unique code and retryable flag.
|
|
6
|
+
*/
|
|
7
|
+
export type ProviderErrorCode = 'RATE_LIMIT' | 'AUTH_FAILED' | 'CONTEXT_LENGTH' | 'INVALID_REQUEST' | 'SERVER_ERROR' | 'TIMEOUT' | 'NETWORK_ERROR' | 'CONTENT_FILTER' | 'MODEL_NOT_FOUND' | 'QUOTA_EXCEEDED' | 'SERVICE_UNAVAILABLE' | 'THINKING_SIGNATURE_INVALID' | 'STREAM_ERROR' | 'PARSE_ERROR';
|
|
8
|
+
export interface ProviderErrorDetails {
|
|
9
|
+
name: string;
|
|
10
|
+
code: ProviderErrorCode;
|
|
11
|
+
message: string;
|
|
12
|
+
provider: string;
|
|
13
|
+
requestId?: string;
|
|
14
|
+
retryable: boolean;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
statusCode?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Base class for all provider errors.
|
|
20
|
+
* Provides common properties and JSON serialization.
|
|
21
|
+
*/
|
|
22
|
+
export declare abstract class ProviderError extends Error {
|
|
23
|
+
abstract readonly code: ProviderErrorCode;
|
|
24
|
+
abstract readonly retryable: boolean;
|
|
25
|
+
readonly provider: string;
|
|
26
|
+
readonly requestId?: string;
|
|
27
|
+
readonly timestamp: number;
|
|
28
|
+
readonly statusCode?: number;
|
|
29
|
+
constructor(message: string, provider: string, options?: {
|
|
30
|
+
requestId?: string;
|
|
31
|
+
statusCode?: number;
|
|
32
|
+
});
|
|
33
|
+
toJSON(): ProviderErrorDetails;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Rate limit exceeded (429).
|
|
37
|
+
* Retryable after the specified delay.
|
|
38
|
+
*/
|
|
39
|
+
export declare class RateLimitError extends ProviderError {
|
|
40
|
+
readonly code: "RATE_LIMIT";
|
|
41
|
+
readonly retryable = true;
|
|
42
|
+
readonly retryAfter?: number;
|
|
43
|
+
readonly limitType?: 'requests' | 'tokens';
|
|
44
|
+
constructor(provider: string, options?: {
|
|
45
|
+
retryAfter?: number;
|
|
46
|
+
limitType?: 'requests' | 'tokens';
|
|
47
|
+
requestId?: string;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Authentication failed (401/403).
|
|
52
|
+
* Not retryable - API key or permissions issue.
|
|
53
|
+
*/
|
|
54
|
+
export declare class AuthenticationError extends ProviderError {
|
|
55
|
+
readonly code: "AUTH_FAILED";
|
|
56
|
+
readonly retryable = false;
|
|
57
|
+
constructor(provider: string, options?: {
|
|
58
|
+
requestId?: string;
|
|
59
|
+
statusCode?: number;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Context/token length exceeded.
|
|
64
|
+
* Not retryable - need to reduce input size.
|
|
65
|
+
*/
|
|
66
|
+
export declare class ContextLengthError extends ProviderError {
|
|
67
|
+
readonly code: "CONTEXT_LENGTH";
|
|
68
|
+
readonly retryable = false;
|
|
69
|
+
readonly maxTokens: number;
|
|
70
|
+
readonly requestedTokens: number;
|
|
71
|
+
constructor(provider: string, maxTokens: number, requestedTokens: number, options?: {
|
|
72
|
+
requestId?: string;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Invalid request (400).
|
|
77
|
+
* Not retryable - request format issue.
|
|
78
|
+
*/
|
|
79
|
+
export declare class InvalidRequestError extends ProviderError {
|
|
80
|
+
readonly code: "INVALID_REQUEST";
|
|
81
|
+
readonly retryable = false;
|
|
82
|
+
readonly details?: Record<string, unknown>;
|
|
83
|
+
constructor(provider: string, message: string, options?: {
|
|
84
|
+
requestId?: string;
|
|
85
|
+
details?: Record<string, unknown>;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Server error (500/502/503/529).
|
|
90
|
+
* Retryable with exponential backoff.
|
|
91
|
+
*/
|
|
92
|
+
export declare class ServerError extends ProviderError {
|
|
93
|
+
readonly code: "SERVER_ERROR";
|
|
94
|
+
readonly retryable = true;
|
|
95
|
+
constructor(provider: string, options?: {
|
|
96
|
+
statusCode?: number;
|
|
97
|
+
requestId?: string;
|
|
98
|
+
message?: string;
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Request timeout.
|
|
103
|
+
* Retryable - may be transient.
|
|
104
|
+
*/
|
|
105
|
+
export declare class TimeoutError extends ProviderError {
|
|
106
|
+
readonly code: "TIMEOUT";
|
|
107
|
+
readonly retryable = true;
|
|
108
|
+
readonly timeoutMs: number;
|
|
109
|
+
constructor(provider: string, timeoutMs: number, options?: {
|
|
110
|
+
requestId?: string;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Network error (connection failed, DNS, etc).
|
|
115
|
+
* Retryable - may be transient.
|
|
116
|
+
*/
|
|
117
|
+
export declare class NetworkError extends ProviderError {
|
|
118
|
+
readonly code: "NETWORK_ERROR";
|
|
119
|
+
readonly retryable = true;
|
|
120
|
+
readonly cause?: Error;
|
|
121
|
+
constructor(provider: string, message: string, options?: {
|
|
122
|
+
cause?: Error;
|
|
123
|
+
requestId?: string;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Content filtered by provider safety systems.
|
|
128
|
+
* Not retryable - content policy violation.
|
|
129
|
+
*/
|
|
130
|
+
export declare class ContentFilterError extends ProviderError {
|
|
131
|
+
readonly code: "CONTENT_FILTER";
|
|
132
|
+
readonly retryable = false;
|
|
133
|
+
readonly category?: string;
|
|
134
|
+
readonly severity?: string;
|
|
135
|
+
constructor(provider: string, options?: {
|
|
136
|
+
category?: string;
|
|
137
|
+
severity?: string;
|
|
138
|
+
requestId?: string;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Model not found or not available.
|
|
143
|
+
* Not retryable - model doesn't exist.
|
|
144
|
+
*/
|
|
145
|
+
export declare class ModelNotFoundError extends ProviderError {
|
|
146
|
+
readonly code: "MODEL_NOT_FOUND";
|
|
147
|
+
readonly retryable = false;
|
|
148
|
+
readonly modelId: string;
|
|
149
|
+
constructor(provider: string, modelId: string, options?: {
|
|
150
|
+
requestId?: string;
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Quota exceeded (different from rate limit).
|
|
155
|
+
* Not retryable without billing action.
|
|
156
|
+
*/
|
|
157
|
+
export declare class QuotaExceededError extends ProviderError {
|
|
158
|
+
readonly code: "QUOTA_EXCEEDED";
|
|
159
|
+
readonly retryable = false;
|
|
160
|
+
readonly quotaType?: 'daily' | 'monthly' | 'total';
|
|
161
|
+
constructor(provider: string, options?: {
|
|
162
|
+
quotaType?: 'daily' | 'monthly' | 'total';
|
|
163
|
+
requestId?: string;
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Service temporarily unavailable.
|
|
168
|
+
* Retryable - usually overload or maintenance.
|
|
169
|
+
*/
|
|
170
|
+
export declare class ServiceUnavailableError extends ProviderError {
|
|
171
|
+
readonly code: "SERVICE_UNAVAILABLE";
|
|
172
|
+
readonly retryable = true;
|
|
173
|
+
readonly retryAfter?: number;
|
|
174
|
+
constructor(provider: string, options?: {
|
|
175
|
+
retryAfter?: number;
|
|
176
|
+
requestId?: string;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Thinking signature invalid (Anthropic/Gemini multi-turn).
|
|
181
|
+
* Not retryable - message history was modified.
|
|
182
|
+
*/
|
|
183
|
+
export declare class ThinkingSignatureError extends ProviderError {
|
|
184
|
+
readonly code: "THINKING_SIGNATURE_INVALID";
|
|
185
|
+
readonly retryable = false;
|
|
186
|
+
constructor(provider: string, options?: {
|
|
187
|
+
requestId?: string;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Stream error during SSE processing.
|
|
192
|
+
* Retryable - stream may have been interrupted.
|
|
193
|
+
*/
|
|
194
|
+
export declare class StreamError extends ProviderError {
|
|
195
|
+
readonly code: "STREAM_ERROR";
|
|
196
|
+
readonly retryable = true;
|
|
197
|
+
readonly cause?: Error;
|
|
198
|
+
constructor(provider: string, message: string, options?: {
|
|
199
|
+
cause?: Error;
|
|
200
|
+
requestId?: string;
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Parse error in response.
|
|
205
|
+
* Not retryable - unexpected response format.
|
|
206
|
+
*/
|
|
207
|
+
export declare class ParseError extends ProviderError {
|
|
208
|
+
readonly code: "PARSE_ERROR";
|
|
209
|
+
readonly retryable = false;
|
|
210
|
+
readonly rawResponse?: string;
|
|
211
|
+
constructor(provider: string, message: string, options?: {
|
|
212
|
+
rawResponse?: string;
|
|
213
|
+
requestId?: string;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Parse error response from provider API and return appropriate ProviderError.
|
|
218
|
+
*/
|
|
219
|
+
export declare function parseProviderError(error: any, provider: string): ProviderError;
|
|
220
|
+
/**
|
|
221
|
+
* Check if an error is retryable.
|
|
222
|
+
*/
|
|
223
|
+
export declare function isRetryableError(error: unknown): boolean;
|
|
224
|
+
/**
|
|
225
|
+
* Check if error is a specific type.
|
|
226
|
+
*/
|
|
227
|
+
export declare function isRateLimitError(error: unknown): error is RateLimitError;
|
|
228
|
+
export declare function isAuthError(error: unknown): error is AuthenticationError;
|
|
229
|
+
export declare function isContextLengthError(error: unknown): error is ContextLengthError;
|
|
230
|
+
export declare function isContentFilterError(error: unknown): error is ContentFilterError;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Provider Error Hierarchy
|
|
4
|
+
*
|
|
5
|
+
* Typed error classes for all provider operations with retry support.
|
|
6
|
+
* Each error type has a unique code and retryable flag.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.ParseError = exports.StreamError = exports.ThinkingSignatureError = exports.ServiceUnavailableError = exports.QuotaExceededError = exports.ModelNotFoundError = exports.ContentFilterError = exports.NetworkError = exports.TimeoutError = exports.ServerError = exports.InvalidRequestError = exports.ContextLengthError = exports.AuthenticationError = exports.RateLimitError = exports.ProviderError = void 0;
|
|
10
|
+
exports.parseProviderError = parseProviderError;
|
|
11
|
+
exports.isRetryableError = isRetryableError;
|
|
12
|
+
exports.isRateLimitError = isRateLimitError;
|
|
13
|
+
exports.isAuthError = isAuthError;
|
|
14
|
+
exports.isContextLengthError = isContextLengthError;
|
|
15
|
+
exports.isContentFilterError = isContentFilterError;
|
|
16
|
+
/**
|
|
17
|
+
* Base class for all provider errors.
|
|
18
|
+
* Provides common properties and JSON serialization.
|
|
19
|
+
*/
|
|
20
|
+
class ProviderError extends Error {
|
|
21
|
+
constructor(message, provider, options) {
|
|
22
|
+
super(message);
|
|
23
|
+
this.name = this.constructor.name;
|
|
24
|
+
this.provider = provider;
|
|
25
|
+
this.requestId = options?.requestId;
|
|
26
|
+
this.statusCode = options?.statusCode;
|
|
27
|
+
this.timestamp = Date.now();
|
|
28
|
+
// Maintain proper stack trace in V8
|
|
29
|
+
if (Error.captureStackTrace) {
|
|
30
|
+
Error.captureStackTrace(this, this.constructor);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
toJSON() {
|
|
34
|
+
return {
|
|
35
|
+
name: this.name,
|
|
36
|
+
code: this.code,
|
|
37
|
+
message: this.message,
|
|
38
|
+
provider: this.provider,
|
|
39
|
+
requestId: this.requestId,
|
|
40
|
+
retryable: this.retryable,
|
|
41
|
+
timestamp: this.timestamp,
|
|
42
|
+
statusCode: this.statusCode,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.ProviderError = ProviderError;
|
|
47
|
+
/**
|
|
48
|
+
* Rate limit exceeded (429).
|
|
49
|
+
* Retryable after the specified delay.
|
|
50
|
+
*/
|
|
51
|
+
class RateLimitError extends ProviderError {
|
|
52
|
+
constructor(provider, options) {
|
|
53
|
+
super(`Rate limit exceeded${options?.retryAfter ? `, retry after ${options.retryAfter}s` : ''}`, provider, { requestId: options?.requestId, statusCode: 429 });
|
|
54
|
+
this.code = 'RATE_LIMIT';
|
|
55
|
+
this.retryable = true;
|
|
56
|
+
this.retryAfter = options?.retryAfter;
|
|
57
|
+
this.limitType = options?.limitType;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
exports.RateLimitError = RateLimitError;
|
|
61
|
+
/**
|
|
62
|
+
* Authentication failed (401/403).
|
|
63
|
+
* Not retryable - API key or permissions issue.
|
|
64
|
+
*/
|
|
65
|
+
class AuthenticationError extends ProviderError {
|
|
66
|
+
constructor(provider, options) {
|
|
67
|
+
super('Authentication failed - check API key and permissions', provider, { requestId: options?.requestId, statusCode: options?.statusCode || 401 });
|
|
68
|
+
this.code = 'AUTH_FAILED';
|
|
69
|
+
this.retryable = false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.AuthenticationError = AuthenticationError;
|
|
73
|
+
/**
|
|
74
|
+
* Context/token length exceeded.
|
|
75
|
+
* Not retryable - need to reduce input size.
|
|
76
|
+
*/
|
|
77
|
+
class ContextLengthError extends ProviderError {
|
|
78
|
+
constructor(provider, maxTokens, requestedTokens, options) {
|
|
79
|
+
super(`Context length ${requestedTokens} exceeds maximum ${maxTokens}`, provider, { requestId: options?.requestId, statusCode: 400 });
|
|
80
|
+
this.code = 'CONTEXT_LENGTH';
|
|
81
|
+
this.retryable = false;
|
|
82
|
+
this.maxTokens = maxTokens;
|
|
83
|
+
this.requestedTokens = requestedTokens;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.ContextLengthError = ContextLengthError;
|
|
87
|
+
/**
|
|
88
|
+
* Invalid request (400).
|
|
89
|
+
* Not retryable - request format issue.
|
|
90
|
+
*/
|
|
91
|
+
class InvalidRequestError extends ProviderError {
|
|
92
|
+
constructor(provider, message, options) {
|
|
93
|
+
super(message, provider, { requestId: options?.requestId, statusCode: 400 });
|
|
94
|
+
this.code = 'INVALID_REQUEST';
|
|
95
|
+
this.retryable = false;
|
|
96
|
+
this.details = options?.details;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.InvalidRequestError = InvalidRequestError;
|
|
100
|
+
/**
|
|
101
|
+
* Server error (500/502/503/529).
|
|
102
|
+
* Retryable with exponential backoff.
|
|
103
|
+
*/
|
|
104
|
+
class ServerError extends ProviderError {
|
|
105
|
+
constructor(provider, options) {
|
|
106
|
+
super(options?.message || `Server error${options?.statusCode ? ` (${options.statusCode})` : ''}`, provider, { requestId: options?.requestId, statusCode: options?.statusCode || 500 });
|
|
107
|
+
this.code = 'SERVER_ERROR';
|
|
108
|
+
this.retryable = true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.ServerError = ServerError;
|
|
112
|
+
/**
|
|
113
|
+
* Request timeout.
|
|
114
|
+
* Retryable - may be transient.
|
|
115
|
+
*/
|
|
116
|
+
class TimeoutError extends ProviderError {
|
|
117
|
+
constructor(provider, timeoutMs, options) {
|
|
118
|
+
super(`Request timed out after ${timeoutMs}ms`, provider, { requestId: options?.requestId });
|
|
119
|
+
this.code = 'TIMEOUT';
|
|
120
|
+
this.retryable = true;
|
|
121
|
+
this.timeoutMs = timeoutMs;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
exports.TimeoutError = TimeoutError;
|
|
125
|
+
/**
|
|
126
|
+
* Network error (connection failed, DNS, etc).
|
|
127
|
+
* Retryable - may be transient.
|
|
128
|
+
*/
|
|
129
|
+
class NetworkError extends ProviderError {
|
|
130
|
+
constructor(provider, message, options) {
|
|
131
|
+
super(message, provider, { requestId: options?.requestId });
|
|
132
|
+
this.code = 'NETWORK_ERROR';
|
|
133
|
+
this.retryable = true;
|
|
134
|
+
this.cause = options?.cause;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.NetworkError = NetworkError;
|
|
138
|
+
/**
|
|
139
|
+
* Content filtered by provider safety systems.
|
|
140
|
+
* Not retryable - content policy violation.
|
|
141
|
+
*/
|
|
142
|
+
class ContentFilterError extends ProviderError {
|
|
143
|
+
constructor(provider, options) {
|
|
144
|
+
super(`Content filtered${options?.category ? `: ${options.category}` : ''}`, provider, { requestId: options?.requestId });
|
|
145
|
+
this.code = 'CONTENT_FILTER';
|
|
146
|
+
this.retryable = false;
|
|
147
|
+
this.category = options?.category;
|
|
148
|
+
this.severity = options?.severity;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
exports.ContentFilterError = ContentFilterError;
|
|
152
|
+
/**
|
|
153
|
+
* Model not found or not available.
|
|
154
|
+
* Not retryable - model doesn't exist.
|
|
155
|
+
*/
|
|
156
|
+
class ModelNotFoundError extends ProviderError {
|
|
157
|
+
constructor(provider, modelId, options) {
|
|
158
|
+
super(`Model not found: ${modelId}`, provider, { requestId: options?.requestId, statusCode: 404 });
|
|
159
|
+
this.code = 'MODEL_NOT_FOUND';
|
|
160
|
+
this.retryable = false;
|
|
161
|
+
this.modelId = modelId;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.ModelNotFoundError = ModelNotFoundError;
|
|
165
|
+
/**
|
|
166
|
+
* Quota exceeded (different from rate limit).
|
|
167
|
+
* Not retryable without billing action.
|
|
168
|
+
*/
|
|
169
|
+
class QuotaExceededError extends ProviderError {
|
|
170
|
+
constructor(provider, options) {
|
|
171
|
+
super(`Quota exceeded${options?.quotaType ? ` (${options.quotaType})` : ''}`, provider, { requestId: options?.requestId, statusCode: 402 });
|
|
172
|
+
this.code = 'QUOTA_EXCEEDED';
|
|
173
|
+
this.retryable = false;
|
|
174
|
+
this.quotaType = options?.quotaType;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.QuotaExceededError = QuotaExceededError;
|
|
178
|
+
/**
|
|
179
|
+
* Service temporarily unavailable.
|
|
180
|
+
* Retryable - usually overload or maintenance.
|
|
181
|
+
*/
|
|
182
|
+
class ServiceUnavailableError extends ProviderError {
|
|
183
|
+
constructor(provider, options) {
|
|
184
|
+
super('Service temporarily unavailable', provider, { requestId: options?.requestId, statusCode: 503 });
|
|
185
|
+
this.code = 'SERVICE_UNAVAILABLE';
|
|
186
|
+
this.retryable = true;
|
|
187
|
+
this.retryAfter = options?.retryAfter;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
exports.ServiceUnavailableError = ServiceUnavailableError;
|
|
191
|
+
/**
|
|
192
|
+
* Thinking signature invalid (Anthropic/Gemini multi-turn).
|
|
193
|
+
* Not retryable - message history was modified.
|
|
194
|
+
*/
|
|
195
|
+
class ThinkingSignatureError extends ProviderError {
|
|
196
|
+
constructor(provider, options) {
|
|
197
|
+
super('Thinking signature invalid - thinking blocks may have been modified', provider, { requestId: options?.requestId, statusCode: 400 });
|
|
198
|
+
this.code = 'THINKING_SIGNATURE_INVALID';
|
|
199
|
+
this.retryable = false;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
exports.ThinkingSignatureError = ThinkingSignatureError;
|
|
203
|
+
/**
|
|
204
|
+
* Stream error during SSE processing.
|
|
205
|
+
* Retryable - stream may have been interrupted.
|
|
206
|
+
*/
|
|
207
|
+
class StreamError extends ProviderError {
|
|
208
|
+
constructor(provider, message, options) {
|
|
209
|
+
super(message, provider, { requestId: options?.requestId });
|
|
210
|
+
this.code = 'STREAM_ERROR';
|
|
211
|
+
this.retryable = true;
|
|
212
|
+
this.cause = options?.cause;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.StreamError = StreamError;
|
|
216
|
+
/**
|
|
217
|
+
* Parse error in response.
|
|
218
|
+
* Not retryable - unexpected response format.
|
|
219
|
+
*/
|
|
220
|
+
class ParseError extends ProviderError {
|
|
221
|
+
constructor(provider, message, options) {
|
|
222
|
+
super(message, provider, { requestId: options?.requestId });
|
|
223
|
+
this.code = 'PARSE_ERROR';
|
|
224
|
+
this.retryable = false;
|
|
225
|
+
this.rawResponse = options?.rawResponse;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
exports.ParseError = ParseError;
|
|
229
|
+
/**
|
|
230
|
+
* Parse error response from provider API and return appropriate ProviderError.
|
|
231
|
+
*/
|
|
232
|
+
function parseProviderError(error, provider) {
|
|
233
|
+
const statusCode = error.status || error.statusCode || error.response?.status;
|
|
234
|
+
const requestId = error.request_id || error.requestId ||
|
|
235
|
+
error.headers?.['x-request-id'] ||
|
|
236
|
+
error.response?.headers?.['x-request-id'];
|
|
237
|
+
const message = error.message || error.error?.message || 'Unknown error';
|
|
238
|
+
// Rate limit (429)
|
|
239
|
+
if (statusCode === 429) {
|
|
240
|
+
const retryAfter = parseRetryAfter(error);
|
|
241
|
+
return new RateLimitError(provider, { retryAfter, requestId });
|
|
242
|
+
}
|
|
243
|
+
// Auth errors (401/403)
|
|
244
|
+
if (statusCode === 401 || statusCode === 403) {
|
|
245
|
+
return new AuthenticationError(provider, { requestId, statusCode });
|
|
246
|
+
}
|
|
247
|
+
// Server overload (529 - Anthropic specific)
|
|
248
|
+
if (statusCode === 529) {
|
|
249
|
+
return new ServerError(provider, {
|
|
250
|
+
statusCode,
|
|
251
|
+
requestId,
|
|
252
|
+
message: 'API temporarily overloaded',
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
// Server errors (500+)
|
|
256
|
+
if (statusCode && statusCode >= 500) {
|
|
257
|
+
if (statusCode === 503) {
|
|
258
|
+
const retryAfter = parseRetryAfter(error);
|
|
259
|
+
return new ServiceUnavailableError(provider, { retryAfter, requestId });
|
|
260
|
+
}
|
|
261
|
+
return new ServerError(provider, { statusCode, requestId });
|
|
262
|
+
}
|
|
263
|
+
// Context length / token errors
|
|
264
|
+
if (error.code === 'context_length_exceeded' ||
|
|
265
|
+
message.toLowerCase().includes('context') ||
|
|
266
|
+
message.toLowerCase().includes('token limit') ||
|
|
267
|
+
message.toLowerCase().includes('too many tokens')) {
|
|
268
|
+
return new ContextLengthError(provider, error.max_tokens || 0, error.requested_tokens || 0, { requestId });
|
|
269
|
+
}
|
|
270
|
+
// Content filter
|
|
271
|
+
if (error.code === 'content_policy_violation' ||
|
|
272
|
+
message.toLowerCase().includes('safety') ||
|
|
273
|
+
message.toLowerCase().includes('content filter') ||
|
|
274
|
+
message.toLowerCase().includes('blocked')) {
|
|
275
|
+
return new ContentFilterError(provider, {
|
|
276
|
+
category: error.category,
|
|
277
|
+
requestId,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
// Thinking signature (Anthropic)
|
|
281
|
+
if (message.toLowerCase().includes('signature')) {
|
|
282
|
+
return new ThinkingSignatureError(provider, { requestId });
|
|
283
|
+
}
|
|
284
|
+
// Model not found (404)
|
|
285
|
+
if (statusCode === 404 || message.toLowerCase().includes('model not found')) {
|
|
286
|
+
return new ModelNotFoundError(provider, error.model || 'unknown', { requestId });
|
|
287
|
+
}
|
|
288
|
+
// Quota exceeded (402)
|
|
289
|
+
if (statusCode === 402 || message.toLowerCase().includes('quota')) {
|
|
290
|
+
return new QuotaExceededError(provider, { requestId });
|
|
291
|
+
}
|
|
292
|
+
// Network errors
|
|
293
|
+
if (error.code === 'ECONNREFUSED' ||
|
|
294
|
+
error.code === 'ENOTFOUND' ||
|
|
295
|
+
error.code === 'ETIMEDOUT' ||
|
|
296
|
+
error.code === 'ECONNRESET') {
|
|
297
|
+
return new NetworkError(provider, message, { cause: error, requestId });
|
|
298
|
+
}
|
|
299
|
+
// Timeout
|
|
300
|
+
if (error.code === 'TIMEOUT' || message.toLowerCase().includes('timeout')) {
|
|
301
|
+
return new TimeoutError(provider, error.timeout || 0, { requestId });
|
|
302
|
+
}
|
|
303
|
+
// Default to invalid request for 400
|
|
304
|
+
if (statusCode === 400) {
|
|
305
|
+
return new InvalidRequestError(provider, message, {
|
|
306
|
+
requestId,
|
|
307
|
+
details: error.error || error.details,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
// Fallback to server error
|
|
311
|
+
return new ServerError(provider, { statusCode, requestId, message });
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Parse retry-after header value.
|
|
315
|
+
*/
|
|
316
|
+
function parseRetryAfter(error) {
|
|
317
|
+
const header = error.headers?.['retry-after'] ||
|
|
318
|
+
error.response?.headers?.['retry-after'];
|
|
319
|
+
if (header) {
|
|
320
|
+
const seconds = parseInt(header, 10);
|
|
321
|
+
if (!isNaN(seconds))
|
|
322
|
+
return seconds;
|
|
323
|
+
}
|
|
324
|
+
// Some providers include retry info in error body
|
|
325
|
+
if (error.retry_after) {
|
|
326
|
+
return error.retry_after;
|
|
327
|
+
}
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Check if an error is retryable.
|
|
332
|
+
*/
|
|
333
|
+
function isRetryableError(error) {
|
|
334
|
+
if (error instanceof ProviderError) {
|
|
335
|
+
return error.retryable;
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Check if error is a specific type.
|
|
341
|
+
*/
|
|
342
|
+
function isRateLimitError(error) {
|
|
343
|
+
return error instanceof RateLimitError;
|
|
344
|
+
}
|
|
345
|
+
function isAuthError(error) {
|
|
346
|
+
return error instanceof AuthenticationError;
|
|
347
|
+
}
|
|
348
|
+
function isContextLengthError(error) {
|
|
349
|
+
return error instanceof ContextLengthError;
|
|
350
|
+
}
|
|
351
|
+
function isContentFilterError(error) {
|
|
352
|
+
return error instanceof ContentFilterError;
|
|
353
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fork Point Detection and Resume Support
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for detecting safe fork points in message history
|
|
5
|
+
* and preparing messages for resume across different providers.
|
|
6
|
+
*/
|
|
7
|
+
import { Message } from '../../../core/types';
|
|
8
|
+
/**
|
|
9
|
+
* Fork point analysis result.
|
|
10
|
+
*/
|
|
11
|
+
export interface ForkPoint {
|
|
12
|
+
messageIndex: number;
|
|
13
|
+
isSafe: boolean;
|
|
14
|
+
reason?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Validation result for resume.
|
|
18
|
+
*/
|
|
19
|
+
export interface ValidationResult {
|
|
20
|
+
valid: boolean;
|
|
21
|
+
errors: string[];
|
|
22
|
+
warnings?: string[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resume handler interface for provider-specific logic.
|
|
26
|
+
*/
|
|
27
|
+
export interface ResumeHandler {
|
|
28
|
+
prepareForResume(messages: Message[]): Message[];
|
|
29
|
+
validateForResume(messages: Message[]): ValidationResult;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Serialization options for message persistence.
|
|
33
|
+
*/
|
|
34
|
+
export interface SerializationOptions {
|
|
35
|
+
reasoningTransport: 'provider' | 'text' | 'omit';
|
|
36
|
+
preserveSignatures: boolean;
|
|
37
|
+
maxContentLength?: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Find all safe fork points in a message sequence.
|
|
41
|
+
*
|
|
42
|
+
* Safe fork points are:
|
|
43
|
+
* 1. User messages
|
|
44
|
+
* 2. Assistant messages without tool_use
|
|
45
|
+
* 3. After a user message containing all tool_results for preceding tool_uses
|
|
46
|
+
*/
|
|
47
|
+
export declare function findSafeForkPoints(messages: Message[]): ForkPoint[];
|
|
48
|
+
/**
|
|
49
|
+
* Get the last safe fork point index.
|
|
50
|
+
*/
|
|
51
|
+
export declare function getLastSafeForkPoint(messages: Message[]): number;
|
|
52
|
+
/**
|
|
53
|
+
* Serialize messages for persistence.
|
|
54
|
+
*/
|
|
55
|
+
export declare function serializeForResume(messages: Message[], options: SerializationOptions): Message[];
|
|
56
|
+
/**
|
|
57
|
+
* Anthropic resume handler.
|
|
58
|
+
* Preserves thinking blocks with signatures for Claude 4+.
|
|
59
|
+
*/
|
|
60
|
+
export declare const anthropicResumeHandler: ResumeHandler;
|
|
61
|
+
/**
|
|
62
|
+
* DeepSeek resume handler.
|
|
63
|
+
* CRITICAL: Must NOT include reasoning_content in message history.
|
|
64
|
+
*/
|
|
65
|
+
export declare const deepseekResumeHandler: ResumeHandler;
|
|
66
|
+
/**
|
|
67
|
+
* Qwen resume handler.
|
|
68
|
+
* Similar to DeepSeek - reasoning should be omitted.
|
|
69
|
+
*/
|
|
70
|
+
export declare const qwenResumeHandler: ResumeHandler;
|
|
71
|
+
/**
|
|
72
|
+
* OpenAI Chat resume handler.
|
|
73
|
+
* Reasoning is converted to text with <think> tags.
|
|
74
|
+
*/
|
|
75
|
+
export declare const openaiChatResumeHandler: ResumeHandler;
|
|
76
|
+
/**
|
|
77
|
+
* OpenAI Responses API resume handler.
|
|
78
|
+
* Uses previous_response_id for state persistence.
|
|
79
|
+
*/
|
|
80
|
+
export declare const openaiResponsesResumeHandler: ResumeHandler;
|
|
81
|
+
/**
|
|
82
|
+
* Gemini resume handler.
|
|
83
|
+
* Preserves thoughtSignature for function calls.
|
|
84
|
+
*/
|
|
85
|
+
export declare const geminiResumeHandler: ResumeHandler;
|
|
86
|
+
/**
|
|
87
|
+
* Get resume handler for a provider.
|
|
88
|
+
*/
|
|
89
|
+
export declare function getResumeHandler(provider: string): ResumeHandler;
|
|
90
|
+
/**
|
|
91
|
+
* Prepare messages for resume with a specific provider.
|
|
92
|
+
*/
|
|
93
|
+
export declare function prepareMessagesForResume(messages: Message[], provider: string): Message[];
|
|
94
|
+
/**
|
|
95
|
+
* Validate messages for resume with a specific provider.
|
|
96
|
+
*/
|
|
97
|
+
export declare function validateMessagesForResume(messages: Message[], provider: string): ValidationResult;
|
|
98
|
+
/**
|
|
99
|
+
* Check if a message sequence can be safely forked at a given index.
|
|
100
|
+
*/
|
|
101
|
+
export declare function canForkAt(messages: Message[], index: number): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Fork messages at a given index.
|
|
104
|
+
* Returns messages up to and including the fork point.
|
|
105
|
+
*/
|
|
106
|
+
export declare function forkAt(messages: Message[], index: number): Message[];
|