@evalgate/sdk 2.0.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.
Files changed (141) hide show
  1. package/CHANGELOG.md +638 -0
  2. package/README.md +398 -0
  3. package/dist/assertions.d.ts +189 -0
  4. package/dist/assertions.js +662 -0
  5. package/dist/batch.d.ts +68 -0
  6. package/dist/batch.js +179 -0
  7. package/dist/cache.d.ts +65 -0
  8. package/dist/cache.js +131 -0
  9. package/dist/cli/api.d.ts +108 -0
  10. package/dist/cli/api.js +132 -0
  11. package/dist/cli/baseline.d.ts +10 -0
  12. package/dist/cli/baseline.js +172 -0
  13. package/dist/cli/check.d.ts +73 -0
  14. package/dist/cli/check.js +355 -0
  15. package/dist/cli/ci-context.d.ts +6 -0
  16. package/dist/cli/ci-context.js +112 -0
  17. package/dist/cli/ci.d.ts +45 -0
  18. package/dist/cli/ci.js +192 -0
  19. package/dist/cli/config.d.ts +30 -0
  20. package/dist/cli/config.js +230 -0
  21. package/dist/cli/constants.d.ts +15 -0
  22. package/dist/cli/constants.js +18 -0
  23. package/dist/cli/diff.d.ts +173 -0
  24. package/dist/cli/diff.js +685 -0
  25. package/dist/cli/discover.d.ts +84 -0
  26. package/dist/cli/discover.js +419 -0
  27. package/dist/cli/doctor.d.ts +88 -0
  28. package/dist/cli/doctor.js +675 -0
  29. package/dist/cli/env.d.ts +21 -0
  30. package/dist/cli/env.js +42 -0
  31. package/dist/cli/explain.d.ts +58 -0
  32. package/dist/cli/explain.js +561 -0
  33. package/dist/cli/formatters/github.d.ts +8 -0
  34. package/dist/cli/formatters/github.js +135 -0
  35. package/dist/cli/formatters/human.d.ts +6 -0
  36. package/dist/cli/formatters/human.js +110 -0
  37. package/dist/cli/formatters/json.d.ts +6 -0
  38. package/dist/cli/formatters/json.js +10 -0
  39. package/dist/cli/formatters/pr-comment.d.ts +12 -0
  40. package/dist/cli/formatters/pr-comment.js +103 -0
  41. package/dist/cli/formatters/types.d.ts +103 -0
  42. package/dist/cli/formatters/types.js +8 -0
  43. package/dist/cli/gate.d.ts +21 -0
  44. package/dist/cli/gate.js +179 -0
  45. package/dist/cli/impact-analysis.d.ts +63 -0
  46. package/dist/cli/impact-analysis.js +252 -0
  47. package/dist/cli/index.d.ts +9 -0
  48. package/dist/cli/index.js +332 -0
  49. package/dist/cli/init.d.ts +16 -0
  50. package/dist/cli/init.js +292 -0
  51. package/dist/cli/manifest.d.ts +103 -0
  52. package/dist/cli/manifest.js +282 -0
  53. package/dist/cli/migrate.d.ts +41 -0
  54. package/dist/cli/migrate.js +349 -0
  55. package/dist/cli/policy-packs.d.ts +23 -0
  56. package/dist/cli/policy-packs.js +89 -0
  57. package/dist/cli/print-config.d.ts +29 -0
  58. package/dist/cli/print-config.js +270 -0
  59. package/dist/cli/profiles.d.ts +28 -0
  60. package/dist/cli/profiles.js +30 -0
  61. package/dist/cli/reason-codes.d.ts +17 -0
  62. package/dist/cli/reason-codes.js +19 -0
  63. package/dist/cli/regression-gate.d.ts +15 -0
  64. package/dist/cli/regression-gate.js +341 -0
  65. package/dist/cli/render/snippet.d.ts +5 -0
  66. package/dist/cli/render/snippet.js +15 -0
  67. package/dist/cli/render/sort.d.ts +10 -0
  68. package/dist/cli/render/sort.js +24 -0
  69. package/dist/cli/report/build-check-report.d.ts +19 -0
  70. package/dist/cli/report/build-check-report.js +132 -0
  71. package/dist/cli/run.d.ts +101 -0
  72. package/dist/cli/run.js +395 -0
  73. package/dist/cli/share.d.ts +17 -0
  74. package/dist/cli/share.js +91 -0
  75. package/dist/cli/upgrade.d.ts +15 -0
  76. package/dist/cli/upgrade.js +492 -0
  77. package/dist/cli/workspace.d.ts +31 -0
  78. package/dist/cli/workspace.js +68 -0
  79. package/dist/client.d.ts +368 -0
  80. package/dist/client.js +893 -0
  81. package/dist/client.request.test.d.ts +1 -0
  82. package/dist/client.request.test.js +232 -0
  83. package/dist/context.d.ts +134 -0
  84. package/dist/context.js +215 -0
  85. package/dist/errors.d.ts +82 -0
  86. package/dist/errors.js +298 -0
  87. package/dist/export.d.ts +195 -0
  88. package/dist/export.js +344 -0
  89. package/dist/index.d.ts +44 -0
  90. package/dist/index.js +153 -0
  91. package/dist/integrations/anthropic.d.ts +91 -0
  92. package/dist/integrations/anthropic.js +163 -0
  93. package/dist/integrations/openai-eval.d.ts +57 -0
  94. package/dist/integrations/openai-eval.js +232 -0
  95. package/dist/integrations/openai.d.ts +92 -0
  96. package/dist/integrations/openai.js +160 -0
  97. package/dist/local.d.ts +39 -0
  98. package/dist/local.js +148 -0
  99. package/dist/logger.d.ts +128 -0
  100. package/dist/logger.js +227 -0
  101. package/dist/matchers/index.d.ts +1 -0
  102. package/dist/matchers/index.js +6 -0
  103. package/dist/matchers/to-pass-gate.d.ts +29 -0
  104. package/dist/matchers/to-pass-gate.js +35 -0
  105. package/dist/pagination.d.ts +74 -0
  106. package/dist/pagination.js +139 -0
  107. package/dist/regression.d.ts +100 -0
  108. package/dist/regression.js +44 -0
  109. package/dist/runtime/adapters/config-to-dsl.d.ts +33 -0
  110. package/dist/runtime/adapters/config-to-dsl.js +400 -0
  111. package/dist/runtime/adapters/testsuite-to-dsl.d.ts +63 -0
  112. package/dist/runtime/adapters/testsuite-to-dsl.js +276 -0
  113. package/dist/runtime/context.d.ts +26 -0
  114. package/dist/runtime/context.js +74 -0
  115. package/dist/runtime/eval.d.ts +46 -0
  116. package/dist/runtime/eval.js +244 -0
  117. package/dist/runtime/execution-mode.d.ts +80 -0
  118. package/dist/runtime/execution-mode.js +357 -0
  119. package/dist/runtime/executor.d.ts +16 -0
  120. package/dist/runtime/executor.js +152 -0
  121. package/dist/runtime/registry.d.ts +78 -0
  122. package/dist/runtime/registry.js +403 -0
  123. package/dist/runtime/run-report.d.ts +200 -0
  124. package/dist/runtime/run-report.js +222 -0
  125. package/dist/runtime/types.d.ts +356 -0
  126. package/dist/runtime/types.js +76 -0
  127. package/dist/snapshot.d.ts +176 -0
  128. package/dist/snapshot.js +322 -0
  129. package/dist/streaming.d.ts +173 -0
  130. package/dist/streaming.js +268 -0
  131. package/dist/testing.d.ts +273 -0
  132. package/dist/testing.js +317 -0
  133. package/dist/types.d.ts +754 -0
  134. package/dist/types.js +54 -0
  135. package/dist/utils/input-hash.d.ts +8 -0
  136. package/dist/utils/input-hash.js +41 -0
  137. package/dist/version.d.ts +7 -0
  138. package/dist/version.js +10 -0
  139. package/dist/workflows.d.ts +389 -0
  140. package/dist/workflows.js +671 -0
  141. package/package.json +117 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,232 @@
