@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.
- package/CHANGELOG.md +638 -0
- package/README.md +398 -0
- package/dist/assertions.d.ts +189 -0
- package/dist/assertions.js +662 -0
- package/dist/batch.d.ts +68 -0
- package/dist/batch.js +179 -0
- package/dist/cache.d.ts +65 -0
- package/dist/cache.js +131 -0
- package/dist/cli/api.d.ts +108 -0
- package/dist/cli/api.js +132 -0
- package/dist/cli/baseline.d.ts +10 -0
- package/dist/cli/baseline.js +172 -0
- package/dist/cli/check.d.ts +73 -0
- package/dist/cli/check.js +355 -0
- package/dist/cli/ci-context.d.ts +6 -0
- package/dist/cli/ci-context.js +112 -0
- package/dist/cli/ci.d.ts +45 -0
- package/dist/cli/ci.js +192 -0
- package/dist/cli/config.d.ts +30 -0
- package/dist/cli/config.js +230 -0
- package/dist/cli/constants.d.ts +15 -0
- package/dist/cli/constants.js +18 -0
- package/dist/cli/diff.d.ts +173 -0
- package/dist/cli/diff.js +685 -0
- package/dist/cli/discover.d.ts +84 -0
- package/dist/cli/discover.js +419 -0
- package/dist/cli/doctor.d.ts +88 -0
- package/dist/cli/doctor.js +675 -0
- package/dist/cli/env.d.ts +21 -0
- package/dist/cli/env.js +42 -0
- package/dist/cli/explain.d.ts +58 -0
- package/dist/cli/explain.js +561 -0
- package/dist/cli/formatters/github.d.ts +8 -0
- package/dist/cli/formatters/github.js +135 -0
- package/dist/cli/formatters/human.d.ts +6 -0
- package/dist/cli/formatters/human.js +110 -0
- package/dist/cli/formatters/json.d.ts +6 -0
- package/dist/cli/formatters/json.js +10 -0
- package/dist/cli/formatters/pr-comment.d.ts +12 -0
- package/dist/cli/formatters/pr-comment.js +103 -0
- package/dist/cli/formatters/types.d.ts +103 -0
- package/dist/cli/formatters/types.js +8 -0
- package/dist/cli/gate.d.ts +21 -0
- package/dist/cli/gate.js +179 -0
- package/dist/cli/impact-analysis.d.ts +63 -0
- package/dist/cli/impact-analysis.js +252 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.js +332 -0
- package/dist/cli/init.d.ts +16 -0
- package/dist/cli/init.js +292 -0
- package/dist/cli/manifest.d.ts +103 -0
- package/dist/cli/manifest.js +282 -0
- package/dist/cli/migrate.d.ts +41 -0
- package/dist/cli/migrate.js +349 -0
- package/dist/cli/policy-packs.d.ts +23 -0
- package/dist/cli/policy-packs.js +89 -0
- package/dist/cli/print-config.d.ts +29 -0
- package/dist/cli/print-config.js +270 -0
- package/dist/cli/profiles.d.ts +28 -0
- package/dist/cli/profiles.js +30 -0
- package/dist/cli/reason-codes.d.ts +17 -0
- package/dist/cli/reason-codes.js +19 -0
- package/dist/cli/regression-gate.d.ts +15 -0
- package/dist/cli/regression-gate.js +341 -0
- package/dist/cli/render/snippet.d.ts +5 -0
- package/dist/cli/render/snippet.js +15 -0
- package/dist/cli/render/sort.d.ts +10 -0
- package/dist/cli/render/sort.js +24 -0
- package/dist/cli/report/build-check-report.d.ts +19 -0
- package/dist/cli/report/build-check-report.js +132 -0
- package/dist/cli/run.d.ts +101 -0
- package/dist/cli/run.js +395 -0
- package/dist/cli/share.d.ts +17 -0
- package/dist/cli/share.js +91 -0
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +492 -0
- package/dist/cli/workspace.d.ts +31 -0
- package/dist/cli/workspace.js +68 -0
- package/dist/client.d.ts +368 -0
- package/dist/client.js +893 -0
- package/dist/client.request.test.d.ts +1 -0
- package/dist/client.request.test.js +232 -0
- package/dist/context.d.ts +134 -0
- package/dist/context.js +215 -0
- package/dist/errors.d.ts +82 -0
- package/dist/errors.js +298 -0
- package/dist/export.d.ts +195 -0
- package/dist/export.js +344 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +153 -0
- package/dist/integrations/anthropic.d.ts +91 -0
- package/dist/integrations/anthropic.js +163 -0
- package/dist/integrations/openai-eval.d.ts +57 -0
- package/dist/integrations/openai-eval.js +232 -0
- package/dist/integrations/openai.d.ts +92 -0
- package/dist/integrations/openai.js +160 -0
- package/dist/local.d.ts +39 -0
- package/dist/local.js +148 -0
- package/dist/logger.d.ts +128 -0
- package/dist/logger.js +227 -0
- package/dist/matchers/index.d.ts +1 -0
- package/dist/matchers/index.js +6 -0
- package/dist/matchers/to-pass-gate.d.ts +29 -0
- package/dist/matchers/to-pass-gate.js +35 -0
- package/dist/pagination.d.ts +74 -0
- package/dist/pagination.js +139 -0
- package/dist/regression.d.ts +100 -0
- package/dist/regression.js +44 -0
- package/dist/runtime/adapters/config-to-dsl.d.ts +33 -0
- package/dist/runtime/adapters/config-to-dsl.js +400 -0
- package/dist/runtime/adapters/testsuite-to-dsl.d.ts +63 -0
- package/dist/runtime/adapters/testsuite-to-dsl.js +276 -0
- package/dist/runtime/context.d.ts +26 -0
- package/dist/runtime/context.js +74 -0
- package/dist/runtime/eval.d.ts +46 -0
- package/dist/runtime/eval.js +244 -0
- package/dist/runtime/execution-mode.d.ts +80 -0
- package/dist/runtime/execution-mode.js +357 -0
- package/dist/runtime/executor.d.ts +16 -0
- package/dist/runtime/executor.js +152 -0
- package/dist/runtime/registry.d.ts +78 -0
- package/dist/runtime/registry.js +403 -0
- package/dist/runtime/run-report.d.ts +200 -0
- package/dist/runtime/run-report.js +222 -0
- package/dist/runtime/types.d.ts +356 -0
- package/dist/runtime/types.js +76 -0
- package/dist/snapshot.d.ts +176 -0
- package/dist/snapshot.js +322 -0
- package/dist/streaming.d.ts +173 -0
- package/dist/streaming.js +268 -0
- package/dist/testing.d.ts +273 -0
- package/dist/testing.js +317 -0
- package/dist/types.d.ts +754 -0
- package/dist/types.js +54 -0
- package/dist/utils/input-hash.d.ts +8 -0
- package/dist/utils/input-hash.js +41 -0
- package/dist/version.d.ts +7 -0
- package/dist/version.js +10 -0
- package/dist/workflows.d.ts +389 -0
- package/dist/workflows.js +671 -0
- 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
|
+
}
|
package/dist/local.d.ts
ADDED
|
@@ -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;
|
package/dist/logger.d.ts
ADDED
|
@@ -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";
|