@observyze/sdk 0.1.2 → 0.1.4

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.
@@ -1,92 +1,9 @@
1
+ import { SpanType, TokenUsage, Span as Span$1, TraceStatus, Trace as Trace$1 } from '@observyze/types';
2
+
1
3
  /**
2
4
  * SDK Configuration and Types
3
5
  */
4
- /**
5
- * Type of span operation
6
- */
7
- declare enum SpanType {
8
- LLM = "llm",
9
- TOOL = "tool",
10
- AGENT = "agent",
11
- CHAIN = "chain",
12
- RETRIEVAL = "retrieval"
13
- }
14
- /**
15
- * Status of trace execution
16
- */
17
- declare enum TraceStatus {
18
- SUCCESS = "success",
19
- ERROR = "error",
20
- TIMEOUT = "timeout",
21
- RUNNING = "running"
22
- }
23
- /**
24
- * Error information for a span
25
- */
26
- interface SpanError {
27
- message: string;
28
- stack?: string;
29
- code?: string;
30
- }
31
- /**
32
- * Token usage information
33
- */
34
- interface TokenUsage {
35
- input: number;
36
- output: number;
37
- total: number;
38
- computed_pixels?: number;
39
- audio_seconds?: number;
40
- }
41
- /**
42
- * Individual operation within a trace
43
- */
44
- interface Span$1 {
45
- span_id: string;
46
- parent_span_id?: string;
47
- name: string;
48
- type: SpanType;
49
- start_time: Date;
50
- end_time: Date;
51
- duration_ms: number;
52
- input: any;
53
- output: any;
54
- error?: SpanError;
55
- metadata: {
56
- model?: string;
57
- provider?: string;
58
- temperature?: number;
59
- max_tokens?: number;
60
- [key: string]: any;
61
- };
62
- tokens?: TokenUsage;
63
- }
64
- /**
65
- * Complete record of an AI workflow execution
66
- */
67
- interface Trace$1 {
68
- trace_id: string;
69
- organization_id: string;
70
- project_id?: string;
71
- name: string;
72
- status: TraceStatus;
73
- start_time: Date;
74
- end_time: Date;
75
- duration_ms: number;
76
- metadata: Record<string, any>;
77
- spans: Span$1[];
78
- tags: string[];
79
- user_id?: string;
80
- session_id?: string;
81
- cost?: number;
82
- cost_breakdown?: {
83
- tokens: number;
84
- pixels: number;
85
- audio: number;
86
- };
87
- created_at: Date;
88
- updated_at: Date;
89
- }
6
+
90
7
  /**
91
8
  * Configuration for Observyze SDK client
92
9
  */
@@ -97,7 +14,7 @@ interface ClientConfig {
97
14
  apiKey: string;
98
15
  /**
99
16
  * Endpoint URL for the Ingestion Service
100
- * @default 'https://api.observyze.com'
17
+ * @default 'http://localhost:3001'
101
18
  */
102
19
  endpoint?: string;
103
20
  /**
@@ -134,16 +51,77 @@ interface ClientConfig {
134
51
  */
135
52
  dryRun?: boolean;
136
53
  /**
137
- * Automatically scrub PII from trace output before network transmission
54
+ * Phase 5: Automatically scrub PII from trace output before network transmission
138
55
  * @default true
139
56
  */
140
57
  enablePiiRedaction?: boolean;
58
+ /**
59
+ * Phase 4: Autonomous Circuit Breaker
60
+ * Hallucination score threshold (0-1) above which execution is blocked
61
+ * @default 0.8
62
+ */
63
+ hallucinationThreshold?: number;
64
+ /**
65
+ * Phase 4: Autonomous Circuit Breaker
66
+ * Safety score threshold (0-1) above which execution is blocked
67
+ * @default 0.9
68
+ */
69
+ safetyThreshold?: number;
70
+ /**
71
+ * Minimum confidence threshold for circuit breaker blocking (0-1).
72
+ * If confidence is below this threshold, high scores trigger alert-only instead of halt.
73
+ * @default 0.4
74
+ */
75
+ confidenceThreshold?: number;
76
+ /**
77
+ * Evaluation service URL for real-time guardrail checks
78
+ * In production, this should be https://api.observyze.com
79
+ * @default 'http://localhost:3000'
80
+ */
81
+ evalEndpoint?: string;
82
+ /**
83
+ * Enable circuit breaker - block execution on high hallucination/safety scores
84
+ * @default true
85
+ */
86
+ enableCircuitBreaker?: boolean;
87
+ /**
88
+ * Fail closed when evaluation service is unreachable.
89
+ * If true, guardrail checks will block execution on errors (safe default).
90
+ * If false, guardrail checks will allow execution on errors (fail open).
91
+ * @default true
92
+ */
93
+ failClosed?: boolean;
94
+ /**
95
+ * Automatically redirect LLM client (OpenAI, Anthropic) base URLs to Observyze proxy gateway
96
+ * to ensure Redis-backed circuit breakers are enforced.
97
+ * @default true
98
+ */
99
+ enableProxyRedirect?: boolean;
141
100
  }