1
+ "use strict";
2
+ var __createBinding =
3
+ (this && this.__createBinding) ||
4
+ (Object.create
5
+ ? function (o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (
9
+ !desc ||
10
+ ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)
11
+ ) {
12
+ desc = {
13
+ enumerable: true,
14
+ get: function () {
15
+ return m[k];
16
+ },
17
+ };
18
+ }
19
+ Object.defineProperty(o, k2, desc);
20
+ }
21
+ : function (o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ o[k2] = m[k];
24
+ });
25
+ var __setModuleDefault =
26
+ (this && this.__setModuleDefault) ||
27
+ (Object.create
28
+ ? function (o, v) {
29
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
30
+ }
31
+ : function (o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar =
35
+ (this && this.__importStar) ||
36
+ (function () {
37
+ var ownKeys = function (o) {
38
+ ownKeys =
39
+ Object.getOwnPropertyNames ||
40
+ function (o) {
41
+ var ar = [];
42
+ for (var k in o)
43
+ if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
44
+ return ar;
45
+ };
46
+ return ownKeys(o);
47
+ };
48
+ return function (mod) {
49
+ if (mod && mod.__esModule) return mod;
50
+ var result = {};
51
+ if (mod != null)
52
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++)
53
+ if (k[i] !== "default") __createBinding(result, mod, k[i]);
54
+ __setModuleDefault(result, mod);
55
+ return result;
56
+ };
57
+ })();
58
+ Object.defineProperty(exports, "__esModule", { value: true });
59
+ const vitest_1 = require("vitest");
60
+ const client_1 = require("./client");
61
+ const errorsModule = __importStar(require("./errors"));
62
+ vitest_1.vi.mock("./cache", () => {
63
+ const cacheTracker = { invalidatedPatterns: [] };
64
+ const shouldCache = vitest_1.vi.fn().mockReturnValue(true);
65
+ const getTTL = vitest_1.vi.fn().mockReturnValue(1000);
66
+ const makeKey = (method, url, params) =>
67
+ `${method}:${url}:${JSON.stringify(params ?? null)}`;
68
+ return {
69
+ __esModule: true,
70
+ shouldCache,
71
+ getTTL,
72
+ cacheTracker,
73
+ RequestCache: class RequestCache {
74
+ constructor() {
75
+ this.store = new Map();
76
+ }
77
+ get(method, url, params) {
78
+ const key = makeKey(method, url, params);
79
+ return this.store.get(key) ?? null;
80
+ }
81
+ set(method, url, data, _ttl, params) {
82
+ const key = makeKey(method, url, params);
83
+ this.store.set(key, data);
84
+ }
85
+ invalidatePattern(pattern) {
86
+ cacheTracker.invalidatedPatterns.push(pattern);
87
+ }
88
+ invalidate(_method, _url, _params) {
89
+ // no-op for tests
90
+ }
91
+ clear() {
92
+ this.store.clear();
93
+ }
94
+ },
95
+ };
96
+ });
97
+ const cache_1 = require("./cache");
98
+ (0, vitest_1.describe)("AIEvalClient.request", () => {
99
+ (0, vitest_1.beforeEach)(() => {
100
+ process.env.EVALAI_API_KEY = "test";
101
+ cache_1.shouldCache.mockReset().mockReturnValue(true);
102
+ cache_1.getTTL.mockReset().mockReturnValue(1000);
103
+ cache_1.cacheTracker.invalidatedPatterns.length = 0;
104
+ });
105
+ (0, vitest_1.it)(
106
+ "caches GET responses and reuses data without re-fetching",
107
+ async () => {
108
+ const client = new client_1.AIEvalClient({
109
+ apiKey: "test",
110
+ baseUrl: "http://localhost",
111
+ timeout: 1000,
112
+ });
113
+ const payload = { items: [1, 2, 3] };
114
+ const fetchMock = vitest_1.vi.fn().mockResolvedValue({
115
+ ok: true,
116
+ status: 200,
117
+ json: async () => payload,
118
+ });
119
+ globalThis.fetch = fetchMock;
120
+ const first = await client.request("/api/traces", { method: "GET" });
121
+ const second = await client.request("/api/traces", { method: "GET" });
122
+ (0, vitest_1.expect)(first).toEqual(payload);
123
+ (0, vitest_1.expect)(second).toEqual(payload);
124
+ (0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(1);
125
+ },
126
+ );
127
+ (0, vitest_1.it)("propagates non-ok responses as SDK errors", async () => {
128
+ const client = new client_1.AIEvalClient({
129
+ apiKey: "test",
130
+ baseUrl: "http://localhost",
131
+ });
132
+ const fetchMock = vitest_1.vi.fn().mockResolvedValue({
133
+ ok: false,
134
+ status: 429,
135
+ json: async () => ({ error: { code: "RATE_LIMIT_EXCEEDED" } }),
136
+ });
137
+ globalThis.fetch = fetchMock;
138
+ const createErrorSpy = vitest_1.vi
139
+ .spyOn(errorsModule, "createErrorFromResponse")
140
+ .mockReturnValue(
141
+ new errorsModule.EvalAIError(
142
+ "rate limited",
143
+ "RATE_LIMIT_EXCEEDED",
144
+ 429,
145
+ ),
146
+ );
147
+ await (0, vitest_1.expect)(
148
+ client.request("/api/fail", { method: "GET" }),
149
+ ).rejects.toHaveProperty("code", "RATE_LIMIT_EXCEEDED");
150
+ createErrorSpy.mockRestore();
151
+ });
152
+ (0, vitest_1.it)(
153
+ "retries on retryable SDK errors and eventually succeeds",
154
+ async () => {
155
+ const client = new client_1.AIEvalClient({
156
+ apiKey: "test",
157
+ baseUrl: "http://localhost",
158
+ timeout: 1000,
159
+ });
160
+ vitest_1.vi.spyOn(client, "calculateBackoff").mockReturnValue(0);
161
+ const failureResponse = {
162
+ ok: false,
163
+ status: 429,
164
+ json: async () => ({ error: { code: "RATE_LIMIT_EXCEEDED" } }),
165
+ };
166
+ const successResponse = {
167
+ ok: true,
168
+ status: 200,
169
+ json: async () => ({ ok: true }),
170
+ };
171
+ const createErrorSpy = vitest_1.vi
172
+ .spyOn(errorsModule, "createErrorFromResponse")
173
+ .mockReturnValue(
174
+ new errorsModule.EvalAIError(
175
+ "rate limited",
176
+ "RATE_LIMIT_EXCEEDED",
177
+ 429,
178
+ ),
179
+ );
180
+ const fetchMock = vitest_1.vi
181
+ .fn()
182
+ .mockResolvedValueOnce(failureResponse)
183
+ .mockResolvedValueOnce(successResponse);
184
+ globalThis.fetch = fetchMock;
185
+ const result = await client.request("/api/retry", { method: "GET" });
186
+ (0, vitest_1.expect)(result).toEqual({ ok: true });
187
+ (0, vitest_1.expect)(fetchMock).toHaveBeenCalledTimes(2);
188
+ createErrorSpy.mockRestore();
189
+ },
190
+ );
191
+ (0, vitest_1.it)("throws a TIMEOUT SDK error when fetch aborts", async () => {
192
+ const client = new client_1.AIEvalClient({
193
+ apiKey: "test",
194
+ baseUrl: "http://localhost",
195
+ timeout: 1000,
196
+ });
197
+ const abortError = Object.assign(new Error("aborted"), {
198
+ name: "AbortError",
199
+ });
200
+ const fetchMock = vitest_1.vi.fn().mockRejectedValue(abortError);
201
+ globalThis.fetch = fetchMock;
202
+ await (0, vitest_1.expect)(
203
+ client.request("/api/timeout", { method: "GET" }),
204
+ ).rejects.toMatchObject({
205
+ code: "TIMEOUT",
206
+ });
207
+ });
208
+ (0, vitest_1.it)(
209
+ "invalidates related cache entries for mutation requests",
210
+ async () => {
211
+ const client = new client_1.AIEvalClient({
212
+ apiKey: "test",
213
+ baseUrl: "http://localhost",
214
+ timeout: 1000,
215
+ });
216
+ cache_1.shouldCache.mockReturnValue(false);
217
+ const fetchMock = vitest_1.vi.fn().mockResolvedValue({
218
+ ok: true,
219
+ status: 201,
220
+ json: async () => ({ result: "ok" }),
221
+ });
222
+ globalThis.fetch = fetchMock;
223
+ await client.request("/api/evaluations", {
224
+ method: "POST",
225
+ body: JSON.stringify({}),
226
+ });
227
+ (0, vitest_1.expect)(cache_1.cacheTracker.invalidatedPatterns).toContain(
228
+ "evaluations",
229
+ );
230
+ },
231
+ );
232
+ });
@@ -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]: unknown;
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 unknown)
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, unknown>): Record<string, unknown>;
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: unknown, _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("node: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 unknown)
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 (_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,82 @@
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 EvalGateError) {
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 EvalGateError 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?: unknown;
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
+ /** Request ID from API (for correlation/debugging) */
51
+ requestId?: string;
52
+ constructor(message: string, code: string, statusCode: number, details?: unknown);
53
+ /**
54
+ * Get formatted error message with solutions
55
+ */
56
+ getDetailedMessage(): string;
57
+ /**
58
+ * Check if this error should be retried
59
+ */
60
+ shouldRetry(): boolean;
61
+ /**
62
+ * Convert to JSON for logging
63
+ */
64
+ toJSON(): Record<string, unknown>;
65
+ }
66
+ /**
67
+ * Create an error from an HTTP response
68
+ */
69
+ export declare function createErrorFromResponse(response: Response, data: unknown): EvalGateError;
70
+ export declare class RateLimitError extends EvalGateError {
71
+ constructor(message: string, retryAfter?: number);
72
+ }
73
+ export declare class AuthenticationError extends EvalGateError {
74
+ constructor(message?: string);
75
+ }
76
+ export declare class ValidationError extends EvalGateError {
77
+ constructor(message?: string, details?: unknown);
78
+ }
79
+ export declare class NetworkError extends EvalGateError {
80
+ constructor(message?: string);
81
+ }
82
+ export { EvalGateError as SDKError };