@doclo/core 0.1.8 → 0.1.9

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.
@@ -263,8 +263,42 @@ var GEN_AI_SYSTEMS = {
263
263
  huggingface: "huggingface",
264
264
  openrouter: "openrouter",
265
265
  // Custom system
266
- ollama: "ollama"
266
+ ollama: "ollama",
267
267
  // Custom system
268
+ // Generic OpenRouter vendors (extracted from model IDs like 'qwen/qwen3-235b')
269
+ // Full list from: curl -s "https://openrouter.ai/api/v1/models" | jq '[.data[].id | split("/")[0]] | unique | sort'
270
+ "generic-or": "openrouter",
271
+ qwen: "qwen",
272
+ "meta-llama": "meta",
273
+ deepseek: "deepseek",
274
+ "z-ai": "zhipu",
275
+ // GLM models
276
+ moonshotai: "moonshot",
277
+ mistralai: "mistral",
278
+ opengvlab: "opengvlab",
279
+ "stepfun-ai": "stepfun",
280
+ nvidia: "nvidia",
281
+ "x-ai": "xai",
282
+ // Grok models
283
+ yi: "yi",
284
+ microsoft: "microsoft",
285
+ databricks: "databricks",
286
+ thudm: "zhipu",
287
+ // THU models (GLM)
288
+ internlm: "internlm",
289
+ amazon: "amazon",
290
+ // Nova models
291
+ baidu: "baidu",
292
+ // ERNIE models
293
+ bytedance: "bytedance",
294
+ // UI-TARS
295
+ minimax: "minimax",
296
+ tencent: "tencent",
297
+ // Hunyuan
298
+ alibaba: "alibaba",
299
+ // Tongyi
300
+ perplexity: "perplexity",
301
+ inflection: "inflection"
268
302
  };