142
101
  /**
143
102
  * Internal configuration with defaults applied
144
103
  */
145
104
  interface ResolvedClientConfig extends Required<ClientConfig> {
146
105
  }
106
+ /**
107
+ * Result of a guardrail evaluation check.
108
+ * score is null when evaluation could not be performed.
109
+ */
110
+ interface GuardrailResult {
111
+ pass: boolean;
112
+ /** The hallucination score (0-1), or null if evaluation failed */
113
+ score: number | null;
114
+ /** Confidence in the evaluation score (0-1), null if unavailable */
115
+ confidence?: number | null;
116
+ /** The safety score (0-1), or null if evaluation failed */
117
+ safetyScore?: number | null;
118
+ /** Human-readable reason for the result */
119
+ reason?: string;
120
+ /** How the evaluation was performed */
121
+ evaluationSource?: 'live' | 'consensus' | 'nli_fast_path' | 'error' | 'disabled' | 'fallback';
122
+ /** Why a live evaluation didn't happen (only set when evaluationSource is 'error' or 'fallback') */
123
+ fallbackReason?: string;
124
+ }
147
125
 
148
126
  /**
149
127
  * Trace and Span classes for capturing AI workflow execution
@@ -340,6 +318,28 @@ declare class ObservyzeClient {
340
318
  private static readonly SENSITIVE_KEYS;
341
319
  private static isSensitiveKey;
342
320
  private sanitizePII;
321
+ /**
322
+ * Phase 4: Autonomous Circuit Breakers (Requirement 4.1)
323
+ * Evaluate a trace or text for hallucination in real-time.
324
+ * If hallucination score > hallucinationThreshold, the SDK blocks execution.
325
+ *
326
+ * Returns GuardrailResult with score: null when evaluation couldn't be performed.
327
+ * In failClosed mode, null scores result in blocked execution.
328
+ * In failOpen mode, null scores allow execution through.
329
+ */
330
+ checkGuardrails(content: string | any): Promise<GuardrailResult>;
331
+ /**
332
+ * Phase 4: Autonomous Circuit Breakers
333
+ * Execute an agent action wrapped with the Circuit Breaker.
334
+ * Pauses execution if hallucination score >= hallucinationThreshold and requests human review.
335
+ * @throws Error when execution is blocked by circuit breaker
336
+ */
337
+ executeWithCircuitBreaker<T>(agentExecution: () => Promise<T>, traceContext?: any): Promise<T>;
338
+ /**
339
+ * Phase 4: Bug Bounty Protocol (Automated) (Requirement 4.2)
340
+ * Automatically shard persistent failure cases to external security researcher endpoints (e.g. HackerOne wrapper)
341
+ */
342
+ reportBugBounty(traceId: string, securityEndpoint: string, failureContext: any): Promise<void>;
343
343
  }
344
344
 
