@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,160 @@
1
+ "use strict";
2
+ /**
3
+ * OpenAI Integration
4
+ * Tier 1.2: Framework Auto-Instrumentation - OpenAI wrapper
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { traceOpenAI } from '@ai-eval-platform/sdk/integrations/openai';
9
+ * import OpenAI from 'openai';
10
+ *
11
+ * const openai = new OpenAI({ apiKey: '...' });
12
+ * const tracedOpenAI = traceOpenAI(openai, client);
13
+ *
14
+ * // All calls are automatically traced
15
+ * const response = await tracedOpenAI.chat.completions.create({
16
+ * model: 'gpt-4',
17
+ * messages: [{ role: 'user', content: 'Hello!' }]
18
+ * });
19
+ * ```
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.traceOpenAI = traceOpenAI;
23
+ exports.traceOpenAICall = traceOpenAICall;
24
+ const context_1 = require("../context");
25
+ /**
26
+ * Wrap OpenAI client with automatic tracing
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import OpenAI from 'openai';
31
+ * import { traceOpenAI } from '@ai-eval-platform/sdk/integrations/openai';
32
+ *
33
+ * const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
34
+ * const tracedOpenAI = traceOpenAI(openai, evalClient);
35
+ *
36
+ * // Automatically traced
37
+ * const completion = await tracedOpenAI.chat.completions.create({
38
+ * model: 'gpt-4',
39
+ * messages: [{ role: 'user', content: 'Hello!' }]
40
+ * });
41
+ * ```
42
+ */
43
+ function traceOpenAI(openai, evalClient, options = {}) {
44
+ const { captureInput = true, captureOutput = true, captureMetadata = true, organizationId, tracePrefix = "openai", } = options;
45
+ // Create proxy for chat.completions.create
46
+ const originalCreate = openai.chat.completions.create.bind(openai.chat.completions);
47
+ openai.chat.completions.create = async (params, requestOptions) => {
48
+ const startTime = Date.now();
49
+ const traceId = `${tracePrefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
50
+ try {
51
+ // Call original method
52
+ const response = await originalCreate(params, requestOptions);
53
+ const durationMs = Date.now() - startTime;
54
+ // Create trace with success status and complete metadata
55
+ const traceMetadata = (0, context_1.mergeWithContext)({
56
+ model: params.model,
57
+ temperature: params.temperature,
58
+ max_tokens: params.max_tokens,
59
+ ...(captureInput ? { input: params.messages } : {}),
60
+ ...(captureOutput ? { output: response.choices[0]?.message } : {}),
61
+ ...(captureMetadata
62
+ ? {
63
+ usage: response.usage,
64
+ finish_reason: response.choices[0]?.finish_reason,
65
+ }
66
+ : {}),
67
+ });
68
+ await evalClient.traces.create({
69
+ name: `OpenAI: ${params.model}`,
70
+ traceId,
71
+ organizationId: organizationId || evalClient.getOrganizationId(),
72
+ status: "success",
73
+ durationMs,
74
+ metadata: traceMetadata,
75
+ });
76
+ return response;
77
+ }
78
+ catch (error) {
79
+ const durationMs = Date.now() - startTime;
80
+ // Create trace with error status
81
+ const errorMetadata = (0, context_1.mergeWithContext)({
82
+ model: params.model,
83
+ temperature: params.temperature,
84
+ max_tokens: params.max_tokens,
85
+ ...(captureInput ? { input: params.messages } : {}),
86
+ ...(captureMetadata ? { params } : {}),
87
+ error: error instanceof Error ? error.message : String(error),
88
+ });
89
+ await evalClient.traces
90
+ .create({
91
+ name: `OpenAI: ${params.model}`,
92
+ traceId,
93
+ organizationId: organizationId || evalClient.getOrganizationId(),
94
+ status: "error",
95
+ durationMs,
96
+ metadata: errorMetadata,
97
+ })
98
+ .catch(() => {
99
+ // Ignore errors in trace creation to avoid masking the original error
100
+ });
101
+ throw error;
102
+ }
103
+ };
104
+ return openai;
105
+ }
106
+ /**
107
+ * Manual trace wrapper for OpenAI calls
108
+ *
109
+ * @example
110
+ * ```typescript
111
+ * const response = await traceOpenAICall(
112
+ * evalClient,
113
+ * 'gpt-4-completion',
114
+ * async () => {
115
+ * return await openai.chat.completions.create({
116
+ * model: 'gpt-4',
117
+ * messages: [{ role: 'user', content: 'Hello!' }]
118
+ * });
119
+ * }
120
+ * );
121
+ * ```
122
+ */
123
+ async function traceOpenAICall(evalClient, name, fn, options = {}) {
124
+ const startTime = Date.now();
125
+ const traceId = `openai-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
126
+ try {
127
+ await evalClient.traces.create({
128
+ name,
129
+ traceId,
130
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
131
+ status: "pending",
132
+ metadata: (0, context_1.mergeWithContext)({}),
133
+ });
134
+ const result = await fn();
135
+ const durationMs = Date.now() - startTime;
136
+ await evalClient.traces.create({
137
+ name,
138
+ traceId,
139
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
140
+ status: "success",
141
+ durationMs,
142
+ metadata: (0, context_1.mergeWithContext)({}),
143
+ });
144
+ return result;
145
+ }
146
+ catch (error) {
147
+ const durationMs = Date.now() - startTime;
148
+ await evalClient.traces.create({
149
+ name,
150
+ traceId,
151
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
152
+ status: "error",
153
+ durationMs,
154
+ metadata: (0, context_1.mergeWithContext)({
155
+ error: error instanceof Error ? error.message : String(error),
156
+ }),
157
+ });
158
+ throw error;
159
+ }
160
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Local Development Mode (Tier 2.10)
3
+ * Offline mode with local storage for development
4
+ *
5
+ * ⚠️ NOTE: This module requires Node.js and will not work in browsers.
6
+ */
7
+ import type { Evaluation, Span, Trace } from "./types";
8
+ export interface LocalStorageOptions {
9
+ directory?: string;
10
+ autoSave?: boolean;
11
+ }
12
+ export declare class LocalStorage {
13
+ private directory;
14
+ private autoSave;
15
+ private traces;
16
+ private evaluations;
17
+ private spans;
18
+ constructor(options?: LocalStorageOptions);
19
+ private initialize;
20
+ private loadAllData;
21
+ private saveTraceToDisk;
22
+ saveTrace(trace: Trace): Promise<void>;
23
+ getTrace(id: string): Promise<Trace | undefined>;
24
+ listTraces(): Promise<Trace[]>;
25
+ private saveEvaluationToDisk;
26
+ saveEvaluation(evaluation: Evaluation): Promise<void>;
27
+ getEvaluation(id: string): Promise<Evaluation | undefined>;
28
+ listEvaluations(): Promise<Evaluation[]>;
29
+ private saveSpansToDisk;
30
+ saveSpans(traceId: string, spans: Span[]): Promise<void>;
31
+ getSpans(traceId: string): Promise<Span[] | undefined>;
32
+ clear(): Promise<void>;
33
+ export(_format: "json"): Promise<string>;
34
+ getStats(): {
35
+ traces: number;
36
+ evaluations: number;
37
+ totalSpans: number;
38
+ };
39
+ }
package/dist/local.js ADDED
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ /**
3
+ * Local Development Mode (Tier 2.10)
4
+ * Offline mode with local storage for development
5
+ *
6
+ * ⚠️ NOTE: This module requires Node.js and will not work in browsers.
7
+ */
8
+ var __importDefault = (this && this.__importDefault) || function (mod) {
9
+ return (mod && mod.__esModule) ? mod : { "default": mod };
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LocalStorage = void 0;
13
+ // Environment check
14
+ const isNode = typeof process !== "undefined" && process.versions?.node;
15
+ if (!isNode) {
16
+ throw new Error("Local storage mode requires Node.js and cannot run in browsers. " +
17
+ "This feature uses the filesystem for storing data.");
18
+ }
19
+ const promises_1 = __importDefault(require("node:fs/promises"));
20
+ const node_path_1 = __importDefault(require("node:path"));
21
+ class LocalStorage {
22
+ constructor(options = {}) {
23
+ this.traces = new Map();
24
+ this.evaluations = new Map();
25
+ this.spans = new Map();
26
+ this.directory = options.directory || "./.evalgate-data";
27
+ this.autoSave = options.autoSave !== false;
28
+ this.initialize();
29
+ }
30
+ async initialize() {
31
+ try {
32
+ await promises_1.default.mkdir(this.directory, { recursive: true });
33
+ await promises_1.default.mkdir(node_path_1.default.join(this.directory, "traces"), { recursive: true });
34
+ await promises_1.default.mkdir(node_path_1.default.join(this.directory, "evaluations"), {
35
+ recursive: true,
36
+ });
37
+ await promises_1.default.mkdir(node_path_1.default.join(this.directory, "spans"), { recursive: true });
38
+ // Load existing data
39
+ await this.loadAllData();
40
+ }
41
+ catch (error) {
42
+ console.warn("Failed to initialize local storage:", error);
43
+ }
44
+ }
45
+ async loadAllData() {
46
+ try {
47
+ // Load traces
48
+ const tracesDir = node_path_1.default.join(this.directory, "traces");
49
+ const traceFiles = await promises_1.default.readdir(tracesDir);
50
+ for (const file of traceFiles) {
51
+ if (file.endsWith(".json")) {
52
+ const content = await promises_1.default.readFile(node_path_1.default.join(tracesDir, file), "utf-8");
53
+ const trace = JSON.parse(content);
54
+ this.traces.set(trace.id.toString(), trace);
55
+ }
56
+ }
57
+ // Load evaluations
58
+ const evalsDir = node_path_1.default.join(this.directory, "evaluations");
59
+ const evalFiles = await promises_1.default.readdir(evalsDir);
60
+ for (const file of evalFiles) {
61
+ if (file.endsWith(".json")) {
62
+ const content = await promises_1.default.readFile(node_path_1.default.join(evalsDir, file), "utf-8");
63
+ const evaluation = JSON.parse(content);
64
+ this.evaluations.set(evaluation.id.toString(), evaluation);
65
+ }
66
+ }
67
+ }
68
+ catch (_error) {
69
+ // Directories might not exist yet, that's fine
70
+ }
71
+ }
72
+ async saveTraceToDisk(trace) {
73
+ const filePath = node_path_1.default.join(this.directory, "traces", `${trace.id}.json`);
74
+ await promises_1.default.writeFile(filePath, JSON.stringify(trace, null, 2));
75
+ }
76
+ async saveTrace(trace) {
77
+ this.traces.set(trace.id.toString(), trace);
78
+ if (this.autoSave) {
79
+ await this.saveTraceToDisk(trace);
80
+ }
81
+ }
82
+ async getTrace(id) {
83
+ return this.traces.get(id);
84
+ }
85
+ async listTraces() {
86
+ return Array.from(this.traces.values());
87
+ }
88
+ async saveEvaluationToDisk(evaluation) {
89
+ const filePath = node_path_1.default.join(this.directory, "evaluations", `${evaluation.id}.json`);
90
+ await promises_1.default.writeFile(filePath, JSON.stringify(evaluation, null, 2));
91
+ }
92
+ async saveEvaluation(evaluation) {
93
+ this.evaluations.set(evaluation.id.toString(), evaluation);
94
+ if (this.autoSave) {
95
+ await this.saveEvaluationToDisk(evaluation);
96
+ }
97
+ }
98
+ async getEvaluation(id) {
99
+ return this.evaluations.get(id);
100
+ }
101
+ async listEvaluations() {
102
+ return Array.from(this.evaluations.values());
103
+ }
104
+ async saveSpansToDisk(traceId, spans) {
105
+ const filePath = node_path_1.default.join(this.directory, "spans", `${traceId}.json`);
106
+ await promises_1.default.writeFile(filePath, JSON.stringify(spans, null, 2));
107
+ }
108
+ async saveSpans(traceId, spans) {
109
+ this.spans.set(traceId, spans);
110
+ if (this.autoSave) {
111
+ await this.saveSpansToDisk(traceId, spans);
112
+ }
113
+ }
114
+ async getSpans(traceId) {
115
+ return this.spans.get(traceId);
116
+ }
117
+ async clear() {
118
+ this.traces.clear();
119
+ this.evaluations.clear();
120
+ this.spans.clear();
121
+ // Optionally delete files
122
+ try {
123
+ await promises_1.default.rm(this.directory, { recursive: true, force: true });
124
+ await this.initialize();
125
+ }
126
+ catch (error) {
127
+ console.warn("Failed to clear local storage:", error);
128
+ }
129
+ }
130
+ async export(_format) {
131
+ const data = {
132
+ traces: Array.from(this.traces.values()),
133
+ evaluations: Array.from(this.evaluations.values()),
134
+ spans: Object.fromEntries(this.spans),
135
+ };
136
+ const exportPath = node_path_1.default.join(this.directory, `export-${Date.now()}.json`);
137
+ await promises_1.default.writeFile(exportPath, JSON.stringify(data, null, 2));
138
+ return exportPath;
139
+ }
140
+ getStats() {
141
+ return {
142
+ traces: this.traces.size,
143
+ evaluations: this.evaluations.size,
144
+ totalSpans: Array.from(this.spans.values()).reduce((sum, spans) => sum + spans.length, 0),
145
+ };
146
+ }
147
+ }
148
+ exports.LocalStorage = LocalStorage;
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Debug Mode with Request Logging
3
+ * Tier 4.17: Troubleshooting utilities
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { createLogger } from '@ai-eval-platform/sdk';
8
+ *
9
+ * const logger = createLogger({ level: 'debug', pretty: true });
10
+ *
11
+ * logger.debug('Trace created', { traceId: '123' });
12
+ * logger.error('Request failed', { error: err });
13
+ * ```
14
+ */
15
+ export type LogLevel = "trace" | "debug" | "info" | "warn" | "error";
16
+ export interface LoggerOptions {
17
+ /** Log level (default: 'info') */
18
+ level?: LogLevel;
19
+ /** Pretty print logs (default: false) */
20
+ pretty?: boolean;
21
+ /** Include timestamps (default: true) */
22
+ timestamps?: boolean;
23
+ /** Custom log handler */
24
+ handler?: (entry: LogEntry) => void;
25
+ /** Prefix for all logs */
26
+ prefix?: string;
27
+ }
28
+ export interface LogEntry {
29
+ level: LogLevel;
30
+ message: string;
31
+ timestamp: string;
32
+ data?: unknown;
33
+ prefix?: string;
34
+ }
35
+ /**
36
+ * Logger for SDK debugging and troubleshooting
37
+ */
38
+ export declare class Logger {
39
+ private options;
40
+ constructor(options?: LoggerOptions);
41
+ /**
42
+ * Log a trace message
43
+ */
44
+ trace(message: string, data?: unknown): void;
45
+ /**
46
+ * Log a debug message
47
+ */
48
+ debug(message: string, data?: unknown): void;
49
+ /**
50
+ * Log an info message
51
+ */
52
+ info(message: string, data?: unknown): void;
53
+ /**
54
+ * Log a warning message
55
+ */
56
+ warn(message: string, data?: unknown): void;
57
+ /**
58
+ * Log an error message
59
+ */
60
+ error(message: string, data?: unknown): void;
61
+ /**
62
+ * Log HTTP request
63
+ */
64
+ logRequest(method: string, url: string, data?: unknown): void;
65
+ /**
66
+ * Log HTTP response
67
+ */
68
+ logResponse(method: string, url: string, status: number, duration: number, data?: unknown): void;
69
+ /**
70
+ * Create child logger with prefix
71
+ */
72
+ child(prefix: string): Logger;
73
+ /**
74
+ * Set log level
75
+ */
76
+ setLevel(level: LogLevel): void;
77
+ /**
78
+ * Check if level is enabled
79
+ */
80
+ isLevelEnabled(level: LogLevel): boolean;
81
+ private log;
82
+ private defaultHandler;
83
+ }
84
+ /**
85
+ * Create a logger instance
86
+ *
87
+ * @example
88
+ * ```typescript
89
+ * const logger = createLogger({ level: 'debug', pretty: true });
90
+ * logger.debug('Starting evaluation');
91
+ * ```
92
+ */
93
+ export declare function createLogger(options?: LoggerOptions): Logger;
94
+ /**
95
+ * Get global logger (creates one if it doesn't exist)
96
+ */
97
+ export declare function getLogger(): Logger;
98
+ /**
99
+ * Set global logger
100
+ */
101
+ export declare function setLogger(logger: Logger): void;
102
+ /**
103
+ * Request/Response interceptor for logging
104
+ */
105
+ export declare class RequestLogger {
106
+ private logger;
107
+ constructor(logger: Logger);
108
+ /**
109
+ * Log request before sending
110
+ */
111
+ logRequest(request: {
112
+ method: string;
113
+ url: string;
114
+ headers?: Record<string, string>;
115
+ body?: unknown;
116
+ }): void;
117
+ /**
118
+ * Log response after receiving
119
+ */
120
+ logResponse(response: {
121
+ method: string;
122
+ url: string;
123
+ status: number;
124
+ duration: number;
125
+ headers?: Record<string, string>;
126
+ body?: unknown;
127
+ }): void;
128
+ }
package/dist/logger.js ADDED
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ /**
3
+ * Debug Mode with Request Logging
4
+ * Tier 4.17: Troubleshooting utilities
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createLogger } from '@ai-eval-platform/sdk';
9
+ *
10
+ * const logger = createLogger({ level: 'debug', pretty: true });
11
+ *
12
+ * logger.debug('Trace created', { traceId: '123' });
13
+ * logger.error('Request failed', { error: err });
14
+ * ```
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.RequestLogger = exports.Logger = void 0;
18
+ exports.createLogger = createLogger;
19
+ exports.getLogger = getLogger;
20
+ exports.setLogger = setLogger;
21
+ const LOG_LEVELS = {
22
+ trace: 0,
23
+ debug: 1,
24
+ info: 2,
25
+ warn: 3,
26
+ error: 4,
27
+ };
28
+ const LOG_COLORS = {
29
+ trace: "\x1b[90m", // gray
30
+ debug: "\x1b[36m", // cyan
31
+ info: "\x1b[32m", // green
32
+ warn: "\x1b[33m", // yellow
33
+ error: "\x1b[31m", // red
34
+ };
35
+ const COLOR_RESET = "\x1b[0m";
36
+ /**
37
+ * Logger for SDK debugging and troubleshooting
38
+ */
39
+ class Logger {
40
+ constructor(options = {}) {
41
+ this.options = {
42
+ level: options.level || "info",
43
+ pretty: options.pretty ?? false,
44
+ timestamps: options.timestamps ?? true,
45
+ handler: options.handler || this.defaultHandler.bind(this),
46
+ prefix: options.prefix || "EvalGate",
47
+ };
48
+ }
49
+ /**
50
+ * Log a trace message
51
+ */
52
+ trace(message, data) {
53
+ this.log("trace", message, data);
54
+ }
55
+ /**
56
+ * Log a debug message
57
+ */
58
+ debug(message, data) {
59
+ this.log("debug", message, data);
60
+ }
61
+ /**
62
+ * Log an info message
63
+ */
64
+ info(message, data) {
65
+ this.log("info", message, data);
66
+ }
67
+ /**
68
+ * Log a warning message
69
+ */
70
+ warn(message, data) {
71
+ this.log("warn", message, data);
72
+ }
73
+ /**
74
+ * Log an error message
75
+ */
76
+ error(message, data) {
77
+ this.log("error", message, data);
78
+ }
79
+ /**
80
+ * Log HTTP request
81
+ */
82
+ logRequest(method, url, data) {
83
+ this.debug(`→ ${method} ${url}`, data);
84
+ }
85
+ /**
86
+ * Log HTTP response
87
+ */
88
+ logResponse(method, url, status, duration, data) {
89
+ const level = status >= 400 ? "error" : status >= 300 ? "warn" : "debug";
90
+ this.log(level, `← ${method} ${url} ${status} (${duration}ms)`, data);
91
+ }
92
+ /**
93
+ * Create child logger with prefix
94
+ */
95
+ child(prefix) {
96
+ return new Logger({
97
+ ...this.options,
98
+ prefix: `${this.options.prefix}:${prefix}`,
99
+ });
100
+ }
101
+ /**
102
+ * Set log level
103
+ */
104
+ setLevel(level) {
105
+ this.options.level = level;
106
+ }
107
+ /**
108
+ * Check if level is enabled
109
+ */
110
+ isLevelEnabled(level) {
111
+ return LOG_LEVELS[level] >= LOG_LEVELS[this.options.level];
112
+ }
113
+ log(level, message, data) {
114
+ if (!this.isLevelEnabled(level))
115
+ return;
116
+ const entry = {
117
+ level,
118
+ message,
119
+ timestamp: new Date().toISOString(),
120
+ data,
121
+ prefix: this.options.prefix,
122
+ };
123
+ this.options.handler(entry);
124
+ }
125
+ defaultHandler(entry) {
126
+ const parts = [];
127
+ // Timestamp
128
+ if (this.options.timestamps) {
129
+ const time = this.options.pretty
130
+ ? new Date(entry.timestamp).toLocaleTimeString()
131
+ : entry.timestamp;
132
+ parts.push(this.options.pretty ? `\x1b[90m${time}${COLOR_RESET}` : time);
133
+ }
134
+ // Level
135
+ const levelStr = entry.level.toUpperCase().padEnd(5);
136
+ parts.push(this.options.pretty
137
+ ? `${LOG_COLORS[entry.level]}${levelStr}${COLOR_RESET}`
138
+ : levelStr);
139
+ // Prefix
140
+ if (entry.prefix) {
141
+ parts.push(this.options.pretty
142
+ ? `\x1b[35m[${entry.prefix}]${COLOR_RESET}`
143
+ : `[${entry.prefix}]`);
144
+ }
145
+ // Message
146
+ parts.push(entry.message);
147
+ // Log
148
+ const logLine = parts.join(" ");
149
+ if (entry.level === "error") {
150
+ console.error(logLine);
151
+ }
152
+ else if (entry.level === "warn") {
153
+ console.warn(logLine);
154
+ }
155
+ else {
156
+ console.log(logLine);
157
+ }
158
+ // Data
159
+ if (entry.data !== undefined) {
160
+ if (this.options.pretty) {
161
+ console.log(JSON.stringify(entry.data, null, 2));
162
+ }
163
+ else {
164
+ console.log(JSON.stringify(entry.data));
165
+ }
166
+ }
167
+ }
168
+ }
169
+ exports.Logger = Logger;
170
+ /**
171
+ * Create a logger instance
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * const logger = createLogger({ level: 'debug', pretty: true });
176
+ * logger.debug('Starting evaluation');
177
+ * ```
178
+ */
179
+ function createLogger(options) {
180
+ return new Logger(options);
181
+ }
182
+ /**
183
+ * Global logger instance
184
+ */
185
+ let globalLogger;
186
+ /**
187
+ * Get global logger (creates one if it doesn't exist)
188
+ */
189
+ function getLogger() {
190
+ if (!globalLogger) {
191
+ globalLogger = new Logger();
192
+ }
193
+ return globalLogger;
194
+ }
195
+ /**
196
+ * Set global logger
197
+ */
198
+ function setLogger(logger) {
199
+ globalLogger = logger;
200
+ }
201
+ /**
202
+ * Request/Response interceptor for logging
203
+ */
204
+ class RequestLogger {
205
+ constructor(logger) {
206
+ this.logger = logger;
207
+ }
208
+ /**
209
+ * Log request before sending
210
+ */
211
+ logRequest(request) {
212
+ this.logger.logRequest(request.method, request.url, {
213
+ headers: request.headers,
214
+ body: request.body,
215
+ });
216
+ }
217
+ /**
218
+ * Log response after receiving
219
+ */
220
+ logResponse(response) {
221
+ this.logger.logResponse(response.method, response.url, response.status, response.duration, {
222
+ headers: response.headers,
223
+ body: response.body,
224
+ });
225
+ }
226
+ }
227
+ exports.RequestLogger = RequestLogger;
@@ -0,0 +1 @@
1
+ export { extendExpectWithToPassGate, toPassGate } from "./to-pass-gate";