@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,72 @@
1
+ /**
2
+ * Anthropic Integration
3
+ * Tier 1.2: Framework Auto-Instrumentation - Anthropic wrapper
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { traceAnthropic } from '@ai-eval-platform/sdk/integrations/anthropic';
8
+ * import Anthropic from '@anthropic-ai/sdk';
9
+ *
10
+ * const anthropic = new Anthropic({ apiKey: '...' });
11
+ * const tracedAnthropic = traceAnthropic(anthropic, client);
12
+ *
13
+ * // All calls are automatically traced
14
+ * const message = await tracedAnthropic.messages.create({
15
+ * model: 'claude-3-5-sonnet-20241022',
16
+ * max_tokens: 1024,
17
+ * messages: [{ role: 'user', content: 'Hello!' }]
18
+ * });
19
+ * ```
20
+ */
21
+ import type { AIEvalClient } from '../client';
22
+ export interface AnthropicTraceOptions {
23
+ /** Whether to capture input (default: true) */
24
+ captureInput?: boolean;
25
+ /** Whether to capture output (default: true) */
26
+ captureOutput?: boolean;
27
+ /** Whether to capture metadata (default: true) */
28
+ captureMetadata?: boolean;
29
+ /** Organization ID for traces */
30
+ organizationId?: number;
31
+ /** Custom trace name prefix */
32
+ tracePrefix?: string;
33
+ }
34
+ /**
35
+ * Wrap Anthropic client with automatic tracing
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * import Anthropic from '@anthropic-ai/sdk';
40
+ * import { traceAnthropic } from '@ai-eval-platform/sdk/integrations/anthropic';
41
+ *
42
+ * const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
43
+ * const tracedAnthropic = traceAnthropic(anthropic, evalClient);
44
+ *
45
+ * // Automatically traced
46
+ * const message = await tracedAnthropic.messages.create({
47
+ * model: 'claude-3-5-sonnet-20241022',
48
+ * max_tokens: 1024,
49
+ * messages: [{ role: 'user', content: 'Hello, Claude!' }]
50
+ * });
51
+ * ```
52
+ */
53
+ export declare function traceAnthropic(anthropic: any, evalClient: AIEvalClient, options?: AnthropicTraceOptions): any;
54
+ /**
55
+ * Manual trace wrapper for Anthropic calls
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const message = await traceAnthropicCall(
60
+ * evalClient,
61
+ * 'claude-completion',
62
+ * async () => {
63
+ * return await anthropic.messages.create({
64
+ * model: 'claude-3-5-sonnet-20241022',
65
+ * max_tokens: 1024,
66
+ * messages: [{ role: 'user', content: 'Hello!' }]
67
+ * });
68
+ * }
69
+ * );
70
+ * ```
71
+ */
72
+ export declare function traceAnthropicCall<T>(evalClient: AIEvalClient, name: string, fn: () => Promise<T>, options?: AnthropicTraceOptions): Promise<T>;
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * Anthropic Integration
4
+ * Tier 1.2: Framework Auto-Instrumentation - Anthropic wrapper
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { traceAnthropic } from '@ai-eval-platform/sdk/integrations/anthropic';
9
+ * import Anthropic from '@anthropic-ai/sdk';
10
+ *
11
+ * const anthropic = new Anthropic({ apiKey: '...' });
12
+ * const tracedAnthropic = traceAnthropic(anthropic, client);
13
+ *
14
+ * // All calls are automatically traced
15
+ * const message = await tracedAnthropic.messages.create({
16
+ * model: 'claude-3-5-sonnet-20241022',
17
+ * max_tokens: 1024,
18
+ * messages: [{ role: 'user', content: 'Hello!' }]
19
+ * });
20
+ * ```
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.traceAnthropic = traceAnthropic;
24
+ exports.traceAnthropicCall = traceAnthropicCall;
25
+ const context_1 = require("../context");
26
+ /**
27
+ * Wrap Anthropic client with automatic tracing
28
+ *
29
+ * @example
30
+ * ```typescript
31
+ * import Anthropic from '@anthropic-ai/sdk';
32
+ * import { traceAnthropic } from '@ai-eval-platform/sdk/integrations/anthropic';
33
+ *
34
+ * const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
35
+ * const tracedAnthropic = traceAnthropic(anthropic, evalClient);
36
+ *
37
+ * // Automatically traced
38
+ * const message = await tracedAnthropic.messages.create({
39
+ * model: 'claude-3-5-sonnet-20241022',
40
+ * max_tokens: 1024,
41
+ * messages: [{ role: 'user', content: 'Hello, Claude!' }]
42
+ * });
43
+ * ```
44
+ */
45
+ function traceAnthropic(anthropic, evalClient, options = {}) {
46
+ const { captureInput = true, captureOutput = true, captureMetadata = true, organizationId, tracePrefix = 'anthropic' } = options;
47
+ // Create proxy for messages.create
48
+ const originalCreate = anthropic.messages.create.bind(anthropic.messages);
49
+ anthropic.messages.create = async (params, requestOptions) => {
50
+ const startTime = Date.now();
51
+ const traceId = `${tracePrefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
52
+ try {
53
+ // Call original method
54
+ const message = await originalCreate(params, requestOptions);
55
+ const durationMs = Date.now() - startTime;
56
+ // Create trace with success status and complete metadata
57
+ const traceMetadata = (0, context_1.mergeWithContext)({
58
+ model: params.model,
59
+ temperature: params.temperature,
60
+ max_tokens: params.max_tokens,
61
+ ...(captureInput ? { input: params.messages } : {}),
62
+ ...(captureOutput ? { output: message.content } : {}),
63
+ ...(captureMetadata ? {
64
+ usage: message.usage,
65
+ stop_reason: message.stop_reason
66
+ } : {})
67
+ });
68
+ await evalClient.traces.create({
69
+ name: `Anthropic: ${params.model}`,
70
+ traceId,
71
+ organizationId: organizationId || evalClient.getOrganizationId(),
72
+ status: 'success',
73
+ durationMs,
74
+ metadata: traceMetadata
75
+ });
76
+ return message;
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.create({
90
+ name: `Anthropic: ${params.model}`,
91
+ traceId,
92
+ organizationId: organizationId || evalClient.getOrganizationId(),
93
+ status: 'error',
94
+ durationMs,
95
+ metadata: errorMetadata
96
+ }).catch(() => {
97
+ // Ignore errors in trace creation to avoid masking the original error
98
+ });
99
+ throw error;
100
+ }
101
+ };
102
+ return anthropic;
103
+ }
104
+ /**
105
+ * Manual trace wrapper for Anthropic calls
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * const message = await traceAnthropicCall(
110
+ * evalClient,
111
+ * 'claude-completion',
112
+ * async () => {
113
+ * return await anthropic.messages.create({
114
+ * model: 'claude-3-5-sonnet-20241022',
115
+ * max_tokens: 1024,
116
+ * messages: [{ role: 'user', content: 'Hello!' }]
117
+ * });
118
+ * }
119
+ * );
120
+ * ```
121
+ */
122
+ async function traceAnthropicCall(evalClient, name, fn, options = {}) {
123
+ const startTime = Date.now();
124
+ const traceId = `anthropic-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
125
+ try {
126
+ await evalClient.traces.create({
127
+ name,
128
+ traceId,
129
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
130
+ status: 'pending',
131
+ metadata: (0, context_1.mergeWithContext)({})
132
+ });
133
+ const result = await fn();
134
+ const durationMs = Date.now() - startTime;
135
+ await evalClient.traces.create({
136
+ name,
137
+ traceId,
138
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
139
+ status: 'success',
140
+ durationMs,
141
+ metadata: (0, context_1.mergeWithContext)({})
142
+ });
143
+ return result;
144
+ }
145
+ catch (error) {
146
+ const durationMs = Date.now() - startTime;
147
+ await evalClient.traces.create({
148
+ name,
149
+ traceId,
150
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
151
+ status: 'error',
152
+ durationMs,
153
+ metadata: (0, context_1.mergeWithContext)({
154
+ error: error instanceof Error ? error.message : String(error)
155
+ })
156
+ });
157
+ throw error;
158
+ }
159
+ }
@@ -0,0 +1,69 @@
1
+ /**
2
+ * OpenAI Integration
3
+ * Tier 1.2: Framework Auto-Instrumentation - OpenAI wrapper
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * import { traceOpenAI } from '@ai-eval-platform/sdk/integrations/openai';
8
+ * import OpenAI from 'openai';
9
+ *
10
+ * const openai = new OpenAI({ apiKey: '...' });
11
+ * const tracedOpenAI = traceOpenAI(openai, client);
12
+ *
13
+ * // All calls are automatically traced
14
+ * const response = await tracedOpenAI.chat.completions.create({
15
+ * model: 'gpt-4',
16
+ * messages: [{ role: 'user', content: 'Hello!' }]
17
+ * });
18
+ * ```
19
+ */
20
+ import type { AIEvalClient } from '../client';
21
+ export interface OpenAITraceOptions {
22
+ /** Whether to capture input (default: true) */
23
+ captureInput?: boolean;
24
+ /** Whether to capture output (default: true) */
25
+ captureOutput?: boolean;
26
+ /** Whether to capture metadata (default: true) */
27
+ captureMetadata?: boolean;
28
+ /** Organization ID for traces */
29
+ organizationId?: number;
30
+ /** Custom trace name prefix */
31
+ tracePrefix?: string;
32
+ }
33
+ /**
34
+ * Wrap OpenAI client with automatic tracing
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * import OpenAI from 'openai';
39
+ * import { traceOpenAI } from '@ai-eval-platform/sdk/integrations/openai';
40
+ *
41
+ * const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
42
+ * const tracedOpenAI = traceOpenAI(openai, evalClient);
43
+ *
44
+ * // Automatically traced
45
+ * const completion = await tracedOpenAI.chat.completions.create({
46
+ * model: 'gpt-4',
47
+ * messages: [{ role: 'user', content: 'Hello!' }]
48
+ * });
49
+ * ```
50
+ */
51
+ export declare function traceOpenAI(openai: any, evalClient: AIEvalClient, options?: OpenAITraceOptions): any;
52
+ /**
53
+ * Manual trace wrapper for OpenAI calls
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * const response = await traceOpenAICall(
58
+ * evalClient,
59
+ * 'gpt-4-completion',
60
+ * async () => {
61
+ * return await openai.chat.completions.create({
62
+ * model: 'gpt-4',
63
+ * messages: [{ role: 'user', content: 'Hello!' }]
64
+ * });
65
+ * }
66
+ * );
67
+ * ```
68
+ */
69
+ export declare function traceOpenAICall<T>(evalClient: AIEvalClient, name: string, fn: () => Promise<T>, options?: OpenAITraceOptions): Promise<T>;
@@ -0,0 +1,156 @@
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
+ usage: response.usage,
63
+ finish_reason: response.choices[0]?.finish_reason
64
+ } : {})
65
+ });
66
+ await evalClient.traces.create({
67
+ name: `OpenAI: ${params.model}`,
68
+ traceId,
69
+ organizationId: organizationId || evalClient.getOrganizationId(),
70
+ status: 'success',
71
+ durationMs,
72
+ metadata: traceMetadata
73
+ });
74
+ return response;
75
+ }
76
+ catch (error) {
77
+ const durationMs = Date.now() - startTime;
78
+ // Create trace with error status
79
+ const errorMetadata = (0, context_1.mergeWithContext)({
80
+ model: params.model,
81
+ temperature: params.temperature,
82
+ max_tokens: params.max_tokens,
83
+ ...(captureInput ? { input: params.messages } : {}),
84
+ ...(captureMetadata ? { params } : {}),
85
+ error: error instanceof Error ? error.message : String(error)
86
+ });
87
+ await evalClient.traces.create({
88
+ name: `OpenAI: ${params.model}`,
89
+ traceId,
90
+ organizationId: organizationId || evalClient.getOrganizationId(),
91
+ status: 'error',
92
+ durationMs,
93
+ metadata: errorMetadata
94
+ }).catch(() => {
95
+ // Ignore errors in trace creation to avoid masking the original error
96
+ });
97
+ throw error;
98
+ }
99
+ };
100
+ return openai;
101
+ }
102
+ /**
103
+ * Manual trace wrapper for OpenAI calls
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const response = await traceOpenAICall(
108
+ * evalClient,
109
+ * 'gpt-4-completion',
110
+ * async () => {
111
+ * return await openai.chat.completions.create({
112
+ * model: 'gpt-4',
113
+ * messages: [{ role: 'user', content: 'Hello!' }]
114
+ * });
115
+ * }
116
+ * );
117
+ * ```
118
+ */
119
+ async function traceOpenAICall(evalClient, name, fn, options = {}) {
120
+ const startTime = Date.now();
121
+ const traceId = `openai-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
122
+ try {
123
+ await evalClient.traces.create({
124
+ name,
125
+ traceId,
126
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
127
+ status: 'pending',
128
+ metadata: (0, context_1.mergeWithContext)({})
129
+ });
130
+ const result = await fn();
131
+ const durationMs = Date.now() - startTime;
132
+ await evalClient.traces.create({
133
+ name,
134
+ traceId,
135
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
136
+ status: 'success',
137
+ durationMs,
138
+ metadata: (0, context_1.mergeWithContext)({})
139
+ });
140
+ return result;
141
+ }
142
+ catch (error) {
143
+ const durationMs = Date.now() - startTime;
144
+ await evalClient.traces.create({
145
+ name,
146
+ traceId,
147
+ organizationId: options.organizationId || evalClient.getOrganizationId(),
148
+ status: 'error',
149
+ durationMs,
150
+ metadata: (0, context_1.mergeWithContext)({
151
+ error: error instanceof Error ? error.message : String(error)
152
+ })
153
+ });
154
+ throw error;
155
+ }
156
+ }
@@ -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 { Trace, Evaluation, Span } 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,146 @@
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("fs/promises"));
20
+ const path_1 = __importDefault(require("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 || './.evalai-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(path_1.default.join(this.directory, 'traces'), { recursive: true });
34
+ await promises_1.default.mkdir(path_1.default.join(this.directory, 'evaluations'), { recursive: true });
35
+ await promises_1.default.mkdir(path_1.default.join(this.directory, 'spans'), { recursive: true });
36
+ // Load existing data
37
+ await this.loadAllData();
38
+ }
39
+ catch (error) {
40
+ console.warn('Failed to initialize local storage:', error);
41
+ }
42
+ }
43
+ async loadAllData() {
44
+ try {
45
+ // Load traces
46
+ const tracesDir = path_1.default.join(this.directory, 'traces');
47
+ const traceFiles = await promises_1.default.readdir(tracesDir);
48
+ for (const file of traceFiles) {
49
+ if (file.endsWith('.json')) {
50
+ const content = await promises_1.default.readFile(path_1.default.join(tracesDir, file), 'utf-8');
51
+ const trace = JSON.parse(content);
52
+ this.traces.set(trace.id.toString(), trace);
53
+ }
54
+ }
55
+ // Load evaluations
56
+ const evalsDir = path_1.default.join(this.directory, 'evaluations');
57
+ const evalFiles = await promises_1.default.readdir(evalsDir);
58
+ for (const file of evalFiles) {
59
+ if (file.endsWith('.json')) {
60
+ const content = await promises_1.default.readFile(path_1.default.join(evalsDir, file), 'utf-8');
61
+ const evaluation = JSON.parse(content);
62
+ this.evaluations.set(evaluation.id.toString(), evaluation);
63
+ }
64
+ }
65
+ }
66
+ catch (error) {
67
+ // Directories might not exist yet, that's fine
68
+ }
69
+ }
70
+ async saveTraceToDisk(trace) {
71
+ const filePath = path_1.default.join(this.directory, 'traces', `${trace.id}.json`);
72
+ await promises_1.default.writeFile(filePath, JSON.stringify(trace, null, 2));
73
+ }
74
+ async saveTrace(trace) {
75
+ this.traces.set(trace.id.toString(), trace);
76
+ if (this.autoSave) {
77
+ await this.saveTraceToDisk(trace);
78
+ }
79
+ }
80
+ async getTrace(id) {
81
+ return this.traces.get(id);
82
+ }
83
+ async listTraces() {
84
+ return Array.from(this.traces.values());
85
+ }
86
+ async saveEvaluationToDisk(evaluation) {
87
+ const filePath = path_1.default.join(this.directory, 'evaluations', `${evaluation.id}.json`);
88
+ await promises_1.default.writeFile(filePath, JSON.stringify(evaluation, null, 2));
89
+ }
90
+ async saveEvaluation(evaluation) {
91
+ this.evaluations.set(evaluation.id.toString(), evaluation);
92
+ if (this.autoSave) {
93
+ await this.saveEvaluationToDisk(evaluation);
94
+ }
95
+ }
96
+ async getEvaluation(id) {
97
+ return this.evaluations.get(id);
98
+ }
99
+ async listEvaluations() {
100
+ return Array.from(this.evaluations.values());
101
+ }
102
+ async saveSpansToDisk(traceId, spans) {
103
+ const filePath = path_1.default.join(this.directory, 'spans', `${traceId}.json`);
104
+ await promises_1.default.writeFile(filePath, JSON.stringify(spans, null, 2));
105
+ }
106
+ async saveSpans(traceId, spans) {
107
+ this.spans.set(traceId, spans);
108
+ if (this.autoSave) {
109
+ await this.saveSpansToDisk(traceId, spans);
110
+ }
111
+ }
112
+ async getSpans(traceId) {
113
+ return this.spans.get(traceId);
114
+ }
115
+ async clear() {
116
+ this.traces.clear();
117
+ this.evaluations.clear();
118
+ this.spans.clear();
119
+ // Optionally delete files
120
+ try {
121
+ await promises_1.default.rm(this.directory, { recursive: true, force: true });
122
+ await this.initialize();
123
+ }
124
+ catch (error) {
125
+ console.warn('Failed to clear local storage:', error);
126
+ }
127
+ }
128
+ async export(format) {
129
+ const data = {
130
+ traces: Array.from(this.traces.values()),
131
+ evaluations: Array.from(this.evaluations.values()),
132
+ spans: Object.fromEntries(this.spans)
133
+ };
134
+ const exportPath = path_1.default.join(this.directory, `export-${Date.now()}.json`);
135
+ await promises_1.default.writeFile(exportPath, JSON.stringify(data, null, 2));
136
+ return exportPath;
137
+ }
138
+ getStats() {
139
+ return {
140
+ traces: this.traces.size,
141
+ evaluations: this.evaluations.size,
142
+ totalSpans: Array.from(this.spans.values()).reduce((sum, spans) => sum + spans.length, 0)
143
+ };
144
+ }
145
+ }
146
+ exports.LocalStorage = LocalStorage;