269
303
  function mapProviderToSystem(provider) {
270
304
  const normalized = provider.toLowerCase();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/observability/hook-executor.ts","../../src/runtime/crypto.ts","../../src/observability/trace-context.ts","../../src/observability/otel-attributes.ts","../../src/observability/defaults.ts","../../src/observability/logger.ts","../../src/observability/index.ts"],"sourcesContent":["/**\n * Hook Executor\n *\n * Executes observability hooks with timeout protection and error isolation.\n * Ensures hooks never crash flow execution.\n *\n * @module @doclo/core/observability/hook-executor\n */\n\nimport type { HookError, ObservabilityConfig, HookContext } from './types.js';\n\n/**\n * Default hook timeout in milliseconds\n */\nconst DEFAULT_HOOK_TIMEOUT = 5000;\n\n/**\n * Generic hook function type.\n * The context parameter accepts any hook context type since this executor\n * handles all observability hooks (onFlowStart, onStepEnd, onLog, etc.).\n * Each specific hook in ObservabilityConfig has its own typed signature.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype GenericHookFunction = (context: any) => void | Promise<void>;\n\n/**\n * Hook execution options\n */\ninterface HookExecutionOptions {\n /** Hook name for error reporting */\n hookName: string;\n /** Observability configuration */\n config: ObservabilityConfig;\n /** Context passed to hook - specific type depends on which hook is being called */\n context: HookContext;\n /** Whether this is a fire-and-forget hook (e.g., onLog) */\n fireAndForget?: boolean;\n}\n\n/**\n * Execute a hook with timeout protection and error isolation\n *\n * @param hook - The hook function to execute\n * @param options - Execution options\n * @returns Promise that resolves when hook completes (or times out)\n */\nexport async function executeHook(\n hook: GenericHookFunction | undefined,\n options: HookExecutionOptions\n): Promise<void> {\n const { hookName, config, context, fireAndForget = false } = options;\n\n // Skip if hook not defined\n if (!hook) {\n return;\n }\n\n // Skip if observability disabled\n if (config.enabled === false) {\n return;\n }\n\n // Fire-and-forget: don't wait for hook\n if (fireAndForget || config.fireAndForget) {\n // Execute hook but don't wait\n executeHookWithErrorHandling(hook, hookName, context, config).catch(() => {\n // Silently ignore errors in fire-and-forget mode\n });\n return;\n }\n\n // Normal execution: wait for hook with timeout\n const timeout = config.hookTimeout ?? DEFAULT_HOOK_TIMEOUT;\n\n try {\n await executeHookWithTimeout(hook, context, timeout, hookName, config);\n } catch (error) {\n // Error already handled in executeHookWithTimeout\n // This catch is just to prevent unhandled rejection\n }\n}\n\n/**\n * Execute hook with error handling\n */\nasync function executeHookWithErrorHandling(\n hook: GenericHookFunction,\n hookName: string,\n context: HookContext,\n config: ObservabilityConfig\n): Promise<void> {\n try {\n const result = hook(context);\n // If hook returns a promise, await it\n if (result && typeof result.then === 'function') {\n await result;\n }\n } catch (error) {\n handleHookError(error as Error, hookName, context, config);\n }\n}\n\n/**\n * Execute hook with timeout protection\n */\nasync function executeHookWithTimeout(\n hook: GenericHookFunction,\n context: HookContext,\n timeoutMs: number,\n hookName: string,\n config: ObservabilityConfig\n): Promise<void> {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Hook '${hookName}' exceeded timeout of ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n // Create hook execution promise\n const hookPromise = executeHookWithErrorHandling(hook, hookName, context, config);\n\n // Race between hook and timeout\n try {\n await Promise.race([hookPromise, timeoutPromise]);\n } catch (error) {\n // Timeout or error occurred\n if (error instanceof Error && error.message.includes('exceeded timeout')) {\n // Timeout error\n handleHookError(error, hookName, context, config);\n }\n // Other errors already handled in executeHookWithErrorHandling\n }\n}\n\n/**\n * Handle hook execution error\n */\nfunction handleHookError(\n error: Error,\n hookName: string,\n context: HookContext,\n config: ObservabilityConfig\n): void {\n const hookError: HookError = {\n hookName,\n error,\n context,\n timestamp: Date.now(),\n };\n\n // Call onHookError if provided\n if (config.onHookError) {\n try {\n config.onHookError(hookError);\n } catch (onHookErrorError) {\n // onHookError itself failed, log to console as fallback\n console.error('[Observability] onHookError handler failed:', onHookErrorError);\n console.error('[Observability] Original hook error:', hookError);\n }\n } else {\n // No onHookError handler, log to console\n console.warn(`[Observability] Hook '${hookName}' failed:`, error);\n }\n\n // If failOnHookError is true, throw the error\n if (config.failOnHookError) {\n throw error;\n }\n\n // Otherwise, silently continue (error isolated)\n}\n\n/**\n * Execute multiple hooks serially with timeout protection\n *\n * This ensures hooks run one at a time in the order they're provided.\n *\n * @param hooks - Array of hook execution configs\n */\nexport async function executeHooksSerial(\n hooks: Array<{\n hook: GenericHookFunction | undefined;\n options: HookExecutionOptions;\n }>\n): Promise<void> {\n for (const { hook, options } of hooks) {\n await executeHook(hook, options);\n }\n}\n\n/**\n * Check if observability is enabled for this execution\n *\n * Takes sampling into account.\n */\nexport function isObservabilityEnabled(config: ObservabilityConfig): boolean {\n // Check if explicitly disabled\n if (config.enabled === false) {\n return false;\n }\n\n // Always enabled if no sampling rate specified\n if (config.samplingRate === undefined || config.samplingRate === 1.0) {\n return true;\n }\n\n // Never sample if rate is 0\n if (config.samplingRate === 0.0) {\n return false;\n }\n\n // Random sampling based on rate\n // Note: This decision is made once per flow execution in flow-builder\n // and stored, so sampling is consistent throughout the execution\n return Math.random() < config.samplingRate;\n}\n","/**\n * Universal Crypto Adapter\n *\n * Provides crypto-secure random byte generation for both Node.js and Edge Runtime.\n * Uses Web Crypto API (available in both environments) for maximum compatibility.\n *\n * @module @doclo/core/runtime/crypto\n */\n\n/**\n * Generate crypto-secure random bytes\n *\n * Uses Web Crypto API which is available in:\n * - Node.js 18+ (globalThis.crypto)\n * - Browsers (window.crypto)\n * - Cloudflare Workers (crypto)\n * - Vercel Edge Functions (crypto)\n *\n * @param length - Number of random bytes to generate\n * @returns Uint8Array containing random bytes\n */\nexport function getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n\n // Use Web Crypto API (available in all supported runtimes)\n // Node.js 18+, Edge Runtime, and browsers all support globalThis.crypto\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(bytes);\n return bytes;\n }\n\n throw new Error(\n 'Web Crypto API not available. This SDK requires:\\n' +\n '- Node.js 18.0.0 or later (has globalThis.crypto)\\n' +\n '- Edge Runtime (Vercel, Cloudflare)\\n' +\n '- Modern browsers'\n );\n}\n\n/**\n * Convert Uint8Array to lowercase hex string\n *\n * @param bytes - Byte array to convert\n * @returns Hex string representation\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate random hex string of specified byte length\n *\n * @param byteLength - Number of random bytes (hex string will be 2x this length)\n * @returns Lowercase hex string\n *\n * @example\n * ```typescript\n * const traceId = randomHex(16); // 32 hex characters\n * const spanId = randomHex(8); // 16 hex characters\n * ```\n */\nexport function randomHex(byteLength: number): string {\n const bytes = getRandomBytes(byteLength);\n return bytesToHex(bytes);\n}\n\n/**\n * Generate a UUID v4 string\n *\n * Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n *\n * @returns UUID v4 string\n *\n * @example\n * ```typescript\n * const id = randomUUID(); // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function randomUUID(): string {\n // Try native crypto.randomUUID() first (Node 19+, all Edge runtimes)\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID();\n }\n\n // Fallback: Manual UUID v4 generation\n const bytes = getRandomBytes(16);\n\n // Set version (4) and variant bits for UUID v4\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 10\n\n // Format as UUID string\n const hex = bytesToHex(bytes);\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\n}\n","/**\n * Trace Context Generator\n *\n * Implements W3C Trace Context standard for distributed tracing.\n * Generates crypto-secure trace IDs, span IDs, and execution IDs.\n *\n * @see https://www.w3.org/TR/trace-context/\n * @module @doclo/core/observability/trace-context\n */\n\nimport { randomHex, randomUUID as cryptoRandomUUID } from '../runtime/crypto.js';\nimport type { TraceContext, TraceContextInput, ObservabilityConfig } from './types.js';\n\n/**\n * W3C Trace Context version (always \"00\")\n */\nconst TRACE_CONTEXT_VERSION = '00';\n\n/**\n * Trace flags for sampled traces\n */\nexport const TRACE_FLAGS_SAMPLED = 0x01;\n\n/**\n * Trace flags for non-sampled traces\n */\nexport const TRACE_FLAGS_NOT_SAMPLED = 0x00;\n\n/**\n * Generate a crypto-secure trace ID (32 lowercase hex characters)\n *\n * Format: 32 hex digits (16 bytes)\n * Example: \"4bf92f3577b34da6a3ce929d0e0e4736\"\n */\nexport function generateTraceId(): string {\n return randomHex(16);\n}\n\n/**\n * Generate a crypto-secure span ID (16 lowercase hex characters)\n *\n * Format: 16 hex digits (8 bytes)\n * Example: \"00f067aa0ba902b7\"\n */\nexport function generateSpanId(): string {\n return randomHex(8);\n}\n\n/**\n * Generate a unique execution ID\n *\n * Uses crypto-secure random bytes for uniqueness.\n * Format: UUID v4 style (xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx)\n */\nexport function generateExecutionId(): string {\n return cryptoRandomUUID();\n}\n\n/**\n * Create a new trace context for flow execution\n *\n * @param config - Observability configuration\n * @param sampled - Whether this execution is sampled\n * @returns Complete trace context\n */\nexport function createTraceContext(\n config: ObservabilityConfig,\n sampled: boolean\n): TraceContext {\n // Use custom generator if provided, otherwise use default\n const traceIdGenerator = config.generateTraceId ?? generateTraceId;\n const spanIdGenerator = config.generateSpanId ?? generateSpanId;\n\n // If trace context propagation is configured, use it\n if (config.traceContext) {\n const input = config.traceContext;\n return {\n traceId: input.traceId,\n spanId: spanIdGenerator(),\n parentSpanId: input.parentSpanId,\n traceFlags: input.traceFlags ?? (sampled ? TRACE_FLAGS_SAMPLED : TRACE_FLAGS_NOT_SAMPLED),\n traceState: input.traceState,\n };\n }\n\n // Create new trace context\n return {\n traceId: traceIdGenerator(),\n spanId: spanIdGenerator(),\n traceFlags: sampled ? TRACE_FLAGS_SAMPLED : TRACE_FLAGS_NOT_SAMPLED,\n };\n}\n\n/**\n * Create a child span context from a parent trace context\n *\n * @param parent - Parent trace context\n * @param config - Observability configuration (for custom span ID generator)\n * @returns New trace context with same traceId but new spanId\n */\nexport function createChildSpanContext(\n parent: TraceContext,\n config?: ObservabilityConfig\n): TraceContext {\n const spanIdGenerator = config?.generateSpanId ?? generateSpanId;\n\n return {\n traceId: parent.traceId,\n spanId: spanIdGenerator(),\n parentSpanId: parent.spanId,\n traceFlags: parent.traceFlags,\n traceState: parent.traceState,\n };\n}\n\n/**\n * Format trace context as W3C traceparent header value\n *\n * Format: \"00-{traceId}-{spanId}-{flags}\"\n * Example: \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\"\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nexport function formatTraceparent(context: TraceContext): string {\n const flags = context.traceFlags.toString(16).padStart(2, '0');\n return `${TRACE_CONTEXT_VERSION}-${context.traceId}-${context.spanId}-${flags}`;\n}\n\n/**\n * Parse W3C traceparent header value\n *\n * @param traceparent - Traceparent header value\n * @returns Parsed trace context input or null if invalid\n */\nexport function parseTraceparent(traceparent: string): TraceContextInput | null {\n // Format: \"00-{traceId}-{spanId}-{flags}\"\n const parts = traceparent.split('-');\n\n if (parts.length !== 4) {\n return null;\n }\n\n const [version, traceId, spanId, flags] = parts;\n\n // Validate version\n if (version !== TRACE_CONTEXT_VERSION) {\n return null;\n }\n\n // Validate traceId (32 hex chars)\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n return null;\n }\n\n // Validate spanId (16 hex chars)\n if (!/^[0-9a-f]{16}$/.test(spanId)) {\n return null;\n }\n\n // Validate flags (2 hex chars)\n if (!/^[0-9a-f]{2}$/.test(flags)) {\n return null;\n }\n\n return {\n traceId,\n parentSpanId: spanId,\n traceFlags: parseInt(flags, 16),\n };\n}\n\n/**\n * Format trace context as W3C tracestate header value\n *\n * @see https://www.w3.org/TR/trace-context/#tracestate-header\n */\nexport function formatTracestate(context: TraceContext): string | undefined {\n return context.traceState;\n}\n\n/**\n * Check if trace context is sampled\n */\nexport function isTraceSampled(context: TraceContext): boolean {\n return (context.traceFlags & TRACE_FLAGS_SAMPLED) === TRACE_FLAGS_SAMPLED;\n}\n\n/**\n * Validate trace ID format\n *\n * Must be 32 lowercase hex characters, not all zeros\n */\nexport function isValidTraceId(traceId: string): boolean {\n // Must be 32 hex characters\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n return false;\n }\n\n // Must not be all zeros\n if (traceId === '00000000000000000000000000000000') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Validate span ID format\n *\n * Must be 16 lowercase hex characters, not all zeros\n */\nexport function isValidSpanId(spanId: string): boolean {\n // Must be 16 hex characters\n if (!/^[0-9a-f]{16}$/.test(spanId)) {\n return false;\n }\n\n // Must not be all zeros\n if (spanId === '0000000000000000') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Trace Context Manager\n *\n * Manages trace context for the current execution.\n */\nexport class TraceContextManager {\n private traceContext: TraceContext | null = null;\n private config: ObservabilityConfig;\n\n constructor(config: ObservabilityConfig) {\n this.config = config;\n }\n\n /**\n * Initialize trace context for new execution\n */\n initialize(sampled: boolean): TraceContext {\n this.traceContext = createTraceContext(this.config, sampled);\n return this.traceContext;\n }\n\n /**\n * Get current trace context\n */\n getTraceContext(): TraceContext | null {\n return this.traceContext;\n }\n\n /**\n * Create child span context\n */\n createChildSpan(): TraceContext {\n if (!this.traceContext) {\n throw new Error('Trace context not initialized');\n }\n return createChildSpanContext(this.traceContext, this.config);\n }\n\n /**\n * Get traceparent header value\n */\n getTraceparent(): string | null {\n if (!this.traceContext) {\n return null;\n }\n return formatTraceparent(this.traceContext);\n }\n\n /**\n * Reset trace context (for testing)\n */\n reset(): void {\n this.traceContext = null;\n }\n}\n","/**\n * OpenTelemetry Semantic Conventions for Gen AI\n *\n * Implements Gen AI semantic conventions (v1.29.0) for observability.\n * Maps SDK data to standard OpenTelemetry attributes.\n *\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/\n * @module @doclo/core/observability/otel-attributes\n */\n\n/**\n * Gen AI system names (standardized)\n */\nconst GEN_AI_SYSTEMS: Record<string, string> = {\n openai: 'openai',\n 'openai-compatible': 'openai',\n anthropic: 'anthropic',\n google: 'vertex_ai', // Google uses Vertex AI\n 'google-ai': 'vertex_ai',\n cohere: 'cohere',\n huggingface: 'huggingface',\n openrouter: 'openrouter', // Custom system\n ollama: 'ollama', // Custom system\n};\n\n/**\n * Map provider name to Gen AI system identifier\n */\nfunction mapProviderToSystem(provider: string): string {\n const normalized = provider.toLowerCase();\n return GEN_AI_SYSTEMS[normalized] ?? normalized;\n}\n\n/**\n * Build OpenTelemetry attributes for LLM operations\n *\n * @param data - Step execution data\n * @returns OpenTelemetry attributes object\n */\nexport function buildOtelAttributes(data: {\n provider?: string;\n model?: string;\n modelUsed?: string;\n stepType?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n}): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {};\n\n // Gen AI system (required)\n if (data.provider) {\n attributes['gen_ai.system'] = mapProviderToSystem(data.provider);\n }\n\n // Operation name (what type of operation)\n if (data.stepType) {\n attributes['gen_ai.operation.name'] = data.stepType;\n }\n\n // Request model (requested model name)\n if (data.model) {\n attributes['gen_ai.request.model'] = data.model;\n }\n\n // Response model (actual model used, may differ from requested)\n if (data.modelUsed) {\n attributes['gen_ai.response.model'] = data.modelUsed;\n }\n\n // Token usage\n if (data.inputTokens !== undefined) {\n attributes['gen_ai.usage.input_tokens'] = data.inputTokens;\n }\n\n if (data.outputTokens !== undefined) {\n attributes['gen_ai.usage.output_tokens'] = data.outputTokens;\n }\n\n // Finish reason (simplified as single string, not array)\n if (data.finishReason) {\n attributes['gen_ai.response.finish_reason'] = data.finishReason;\n }\n\n // Request parameters\n if (data.temperature !== undefined) {\n attributes['gen_ai.request.temperature'] = data.temperature;\n }\n\n if (data.maxTokens !== undefined) {\n attributes['gen_ai.request.max_tokens'] = data.maxTokens;\n }\n\n if (data.topP !== undefined) {\n attributes['gen_ai.request.top_p'] = data.topP;\n }\n\n if (data.topK !== undefined) {\n attributes['gen_ai.request.top_k'] = data.topK;\n }\n\n return attributes;\n}\n\n/**\n * Build OpenTelemetry attributes for provider requests\n *\n * Used for onProviderRequest hooks\n */\nexport function buildProviderRequestAttributes(data: {\n provider: string;\n model: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n provider: data.provider,\n model: data.model,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n}\n\n/**\n * Build OpenTelemetry attributes for provider responses\n *\n * Used for onProviderResponse hooks\n */\nexport function buildProviderResponseAttributes(data: {\n provider: string;\n model: string;\n modelUsed?: string;\n inputTokens: number;\n outputTokens: number;\n finishReason?: string;\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n });\n}\n\n/**\n * Build OpenTelemetry attributes for step execution\n *\n * Used for onStepEnd hooks\n */\nexport function buildStepAttributes(data: {\n stepType: string;\n provider?: string;\n model?: string;\n modelUsed?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n stepType: data.stepType,\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n}\n\n/**\n * Standard finish reason mappings\n *\n * Maps provider-specific finish reasons to standard values\n */\nexport const FINISH_REASON_MAPPING: Record<string, string> = {\n // OpenAI\n stop: 'stop',\n length: 'length',\n content_filter: 'content_filter',\n tool_calls: 'tool_calls',\n function_call: 'function_call',\n\n // Anthropic\n end_turn: 'stop',\n max_tokens: 'length',\n stop_sequence: 'stop',\n\n // Google\n STOP: 'stop',\n MAX_TOKENS: 'length',\n SAFETY: 'content_filter',\n RECITATION: 'content_filter',\n\n // Generic\n complete: 'stop',\n truncated: 'length',\n filtered: 'content_filter',\n};\n\n/**\n * Normalize finish reason to standard value\n */\nexport function normalizeFinishReason(reason: string | undefined): string | undefined {\n if (!reason) {\n return undefined;\n }\n\n return FINISH_REASON_MAPPING[reason] ?? reason;\n}\n\n/**\n * Add standard OpenTelemetry span attributes\n *\n * These are generic attributes that apply to all spans\n */\nexport function addStandardSpanAttributes(attributes: Record<string, string | number | boolean>, data: {\n spanKind?: 'client' | 'server' | 'internal';\n serviceName?: string;\n serviceVersion?: string;\n}): void {\n if (data.spanKind) {\n attributes['span.kind'] = data.spanKind;\n }\n\n if (data.serviceName) {\n attributes['service.name'] = data.serviceName;\n }\n\n if (data.serviceVersion) {\n attributes['service.version'] = data.serviceVersion;\n }\n}\n\n/**\n * Build full OpenTelemetry context for export\n *\n * Combines Gen AI attributes with standard span attributes\n */\nexport function buildFullOtelContext(data: {\n // Gen AI attributes\n stepType?: string;\n provider?: string;\n model?: string;\n modelUsed?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n\n // Standard span attributes\n spanKind?: 'client' | 'server' | 'internal';\n serviceName?: string;\n serviceVersion?: string;\n}): Record<string, string | number | boolean> {\n const attributes = buildOtelAttributes({\n stepType: data.stepType,\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n\n addStandardSpanAttributes(attributes, {\n spanKind: data.spanKind,\n serviceName: data.serviceName,\n serviceVersion: data.serviceVersion,\n });\n\n return attributes;\n}\n","/**\n * Observability Configuration Defaults\n *\n * Provides default configuration values and config merging utilities.\n *\n * @module @doclo/core/observability/defaults\n */\n\nimport type { ObservabilityConfig } from './types.js';\n\n/**\n * Default observability configuration\n */\nexport const DEFAULT_OBSERVABILITY_CONFIG: Required<Omit<ObservabilityConfig,\n | 'onFlowStart' | 'onFlowEnd' | 'onFlowError'\n | 'onStepStart' | 'onStepEnd' | 'onStepError'\n | 'onConsensusStart' | 'onConsensusRunRetry' | 'onConsensusRunComplete' | 'onConsensusComplete'\n | 'onBatchStart' | 'onBatchItemStart' | 'onBatchItemEnd' | 'onBatchEnd'\n | 'onProviderRequest' | 'onProviderResponse' | 'onProviderRetry' | 'onCircuitBreakerTriggered'\n | 'onLog' | 'onHookError'\n | 'customSampler' | 'generateTraceId' | 'generateSpanId' | 'generateExecutionId'\n | 'traceContext' | 'observabilityVersion'\n>> = {\n enabled: true,\n samplingRate: 1.0,\n samplingStrategy: 'random',\n asyncHooks: true,\n fireAndForget: false,\n hookTimeout: 5000,\n failOnHookError: false,\n};\n\n/**\n * Merge user config with defaults\n *\n * User config takes precedence over defaults.\n */\nexport function mergeConfig(userConfig?: ObservabilityConfig): ObservabilityConfig {\n if (!userConfig) {\n return { ...DEFAULT_OBSERVABILITY_CONFIG };\n }\n\n return {\n ...DEFAULT_OBSERVABILITY_CONFIG,\n ...userConfig,\n };\n}\n\n/**\n * Determine if execution should be sampled\n *\n * Uses sampling strategy from config.\n */\nexport function shouldSample(config: ObservabilityConfig): boolean {\n // Always sample if no rate specified\n if (config.samplingRate === undefined || config.samplingRate === 1.0) {\n return true;\n }\n\n // Never sample if rate is 0\n if (config.samplingRate === 0.0) {\n return false;\n }\n\n // Custom sampler (will be called later with flow context)\n if (config.samplingStrategy === 'custom' && config.customSampler) {\n // Custom sampler will be called in flow execution\n // For now, assume sampled (decision made later)\n return true;\n }\n\n // Random sampling (default)\n return Math.random() < config.samplingRate;\n}\n\n/**\n * Validate observability configuration\n *\n * Checks for invalid values and warns about issues.\n */\nexport function validateConfig(config: ObservabilityConfig): {\n valid: boolean;\n warnings: string[];\n errors: string[];\n} {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Validate sampling rate\n if (config.samplingRate !== undefined) {\n if (config.samplingRate < 0 || config.samplingRate > 1) {\n errors.push('samplingRate must be between 0.0 and 1.0');\n }\n }\n\n // Validate hook timeout\n if (config.hookTimeout !== undefined) {\n if (config.hookTimeout <= 0) {\n errors.push('hookTimeout must be positive');\n }\n if (config.hookTimeout > 60000) {\n warnings.push('hookTimeout > 60s may cause long execution delays');\n }\n }\n\n // Validate sampling strategy\n if (config.samplingStrategy === 'custom' && !config.customSampler) {\n errors.push('customSampler required when samplingStrategy is \"custom\"');\n }\n\n // Validate trace context propagation\n if (config.traceContext) {\n const { traceId, parentSpanId } = config.traceContext;\n\n // Validate trace ID format\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n errors.push('traceContext.traceId must be 32 lowercase hex characters');\n }\n\n // Validate parent span ID format\n if (!/^[0-9a-f]{16}$/.test(parentSpanId)) {\n errors.push('traceContext.parentSpanId must be 16 lowercase hex characters');\n }\n\n // Validate trace ID is not all zeros\n if (traceId === '00000000000000000000000000000000') {\n errors.push('traceContext.traceId cannot be all zeros');\n }\n\n // Validate parent span ID is not all zeros\n if (parentSpanId === '0000000000000000') {\n errors.push('traceContext.parentSpanId cannot be all zeros');\n }\n }\n\n // Warn about conflicting options\n if (config.asyncHooks === false && config.hookTimeout !== undefined) {\n warnings.push('hookTimeout has no effect when asyncHooks is false');\n }\n\n if (config.fireAndForget === true && config.hookTimeout !== undefined) {\n warnings.push('hookTimeout has no effect when fireAndForget is true');\n }\n\n if (config.enabled === false && Object.keys(config).length > 1) {\n warnings.push('Observability is disabled, other config options have no effect');\n }\n\n return {\n valid: errors.length === 0,\n warnings,\n errors,\n };\n}\n\n/**\n * Get observability version\n *\n * Returns the version of the observability contract.\n */\nexport function getObservabilityVersion(config?: ObservabilityConfig): string {\n return config?.observabilityVersion ?? '1.0.0';\n}\n\n/**\n * Check if observability is effectively disabled\n *\n * Returns true if observability is explicitly disabled or sampling rate is 0.\n */\nexport function isObservabilityDisabled(config: ObservabilityConfig): boolean {\n return config.enabled === false || config.samplingRate === 0.0;\n}\n\n/**\n * Check if any hooks are configured\n *\n * Returns true if at least one hook is defined.\n */\nexport function hasAnyHooks(config: ObservabilityConfig): boolean {\n return !!(\n config.onFlowStart ||\n config.onFlowEnd ||\n config.onFlowError ||\n config.onStepStart ||\n config.onStepEnd ||\n config.onStepError ||\n config.onConsensusStart ||\n config.onConsensusRunRetry ||\n config.onConsensusRunComplete ||\n config.onConsensusComplete ||\n config.onBatchStart ||\n config.onBatchItemStart ||\n config.onBatchItemEnd ||\n config.onBatchEnd ||\n config.onProviderRequest ||\n config.onProviderResponse ||\n config.onProviderRetry ||\n config.onCircuitBreakerTriggered ||\n config.onLog\n );\n}\n\n/**\n * Create minimal config for testing\n *\n * Useful for unit tests that don't need full observability.\n */\nexport function createMinimalConfig(overrides?: Partial<ObservabilityConfig>): ObservabilityConfig {\n return {\n enabled: true,\n samplingRate: 1.0,\n asyncHooks: false, // Faster for tests\n fireAndForget: false,\n hookTimeout: 1000, // Shorter for tests\n failOnHookError: false,\n ...overrides,\n };\n}\n","/**\n * Logging Utility for Observability\n *\n * Provides a logger that integrates with the observability system.\n * Logs are sent to the onLog hook with fire-and-forget execution.\n *\n * @module @doclo/core/observability/logger\n */\n\nimport type { ObservabilityConfig, LogContext, TraceContext } from './types.js';\nimport { executeHook } from './hook-executor.js';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LoggerOptions {\n observability?: ObservabilityConfig;\n flowId?: string;\n executionId?: string;\n stepId?: string;\n traceContext?: TraceContext;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Logger class that integrates with observability hooks\n */\nexport class Logger {\n private options: LoggerOptions;\n\n constructor(options: LoggerOptions = {}) {\n this.options = options;\n }\n\n /**\n * Log a debug message\n */\n debug(message: string, data?: unknown): void {\n this.log('debug', message, data);\n }\n\n /**\n * Log an info message\n */\n info(message: string, data?: unknown): void {\n this.log('info', message, data);\n }\n\n /**\n * Log a warning message\n */\n warn(message: string, data?: unknown): void {\n this.log('warn', message, data);\n }\n\n /**\n * Log an error message\n */\n error(message: string, error?: Error | unknown, data?: unknown): void {\n this.log('error', message, data, error instanceof Error ? error : undefined);\n }\n\n /**\n * Internal log method that sends to onLog hook\n */\n private log(level: LogLevel, message: string, data?: unknown, error?: Error): void {\n const timestamp = Date.now();\n\n // Always output to console as fallback\n const consoleMethod = level === 'error' ? console.error : level === 'warn' ? console.warn : console.log;\n if (error) {\n consoleMethod(`[${level.toUpperCase()}] ${message}`, data, error);\n } else if (data !== undefined) {\n consoleMethod(`[${level.toUpperCase()}] ${message}`, data);\n } else {\n consoleMethod(`[${level.toUpperCase()}] ${message}`);\n }\n\n // Send to onLog hook (fire-and-forget)\n if (this.options.observability?.onLog && this.options.traceContext) {\n // Combine data and error into metadata\n const combinedMetadata: Record<string, unknown> = {\n ...(this.options.metadata || {}),\n };\n if (data !== undefined) {\n combinedMetadata.data = data;\n }\n if (error) {\n combinedMetadata.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n }\n\n const logContext: LogContext = {\n flowId: this.options.flowId ?? 'unknown',\n executionId: this.options.executionId ?? 'unknown',\n stepId: this.options.stepId,\n timestamp,\n level,\n message,\n metadata: combinedMetadata,\n traceContext: this.options.traceContext,\n };\n\n // Fire-and-forget execution (don't await)\n executeHook(this.options.observability.onLog, {\n hookName: 'onLog',\n config: this.options.observability,\n context: logContext,\n fireAndForget: true, // Special handling for onLog\n }).catch(() => {\n // Silently ignore onLog errors\n });\n }\n }\n}\n\n/**\n * Create a logger instance with observability integration\n */\nexport function createLogger(options: LoggerOptions = {}): Logger {\n return new Logger(options);\n}\n","/**\n * Observability Module\n *\n * Comprehensive observability system for the doclo-sdk SDK.\n * Provides hooks, tracing, and monitoring capabilities.\n *\n * @module @doclo/core/observability\n * @example\n * ```typescript\n * import { ObservabilityConfig } from '@doclo/core/observability';\n *\n * const config: ObservabilityConfig = {\n * onFlowStart: (ctx) => console.log('Flow started:', ctx.flowId),\n * onStepEnd: (ctx) => console.log('Step completed:', ctx.stepId, ctx.duration),\n * };\n * ```\n */\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type {\n // Main configuration\n ObservabilityConfig,\n\n // Flow-level contexts\n FlowStartContext,\n FlowEndContext,\n FlowErrorContext,\n FlowStats,\n\n // Step-level contexts\n StepStartContext,\n StepEndContext,\n StepErrorContext,\n\n // Consensus contexts\n ConsensusStartContext,\n ConsensusRunRetryContext,\n ConsensusRunContext,\n ConsensusCompleteContext,\n\n // Batch/forEach contexts\n BatchStartContext,\n BatchItemContext,\n BatchItemEndContext,\n BatchEndContext,\n\n // Provider-level contexts\n ProviderRequestContext,\n ProviderResponseContext,\n ProviderRetryContext,\n CircuitBreakerContext,\n\n // Logging context\n LogContext,\n\n // Error handling\n HookError,\n\n // Trace context\n TraceContext,\n TraceContextInput,\n\n // Execution context\n ExecutionContext,\n CustomMetric,\n} from './types.js';\n\n// ============================================================================\n// Hook Executor\n// ============================================================================\n\n// Note: Hook executor is for SDK internal use (not for end users)\n// It's used by the SDK to execute hooks with timeout/error protection\n\nexport {\n executeHook,\n executeHooksSerial,\n isObservabilityEnabled,\n} from './hook-executor.js';\n\n// ============================================================================\n// Trace Context Utilities\n// ============================================================================\n\nexport {\n generateTraceId,\n generateSpanId,\n generateExecutionId,\n createTraceContext,\n createChildSpanContext,\n formatTraceparent,\n parseTraceparent,\n formatTracestate,\n isTraceSampled,\n isValidTraceId,\n isValidSpanId,\n TraceContextManager,\n TRACE_FLAGS_SAMPLED,\n TRACE_FLAGS_NOT_SAMPLED,\n} from './trace-context.js';\n\n// ============================================================================\n// OpenTelemetry Attributes\n// ============================================================================\n\nexport {\n buildOtelAttributes,\n buildProviderRequestAttributes,\n buildProviderResponseAttributes,\n buildStepAttributes,\n buildFullOtelContext,\n normalizeFinishReason,\n addStandardSpanAttributes,\n FINISH_REASON_MAPPING,\n} from './otel-attributes.js';\n\n// ============================================================================\n// Configuration Defaults\n// ============================================================================\n\nexport {\n DEFAULT_OBSERVABILITY_CONFIG,\n mergeConfig,\n shouldSample,\n validateConfig,\n getObservabilityVersion,\n isObservabilityDisabled,\n hasAnyHooks,\n createMinimalConfig,\n} from './defaults.js';\n\n// ============================================================================\n// Logger\n// ============================================================================\n\nexport {\n Logger,\n createLogger,\n type LogLevel,\n type LoggerOptions,\n} from './logger.js';\n\n// ============================================================================\n// Version\n// ============================================================================\n\n/**\n * Observability module version\n */\nexport const OBSERVABILITY_VERSION = '1.0.0';\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/observability/hook-executor.ts","../../src/runtime/crypto.ts","../../src/observability/trace-context.ts","../../src/observability/otel-attributes.ts","../../src/observability/defaults.ts","../../src/observability/logger.ts","../../src/observability/index.ts"],"sourcesContent":["/**\n * Hook Executor\n *\n * Executes observability hooks with timeout protection and error isolation.\n * Ensures hooks never crash flow execution.\n *\n * @module @doclo/core/observability/hook-executor\n */\n\nimport type { HookError, ObservabilityConfig, HookContext } from './types.js';\n\n/**\n * Default hook timeout in milliseconds\n */\nconst DEFAULT_HOOK_TIMEOUT = 5000;\n\n/**\n * Generic hook function type.\n * The context parameter accepts any hook context type since this executor\n * handles all observability hooks (onFlowStart, onStepEnd, onLog, etc.).\n * Each specific hook in ObservabilityConfig has its own typed signature.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype GenericHookFunction = (context: any) => void | Promise<void>;\n\n/**\n * Hook execution options\n */\ninterface HookExecutionOptions {\n /** Hook name for error reporting */\n hookName: string;\n /** Observability configuration */\n config: ObservabilityConfig;\n /** Context passed to hook - specific type depends on which hook is being called */\n context: HookContext;\n /** Whether this is a fire-and-forget hook (e.g., onLog) */\n fireAndForget?: boolean;\n}\n\n/**\n * Execute a hook with timeout protection and error isolation\n *\n * @param hook - The hook function to execute\n * @param options - Execution options\n * @returns Promise that resolves when hook completes (or times out)\n */\nexport async function executeHook(\n hook: GenericHookFunction | undefined,\n options: HookExecutionOptions\n): Promise<void> {\n const { hookName, config, context, fireAndForget = false } = options;\n\n // Skip if hook not defined\n if (!hook) {\n return;\n }\n\n // Skip if observability disabled\n if (config.enabled === false) {\n return;\n }\n\n // Fire-and-forget: don't wait for hook\n if (fireAndForget || config.fireAndForget) {\n // Execute hook but don't wait\n executeHookWithErrorHandling(hook, hookName, context, config).catch(() => {\n // Silently ignore errors in fire-and-forget mode\n });\n return;\n }\n\n // Normal execution: wait for hook with timeout\n const timeout = config.hookTimeout ?? DEFAULT_HOOK_TIMEOUT;\n\n try {\n await executeHookWithTimeout(hook, context, timeout, hookName, config);\n } catch (error) {\n // Error already handled in executeHookWithTimeout\n // This catch is just to prevent unhandled rejection\n }\n}\n\n/**\n * Execute hook with error handling\n */\nasync function executeHookWithErrorHandling(\n hook: GenericHookFunction,\n hookName: string,\n context: HookContext,\n config: ObservabilityConfig\n): Promise<void> {\n try {\n const result = hook(context);\n // If hook returns a promise, await it\n if (result && typeof result.then === 'function') {\n await result;\n }\n } catch (error) {\n handleHookError(error as Error, hookName, context, config);\n }\n}\n\n/**\n * Execute hook with timeout protection\n */\nasync function executeHookWithTimeout(\n hook: GenericHookFunction,\n context: HookContext,\n timeoutMs: number,\n hookName: string,\n config: ObservabilityConfig\n): Promise<void> {\n // Create timeout promise\n const timeoutPromise = new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(`Hook '${hookName}' exceeded timeout of ${timeoutMs}ms`));\n }, timeoutMs);\n });\n\n // Create hook execution promise\n const hookPromise = executeHookWithErrorHandling(hook, hookName, context, config);\n\n // Race between hook and timeout\n try {\n await Promise.race([hookPromise, timeoutPromise]);\n } catch (error) {\n // Timeout or error occurred\n if (error instanceof Error && error.message.includes('exceeded timeout')) {\n // Timeout error\n handleHookError(error, hookName, context, config);\n }\n // Other errors already handled in executeHookWithErrorHandling\n }\n}\n\n/**\n * Handle hook execution error\n */\nfunction handleHookError(\n error: Error,\n hookName: string,\n context: HookContext,\n config: ObservabilityConfig\n): void {\n const hookError: HookError = {\n hookName,\n error,\n context,\n timestamp: Date.now(),\n };\n\n // Call onHookError if provided\n if (config.onHookError) {\n try {\n config.onHookError(hookError);\n } catch (onHookErrorError) {\n // onHookError itself failed, log to console as fallback\n console.error('[Observability] onHookError handler failed:', onHookErrorError);\n console.error('[Observability] Original hook error:', hookError);\n }\n } else {\n // No onHookError handler, log to console\n console.warn(`[Observability] Hook '${hookName}' failed:`, error);\n }\n\n // If failOnHookError is true, throw the error\n if (config.failOnHookError) {\n throw error;\n }\n\n // Otherwise, silently continue (error isolated)\n}\n\n/**\n * Execute multiple hooks serially with timeout protection\n *\n * This ensures hooks run one at a time in the order they're provided.\n *\n * @param hooks - Array of hook execution configs\n */\nexport async function executeHooksSerial(\n hooks: Array<{\n hook: GenericHookFunction | undefined;\n options: HookExecutionOptions;\n }>\n): Promise<void> {\n for (const { hook, options } of hooks) {\n await executeHook(hook, options);\n }\n}\n\n/**\n * Check if observability is enabled for this execution\n *\n * Takes sampling into account.\n */\nexport function isObservabilityEnabled(config: ObservabilityConfig): boolean {\n // Check if explicitly disabled\n if (config.enabled === false) {\n return false;\n }\n\n // Always enabled if no sampling rate specified\n if (config.samplingRate === undefined || config.samplingRate === 1.0) {\n return true;\n }\n\n // Never sample if rate is 0\n if (config.samplingRate === 0.0) {\n return false;\n }\n\n // Random sampling based on rate\n // Note: This decision is made once per flow execution in flow-builder\n // and stored, so sampling is consistent throughout the execution\n return Math.random() < config.samplingRate;\n}\n","/**\n * Universal Crypto Adapter\n *\n * Provides crypto-secure random byte generation for both Node.js and Edge Runtime.\n * Uses Web Crypto API (available in both environments) for maximum compatibility.\n *\n * @module @doclo/core/runtime/crypto\n */\n\n/**\n * Generate crypto-secure random bytes\n *\n * Uses Web Crypto API which is available in:\n * - Node.js 18+ (globalThis.crypto)\n * - Browsers (window.crypto)\n * - Cloudflare Workers (crypto)\n * - Vercel Edge Functions (crypto)\n *\n * @param length - Number of random bytes to generate\n * @returns Uint8Array containing random bytes\n */\nexport function getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n\n // Use Web Crypto API (available in all supported runtimes)\n // Node.js 18+, Edge Runtime, and browsers all support globalThis.crypto\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.getRandomValues) {\n globalThis.crypto.getRandomValues(bytes);\n return bytes;\n }\n\n throw new Error(\n 'Web Crypto API not available. This SDK requires:\\n' +\n '- Node.js 18.0.0 or later (has globalThis.crypto)\\n' +\n '- Edge Runtime (Vercel, Cloudflare)\\n' +\n '- Modern browsers'\n );\n}\n\n/**\n * Convert Uint8Array to lowercase hex string\n *\n * @param bytes - Byte array to convert\n * @returns Hex string representation\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map(b => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/**\n * Generate random hex string of specified byte length\n *\n * @param byteLength - Number of random bytes (hex string will be 2x this length)\n * @returns Lowercase hex string\n *\n * @example\n * ```typescript\n * const traceId = randomHex(16); // 32 hex characters\n * const spanId = randomHex(8); // 16 hex characters\n * ```\n */\nexport function randomHex(byteLength: number): string {\n const bytes = getRandomBytes(byteLength);\n return bytesToHex(bytes);\n}\n\n/**\n * Generate a UUID v4 string\n *\n * Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\n *\n * @returns UUID v4 string\n *\n * @example\n * ```typescript\n * const id = randomUUID(); // \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function randomUUID(): string {\n // Try native crypto.randomUUID() first (Node 19+, all Edge runtimes)\n if (typeof globalThis !== 'undefined' && globalThis.crypto?.randomUUID) {\n return globalThis.crypto.randomUUID();\n }\n\n // Fallback: Manual UUID v4 generation\n const bytes = getRandomBytes(16);\n\n // Set version (4) and variant bits for UUID v4\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4\n bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 10\n\n // Format as UUID string\n const hex = bytesToHex(bytes);\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;\n}\n","/**\n * Trace Context Generator\n *\n * Implements W3C Trace Context standard for distributed tracing.\n * Generates crypto-secure trace IDs, span IDs, and execution IDs.\n *\n * @see https://www.w3.org/TR/trace-context/\n * @module @doclo/core/observability/trace-context\n */\n\nimport { randomHex, randomUUID as cryptoRandomUUID } from '../runtime/crypto.js';\nimport type { TraceContext, TraceContextInput, ObservabilityConfig } from './types.js';\n\n/**\n * W3C Trace Context version (always \"00\")\n */\nconst TRACE_CONTEXT_VERSION = '00';\n\n/**\n * Trace flags for sampled traces\n */\nexport const TRACE_FLAGS_SAMPLED = 0x01;\n\n/**\n * Trace flags for non-sampled traces\n */\nexport const TRACE_FLAGS_NOT_SAMPLED = 0x00;\n\n/**\n * Generate a crypto-secure trace ID (32 lowercase hex characters)\n *\n * Format: 32 hex digits (16 bytes)\n * Example: \"4bf92f3577b34da6a3ce929d0e0e4736\"\n */\nexport function generateTraceId(): string {\n return randomHex(16);\n}\n\n/**\n * Generate a crypto-secure span ID (16 lowercase hex characters)\n *\n * Format: 16 hex digits (8 bytes)\n * Example: \"00f067aa0ba902b7\"\n */\nexport function generateSpanId(): string {\n return randomHex(8);\n}\n\n/**\n * Generate a unique execution ID\n *\n * Uses crypto-secure random bytes for uniqueness.\n * Format: UUID v4 style (xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx)\n */\nexport function generateExecutionId(): string {\n return cryptoRandomUUID();\n}\n\n/**\n * Create a new trace context for flow execution\n *\n * @param config - Observability configuration\n * @param sampled - Whether this execution is sampled\n * @returns Complete trace context\n */\nexport function createTraceContext(\n config: ObservabilityConfig,\n sampled: boolean\n): TraceContext {\n // Use custom generator if provided, otherwise use default\n const traceIdGenerator = config.generateTraceId ?? generateTraceId;\n const spanIdGenerator = config.generateSpanId ?? generateSpanId;\n\n // If trace context propagation is configured, use it\n if (config.traceContext) {\n const input = config.traceContext;\n return {\n traceId: input.traceId,\n spanId: spanIdGenerator(),\n parentSpanId: input.parentSpanId,\n traceFlags: input.traceFlags ?? (sampled ? TRACE_FLAGS_SAMPLED : TRACE_FLAGS_NOT_SAMPLED),\n traceState: input.traceState,\n };\n }\n\n // Create new trace context\n return {\n traceId: traceIdGenerator(),\n spanId: spanIdGenerator(),\n traceFlags: sampled ? TRACE_FLAGS_SAMPLED : TRACE_FLAGS_NOT_SAMPLED,\n };\n}\n\n/**\n * Create a child span context from a parent trace context\n *\n * @param parent - Parent trace context\n * @param config - Observability configuration (for custom span ID generator)\n * @returns New trace context with same traceId but new spanId\n */\nexport function createChildSpanContext(\n parent: TraceContext,\n config?: ObservabilityConfig\n): TraceContext {\n const spanIdGenerator = config?.generateSpanId ?? generateSpanId;\n\n return {\n traceId: parent.traceId,\n spanId: spanIdGenerator(),\n parentSpanId: parent.spanId,\n traceFlags: parent.traceFlags,\n traceState: parent.traceState,\n };\n}\n\n/**\n * Format trace context as W3C traceparent header value\n *\n * Format: \"00-{traceId}-{spanId}-{flags}\"\n * Example: \"00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01\"\n *\n * @see https://www.w3.org/TR/trace-context/#traceparent-header\n */\nexport function formatTraceparent(context: TraceContext): string {\n const flags = context.traceFlags.toString(16).padStart(2, '0');\n return `${TRACE_CONTEXT_VERSION}-${context.traceId}-${context.spanId}-${flags}`;\n}\n\n/**\n * Parse W3C traceparent header value\n *\n * @param traceparent - Traceparent header value\n * @returns Parsed trace context input or null if invalid\n */\nexport function parseTraceparent(traceparent: string): TraceContextInput | null {\n // Format: \"00-{traceId}-{spanId}-{flags}\"\n const parts = traceparent.split('-');\n\n if (parts.length !== 4) {\n return null;\n }\n\n const [version, traceId, spanId, flags] = parts;\n\n // Validate version\n if (version !== TRACE_CONTEXT_VERSION) {\n return null;\n }\n\n // Validate traceId (32 hex chars)\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n return null;\n }\n\n // Validate spanId (16 hex chars)\n if (!/^[0-9a-f]{16}$/.test(spanId)) {\n return null;\n }\n\n // Validate flags (2 hex chars)\n if (!/^[0-9a-f]{2}$/.test(flags)) {\n return null;\n }\n\n return {\n traceId,\n parentSpanId: spanId,\n traceFlags: parseInt(flags, 16),\n };\n}\n\n/**\n * Format trace context as W3C tracestate header value\n *\n * @see https://www.w3.org/TR/trace-context/#tracestate-header\n */\nexport function formatTracestate(context: TraceContext): string | undefined {\n return context.traceState;\n}\n\n/**\n * Check if trace context is sampled\n */\nexport function isTraceSampled(context: TraceContext): boolean {\n return (context.traceFlags & TRACE_FLAGS_SAMPLED) === TRACE_FLAGS_SAMPLED;\n}\n\n/**\n * Validate trace ID format\n *\n * Must be 32 lowercase hex characters, not all zeros\n */\nexport function isValidTraceId(traceId: string): boolean {\n // Must be 32 hex characters\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n return false;\n }\n\n // Must not be all zeros\n if (traceId === '00000000000000000000000000000000') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Validate span ID format\n *\n * Must be 16 lowercase hex characters, not all zeros\n */\nexport function isValidSpanId(spanId: string): boolean {\n // Must be 16 hex characters\n if (!/^[0-9a-f]{16}$/.test(spanId)) {\n return false;\n }\n\n // Must not be all zeros\n if (spanId === '0000000000000000') {\n return false;\n }\n\n return true;\n}\n\n/**\n * Trace Context Manager\n *\n * Manages trace context for the current execution.\n */\nexport class TraceContextManager {\n private traceContext: TraceContext | null = null;\n private config: ObservabilityConfig;\n\n constructor(config: ObservabilityConfig) {\n this.config = config;\n }\n\n /**\n * Initialize trace context for new execution\n */\n initialize(sampled: boolean): TraceContext {\n this.traceContext = createTraceContext(this.config, sampled);\n return this.traceContext;\n }\n\n /**\n * Get current trace context\n */\n getTraceContext(): TraceContext | null {\n return this.traceContext;\n }\n\n /**\n * Create child span context\n */\n createChildSpan(): TraceContext {\n if (!this.traceContext) {\n throw new Error('Trace context not initialized');\n }\n return createChildSpanContext(this.traceContext, this.config);\n }\n\n /**\n * Get traceparent header value\n */\n getTraceparent(): string | null {\n if (!this.traceContext) {\n return null;\n }\n return formatTraceparent(this.traceContext);\n }\n\n /**\n * Reset trace context (for testing)\n */\n reset(): void {\n this.traceContext = null;\n }\n}\n","/**\n * OpenTelemetry Semantic Conventions for Gen AI\n *\n * Implements Gen AI semantic conventions (v1.29.0) for observability.\n * Maps SDK data to standard OpenTelemetry attributes.\n *\n * @see https://opentelemetry.io/docs/specs/semconv/gen-ai/\n * @module @doclo/core/observability/otel-attributes\n */\n\n/**\n * Gen AI system names (standardized)\n */\nconst GEN_AI_SYSTEMS: Record<string, string> = {\n openai: 'openai',\n 'openai-compatible': 'openai',\n anthropic: 'anthropic',\n google: 'vertex_ai', // Google uses Vertex AI\n 'google-ai': 'vertex_ai',\n cohere: 'cohere',\n huggingface: 'huggingface',\n openrouter: 'openrouter', // Custom system\n ollama: 'ollama', // Custom system\n // Generic OpenRouter vendors (extracted from model IDs like 'qwen/qwen3-235b')\n // Full list from: curl -s \"https://openrouter.ai/api/v1/models\" | jq '[.data[].id | split(\"/\")[0]] | unique | sort'\n 'generic-or': 'openrouter',\n qwen: 'qwen',\n 'meta-llama': 'meta',\n deepseek: 'deepseek',\n 'z-ai': 'zhipu', // GLM models\n moonshotai: 'moonshot',\n mistralai: 'mistral',\n opengvlab: 'opengvlab',\n 'stepfun-ai': 'stepfun',\n nvidia: 'nvidia',\n 'x-ai': 'xai', // Grok models\n yi: 'yi',\n microsoft: 'microsoft',\n databricks: 'databricks',\n thudm: 'zhipu', // THU models (GLM)\n internlm: 'internlm',\n amazon: 'amazon', // Nova models\n baidu: 'baidu', // ERNIE models\n bytedance: 'bytedance', // UI-TARS\n minimax: 'minimax',\n tencent: 'tencent', // Hunyuan\n alibaba: 'alibaba', // Tongyi\n perplexity: 'perplexity',\n inflection: 'inflection',\n};\n\n/**\n * Map provider name to Gen AI system identifier\n */\nfunction mapProviderToSystem(provider: string): string {\n const normalized = provider.toLowerCase();\n return GEN_AI_SYSTEMS[normalized] ?? normalized;\n}\n\n/**\n * Build OpenTelemetry attributes for LLM operations\n *\n * @param data - Step execution data\n * @returns OpenTelemetry attributes object\n */\nexport function buildOtelAttributes(data: {\n provider?: string;\n model?: string;\n modelUsed?: string;\n stepType?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n}): Record<string, string | number | boolean> {\n const attributes: Record<string, string | number | boolean> = {};\n\n // Gen AI system (required)\n if (data.provider) {\n attributes['gen_ai.system'] = mapProviderToSystem(data.provider);\n }\n\n // Operation name (what type of operation)\n if (data.stepType) {\n attributes['gen_ai.operation.name'] = data.stepType;\n }\n\n // Request model (requested model name)\n if (data.model) {\n attributes['gen_ai.request.model'] = data.model;\n }\n\n // Response model (actual model used, may differ from requested)\n if (data.modelUsed) {\n attributes['gen_ai.response.model'] = data.modelUsed;\n }\n\n // Token usage\n if (data.inputTokens !== undefined) {\n attributes['gen_ai.usage.input_tokens'] = data.inputTokens;\n }\n\n if (data.outputTokens !== undefined) {\n attributes['gen_ai.usage.output_tokens'] = data.outputTokens;\n }\n\n // Finish reason (simplified as single string, not array)\n if (data.finishReason) {\n attributes['gen_ai.response.finish_reason'] = data.finishReason;\n }\n\n // Request parameters\n if (data.temperature !== undefined) {\n attributes['gen_ai.request.temperature'] = data.temperature;\n }\n\n if (data.maxTokens !== undefined) {\n attributes['gen_ai.request.max_tokens'] = data.maxTokens;\n }\n\n if (data.topP !== undefined) {\n attributes['gen_ai.request.top_p'] = data.topP;\n }\n\n if (data.topK !== undefined) {\n attributes['gen_ai.request.top_k'] = data.topK;\n }\n\n return attributes;\n}\n\n/**\n * Build OpenTelemetry attributes for provider requests\n *\n * Used for onProviderRequest hooks\n */\nexport function buildProviderRequestAttributes(data: {\n provider: string;\n model: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n provider: data.provider,\n model: data.model,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n}\n\n/**\n * Build OpenTelemetry attributes for provider responses\n *\n * Used for onProviderResponse hooks\n */\nexport function buildProviderResponseAttributes(data: {\n provider: string;\n model: string;\n modelUsed?: string;\n inputTokens: number;\n outputTokens: number;\n finishReason?: string;\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n });\n}\n\n/**\n * Build OpenTelemetry attributes for step execution\n *\n * Used for onStepEnd hooks\n */\nexport function buildStepAttributes(data: {\n stepType: string;\n provider?: string;\n model?: string;\n modelUsed?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n}): Record<string, string | number | boolean> {\n return buildOtelAttributes({\n stepType: data.stepType,\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n}\n\n/**\n * Standard finish reason mappings\n *\n * Maps provider-specific finish reasons to standard values\n */\nexport const FINISH_REASON_MAPPING: Record<string, string> = {\n // OpenAI\n stop: 'stop',\n length: 'length',\n content_filter: 'content_filter',\n tool_calls: 'tool_calls',\n function_call: 'function_call',\n\n // Anthropic\n end_turn: 'stop',\n max_tokens: 'length',\n stop_sequence: 'stop',\n\n // Google\n STOP: 'stop',\n MAX_TOKENS: 'length',\n SAFETY: 'content_filter',\n RECITATION: 'content_filter',\n\n // Generic\n complete: 'stop',\n truncated: 'length',\n filtered: 'content_filter',\n};\n\n/**\n * Normalize finish reason to standard value\n */\nexport function normalizeFinishReason(reason: string | undefined): string | undefined {\n if (!reason) {\n return undefined;\n }\n\n return FINISH_REASON_MAPPING[reason] ?? reason;\n}\n\n/**\n * Add standard OpenTelemetry span attributes\n *\n * These are generic attributes that apply to all spans\n */\nexport function addStandardSpanAttributes(attributes: Record<string, string | number | boolean>, data: {\n spanKind?: 'client' | 'server' | 'internal';\n serviceName?: string;\n serviceVersion?: string;\n}): void {\n if (data.spanKind) {\n attributes['span.kind'] = data.spanKind;\n }\n\n if (data.serviceName) {\n attributes['service.name'] = data.serviceName;\n }\n\n if (data.serviceVersion) {\n attributes['service.version'] = data.serviceVersion;\n }\n}\n\n/**\n * Build full OpenTelemetry context for export\n *\n * Combines Gen AI attributes with standard span attributes\n */\nexport function buildFullOtelContext(data: {\n // Gen AI attributes\n stepType?: string;\n provider?: string;\n model?: string;\n modelUsed?: string;\n inputTokens?: number;\n outputTokens?: number;\n finishReason?: string;\n config?: {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n topK?: number;\n };\n\n // Standard span attributes\n spanKind?: 'client' | 'server' | 'internal';\n serviceName?: string;\n serviceVersion?: string;\n}): Record<string, string | number | boolean> {\n const attributes = buildOtelAttributes({\n stepType: data.stepType,\n provider: data.provider,\n model: data.model,\n modelUsed: data.modelUsed,\n inputTokens: data.inputTokens,\n outputTokens: data.outputTokens,\n finishReason: data.finishReason,\n temperature: data.config?.temperature,\n maxTokens: data.config?.maxTokens,\n topP: data.config?.topP,\n topK: data.config?.topK,\n });\n\n addStandardSpanAttributes(attributes, {\n spanKind: data.spanKind,\n serviceName: data.serviceName,\n serviceVersion: data.serviceVersion,\n });\n\n return attributes;\n}\n","/**\n * Observability Configuration Defaults\n *\n * Provides default configuration values and config merging utilities.\n *\n * @module @doclo/core/observability/defaults\n */\n\nimport type { ObservabilityConfig } from './types.js';\n\n/**\n * Default observability configuration\n */\nexport const DEFAULT_OBSERVABILITY_CONFIG: Required<Omit<ObservabilityConfig,\n | 'onFlowStart' | 'onFlowEnd' | 'onFlowError'\n | 'onStepStart' | 'onStepEnd' | 'onStepError'\n | 'onConsensusStart' | 'onConsensusRunRetry' | 'onConsensusRunComplete' | 'onConsensusComplete'\n | 'onBatchStart' | 'onBatchItemStart' | 'onBatchItemEnd' | 'onBatchEnd'\n | 'onProviderRequest' | 'onProviderResponse' | 'onProviderRetry' | 'onCircuitBreakerTriggered'\n | 'onLog' | 'onHookError'\n | 'customSampler' | 'generateTraceId' | 'generateSpanId' | 'generateExecutionId'\n | 'traceContext' | 'observabilityVersion'\n>> = {\n enabled: true,\n samplingRate: 1.0,\n samplingStrategy: 'random',\n asyncHooks: true,\n fireAndForget: false,\n hookTimeout: 5000,\n failOnHookError: false,\n};\n\n/**\n * Merge user config with defaults\n *\n * User config takes precedence over defaults.\n */\nexport function mergeConfig(userConfig?: ObservabilityConfig): ObservabilityConfig {\n if (!userConfig) {\n return { ...DEFAULT_OBSERVABILITY_CONFIG };\n }\n\n return {\n ...DEFAULT_OBSERVABILITY_CONFIG,\n ...userConfig,\n };\n}\n\n/**\n * Determine if execution should be sampled\n *\n * Uses sampling strategy from config.\n */\nexport function shouldSample(config: ObservabilityConfig): boolean {\n // Always sample if no rate specified\n if (config.samplingRate === undefined || config.samplingRate === 1.0) {\n return true;\n }\n\n // Never sample if rate is 0\n if (config.samplingRate === 0.0) {\n return false;\n }\n\n // Custom sampler (will be called later with flow context)\n if (config.samplingStrategy === 'custom' && config.customSampler) {\n // Custom sampler will be called in flow execution\n // For now, assume sampled (decision made later)\n return true;\n }\n\n // Random sampling (default)\n return Math.random() < config.samplingRate;\n}\n\n/**\n * Validate observability configuration\n *\n * Checks for invalid values and warns about issues.\n */\nexport function validateConfig(config: ObservabilityConfig): {\n valid: boolean;\n warnings: string[];\n errors: string[];\n} {\n const warnings: string[] = [];\n const errors: string[] = [];\n\n // Validate sampling rate\n if (config.samplingRate !== undefined) {\n if (config.samplingRate < 0 || config.samplingRate > 1) {\n errors.push('samplingRate must be between 0.0 and 1.0');\n }\n }\n\n // Validate hook timeout\n if (config.hookTimeout !== undefined) {\n if (config.hookTimeout <= 0) {\n errors.push('hookTimeout must be positive');\n }\n if (config.hookTimeout > 60000) {\n warnings.push('hookTimeout > 60s may cause long execution delays');\n }\n }\n\n // Validate sampling strategy\n if (config.samplingStrategy === 'custom' && !config.customSampler) {\n errors.push('customSampler required when samplingStrategy is \"custom\"');\n }\n\n // Validate trace context propagation\n if (config.traceContext) {\n const { traceId, parentSpanId } = config.traceContext;\n\n // Validate trace ID format\n if (!/^[0-9a-f]{32}$/.test(traceId)) {\n errors.push('traceContext.traceId must be 32 lowercase hex characters');\n }\n\n // Validate parent span ID format\n if (!/^[0-9a-f]{16}$/.test(parentSpanId)) {\n errors.push('traceContext.parentSpanId must be 16 lowercase hex characters');\n }\n\n // Validate trace ID is not all zeros\n if (traceId === '00000000000000000000000000000000') {\n errors.push('traceContext.traceId cannot be all zeros');\n }\n\n // Validate parent span ID is not all zeros\n if (parentSpanId === '0000000000000000') {\n errors.push('traceContext.parentSpanId cannot be all zeros');\n }\n }\n\n // Warn about conflicting options\n if (config.asyncHooks === false && config.hookTimeout !== undefined) {\n warnings.push('hookTimeout has no effect when asyncHooks is false');\n }\n\n if (config.fireAndForget === true && config.hookTimeout !== undefined) {\n warnings.push('hookTimeout has no effect when fireAndForget is true');\n }\n\n if (config.enabled === false && Object.keys(config).length > 1) {\n warnings.push('Observability is disabled, other config options have no effect');\n }\n\n return {\n valid: errors.length === 0,\n warnings,\n errors,\n };\n}\n\n/**\n * Get observability version\n *\n * Returns the version of the observability contract.\n */\nexport function getObservabilityVersion(config?: ObservabilityConfig): string {\n return config?.observabilityVersion ?? '1.0.0';\n}\n\n/**\n * Check if observability is effectively disabled\n *\n * Returns true if observability is explicitly disabled or sampling rate is 0.\n */\nexport function isObservabilityDisabled(config: ObservabilityConfig): boolean {\n return config.enabled === false || config.samplingRate === 0.0;\n}\n\n/**\n * Check if any hooks are configured\n *\n * Returns true if at least one hook is defined.\n */\nexport function hasAnyHooks(config: ObservabilityConfig): boolean {\n return !!(\n config.onFlowStart ||\n config.onFlowEnd ||\n config.onFlowError ||\n config.onStepStart ||\n config.onStepEnd ||\n config.onStepError ||\n config.onConsensusStart ||\n config.onConsensusRunRetry ||\n config.onConsensusRunComplete ||\n config.onConsensusComplete ||\n config.onBatchStart ||\n config.onBatchItemStart ||\n config.onBatchItemEnd ||\n config.onBatchEnd ||\n config.onProviderRequest ||\n config.onProviderResponse ||\n config.onProviderRetry ||\n config.onCircuitBreakerTriggered ||\n config.onLog\n );\n}\n\n/**\n * Create minimal config for testing\n *\n * Useful for unit tests that don't need full observability.\n */\nexport function createMinimalConfig(overrides?: Partial<ObservabilityConfig>): ObservabilityConfig {\n return {\n enabled: true,\n samplingRate: 1.0,\n asyncHooks: false, // Faster for tests\n fireAndForget: false,\n hookTimeout: 1000, // Shorter for tests\n failOnHookError: false,\n ...overrides,\n };\n}\n","/**\n * Logging Utility for Observability\n *\n * Provides a logger that integrates with the observability system.\n * Logs are sent to the onLog hook with fire-and-forget execution.\n *\n * @module @doclo/core/observability/logger\n */\n\nimport type { ObservabilityConfig, LogContext, TraceContext } from './types.js';\nimport { executeHook } from './hook-executor.js';\n\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport interface LoggerOptions {\n observability?: ObservabilityConfig;\n flowId?: string;\n executionId?: string;\n stepId?: string;\n traceContext?: TraceContext;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Logger class that integrates with observability hooks\n */\nexport class Logger {\n private options: LoggerOptions;\n\n constructor(options: LoggerOptions = {}) {\n this.options = options;\n }\n\n /**\n * Log a debug message\n */\n debug(message: string, data?: unknown): void {\n this.log('debug', message, data);\n }\n\n /**\n * Log an info message\n */\n info(message: string, data?: unknown): void {\n this.log('info', message, data);\n }\n\n /**\n * Log a warning message\n */\n warn(message: string, data?: unknown): void {\n this.log('warn', message, data);\n }\n\n /**\n * Log an error message\n */\n error(message: string, error?: Error | unknown, data?: unknown): void {\n this.log('error', message, data, error instanceof Error ? error : undefined);\n }\n\n /**\n * Internal log method that sends to onLog hook\n */\n private log(level: LogLevel, message: string, data?: unknown, error?: Error): void {\n const timestamp = Date.now();\n\n // Always output to console as fallback\n const consoleMethod = level === 'error' ? console.error : level === 'warn' ? console.warn : console.log;\n if (error) {\n consoleMethod(`[${level.toUpperCase()}] ${message}`, data, error);\n } else if (data !== undefined) {\n consoleMethod(`[${level.toUpperCase()}] ${message}`, data);\n } else {\n consoleMethod(`[${level.toUpperCase()}] ${message}`);\n }\n\n // Send to onLog hook (fire-and-forget)\n if (this.options.observability?.onLog && this.options.traceContext) {\n // Combine data and error into metadata\n const combinedMetadata: Record<string, unknown> = {\n ...(this.options.metadata || {}),\n };\n if (data !== undefined) {\n combinedMetadata.data = data;\n }\n if (error) {\n combinedMetadata.error = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n }\n\n const logContext: LogContext = {\n flowId: this.options.flowId ?? 'unknown',\n executionId: this.options.executionId ?? 'unknown',\n stepId: this.options.stepId,\n timestamp,\n level,\n message,\n metadata: combinedMetadata,\n traceContext: this.options.traceContext,\n };\n\n // Fire-and-forget execution (don't await)\n executeHook(this.options.observability.onLog, {\n hookName: 'onLog',\n config: this.options.observability,\n context: logContext,\n fireAndForget: true, // Special handling for onLog\n }).catch(() => {\n // Silently ignore onLog errors\n });\n }\n }\n}\n\n/**\n * Create a logger instance with observability integration\n */\nexport function createLogger(options: LoggerOptions = {}): Logger {\n return new Logger(options);\n}\n","/**\n * Observability Module\n *\n * Comprehensive observability system for the doclo-sdk SDK.\n * Provides hooks, tracing, and monitoring capabilities.\n *\n * @module @doclo/core/observability\n * @example\n * ```typescript\n * import { ObservabilityConfig } from '@doclo/core/observability';\n *\n * const config: ObservabilityConfig = {\n * onFlowStart: (ctx) => console.log('Flow started:', ctx.flowId),\n * onStepEnd: (ctx) => console.log('Step completed:', ctx.stepId, ctx.duration),\n * };\n * ```\n */\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type {\n // Main configuration\n ObservabilityConfig,\n\n // Flow-level contexts\n FlowStartContext,\n FlowEndContext,\n FlowErrorContext,\n FlowStats,\n\n // Step-level contexts\n StepStartContext,\n StepEndContext,\n StepErrorContext,\n\n // Consensus contexts\n ConsensusStartContext,\n ConsensusRunRetryContext,\n ConsensusRunContext,\n ConsensusCompleteContext,\n\n // Batch/forEach contexts\n BatchStartContext,\n BatchItemContext,\n BatchItemEndContext,\n BatchEndContext,\n\n // Provider-level contexts\n ProviderRequestContext,\n ProviderResponseContext,\n ProviderRetryContext,\n CircuitBreakerContext,\n\n // Logging context\n LogContext,\n\n // Error handling\n HookError,\n\n // Trace context\n TraceContext,\n TraceContextInput,\n\n // Execution context\n ExecutionContext,\n CustomMetric,\n} from './types.js';\n\n// ============================================================================\n// Hook Executor\n// ============================================================================\n\n// Note: Hook executor is for SDK internal use (not for end users)\n// It's used by the SDK to execute hooks with timeout/error protection\n\nexport {\n executeHook,\n executeHooksSerial,\n isObservabilityEnabled,\n} from './hook-executor.js';\n\n// ============================================================================\n// Trace Context Utilities\n// ============================================================================\n\nexport {\n generateTraceId,\n generateSpanId,\n generateExecutionId,\n createTraceContext,\n createChildSpanContext,\n formatTraceparent,\n parseTraceparent,\n formatTracestate,\n isTraceSampled,\n isValidTraceId,\n isValidSpanId,\n TraceContextManager,\n TRACE_FLAGS_SAMPLED,\n TRACE_FLAGS_NOT_SAMPLED,\n} from './trace-context.js';\n\n// ============================================================================\n// OpenTelemetry Attributes\n// ============================================================================\n\nexport {\n buildOtelAttributes,\n buildProviderRequestAttributes,\n buildProviderResponseAttributes,\n buildStepAttributes,\n buildFullOtelContext,\n normalizeFinishReason,\n addStandardSpanAttributes,\n FINISH_REASON_MAPPING,\n} from './otel-attributes.js';\n\n// ============================================================================\n// Configuration Defaults\n// ============================================================================\n\nexport {\n DEFAULT_OBSERVABILITY_CONFIG,\n mergeConfig,\n shouldSample,\n validateConfig,\n getObservabilityVersion,\n isObservabilityDisabled,\n hasAnyHooks,\n createMinimalConfig,\n} from './defaults.js';\n\n// ============================================================================\n// Logger\n// ============================================================================\n\nexport {\n Logger,\n createLogger,\n type LogLevel,\n type LoggerOptions,\n} from './logger.js';\n\n// ============================================================================\n// Version\n// ============================================================================\n\n/**\n * Observability module version\n */\nexport const OBSERVABILITY_VERSION = '1.0.0';\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@doclo/core",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Core types, utilities, and security features for the Doclo SDK",
5
5
  "license": "MIT",
6
6
  "repository": {