345
345
  /**
@@ -402,4 +402,4 @@ declare class ObservyzeSpanExporter {
402
402
  forceFlush(): Promise<void>;
403
403
  }
404
404
 
405
- export { type ClientConfig as C, ObservyzeClient as O, type ResolvedClientConfig as R, Span as S, type TokenUsage as T, type ObservyzeExporterConfig as a, ObservyzeSpanExporter as b, type Span$1 as c, type SpanError as d, SpanType as e, Trace as f, type Trace$1 as g, TraceStatus as h };
405
+ export { type ClientConfig as C, ObservyzeClient as O, type ResolvedClientConfig as R, Span as S, Trace as T, type ObservyzeExporterConfig as a, ObservyzeSpanExporter as b };
@@ -0,0 +1,429 @@
1
+ import { SpanType, TokenUsage, Span as Span$1, TraceStatus, Trace as Trace$1 } from '@observyze/types';
2
+
3
+ /**
4
+ * SDK Configuration and Types
5
+ */
6
+
7
+ /**
8
+ * Configuration for Observyze SDK client
9
+ */
10
+ interface ClientConfig {
11
+ /**
12
+ * API key for authentication with Observyze Ingestion Service
13
+ */
14
+ apiKey: string;
15
+ /**
16
+ * Endpoint URL for the Ingestion Service
17
+ * @default 'http://localhost:3001'
18
+ */
19
+ endpoint?: string;
20
+ /**
21
+ * Maximum number of traces to buffer before flushing
22
+ * @default 100
23
+ */
24
+ batchSize?: number;
25
+ /**
26
+ * Time in milliseconds to wait before auto-flushing buffered traces
27
+ * @default 5000
28
+ */
29
+ flushInterval?: number;
30
+ /**
31
+ * Enable automatic instrumentation of popular LLM libraries
32
+ * @default true
33
+ */
34
+ enableAutoInstrumentation?: boolean;
35
+ /**
36
+ * Organization ID (optional, can be extracted from API key)
37
+ */
38
+ organizationId?: string;
39
+ /**
40
+ * Project ID for trace attribution
41
+ */
42
+ projectId?: string;
43
+ /**
44
+ * Enable debug logging
45
+ * @default false
46
+ */
47
+ debug?: boolean;
48
+ /**
49
+ * Dry run mode - don't send traces to server (useful for testing)
50
+ * @default false
51
+ */
52
+ dryRun?: boolean;
53
+ /**
54
+ * Phase 5: Automatically scrub PII from trace output before network transmission
55
+ * @default true
56
+ */
57
+ enablePiiRedaction?: boolean;
58
+ /**
59
+ * Phase 4: Autonomous Circuit Breaker
60
+ * Hallucination score threshold (0-1) above which execution is blocked
61
+ * @default 0.8
62
+ */
63
+ hallucinationThreshold?: number;
64
+ /**
65
+ * Phase 4: Autonomous Circuit Breaker
66
+ * Safety score threshold (0-1) above which execution is blocked
67
+ * @default 0.9
68
+ */
69
+ safetyThreshold?: number;
70
+ /**
71
+ * Minimum confidence threshold for circuit breaker blocking (0-1).
72
+ * If confidence is below this threshold, high scores trigger alert-only instead of halt.
73
+ * @default 0.4
74
+ */
75
+ confidenceThreshold?: number;
76
+ /**
77
+ * Evaluation service URL for real-time guardrail checks
78
+ * In production, this should be https://api.observyze.com
79
+ * @default 'http://localhost:3000'
80
+ */
81
+ evalEndpoint?: string;
82
+ /**
83
+ * Enable circuit breaker - block execution on high hallucination/safety scores
84
+ * @default true
85
+ */
86
+ enableCircuitBreaker?: boolean;
87
+ /**
88
+ * Fail closed when evaluation service is unreachable.
89
+ * If true, guardrail checks will block execution on errors (safe default).
90
+ * If false, guardrail checks will allow execution on errors (fail open).
91
+ * @default true
92
+ */
93
+ failClosed?: boolean;
94
+ /**
95
+ * Automatically redirect LLM client (OpenAI, Anthropic) base URLs to Observyze proxy gateway
96
+ * to ensure Redis-backed circuit breakers are enforced.
97
+ * @default true
98
+ */
99
+ enableProxyRedirect?: boolean;
100
+ }
101
+ /**
102
+ * Internal configuration with defaults applied
103
+ */
104
+ interface ResolvedClientConfig extends Required<ClientConfig> {
105
+ }
106
+ /**
107
+ * Result of a guardrail evaluation check.
108
+ * score is null when evaluation could not be performed.
109
+ */
110
+ interface GuardrailResult {
111
+ pass: boolean;
112
+ /** The hallucination score (0-1), or null if evaluation failed */
113
+ score: number | null;
114
+ /** Confidence in the evaluation score (0-1), null if unavailable */
115
+ confidence?: number | null;
116
+ /** The safety score (0-1), or null if evaluation failed */
117
+ safetyScore?: number | null;
118
+ /** Human-readable reason for the result */
119
+ reason?: string;
120
+ /** How the evaluation was performed */
121
+ evaluationSource?: 'live' | 'consensus' | 'nli_fast_path' | 'error' | 'disabled' | 'fallback';
122
+ /** Why a live evaluation didn't happen (only set when evaluationSource is 'error' or 'fallback') */
123
+ fallbackReason?: string;
124
+ }
125
+
126
+ /**
127
+ * Trace and Span classes for capturing AI workflow execution
128
+ */
129
+
130
+ /**
131
+ * Represents an individual operation within a trace
132
+ */
133
+ declare class Span {
134
+ private data;
135
+ private startTime;
136
+ constructor(name: string, type: SpanType, parentSpanId?: string);
137
+ /**
138
+ * Set the input data for this span
139
+ */
140
+ setInput(input: any): this;
141
+ /**
142
+ * Set the output data for this span
143
+ */
144
+ setOutput(output: any): this;
145
+ /**
146
+ * Record an error that occurred during span execution
147
+ */
148
+ setError(error: Error): this;
149
+ /**
150
+ * Set metadata for this span
151
+ */
152
+ setMetadata(key: string, value: any): this;
153
+ /**
154
+ * Set multiple metadata fields at once
155
+ */
156
+ setMetadataAll(metadata: Record<string, any>): this;
157
+ /**
158
+ * Set token usage information
159
+ */
160
+ setTokens(tokens: TokenUsage): this;
161
+ /**
162
+ * End the span and calculate duration
163
+ */
164
+ end(): void;
165
+ /**
166
+ * Get the span ID
167
+ */
168
+ get id(): string;
169
+ /**
170
+ * Get the span data for serialization
171
+ */
172
+ toJSON(): Span$1;
173
+ }
174
+ /**
175
+ * Represents a complete AI workflow execution
176
+ */
177
+ declare class Trace {
178
+ private data;
179
+ private startTime;
180
+ private spans;
181
+ private ended;
182
+ constructor(name: string, organizationId: string, projectId?: string);
183
+ /**
184
+ * Start a new span within this trace
185
+ */
186
+ startSpan(name: string, type: SpanType, parentSpanId?: string): Span;
187
+ /**
188
+ * Add metadata to the trace
189
+ */
190
+ setMetadata(key: string, value: any): this;
191
+ /**
192
+ * Set multiple metadata fields at once
193
+ */
194
+ setMetadataAll(metadata: Record<string, any>): this;
195
+ /**
196
+ * Add tags to the trace
197
+ */
198
+ addTag(tag: string): this;
199
+ /**
200
+ * Add multiple tags at once
201
+ */
202
+ addTags(tags: string[]): this;
203
+ /**
204
+ * Set the user ID associated with this trace
205
+ */
206
+ setUserId(userId: string): this;
207
+ /**
208
+ * Set the session ID associated with this trace
209
+ */
210
+ setSessionId(sessionId: string): this;
211
+ /**
212
+ * End the trace with a final status
213
+ */
214
+ end(status?: TraceStatus): void;
215
+ /**
216
+ * Get the trace ID
217
+ */
218
+ get id(): string;
219
+ /**
220
+ * Check if the trace has ended
221
+ */
222
+ get isEnded(): boolean;
223
+ /**
224
+ * Get the trace data for serialization
225
+ */
226
+ toJSON(): Omit<Trace$1, '_id' | 'created_at' | 'updated_at'>;
227
+ }
228
+
229
+ /**
230
+ * Auto-Instrumentation API
231
+ * Provides nw.wrap() API for instrumenting LLM clients
232
+ */
233
+
234
+ /**
235
+ * Supported client types for auto-instrumentation
236
+ */
237
+ type SupportedClient = {
238
+ chat: {
239
+ completions: {
240
+ create: Function;
241
+ };
242
+ };
243
+ } | {
244
+ messages: {
245
+ create: Function;
246
+ };
247
+ };
248
+ /**
249
+ * Detect the type of LLM client and apply appropriate instrumentation
250
+ */
251
+ declare function wrap<T extends SupportedClient>(client: T, nwClient: ObservyzeClient): T;
252
+
253
+ /**
254
+ * Observyze SDK Client
255
+ * Main entry point for instrumenting AI applications
256
+ */
257
+
258
+ /**
259
+ * Main SDK client for Observyze
260
+ */
261
+ declare class ObservyzeClient {
262
+ private config;
263
+ private traceBuffer;
264
+ private flushTimer;
265
+ private isShuttingDown;
266
+ private readonly MAX_QUEUE_SIZE;
267
+ private readonly RETRY_DELAYS;
268
+ constructor(config: ClientConfig);
269
+ /**
270
+ * Start a new trace
271
+ */
272
+ startTrace(name: string, metadata?: Record<string, any>): Trace;
273
+ /**
274
+ * Buffer a completed trace for batch sending
275
+ */
276
+ private bufferTrace;
277
+ /**
278
+ * Start the auto-flush timer
279
+ */
280
+ private startFlushTimer;
281
+ /**
282
+ * Flush all buffered traces to the Ingestion Service
283
+ */
284
+ flush(): Promise<void>;
285
+ /**
286
+ * Send traces with exponential backoff retry
287
+ */
288
+ private sendWithRetry;
289
+ /**
290
+ * Shutdown the SDK and flush remaining traces
291
+ */
292
+ shutdown(): Promise<void>;
293
+ /**
294
+ * Get current buffer size
295
+ */
296
+ get bufferSize(): number;
297
+ /**
298
+ * Get SDK configuration
299
+ */
300
+ getConfig(): Readonly<ResolvedClientConfig>;
301
+ /**
302
+ * Wrap an LLM client (OpenAI, Anthropic) to enable auto-instrumentation
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * import OpenAI from 'openai'
307
+ * import { ObservyzeClient } from '@observyze/sdk'
308
+ *
309
+ * const nw = new ObservyzeClient({ apiKey: 'your-api-key' })
310
+ * const openai = new OpenAI({ apiKey: 'openai-key' })
311
+ *
312
+ * // Wrap the client to enable auto-instrumentation
313
+ * nw.wrap(openai)
314
+ *
315
+ * // All calls are now automatically traced
316
+ * const response = await openai.chat.completions.create({
317
+ * model: 'gpt-4',
318
+ * messages: [{ role: 'user', content: 'Hello!' }]
319
+ * })
320
+ * ```
321
+ */
322
+ wrap<T extends SupportedClient>(client: T): T;
323
+ /**
324
+ * Sync local agent .history file to Observyze cloud
325
+ * Parses JSON/NDJSON agent history and sends to ingestion endpoint.
326
+ */
327
+ syncLocalHistory(filePath: string): Promise<void>;
328
+ /**
329
+ * Industry-grade PII Redaction (Compliance & RBAC)
330
+ *
331
+ * Recursively scrubs PII from trace data before transmission to the cloud.
332
+ * Coverage: emails, JWTs, bearer tokens, AWS/API keys, SSNs, credit cards,
333
+ * phone numbers (US + E.164), IPv4/IPv6, passport numbers, ZIP codes, plus
334
+ * key-based redaction for sensitive JSON fields (password, token, api_key, etc.).
335
+ *
336
+ * Design:
337
+ * - Pure function, never mutates the original object
338
+ * - Depth-limited to 16 levels to prevent stack overflow on deep agent outputs
339
+ * - Key-aware: sensitive key names are fully redacted regardless of value format
340
+ */
341
+ private static readonly PII_PATTERNS;
342
+ private static readonly SENSITIVE_KEYS;
343
+ private static isSensitiveKey;
344
+ private sanitizePII;
345
+ /**
346
+ * Phase 4: Autonomous Circuit Breakers (Requirement 4.1)
347
+ * Evaluate a trace or text for hallucination in real-time.
348
+ * If hallucination score > hallucinationThreshold, the SDK blocks execution.
349
+ *
350
+ * Returns GuardrailResult with score: null when evaluation couldn't be performed.
351
+ * In failClosed mode, null scores result in blocked execution.
352
+ * In failOpen mode, null scores allow execution through.
353
+ */
354
+ checkGuardrails(content: string | any): Promise<GuardrailResult>;
355
+ /**
356
+ * Phase 4: Autonomous Circuit Breakers
357
+ * Execute an agent action wrapped with the Circuit Breaker.
358
+ * Pauses execution if hallucination score >= hallucinationThreshold and requests human review.
359
+ * @throws Error when execution is blocked by circuit breaker
360
+ */
361
+ executeWithCircuitBreaker<T>(agentExecution: () => Promise<T>, traceContext?: any): Promise<T>;
362
+ /**
363
+ * Phase 4: Bug Bounty Protocol (Automated) (Requirement 4.2)
364
+ * Automatically shard persistent failure cases to external security researcher endpoints (e.g. HackerOne wrapper)
365
+ */
366
+ reportBugBounty(traceId: string, securityEndpoint: string, failureContext: any): Promise<void>;
367
+ }
368
+
369
+ /**
370
+ * Observyze OpenTelemetry Span Exporter
371
+ *
372
+ * Implements `@opentelemetry/sdk-trace-base`'s `SpanExporter` interface
373
+ * so users can use the standard OTel Node.js SDK and export spans to
374
+ * the Observyze platform.
375
+ *
376
+ * Usage:
377
+ * ```typescript
378
+ * import { ObservyzeClient } from '@observyze/sdk'
379
+ * import { ObservyzeSpanExporter } from '@observyze/sdk/opentelemetry'
380
+ * import { NodeSDK } from '@opentelemetry/sdk-node'
381
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'
382
+ *
383
+ * const nw = new ObservyzeClient({ apiKey: 'nw_...' })
384
+ *
385
+ * const sdk = new NodeSDK({
386
+ * spanProcessor: new BatchSpanProcessor(
387
+ * new ObservyzeSpanExporter(nw, { serviceName: 'my-app' })
388
+ * )
389
+ * })
390
+ * sdk.start()
391
+ * ```
392
+ */
393
+
394
+ /**
395
+ * Exporter configuration
396
+ */
397
+ interface ObservyzeExporterConfig {
398
+ serviceName?: string;
399
+ projectId?: string;
400
+ defaultSpanType?: SpanType | 'llm' | 'tool' | 'agent' | 'chain' | 'retrieval';
401
+ headers?: Record<string, string>;
402
+ }
403
+ /**
404
+ * Observyze OpenTelemetry Span Exporter
405
+ */
406
+ declare class ObservyzeSpanExporter {
407
+ private client;
408
+ private config;
409
+ constructor(client: ObservyzeClient, config?: ObservyzeExporterConfig);
410
+ /**
411
+ * Export spans — called by OTel SDK when spans are ready.
412
+ * Converts OTel spans to Observyze traces and buffers them.
413
+ */
414
+ export(spans: any[], resultCallback: (result: {
415
+ code: number;
416
+ error?: Error;
417
+ }) => void): Promise<void>;
418
+ /**
419
+ * Called when the exporter is shut down.
420
+ * Flushes any remaining buffered traces via the SDK client.
421
+ */
422
+ shutdown(): Promise<void>;
423
+ /**
424
+ * Called by the OTel SDK to force-export buffered spans.
425
+ */
426
+ forceFlush(): Promise<void>;
427
+ }
428
+
429
+ export { type ClientConfig as C, ObservyzeClient as O, type ResolvedClientConfig as R, Span as S, Trace as T, type ObservyzeExporterConfig as a, ObservyzeSpanExporter as b, type SupportedClient as c, wrap as w };