@pauly4010/evalai-sdk 1.3.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.
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Context Propagation System
3
+ * Tier 2.9: Automatic metadata injection
4
+ *
5
+ * NOTE: In Node.js, uses AsyncLocalStorage for true async context propagation.
6
+ * In browsers, uses a simpler stack-based approach (not safe across async boundaries).
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { createContext } from '@ai-eval-platform/sdk';
11
+ *
12
+ * const context = createContext({ userId: '123', sessionId: 'abc' });
13
+ *
14
+ * await context.run(async () => {
15
+ * // All SDK calls inherit the context
16
+ * await client.traces.create({ name: 'test' });
17
+ * // ^ Automatically includes userId and sessionId
18
+ * });
19
+ * ```
20
+ */
21
+ /**
22
+ * Context metadata that will be automatically injected
23
+ */
24
+ export interface ContextMetadata {
25
+ [key: string]: any;
26
+ }
27
+ /**
28
+ * Context manager for automatic metadata propagation
29
+ */
30
+ export declare class EvalContext {
31
+ private metadata;
32
+ constructor(metadata: ContextMetadata);
33
+ /**
34
+ * Run a function with this context
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const context = new EvalContext({ userId: '123' });
39
+ *
40
+ * await context.run(async () => {
41
+ * // All operations inherit context
42
+ * await client.traces.create({ name: 'test' });
43
+ * });
44
+ * ```
45
+ */
46
+ run<T>(fn: () => Promise<T>): Promise<T>;
47
+ /**
48
+ * Run a synchronous function with this context
49
+ */
50
+ runSync<T>(fn: () => T): T;
51
+ /**
52
+ * Get the current context metadata
53
+ */
54
+ getMetadata(): ContextMetadata;
55
+ /**
56
+ * Merge additional metadata into context
57
+ */
58
+ with(additionalMetadata: ContextMetadata): EvalContext;
59
+ }
60
+ /**
61
+ * Create a new context with metadata
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const context = createContext({
66
+ * userId: '123',
67
+ * sessionId: 'abc',
68
+ * environment: 'production'
69
+ * });
70
+ *
71
+ * await context.run(async () => {
72
+ * // All SDK operations inherit context
73
+ * });
74
+ * ```
75
+ */
76
+ export declare function createContext(metadata: ContextMetadata): EvalContext;
77
+ /**
78
+ * Get the current context metadata (if any)
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * const metadata = getCurrentContext();
83
+ * if (metadata) {
84
+ * console.log(metadata.userId);
85
+ * }
86
+ * ```
87
+ */
88
+ export declare function getCurrentContext(): ContextMetadata | undefined;
89
+ /**
90
+ * Merge current context with additional metadata
91
+ * Returns combined metadata for use in API calls
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const params = {
96
+ * name: 'My Trace',
97
+ * metadata: mergeWithContext({ custom: 'value' })
98
+ * };
99
+ * ```
100
+ */
101
+ export declare function mergeWithContext(metadata?: Record<string, any>): Record<string, any>;
102
+ /**
103
+ * Run with nested context (merges parent context)
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * await withContext({ userId: '123' }, async () => {
108
+ * await withContext({ requestId: 'req-456' }, async () => {
109
+ * // Has both userId and requestId
110
+ * const ctx = getCurrentContext();
111
+ * console.log(ctx); // { userId: '123', requestId: 'req-456' }
112
+ * });
113
+ * });
114
+ * ```
115
+ */
116
+ export declare function withContext<T>(metadata: ContextMetadata, fn: () => Promise<T>): Promise<T>;
117
+ /**
118
+ * Run with nested context (synchronous)
119
+ */
120
+ export declare function withContextSync<T>(metadata: ContextMetadata, fn: () => T): T;
121
+ /**
122
+ * Decorator for automatic context injection (for class methods)
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * class MyService {
127
+ * @WithContext({ service: 'MyService' })
128
+ * async process() {
129
+ * // Automatically has service context
130
+ * }
131
+ * }
132
+ * ```
133
+ */
134
+ export declare function WithContext(metadata: ContextMetadata): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ /**
3
+ * Context Propagation System
4
+ * Tier 2.9: Automatic metadata injection
5
+ *
6
+ * NOTE: In Node.js, uses AsyncLocalStorage for true async context propagation.
7
+ * In browsers, uses a simpler stack-based approach (not safe across async boundaries).
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { createContext } from '@ai-eval-platform/sdk';
12
+ *
13
+ * const context = createContext({ userId: '123', sessionId: 'abc' });
14
+ *
15
+ * await context.run(async () => {
16
+ * // All SDK calls inherit the context
17
+ * await client.traces.create({ name: 'test' });
18
+ * // ^ Automatically includes userId and sessionId
19
+ * });
20
+ * ```
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.EvalContext = void 0;
24
+ exports.createContext = createContext;
25
+ exports.getCurrentContext = getCurrentContext;
26
+ exports.mergeWithContext = mergeWithContext;
27
+ exports.withContext = withContext;
28
+ exports.withContextSync = withContextSync;
29
+ exports.WithContext = WithContext;
30
+ // Detect environment
31
+ const isNode = typeof process !== 'undefined' &&
32
+ process.versions?.node &&
33
+ typeof require !== 'undefined';
34
+ // Browser fallback: simple context stack
35
+ class BrowserContextStorage {
36
+ constructor() {
37
+ this.stack = [];
38
+ }
39
+ run(context, fn) {
40
+ this.stack.push(context);
41
+ try {
42
+ return fn();
43
+ }
44
+ finally {
45
+ this.stack.pop();
46
+ }
47
+ }
48
+ getStore() {
49
+ return this.stack[this.stack.length - 1];
50
+ }
51
+ }
52
+ /**
53
+ * Context storage implementation
54
+ * Uses AsyncLocalStorage in Node.js, simple stack in browsers
55
+ */
56
+ let contextStorage;
57
+ if (isNode) {
58
+ try {
59
+ // Dynamic import for Node.js only
60
+ const { AsyncLocalStorage } = require('async_hooks');
61
+ // Create without type argument due to require() being untyped
62
+ contextStorage = new AsyncLocalStorage();
63
+ }
64
+ catch (error) {
65
+ // Fallback if async_hooks is not available
66
+ contextStorage = new BrowserContextStorage();
67
+ }
68
+ }
69
+ else {
70
+ // Use browser storage for non-Node environments
71
+ contextStorage = new BrowserContextStorage();
72
+ }
73
+ /**
74
+ * Context manager for automatic metadata propagation
75
+ */
76
+ class EvalContext {
77
+ constructor(metadata) {
78
+ this.metadata = metadata;
79
+ }
80
+ /**
81
+ * Run a function with this context
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const context = new EvalContext({ userId: '123' });
86
+ *
87
+ * await context.run(async () => {
88
+ * // All operations inherit context
89
+ * await client.traces.create({ name: 'test' });
90
+ * });
91
+ * ```
92
+ */
93
+ async run(fn) {
94
+ return contextStorage.run(this.metadata, fn);
95
+ }
96
+ /**
97
+ * Run a synchronous function with this context
98
+ */
99
+ runSync(fn) {
100
+ return contextStorage.run(this.metadata, fn);
101
+ }
102
+ /**
103
+ * Get the current context metadata
104
+ */
105
+ getMetadata() {
106
+ return { ...this.metadata };
107
+ }
108
+ /**
109
+ * Merge additional metadata into context
110
+ */
111
+ with(additionalMetadata) {
112
+ return new EvalContext({ ...this.metadata, ...additionalMetadata });
113
+ }
114
+ }
115
+ exports.EvalContext = EvalContext;
116
+ /**
117
+ * Create a new context with metadata
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const context = createContext({
122
+ * userId: '123',
123
+ * sessionId: 'abc',
124
+ * environment: 'production'
125
+ * });
126
+ *
127
+ * await context.run(async () => {
128
+ * // All SDK operations inherit context
129
+ * });
130
+ * ```
131
+ */
132
+ function createContext(metadata) {
133
+ return new EvalContext(metadata);
134
+ }
135
+ /**
136
+ * Get the current context metadata (if any)
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * const metadata = getCurrentContext();
141
+ * if (metadata) {
142
+ * console.log(metadata.userId);
143
+ * }
144
+ * ```
145
+ */
146
+ function getCurrentContext() {
147
+ return contextStorage.getStore();
148
+ }
149
+ /**
150
+ * Merge current context with additional metadata
151
+ * Returns combined metadata for use in API calls
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * const params = {
156
+ * name: 'My Trace',
157
+ * metadata: mergeWithContext({ custom: 'value' })
158
+ * };
159
+ * ```
160
+ */
161
+ function mergeWithContext(metadata) {
162
+ const current = getCurrentContext();
163
+ if (!current)
164
+ return metadata || {};
165
+ return { ...current, ...metadata };
166
+ }
167
+ /**
168
+ * Run with nested context (merges parent context)
169
+ *
170
+ * @example
171
+ * ```typescript
172
+ * await withContext({ userId: '123' }, async () => {
173
+ * await withContext({ requestId: 'req-456' }, async () => {
174
+ * // Has both userId and requestId
175
+ * const ctx = getCurrentContext();
176
+ * console.log(ctx); // { userId: '123', requestId: 'req-456' }
177
+ * });
178
+ * });
179
+ * ```
180
+ */
181
+ async function withContext(metadata, fn) {
182
+ const current = getCurrentContext() || {};
183
+ const merged = { ...current, ...metadata };
184
+ return contextStorage.run(merged, fn);
185
+ }
186
+ /**
187
+ * Run with nested context (synchronous)
188
+ */
189
+ function withContextSync(metadata, fn) {
190
+ const current = getCurrentContext() || {};
191
+ const merged = { ...current, ...metadata };
192
+ return contextStorage.run(merged, fn);
193
+ }
194
+ /**
195
+ * Decorator for automatic context injection (for class methods)
196
+ *
197
+ * @example
198
+ * ```typescript
199
+ * class MyService {
200
+ * @WithContext({ service: 'MyService' })
201
+ * async process() {
202
+ * // Automatically has service context
203
+ * }
204
+ * }
205
+ * ```
206
+ */
207
+ function WithContext(metadata) {
208
+ return function (target, propertyKey, descriptor) {
209
+ const originalMethod = descriptor.value;
210
+ descriptor.value = async function (...args) {
211
+ return withContext(metadata, () => originalMethod.apply(this, args));
212
+ };
213
+ return descriptor;
214
+ };
215
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Enhanced SDK Error system with documentation links
3
+ * Tier 1.5: Rich Error Messages
4
+ */
5
+ export interface ErrorDocumentation {
6
+ code: string;
7
+ message: string;
8
+ documentation: string;
9
+ solutions: string[];
10
+ retryable: boolean;
11
+ }
12
+ /**
13
+ * Enhanced SDK Error class with rich error information and documentation
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * try {
18
+ * await client.traces.create({ ... });
19
+ * } catch (error) {
20
+ * if (error instanceof EvalAIError) {
21
+ * console.log(error.code); // 'RATE_LIMIT_EXCEEDED'
22
+ * console.log(error.documentation); // Link to docs
23
+ * console.log(error.solutions); // Array of solutions
24
+ * console.log(error.retryable); // true/false
25
+ *
26
+ * if (error.retryAfter) {
27
+ * console.log(`Retry after ${error.retryAfter} seconds`);
28
+ * }
29
+ * }
30
+ * }
31
+ * ```
32
+ */
33
+ export declare class EvalAIError extends Error {
34
+ /** Error code for programmatic handling */
35
+ code: string;
36
+ /** HTTP status code */
37
+ statusCode: number;
38
+ /** Link to detailed documentation */
39
+ documentation: string;
40
+ /** Array of suggested solutions */
41
+ solutions: string[];
42
+ /** Whether this error is retryable */
43
+ retryable: boolean;
44
+ /** Additional error details from the API */
45
+ details?: any;
46
+ /** When to retry (for rate limit errors) in seconds */
47
+ retryAfter?: number;
48
+ /** When the limit resets (for feature limit errors) */
49
+ resetAt?: Date;
50
+ constructor(message: string, code: string, statusCode: number, details?: any);
51
+ /**
52
+ * Get formatted error message with solutions
53
+ */
54
+ getDetailedMessage(): string;
55
+ /**
56
+ * Check if this error should be retried
57
+ */
58
+ shouldRetry(): boolean;
59
+ /**
60
+ * Convert to JSON for logging
61
+ */
62
+ toJSON(): Record<string, any>;
63
+ }
64
+ /**
65
+ * Create an error from an HTTP response
66
+ */
67
+ export declare function createErrorFromResponse(response: Response, data: any): EvalAIError;
68
+ export declare class RateLimitError extends EvalAIError {
69
+ constructor(message: string, retryAfter?: number);
70
+ }
71
+ export declare class AuthenticationError extends EvalAIError {
72
+ constructor(message?: string);
73
+ }
74
+ export declare class ValidationError extends EvalAIError {
75
+ constructor(message?: string, details?: any);
76
+ }
77
+ export declare class NetworkError extends EvalAIError {
78
+ constructor(message?: string);
79
+ }
80
+ export { EvalAIError as SDKError };
package/dist/errors.js ADDED
@@ -0,0 +1,285 @@
1
+ "use strict";
2
+ /**
3
+ * Enhanced SDK Error system with documentation links
4
+ * Tier 1.5: Rich Error Messages
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SDKError = exports.NetworkError = exports.ValidationError = exports.AuthenticationError = exports.RateLimitError = exports.EvalAIError = void 0;
8
+ exports.createErrorFromResponse = createErrorFromResponse;
9
+ /**
10
+ * Comprehensive error documentation
11
+ */
12
+ const ERROR_DOCS = {
13
+ MISSING_API_KEY: {
14
+ code: 'MISSING_API_KEY',
15
+ message: 'API key is required to initialize the SDK',
16
+ documentation: 'https://docs.ai-eval-platform.com/errors/missing-api-key',
17
+ solutions: [
18
+ 'Set EVALAI_API_KEY environment variable',
19
+ 'Pass apiKey in config: new AIEvalClient({ apiKey: "..." })',
20
+ 'Get your API key from https://platform.ai-eval-platform.com/settings/api-keys'
21
+ ],
22
+ retryable: false
23
+ },
24
+ MISSING_ORGANIZATION_ID: {
25
+ code: 'MISSING_ORGANIZATION_ID',
26
+ message: 'Organization ID is required for this operation',
27
+ documentation: 'https://docs.ai-eval-platform.com/errors/missing-org-id',
28
+ solutions: [
29
+ 'Set EVALAI_ORGANIZATION_ID environment variable',
30
+ 'Pass organizationId in config: new AIEvalClient({ organizationId: 123 })',
31
+ 'Pass organizationId in method params'
32
+ ],
33
+ retryable: false
34
+ },
35
+ RATE_LIMIT_EXCEEDED: {
36
+ code: 'RATE_LIMIT_EXCEEDED',
37
+ message: 'Rate limit exceeded',
38
+ documentation: 'https://docs.ai-eval-platform.com/errors/rate-limit',
39
+ solutions: [
40
+ 'Wait before retrying (check retryAfter property)',
41
+ 'Upgrade your plan for higher rate limits',
42
+ 'Implement exponential backoff in your application'
43
+ ],
44
+ retryable: true
45
+ },
46
+ TIMEOUT: {
47
+ code: 'TIMEOUT',
48
+ message: 'Request timed out',
49
+ documentation: 'https://docs.ai-eval-platform.com/errors/timeout',
50
+ solutions: [
51
+ 'Increase timeout: new AIEvalClient({ timeout: 60000 })',
52
+ 'Check your network connection',
53
+ 'The service may be experiencing high load'
54
+ ],
55
+ retryable: true
56
+ },
57
+ NETWORK_ERROR: {
58
+ code: 'NETWORK_ERROR',
59
+ message: 'Network connectivity issue',
60
+ documentation: 'https://docs.ai-eval-platform.com/errors/network',
61
+ solutions: [
62
+ 'Check your internet connection',
63
+ 'Verify the baseUrl is correct',
64
+ 'Check if you can reach the API endpoint'
65
+ ],
66
+ retryable: true
67
+ },
68
+ UNAUTHORIZED: {
69
+ code: 'UNAUTHORIZED',
70
+ message: 'Authentication failed',
71
+ documentation: 'https://docs.ai-eval-platform.com/errors/unauthorized',
72
+ solutions: [
73
+ 'Verify your API key is correct',
74
+ 'Check if your API key has expired',
75
+ 'Ensure your API key has the required permissions'
76
+ ],
77
+ retryable: false
78
+ },
79
+ FORBIDDEN: {
80
+ code: 'FORBIDDEN',
81
+ message: 'Access forbidden',
82
+ documentation: 'https://docs.ai-eval-platform.com/errors/forbidden',
83
+ solutions: [
84
+ 'Check if you have permission for this resource',
85
+ 'Verify you\'re using the correct organization ID',
86
+ 'Contact support if you believe this is an error'
87
+ ],
88
+ retryable: false
89
+ },
90
+ NOT_FOUND: {
91
+ code: 'NOT_FOUND',
92
+ message: 'Resource not found',
93
+ documentation: 'https://docs.ai-eval-platform.com/errors/not-found',
94
+ solutions: [
95
+ 'Verify the resource ID is correct',
96
+ 'Check if the resource was deleted',
97
+ 'Ensure you\'re querying the correct organization'
98
+ ],
99
+ retryable: false
100
+ },
101
+ VALIDATION_ERROR: {
102
+ code: 'VALIDATION_ERROR',
103
+ message: 'Request validation failed',
104
+ documentation: 'https://docs.ai-eval-platform.com/errors/validation',
105
+ solutions: [
106
+ 'Check the error details for specific validation failures',
107
+ 'Verify all required fields are provided',
108
+ 'Ensure field types match the expected format'
109
+ ],
110
+ retryable: false
111
+ },
112
+ INTERNAL_SERVER_ERROR: {
113
+ code: 'INTERNAL_SERVER_ERROR',
114
+ message: 'Internal server error',
115
+ documentation: 'https://docs.ai-eval-platform.com/errors/server-error',
116
+ solutions: [
117
+ 'Retry the request after a brief delay',
118
+ 'Check status page: https://status.ai-eval-platform.com',
119
+ 'Contact support if the issue persists'
120
+ ],
121
+ retryable: true
122
+ },
123
+ FEATURE_LIMIT_REACHED: {
124
+ code: 'FEATURE_LIMIT_REACHED',
125
+ message: 'Feature usage limit reached',
126
+ documentation: 'https://docs.ai-eval-platform.com/errors/feature-limit',
127
+ solutions: [
128
+ 'Upgrade your plan for higher limits',
129
+ 'Wait for your usage to reset (check resetAt property)',
130
+ 'Optimize your usage patterns'
131
+ ],
132
+ retryable: false
133
+ }
134
+ };
135
+ /**
136
+ * Enhanced SDK Error class with rich error information and documentation
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * try {
141
+ * await client.traces.create({ ... });
142
+ * } catch (error) {
143
+ * if (error instanceof EvalAIError) {
144
+ * console.log(error.code); // 'RATE_LIMIT_EXCEEDED'
145
+ * console.log(error.documentation); // Link to docs
146
+ * console.log(error.solutions); // Array of solutions
147
+ * console.log(error.retryable); // true/false
148
+ *
149
+ * if (error.retryAfter) {
150
+ * console.log(`Retry after ${error.retryAfter} seconds`);
151
+ * }
152
+ * }
153
+ * }
154
+ * ```
155
+ */
156
+ class EvalAIError extends Error {
157
+ constructor(message, code, statusCode, details) {
158
+ super(message);
159
+ this.name = 'EvalAIError';
160
+ this.code = code;
161
+ this.statusCode = statusCode;
162
+ this.details = details;
163
+ // Get documentation and solutions
164
+ const errorDoc = ERROR_DOCS[code];
165
+ if (errorDoc) {
166
+ this.documentation = errorDoc.documentation;
167
+ this.solutions = errorDoc.solutions;
168
+ this.retryable = errorDoc.retryable;
169
+ }
170
+ else {
171
+ this.documentation = 'https://docs.ai-eval-platform.com/errors';
172
+ this.solutions = ['Check the API documentation for more information'];
173
+ this.retryable = false;
174
+ }
175
+ // Extract retry-after for rate limits
176
+ if (code === 'RATE_LIMIT_EXCEEDED' && details?.retryAfter) {
177
+ this.retryAfter = details.retryAfter;
178
+ }
179
+ // Extract reset time for feature limits
180
+ if (code === 'FEATURE_LIMIT_REACHED' && details?.resetAt) {
181
+ this.resetAt = new Date(details.resetAt);
182
+ }
183
+ // Ensure proper prototype chain
184
+ Object.setPrototypeOf(this, EvalAIError.prototype);
185
+ }
186
+ /**
187
+ * Get formatted error message with solutions
188
+ */
189
+ getDetailedMessage() {
190
+ let msg = `${this.code}: ${this.message}\n\n`;
191
+ msg += `Documentation: ${this.documentation}\n\n`;
192
+ msg += 'Suggested solutions:\n';
193
+ this.solutions.forEach((solution, i) => {
194
+ msg += ` ${i + 1}. ${solution}\n`;
195
+ });
196
+ if (this.retryAfter) {
197
+ msg += `\nRetry after: ${this.retryAfter} seconds`;
198
+ }
199
+ if (this.resetAt) {
200
+ msg += `\nLimit resets at: ${this.resetAt.toISOString()}`;
201
+ }
202
+ return msg;
203
+ }
204
+ /**
205
+ * Check if this error should be retried
206
+ */
207
+ shouldRetry() {
208
+ return this.retryable;
209
+ }
210
+ /**
211
+ * Convert to JSON for logging
212
+ */
213
+ toJSON() {
214
+ return {
215
+ name: this.name,
216
+ code: this.code,
217
+ message: this.message,
218
+ statusCode: this.statusCode,
219
+ documentation: this.documentation,
220
+ solutions: this.solutions,
221
+ retryable: this.retryable,
222
+ retryAfter: this.retryAfter,
223
+ resetAt: this.resetAt,
224
+ details: this.details
225
+ };
226
+ }
227
+ }
228
+ exports.EvalAIError = EvalAIError;
229
+ exports.SDKError = EvalAIError;
230
+ /**
231
+ * Create an error from an HTTP response
232
+ */
233
+ function createErrorFromResponse(response, data) {
234
+ const status = response.status;
235
+ let code = data?.code || 'UNKNOWN_ERROR';
236
+ let message = data?.error || data?.message || response.statusText;
237
+ // Map HTTP status to error codes
238
+ if (!data?.code) {
239
+ if (status === 401)
240
+ code = 'UNAUTHORIZED';
241
+ else if (status === 403)
242
+ code = 'FORBIDDEN';
243
+ else if (status === 404)
244
+ code = 'NOT_FOUND';
245
+ else if (status === 408)
246
+ code = 'TIMEOUT';
247
+ else if (status === 422)
248
+ code = 'VALIDATION_ERROR';
249
+ else if (status === 429)
250
+ code = 'RATE_LIMIT_EXCEEDED';
251
+ else if (status >= 500)
252
+ code = 'INTERNAL_SERVER_ERROR';
253
+ }
254
+ return new EvalAIError(message, code, status, data);
255
+ }
256
+ // Specific error types
257
+ class RateLimitError extends EvalAIError {
258
+ constructor(message, retryAfter) {
259
+ super(message, 'RATE_LIMIT_EXCEEDED', 429, { retryAfter });
260
+ this.name = 'RateLimitError';
261
+ }
262
+ }
263
+ exports.RateLimitError = RateLimitError;
264
+ class AuthenticationError extends EvalAIError {
265
+ constructor(message = 'Authentication failed') {
266
+ super(message, 'AUTHENTICATION_ERROR', 401);
267
+ this.name = 'AuthenticationError';
268
+ }
269
+ }
270
+ exports.AuthenticationError = AuthenticationError;
271
+ class ValidationError extends EvalAIError {
272
+ constructor(message = 'Validation failed', details) {
273
+ super(message, 'VALIDATION_ERROR', 400, details);
274
+ this.name = 'ValidationError';
275
+ }
276
+ }
277
+ exports.ValidationError = ValidationError;
278
+ class NetworkError extends EvalAIError {
279
+ constructor(message = 'Network request failed') {
280
+ super(message, 'NETWORK_ERROR', 0);
281
+ this.name = 'NetworkError';
282
+ this.retryable = true;
283
+ }
284
+ }
285
+ exports.NetworkError = NetworkError;