@saguiitay/eventhouse-ai-observability 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +125 -18
- package/dist/adapters/openai.d.ts +25 -0
- package/dist/adapters/vercel.d.ts +25 -0
- package/dist/{chunk-XQFUPGYU.js → chunk-XGCHW72B.js} +11 -55
- package/dist/{chunk-XQFUPGYU.js.map → chunk-XGCHW72B.js.map} +1 -1
- package/dist/copilot.js +5 -3
- package/dist/copilot.js.map +1 -1
- package/dist/index.d.ts +1 -6
- package/dist/index.js +3 -11
- package/dist/openai.d.ts +12 -0
- package/dist/openai.js +408 -0
- package/dist/openai.js.map +1 -0
- package/dist/validate.d.ts +2 -0
- package/dist/validate.js +237 -0
- package/dist/validate.js.map +1 -0
- package/dist/validation/fabric.d.ts +29 -0
- package/dist/vercel.d.ts +15 -0
- package/dist/vercel.js +369 -0
- package/dist/vercel.js.map +1 -0
- package/docs/architecture.md +19 -3
- package/docs/copilot-adapter.md +1 -1
- package/docs/extending.md +45 -1
- package/docs/fabric-setup.md +24 -0
- package/docs/implementation-report.md +62 -18
- package/docs/openai-adapter.md +137 -0
- package/docs/quickstart.md +75 -6
- package/docs/research-eventstream.md +8 -6
- package/docs/research.md +1 -1
- package/docs/security.md +1 -1
- package/docs/telemetry-schema.md +18 -0
- package/docs/vercel-adapter.md +201 -0
- package/examples/README.md +75 -6
- package/examples/copilot-basic/package.json +1 -1
- package/examples/openai-basic/env.example +8 -0
- package/examples/openai-basic/index.ts +46 -0
- package/examples/shared.ts +3 -62
- package/examples/telemetry.ts +124 -0
- package/examples/vercel-basic/env.example +8 -0
- package/examples/vercel-basic/index.ts +60 -0
- package/fabric-setup.zip +0 -0
- package/package.json +39 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/engine.ts","../src/diagnostics.ts","../src/exporters/eventstream.ts","../src/exporters/serialize.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n context,\n trace,\n ROOT_CONTEXT,\n INVALID_SPAN_CONTEXT,\n type Attributes,\n type AttributeValue,\n type Context,\n type Span,\n type SpanOptions,\n} from \"@opentelemetry/api\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n classifyError,\n diagnosticEvent,\n type DiagnosticCategory,\n type DiagnosticEvent,\n} from \"./diagnostics.js\";\nimport {\n TracerProvider,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanExporter,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace\";\n\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport type { DiagnosticCategory, DiagnosticEvent } from \"./diagnostics.js\";\n\nexport interface Diagnostics {\n eventsGenerated: number;\n eventsExported: number;\n eventsRetried: number;\n eventsDropped: number;\n exportFailures: number;\n /** Admitted spans awaiting export; excludes batches already in flight. */\n queueDepth: number;\n activeSpans: number;\n /** Latest sanitized failure only; never includes the original error or configuration. */\n lastError?: DiagnosticEvent;\n}\n\nexport type Redactor = (\n key: string,\n value: AttributeValue,\n) => AttributeValue | undefined;\n\nexport interface CoreOptions {\n exporter: SpanExporter;\n serviceName?: string;\n serviceVersion?: string;\n environment?: string;\n resourceAttributes?: Attributes;\n captureContent?: boolean;\n redact?: Redactor;\n /** Receives sanitized failure categories. Callback exceptions are contained. */\n onDiagnostic?: (event: DiagnosticEvent) => void;\n /** Prints only sanitized failure categories and fixed troubleshooting hints. */\n debug?: boolean;\n samplingRatio?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n /** Export callback deadline in milliseconds. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Underlying exports, including timed-out calls still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n /** Overall shutdown deadline in milliseconds, including transport cleanup. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n maxQueueSize?: number;\n maxActiveSpans?: number;\n}\n\nexport interface Observability {\n readonly captureContent: boolean;\n readonly maxActiveSpans: number;\n startSpan(\n name: string,\n options?: SpanOptions & { parent?: Span | Context },\n ): Span;\n withSpan<T>(span: Span, callback: () => T): T;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nfunction bounded(\n value: number,\n name: string,\n min: number,\n max: number,\n): number {\n if (!Number.isFinite(value) || value < min || value > max) {\n throw new Error(`${name} must be between ${min} and ${max}`);\n }\n return value;\n}\n\nconst secretKey =\n /(?:password|secret|authorization|connection.?string|api[_.-]?key|sharedaccess|access[_.-]?token)/i;\nconst contentKey =\n /(?:prompt|completion|response\\.content|input\\.messages|output\\.messages|tool\\.(?:arguments|result|output))/i;\n\nexport function redactSecrets(value: string): string {\n return value\n .replace(/(?:Endpoint=sb:\\/\\/)[^\\s\"']+/gi, \"[REDACTED_CONNECTION_STRING]\")\n .replace(/SharedAccess(?:Key|Signature)(?:Name)?=[^;\\s\"']+/gi, \"[REDACTED]\")\n .replace(/\\bBearer\\s+[A-Za-z0-9._~+/-]+=*/gi, \"Bearer [REDACTED]\")\n .replace(/([?&](?:sig|token|key)=)[^&\\s\"']+/gi, \"$1[REDACTED]\");\n}\n\nfunction makeSanitizer(options: CoreOptions) {\n const cleanValue = (\n key: string,\n value: AttributeValue,\n ): AttributeValue | undefined => {\n if (\n secretKey.test(key) ||\n (!options.captureContent && contentKey.test(key))\n )\n return undefined;\n const clean = (item: string | number | boolean | null | undefined) =>\n typeof item === \"string\" ? redactSecrets(item).slice(0, 4096) : item;\n let result: AttributeValue = Array.isArray(value)\n ? (value.slice(0, 64).map(clean) as AttributeValue)\n : (clean(value as string | number | boolean) as AttributeValue);\n if (options.redact) {\n try {\n const redacted = options.redact(key, result);\n if (redacted === undefined) return undefined;\n result = Array.isArray(redacted)\n ? (redacted.slice(0, 64).map(clean) as AttributeValue)\n : (clean(redacted as string | number | boolean) as AttributeValue);\n } catch {\n return undefined;\n }\n }\n return result;\n };\n const cleanAttributes = (attributes: Attributes): Attributes => {\n const result: Attributes = {};\n for (const [key, value] of Object.entries(attributes).slice(0, 64)) {\n if (value !== undefined) {\n const cleaned = cleanValue(key, value);\n if (cleaned !== undefined)\n result[redactSecrets(key).slice(0, 256)] = cleaned;\n }\n }\n return result;\n };\n return (span: ReadableSpan): ReadableSpan => ({\n spanContext: () => span.spanContext(),\n ...(span.parentSpanContext\n ? { parentSpanContext: span.parentSpanContext }\n : {}),\n kind: span.kind,\n startTime: span.startTime,\n endTime: span.endTime,\n duration: span.duration,\n ended: span.ended,\n instrumentationScope: span.instrumentationScope,\n droppedAttributesCount: span.droppedAttributesCount,\n droppedEventsCount: span.droppedEventsCount,\n droppedLinksCount: span.droppedLinksCount,\n name: redactSecrets(span.name).slice(0, 512),\n attributes: cleanAttributes(span.attributes),\n resource: resourceFromAttributes(cleanAttributes(span.resource.attributes)),\n status: {\n code: span.status.code,\n ...(options.captureContent && span.status.message\n ? { message: redactSecrets(span.status.message).slice(0, 4096) }\n : {}),\n },\n events: span.events.map((event) => ({\n ...event,\n name: redactSecrets(event.name).slice(0, 512),\n ...(event.attributes\n ? { attributes: cleanAttributes(event.attributes) }\n : {}),\n })),\n links: span.links.map((link) => ({\n ...link,\n ...(link.attributes\n ? { attributes: cleanAttributes(link.attributes) }\n : {}),\n })),\n });\n}\n\nclass ManagedBatchProcessor implements SpanProcessor {\n private readonly processor: BatchSpanProcessor;\n private readonly inFlight = new Set<Promise<void>>();\n private flushPromise: Promise<void> | undefined;\n private closed = false;\n private shutdownPromise: Promise<void> | undefined;\n private exporterShutdownPromise: Promise<void> | undefined;\n private readonly finishers = new Set<() => void>();\n private readonly waiters = new Set<() => void>();\n private readonly shutdownController = new AbortController();\n private underlyingExports = 0;\n private disposed = false;\n readonly counters: Diagnostics = {\n eventsGenerated: 0,\n eventsExported: 0,\n eventsRetried: 0,\n eventsDropped: 0,\n exportFailures: 0,\n queueDepth: 0,\n activeSpans: 0,\n };\n\n constructor(\n private readonly exporter: SpanExporter,\n private readonly maxQueueSize: number,\n batchSize: number,\n interval: number,\n timeout: number,\n private readonly maxConcurrentExports: number,\n private readonly shutdownTimeout: number,\n private readonly sanitize: (span: ReadableSpan) => ReadableSpan,\n private readonly onDiagnostic: CoreOptions[\"onDiagnostic\"],\n private readonly debug: boolean,\n ) {\n this.processor = new BatchSpanProcessor({\n exporter: {\n export: (spans, callback) => {\n let complete!: () => void;\n const pending = new Promise<void>((resolve) => {\n complete = resolve;\n });\n this.inFlight.add(pending);\n let settled = false;\n let queued = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let attempt!: () => void;\n const dequeue = () => {\n if (!queued) return;\n queued = false;\n this.counters.queueDepth -= spans.length;\n };\n const controller = new AbortController();\n const expire = () => {\n controller.abort();\n finish(false, undefined, \"timeout\");\n };\n const finish = (\n success: boolean,\n result?: {\n exportedSpans?: number;\n droppedSpans?: number;\n error?: unknown;\n },\n category?: DiagnosticCategory,\n ) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n this.finishers.delete(expire);\n this.waiters.delete(attempt);\n dequeue();\n const exported = result?.exportedSpans;\n const dropped = result?.droppedSpans;\n const hasCounts =\n Number.isInteger(exported) &&\n Number.isInteger(dropped) &&\n exported! >= 0 &&\n dropped! >= 0 &&\n exported! + dropped! === spans.length;\n this.counters.eventsExported += hasCounts\n ? exported!\n : success\n ? spans.length\n : 0;\n this.counters.eventsDropped += hasCounts\n ? dropped!\n : success\n ? 0\n : spans.length;\n if (!success) {\n this.counters.exportFailures++;\n this.report(\"export\", result?.error, category);\n }\n this.inFlight.delete(pending);\n complete();\n // Failures are accounted for here, never forwarded to OTel's global logger.\n callback({ code: 0 });\n this.wakeWaiter();\n };\n this.finishers.add(expire);\n // BSP can start an export directly in onEnd when the batch fills.\n attempt = () => {\n if (settled) return;\n if (this.disposed) {\n finish(false, undefined, \"shutdown\");\n return;\n }\n if (this.underlyingExports >= this.maxConcurrentExports) {\n this.waiters.add(attempt);\n deadline ??= setTimeout(expire, timeout);\n return;\n }\n this.waiters.delete(attempt);\n dequeue();\n this.underlyingExports++;\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n this.underlyingExports--;\n this.wakeWaiter();\n };\n try {\n // Standard exporters ignore the optional signal; Eventstream honors it.\n const exporter = this.exporter as SpanExporter & {\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void;\n };\n const result = exporter.export(\n spans,\n (result) => {\n release();\n finish(\n result.code === 0,\n result as typeof result & {\n exportedSpans?: number;\n droppedSpans?: number;\n },\n );\n },\n controller.signal,\n );\n // Also contain exporters incorrectly returning a rejected promise.\n void Promise.resolve(result).catch((error: unknown) => {\n release();\n finish(false, { error });\n });\n } catch (error) {\n release();\n finish(false, { error });\n }\n if (!settled) deadline ??= setTimeout(expire, timeout);\n };\n queueMicrotask(attempt);\n },\n shutdown: async () => {\n await this.waitForExports();\n await this.shutdownExporter();\n },\n },\n maxExportBatchSize: batchSize,\n maxQueueSize,\n scheduledDelayMillis: interval,\n // The callback deadline settles batches before BSP's fallback timeout.\n exportTimeoutMillis: timeout + 1000,\n });\n }\n\n onStart(): void {}\n\n onEnd(span: ReadableSpan): void {\n this.counters.eventsGenerated++;\n if (this.closed || this.counters.queueDepth >= this.maxQueueSize) {\n this.counters.eventsDropped++;\n return;\n }\n try {\n const sanitized = this.sanitize(span);\n this.counters.queueDepth++;\n this.processor.onEnd(sanitized);\n } catch {\n this.counters.eventsDropped++;\n }\n }\n\n forceFlush(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.flushPromise ??= Promise.resolve().then(async () => {\n try {\n do {\n await this.processor.forceFlush();\n await this.waitForExports();\n } while (this.counters.queueDepth > 0);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"flush\", error);\n } finally {\n this.flushPromise = undefined;\n }\n });\n return this.flushPromise;\n }\n\n private async waitForExports(): Promise<void> {\n while (this.inFlight.size > 0) await Promise.all(this.inFlight);\n }\n\n private wakeWaiter(): void {\n if (this.underlyingExports >= this.maxConcurrentExports) return;\n const waiter = this.waiters.values().next().value;\n if (!waiter) return;\n this.waiters.delete(waiter);\n queueMicrotask(() => {\n waiter();\n this.wakeWaiter();\n });\n }\n\n shutdown(): Promise<void> {\n this.shutdownPromise ??= (async () => {\n this.closed = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.processor.shutdown(),\n new Promise<void>((resolve) => {\n deadline = setTimeout(() => {\n this.counters.exportFailures++;\n this.report(\"shutdown\", undefined, \"timeout\");\n this.shutdownController.abort();\n resolve();\n }, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n } finally {\n clearTimeout(deadline);\n this.disposed = true;\n for (const finish of this.finishers) finish();\n this.counters.eventsDropped += this.counters.queueDepth;\n this.counters.queueDepth = 0;\n // Even when draining times out, initiate cleanup exactly once.\n void this.shutdownExporter();\n }\n })();\n return this.shutdownPromise;\n }\n\n private shutdownExporter(): Promise<void> {\n this.exporterShutdownPromise ??= Promise.resolve()\n .then(() => {\n const exporter = this.exporter as SpanExporter & {\n shutdown(signal?: AbortSignal): Promise<void>;\n };\n return exporter.shutdown(this.shutdownController.signal);\n })\n .catch((error: unknown) => {\n if (!this.disposed && !this.shutdownController.signal.aborted) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n }\n });\n return this.exporterShutdownPromise;\n }\n\n getRetries(): number {\n try {\n const exporter = this.exporter as SpanExporter & {\n getDiagnostics?(): { eventsRetried: number };\n };\n return exporter.getDiagnostics?.().eventsRetried ?? 0;\n } catch {\n return 0;\n }\n }\n\n private report(\n operation: DiagnosticEvent[\"operation\"],\n error: unknown,\n fallback?: DiagnosticCategory,\n ): void {\n const event = diagnosticEvent(operation, classifyError(error, fallback));\n this.counters.lastError = event;\n try {\n void Promise.resolve(this.onDiagnostic?.(event)).catch(() => {});\n } catch {}\n if (this.debug) {\n try {\n console.warn(\n `[ai-observability] ${event.operation}: ${event.category}. ${event.message}`,\n );\n } catch {}\n }\n }\n}\n\nexport function createEngine(options: CoreOptions): Observability {\n const ratio = bounded(options.samplingRatio ?? 1, \"samplingRatio\", 0, 1);\n const maxQueue = bounded(\n options.maxQueueSize ?? 2048,\n \"maxQueueSize\",\n 1,\n 100000,\n );\n const batchSize = bounded(options.batchSize ?? 256, \"batchSize\", 1, maxQueue);\n const interval = bounded(\n options.flushIntervalMs ?? 5000,\n \"flushIntervalMs\",\n 1,\n 3600000,\n );\n const timeout = bounded(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 1,\n 3600000,\n );\n const maxConcurrentExports = bounded(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1,\n 1024,\n );\n const shutdownTimeout = bounded(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 1,\n 3600000,\n );\n const maxActiveSpans = bounded(\n options.maxActiveSpans ?? 4096,\n \"maxActiveSpans\",\n 1,\n 100000,\n );\n for (const [name, value] of Object.entries({\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n maxActiveSpans,\n })) {\n if (!Number.isInteger(value)) throw new Error(`${name} must be an integer`);\n }\n const processor = new ManagedBatchProcessor(\n options.exporter,\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n makeSanitizer(options),\n options.onDiagnostic,\n options.debug ?? false,\n );\n const provider = new TracerProvider({\n resource: resourceFromAttributes({\n ...options.resourceAttributes,\n \"service.name\": options.serviceName ?? \"ai-application\",\n ...(options.serviceVersion\n ? { \"service.version\": options.serviceVersion }\n : {}),\n ...(options.environment\n ? { \"deployment.environment.name\": options.environment }\n : {}),\n }),\n sampler: new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(ratio),\n }),\n spanProcessors: [processor],\n spanLimits: {\n attributeCountLimit: 64,\n attributeValueLengthLimit: 4096,\n eventCountLimit: 64,\n linkCountLimit: 32,\n attributePerEventCountLimit: 32,\n attributePerLinkCountLimit: 32,\n },\n });\n const tracer = provider.getTracer(\n \"@saguiitay/eventhouse-ai-observability\",\n \"0.1.2\",\n );\n const localContext = new AsyncLocalStorage<Context>();\n const active = new Set<Span>();\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n const engine: Observability = {\n captureContent: options.captureContent ?? false,\n maxActiveSpans,\n startSpan(name, spanOptions = {}) {\n if (closed || active.size >= maxActiveSpans) {\n processor.counters.eventsDropped++;\n return trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n }\n const { parent, ...otelOptions } = spanOptions;\n const ambient = localContext.getStore() ?? context.active();\n const parentContext = parent\n ? \"spanContext\" in parent\n ? trace.setSpan(ambient, parent)\n : parent\n : ambient;\n const span = tracer.startSpan(name, otelOptions, parentContext);\n if (span.isRecording()) {\n active.add(span);\n const end = span.end.bind(span);\n span.end = (time) => {\n active.delete(span);\n end(time);\n };\n }\n return span;\n },\n withSpan(span, callback) {\n if (closed) return callback();\n const parent =\n localContext.getStore() ?? context.active() ?? ROOT_CONTEXT;\n const current = trace.setSpan(parent, span);\n return localContext.run(current, () => context.with(current, callback));\n },\n flush: () => processor.forceFlush(),\n shutdown() {\n shutdownPromise ??= (async () => {\n closed = true;\n for (const span of active) {\n span.setAttribute(\"observability.incomplete\", true);\n span.end();\n }\n try {\n await provider.shutdown();\n } finally {\n localContext.disable();\n }\n })();\n return shutdownPromise;\n },\n getDiagnostics() {\n return {\n ...processor.counters,\n eventsRetried: processor.getRetries(),\n activeSpans: active.size,\n };\n },\n };\n return engine;\n}\n","export type DiagnosticCategory =\n | \"authentication\"\n | \"network\"\n | \"timeout\"\n | \"throttling\"\n | \"oversized\"\n | \"capacity\"\n | \"shutdown\"\n | \"unknown\";\n\nexport interface DiagnosticEvent {\n readonly operation: \"export\" | \"flush\" | \"shutdown\";\n readonly category: DiagnosticCategory;\n readonly message: string;\n}\n\nconst messages: Record<DiagnosticCategory, string> = {\n authentication:\n \"Check transport credentials and permissions; Eventstream requires producer Send access.\",\n network: \"Check endpoint availability, DNS, and required network egress.\",\n timeout: \"The operation exceeded its deadline; delivery may be uncertain.\",\n throttling: \"The service is throttling; check capacity and reduce load.\",\n oversized:\n \"Reduce span content or attributes to fit the service message limit.\",\n capacity:\n \"The local export bound was reached; check load and exporter health.\",\n shutdown: \"Exporter cleanup did not complete successfully.\",\n unknown: \"Check transport configuration and endpoint health.\",\n};\n\nconst codes = new Map<string | number, DiagnosticCategory>([\n [401, \"authentication\"],\n [403, \"authentication\"],\n [429, \"throttling\"],\n [\"unauthorizedaccess\", \"authentication\"],\n [\"unauthorizederror\", \"authentication\"],\n [\"authenticationerror\", \"authentication\"],\n [\"authenticationfailed\", \"authentication\"],\n [\"amqp:unauthorized-access\", \"authentication\"],\n [\"enotfound\", \"network\"],\n [\"eai_again\", \"network\"],\n [\"econnrefused\", \"network\"],\n [\"econnreset\", \"network\"],\n [\"servicecommunicationerror\", \"network\"],\n [\"serviceunavailableerror\", \"network\"],\n [\"messagingcommunicationerror\", \"network\"],\n [\"connectionlosterror\", \"network\"],\n [\"etimedout\", \"timeout\"],\n [\"timeouterror\", \"timeout\"],\n [\"operationtimeouterror\", \"timeout\"],\n [\"aborterror\", \"timeout\"],\n [\"serverbusyerror\", \"throttling\"],\n [\"servicebusyerror\", \"throttling\"],\n [\"amqp:resource-limit-exceeded\", \"throttling\"],\n]);\nfor (const category of Object.keys(messages) as DiagnosticCategory[])\n codes.set(`eventhouse_${category}`, category);\n\nexport function classifyError(\n error: unknown,\n fallback: DiagnosticCategory = \"unknown\",\n): DiagnosticCategory {\n try {\n for (\n let depth = 0;\n depth < 3 && error && typeof error === \"object\";\n depth++\n ) {\n const current = error as {\n code?: unknown;\n name?: unknown;\n statusCode?: unknown;\n cause?: unknown;\n };\n for (const value of [current.code, current.name, current.statusCode]) {\n const key =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\" && value.length <= 128\n ? value.toLowerCase()\n : undefined;\n const category = key === undefined ? undefined : codes.get(key);\n if (category) return category;\n }\n error = current.cause;\n }\n } catch {\n // Error objects and their getters belong to third-party exporters.\n }\n return fallback;\n}\n\nexport function diagnosticEvent(\n operation: DiagnosticEvent[\"operation\"],\n category: DiagnosticCategory,\n): DiagnosticEvent {\n return Object.freeze({ operation, category, message: messages[category] });\n}\n\nexport function categorizedError(\n category: DiagnosticCategory,\n message: string,\n) {\n return Object.assign(new Error(message), { code: `EVENTHOUSE_${category}` });\n}\n","import { EventHubProducerClient } from \"@azure/event-hubs\";\nimport type { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace\";\nimport { serializeSpan } from \"./serialize.js\";\nimport { categorizedError, classifyError } from \"../diagnostics.js\";\n\nexport { serializeSpan } from \"./serialize.js\";\nexport type { SerializedSpan } from \"./serialize.js\";\n\nexport interface EventstreamExporterOptions {\n connectionString: string;\n entityName?: string;\n maxBatchSizeBytes?: number;\n /** Total deadline for one export, including SDK retries. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Overall drain/close deadline. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n /** Maximum underlying operations, including aborted operations still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n}\n\nfunction positiveInteger(value: number, name: string, max: number): number {\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error(\n `Eventstream ${name} must be an integer between 1 and ${max}.`,\n );\n return value;\n}\n\nfunction invalidConfiguration(): never {\n throw new Error(\"Invalid Eventstream connection configuration.\");\n}\n\nfunction validateConnection(\n options: EventstreamExporterOptions,\n): string | undefined {\n if (\n typeof options.connectionString !== \"string\" ||\n !options.connectionString.trim()\n ) {\n invalidConfiguration();\n }\n const fields = new Map<string, string>();\n for (const part of options.connectionString.trim().split(\";\")) {\n if (!part.trim()) continue;\n const separator = part.indexOf(\"=\");\n if (separator <= 0) invalidConfiguration();\n const name = part.slice(0, separator).trim().toLowerCase();\n const value = part.slice(separator + 1).trim();\n if (fields.has(name) || !value || /[\\r\\n\\0]/u.test(value))\n invalidConfiguration();\n if (\n ![\n \"endpoint\",\n \"sharedaccesskeyname\",\n \"sharedaccesskey\",\n \"entitypath\",\n ].includes(name)\n ) {\n invalidConfiguration();\n }\n fields.set(name, value);\n }\n if (!fields.has(\"sharedaccesskeyname\") || !fields.has(\"sharedaccesskey\")) {\n invalidConfiguration();\n }\n try {\n const endpoint = new URL(fields.get(\"endpoint\") ?? \"\");\n if (\n endpoint.protocol !== \"sb:\" ||\n !endpoint.hostname ||\n endpoint.username ||\n endpoint.password ||\n endpoint.search ||\n endpoint.hash ||\n (endpoint.pathname !== \"/\" && endpoint.pathname !== \"\")\n )\n invalidConfiguration();\n } catch {\n invalidConfiguration();\n }\n const entityPath = fields.get(\"entitypath\");\n if (\n options.entityName !== undefined &&\n (typeof options.entityName !== \"string\" ||\n !options.entityName.trim() ||\n /[;\\r\\n\\0]/u.test(options.entityName))\n )\n invalidConfiguration();\n const entityName = options.entityName?.trim();\n if (!entityPath && !entityName) invalidConfiguration();\n if (entityPath && entityName && entityPath !== entityName)\n invalidConfiguration();\n if (\n options.maxBatchSizeBytes !== undefined &&\n (!Number.isSafeInteger(options.maxBatchSizeBytes) ||\n options.maxBatchSizeBytes <= 0)\n ) {\n throw new Error(\n \"Eventstream maxBatchSizeBytes must be a positive safe integer.\",\n );\n }\n return entityPath ? undefined : entityName;\n}\n\n/** Sends JSON events to Fabric's Custom endpoint SOURCE using AMQP over TLS. */\nexport class EventstreamExporter implements SpanExporter {\n private readonly producer: EventHubProducerClient;\n private readonly maxBatchSizeBytes: number | undefined;\n private readonly active = new Map<\n AbortController,\n { operation: Promise<void>; expire: () => void }\n >();\n private readonly exportTimeout: number;\n private readonly shutdownTimeout: number;\n private readonly maxConcurrentExports: number;\n private closing = false;\n private shutdownPromise: Promise<void> | undefined;\n private producerClosePromise: Promise<void> | undefined;\n\n constructor(options: EventstreamExporterOptions) {\n const entityName = validateConnection(options);\n this.maxBatchSizeBytes = options.maxBatchSizeBytes;\n this.exportTimeout = positiveInteger(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 3600000,\n );\n this.shutdownTimeout = positiveInteger(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 3600000,\n );\n this.maxConcurrentExports = positiveInteger(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1024,\n );\n try {\n this.producer = entityName\n ? new EventHubProducerClient(options.connectionString, entityName)\n : new EventHubProducerClient(options.connectionString);\n } catch {\n throw new Error(\"Unable to initialize Eventstream transport.\");\n }\n }\n\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void {\n if (this.closing) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"shutdown\",\n \"Eventstream exporter is shut down.\",\n ),\n }),\n );\n return;\n }\n if (spans.length === 0) {\n queueMicrotask(() => callback({ code: 0 }));\n return;\n }\n if (this.active.size >= this.maxConcurrentExports) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"capacity\",\n \"Eventstream export concurrency limit reached.\",\n ),\n }),\n );\n return;\n }\n const controller = new AbortController();\n const progress = { exportedSpans: 0 };\n let settled = false;\n const finish = (failed: boolean, error?: unknown) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n signal?.removeEventListener(\"abort\", expire);\n const droppedSpans = spans.length - progress.exportedSpans;\n // This optional result extension preserves ordinary SpanExporter consumers.\n const result = {\n code: failed || droppedSpans > 0 ? 1 : 0,\n exportedSpans: progress.exportedSpans,\n droppedSpans,\n ...(failed || droppedSpans > 0\n ? {\n error: categorizedError(\n classifyError(error, failed ? \"unknown\" : \"oversized\"),\n \"Eventstream export failed; events may have been partially delivered.\",\n ),\n }\n : {}),\n };\n callback(result);\n };\n const expire = () => {\n controller.abort();\n finish(\n true,\n categorizedError(\"timeout\", \"Eventstream export deadline expired.\"),\n );\n };\n const deadline = setTimeout(expire, this.exportTimeout);\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) {\n expire();\n return;\n }\n const operation = this.send(spans, controller.signal, progress);\n this.active.set(controller, { operation, expire });\n const complete = (failed: boolean, error?: unknown) => {\n this.active.delete(controller);\n finish(failed, error);\n };\n // Keep the slot until I/O actually settles, even if an SDK ignores abort.\n void operation.then(\n () => complete(false),\n (error: unknown) => complete(true, error),\n );\n }\n\n private async send(\n spans: readonly ReadableSpan[],\n signal: AbortSignal,\n progress: { exportedSpans: number },\n ): Promise<void> {\n const options = {\n abortSignal: signal,\n ...(this.maxBatchSizeBytes === undefined\n ? {}\n : { maxSizeInBytes: this.maxBatchSizeBytes }),\n };\n let batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n const sendBatch = async () => {\n const count = batch.count;\n if (count === 0) return;\n signal.throwIfAborted();\n await this.producer.sendBatch(batch, { abortSignal: signal });\n progress.exportedSpans += count;\n signal.throwIfAborted();\n };\n for (const span of spans) {\n signal.throwIfAborted();\n const event = {\n body: serializeSpan(span),\n contentType: \"application/json\",\n };\n if (batch.tryAdd(event)) continue;\n // A fresh empty batch is authoritative for oversized messages.\n if (batch.count === 0) continue;\n await sendBatch();\n batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n if (!batch.tryAdd(event)) {\n continue;\n }\n }\n await sendBatch();\n }\n\n shutdown(signal?: AbortSignal): Promise<void> {\n if (!this.shutdownPromise) {\n this.closing = true;\n this.shutdownPromise = this.close(signal);\n }\n return this.shutdownPromise;\n }\n\n private async close(signal?: AbortSignal): Promise<void> {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let expire: (() => void) | undefined;\n try {\n await Promise.race([\n (async () => {\n await Promise.allSettled(\n [...this.active.values()].map(({ operation }) => operation),\n );\n await this.closeProducer();\n })(),\n new Promise<never>((_resolve, reject) => {\n expire = () => {\n for (const { expire } of this.active.values()) expire();\n void this.closeProducer().catch(() => {});\n reject(categorizedError(\"timeout\", \"Eventstream shutdown failed.\"));\n };\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) expire();\n else deadline = setTimeout(expire, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n throw categorizedError(\n classifyError(error, \"shutdown\"),\n \"Eventstream shutdown failed.\",\n );\n } finally {\n clearTimeout(deadline);\n if (expire) signal?.removeEventListener(\"abort\", expire);\n this.active.clear();\n }\n }\n\n private closeProducer(): Promise<void> {\n this.producerClosePromise ??= Promise.resolve().then(() =>\n this.producer.close(),\n );\n return this.producerClosePromise;\n }\n}\n","import type { ReadableSpan } from \"@opentelemetry/sdk-trace\";\n\ntype HrTime = ReadableSpan[\"startTime\"];\n\nfunction isoTime(time: HrTime): string {\n return new Date(\n time[0] * 1_000 + Math.floor(time[1] / 1_000_000),\n ).toISOString();\n}\n\nfunction stringAttribute(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\n/** JSON-compatible, framework-neutral Eventstream schema. Times are UTC ISO 8601. */\nexport function serializeSpan(span: ReadableSpan) {\n const context = span.spanContext();\n const resourceAttributes = { ...span.resource.attributes };\n const startTime = isoTime(span.startTime);\n const endTime = isoTime(span.endTime);\n return {\n schemaVersion: \"1.0\" as const,\n timestamp: endTime,\n traceId: context.traceId,\n spanId: context.spanId,\n parentSpanId: span.parentSpanContext?.spanId ?? null,\n spanName: span.name,\n spanKind: span.kind,\n startTime,\n endTime,\n durationMs: span.duration[0] * 1_000 + span.duration[1] / 1_000_000,\n status: span.status.code,\n statusMessage: span.status.message ?? null,\n serviceName: stringAttribute(resourceAttributes[\"service.name\"]),\n serviceVersion: stringAttribute(resourceAttributes[\"service.version\"]),\n environment: stringAttribute(\n resourceAttributes[\"deployment.environment.name\"] ??\n resourceAttributes[\"deployment.environment\"],\n ),\n resourceAttributes,\n spanAttributes: { ...span.attributes },\n events: span.events.map((event) => ({\n name: event.name,\n timestamp: isoTime(event.time),\n attributes: { ...event.attributes },\n droppedAttributesCount: event.droppedAttributesCount ?? 0,\n })),\n links: span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n traceFlags: link.context.traceFlags,\n traceState: link.context.traceState?.serialize() ?? null,\n attributes: { ...link.attributes },\n droppedAttributesCount: link.droppedAttributesCount ?? 0,\n })),\n };\n}\n\nexport type SerializedSpan = ReturnType<typeof serializeSpan>;\n","import {\n createEngine,\n type CoreOptions,\n type Observability,\n} from \"./engine.js\";\nimport { EventstreamExporter } from \"./exporters/eventstream.js\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\nimport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\n\nexport { createEngine, redactSecrets } from \"./engine.js\";\nexport type {\n CoreOptions,\n Diagnostics,\n DiagnosticCategory,\n DiagnosticEvent,\n Observability,\n Redactor,\n} from \"./engine.js\";\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport { EventstreamExporter, serializeSpan } from \"./exporters/eventstream.js\";\nexport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-http\";\n\nexport interface EventhouseObservabilityOptions extends Omit<\n CoreOptions,\n \"exporter\"\n> {\n connectionString?: string;\n entityName?: string;\n transport?: \"eventstream\" | \"otlp\";\n exporter?: SpanExporter;\n endpoint?: string;\n headers?: Record<string, string>;\n maxBatchSizeBytes?: number;\n}\n\nfunction envNumber(name: string): number | undefined {\n const raw = process.env[name];\n if (raw === undefined) return undefined;\n if (raw.trim() === \"\" || !Number.isFinite(Number(raw))) {\n throw new Error(`${name} must be a finite number`);\n }\n return Number(raw);\n}\n\nfunction envHeaders(): Record<string, string> | undefined {\n const raw =\n process.env.OTEL_EXPORTER_OTLP_TRACES_HEADERS ??\n process.env.OTEL_EXPORTER_OTLP_HEADERS;\n if (!raw) return undefined;\n const result: Record<string, string> = {};\n for (const entry of raw.split(\",\")) {\n const equals = entry.indexOf(\"=\");\n if (equals < 1)\n throw new Error(\"Invalid OTLP header environment configuration\");\n try {\n result[entry.slice(0, equals).trim()] = decodeURIComponent(\n entry.slice(equals + 1).trim(),\n );\n } catch {\n throw new Error(\"Invalid OTLP header environment configuration\");\n }\n }\n return result;\n}\n\nexport function createObservability(\n options: EventhouseObservabilityOptions = {},\n): Observability {\n const connectionString =\n options.connectionString ??\n process.env.FABRIC_EVENTSTREAM_CONNECTION_STRING;\n const selection =\n options.transport ?? (connectionString ? \"eventstream\" : \"otlp\");\n let exporter: SpanExporter;\n if (options.exporter) {\n exporter = options.exporter;\n } else if (selection === \"eventstream\") {\n if (!connectionString)\n throw new Error(\"Fabric Eventstream connectionString is required\");\n const entityName =\n options.entityName ?? process.env.FABRIC_EVENTSTREAM_ENTITY_NAME;\n exporter = new EventstreamExporter({\n connectionString,\n ...(entityName ? { entityName } : {}),\n ...(options.maxBatchSizeBytes\n ? { maxBatchSizeBytes: options.maxBatchSizeBytes }\n : {}),\n ...(options.exportTimeoutMs !== undefined\n ? { exportTimeoutMs: options.exportTimeoutMs }\n : {}),\n ...(options.shutdownTimeoutMs !== undefined\n ? { shutdownTimeoutMs: options.shutdownTimeoutMs }\n : {}),\n ...(options.maxConcurrentExports !== undefined\n ? { maxConcurrentExports: options.maxConcurrentExports }\n : {}),\n });\n } else if (selection === \"otlp\") {\n const base = process.env.OTEL_EXPORTER_OTLP_ENDPOINT;\n const endpoint =\n options.endpoint ??\n process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ??\n (base ? `${base.replace(/\\/$/, \"\")}/v1/traces` : undefined);\n if (!endpoint)\n throw new Error(\n \"Supply a Fabric connection string or an explicit OTLP traces endpoint\",\n );\n const headers = options.headers ?? envHeaders();\n try {\n const url = new URL(endpoint);\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new Error(\"Invalid OTLP endpoint configuration.\");\n }\n for (const [name, value] of Object.entries(headers ?? {})) {\n if (\n !/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(name) ||\n /[\\r\\n\\0]/u.test(value)\n ) {\n throw new Error(\"Invalid OTLP headers configuration.\");\n }\n }\n exporter = new OTLPTraceExporter({\n url: endpoint,\n ...(headers ? { headers } : {}),\n });\n } else {\n throw new Error(\"Unsupported telemetry transport\");\n }\n const serviceName = options.serviceName ?? process.env.OTEL_SERVICE_NAME;\n const serviceVersion =\n options.serviceVersion ?? process.env.OTEL_SERVICE_VERSION;\n const environment = options.environment ?? process.env.DEPLOYMENT_ENVIRONMENT;\n const samplingRatio =\n options.samplingRatio ?? envNumber(\"EVENTHOUSE_SAMPLING_RATIO\");\n const batchSize = options.batchSize ?? envNumber(\"EVENTHOUSE_BATCH_SIZE\");\n const flushIntervalMs =\n options.flushIntervalMs ?? envNumber(\"EVENTHOUSE_FLUSH_INTERVAL_MS\");\n return createEngine({\n ...options,\n exporter,\n ...(serviceName ? { serviceName } : {}),\n ...(serviceVersion ? { serviceVersion } : {}),\n ...(environment ? { environment } : {}),\n ...(samplingRatio !== undefined ? { samplingRatio } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(flushIntervalMs !== undefined ? { flushIntervalMs } : {}),\n });\n}\n"],"mappings":"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","names":["exporter","result","context","expire","OTLPTraceExporter"]}
|
|
1
|
+
{"version":3,"sources":["../src/engine.ts","../src/diagnostics.ts","../src/exporters/eventstream.ts","../src/exporters/serialize.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport {\n context,\n trace,\n ROOT_CONTEXT,\n INVALID_SPAN_CONTEXT,\n type Attributes,\n type AttributeValue,\n type Context,\n type Span,\n type SpanOptions,\n} from \"@opentelemetry/api\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\nimport {\n classifyError,\n diagnosticEvent,\n type DiagnosticCategory,\n type DiagnosticEvent,\n} from \"./diagnostics.js\";\nimport {\n TracerProvider,\n ParentBasedSampler,\n TraceIdRatioBasedSampler,\n BatchSpanProcessor,\n type ReadableSpan,\n type SpanExporter,\n type SpanProcessor,\n} from \"@opentelemetry/sdk-trace\";\n\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport type { DiagnosticCategory, DiagnosticEvent } from \"./diagnostics.js\";\n\nexport interface Diagnostics {\n eventsGenerated: number;\n eventsExported: number;\n eventsRetried: number;\n eventsDropped: number;\n exportFailures: number;\n /** Admitted spans awaiting export; excludes batches already in flight. */\n queueDepth: number;\n activeSpans: number;\n /** Latest sanitized failure only; never includes the original error or configuration. */\n lastError?: DiagnosticEvent;\n}\n\nexport type Redactor = (\n key: string,\n value: AttributeValue,\n) => AttributeValue | undefined;\n\nexport interface CoreOptions {\n exporter: SpanExporter;\n serviceName?: string;\n serviceVersion?: string;\n environment?: string;\n resourceAttributes?: Attributes;\n captureContent?: boolean;\n redact?: Redactor;\n /** Receives sanitized failure categories. Callback exceptions are contained. */\n onDiagnostic?: (event: DiagnosticEvent) => void;\n /** Prints only sanitized failure categories and fixed troubleshooting hints. */\n debug?: boolean;\n samplingRatio?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n /** Export callback deadline in milliseconds. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Underlying exports, including timed-out calls still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n /** Overall shutdown deadline in milliseconds, including transport cleanup. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n maxQueueSize?: number;\n maxActiveSpans?: number;\n}\n\nexport interface Observability {\n readonly captureContent: boolean;\n readonly maxActiveSpans: number;\n startSpan(\n name: string,\n options?: SpanOptions & { parent?: Span | Context },\n ): Span;\n withSpan<T>(span: Span, callback: () => T): T;\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nfunction bounded(\n value: number,\n name: string,\n min: number,\n max: number,\n): number {\n if (!Number.isFinite(value) || value < min || value > max) {\n throw new Error(`${name} must be between ${min} and ${max}`);\n }\n return value;\n}\n\nconst secretKey =\n /(?:password|secret|authorization|connection.?string|api[_.-]?key|sharedaccess|access[_.-]?token)/i;\nconst contentKey =\n /(?:prompt|completion|response\\.content|input\\.messages|output\\.messages|tool\\.(?:arguments|result|output))/i;\n\nexport function redactSecrets(value: string): string {\n return value\n .replace(/(?:Endpoint=sb:\\/\\/)[^\\s\"']+/gi, \"[REDACTED_CONNECTION_STRING]\")\n .replace(/SharedAccess(?:Key|Signature)(?:Name)?=[^;\\s\"']+/gi, \"[REDACTED]\")\n .replace(/\\bBearer\\s+[A-Za-z0-9._~+/-]+=*/gi, \"Bearer [REDACTED]\")\n .replace(/([?&](?:sig|token|key)=)[^&\\s\"']+/gi, \"$1[REDACTED]\");\n}\n\nfunction makeSanitizer(options: CoreOptions) {\n const cleanValue = (\n key: string,\n value: AttributeValue,\n ): AttributeValue | undefined => {\n if (\n secretKey.test(key) ||\n (!options.captureContent && contentKey.test(key))\n )\n return undefined;\n const clean = (item: string | number | boolean | null | undefined) =>\n typeof item === \"string\" ? redactSecrets(item).slice(0, 4096) : item;\n let result: AttributeValue = Array.isArray(value)\n ? (value.slice(0, 64).map(clean) as AttributeValue)\n : (clean(value as string | number | boolean) as AttributeValue);\n if (options.redact) {\n try {\n const redacted = options.redact(key, result);\n if (redacted === undefined) return undefined;\n result = Array.isArray(redacted)\n ? (redacted.slice(0, 64).map(clean) as AttributeValue)\n : (clean(redacted as string | number | boolean) as AttributeValue);\n } catch {\n return undefined;\n }\n }\n return result;\n };\n const cleanAttributes = (attributes: Attributes): Attributes => {\n const result: Attributes = {};\n for (const [key, value] of Object.entries(attributes).slice(0, 64)) {\n if (value !== undefined) {\n const cleaned = cleanValue(key, value);\n if (cleaned !== undefined)\n result[redactSecrets(key).slice(0, 256)] = cleaned;\n }\n }\n return result;\n };\n return (span: ReadableSpan): ReadableSpan => ({\n spanContext: () => span.spanContext(),\n ...(span.parentSpanContext\n ? { parentSpanContext: span.parentSpanContext }\n : {}),\n kind: span.kind,\n startTime: span.startTime,\n endTime: span.endTime,\n duration: span.duration,\n ended: span.ended,\n instrumentationScope: span.instrumentationScope,\n droppedAttributesCount: span.droppedAttributesCount,\n droppedEventsCount: span.droppedEventsCount,\n droppedLinksCount: span.droppedLinksCount,\n name: redactSecrets(span.name).slice(0, 512),\n attributes: cleanAttributes(span.attributes),\n resource: resourceFromAttributes(cleanAttributes(span.resource.attributes)),\n status: {\n code: span.status.code,\n ...(options.captureContent && span.status.message\n ? { message: redactSecrets(span.status.message).slice(0, 4096) }\n : {}),\n },\n events: span.events.map((event) => ({\n ...event,\n name: redactSecrets(event.name).slice(0, 512),\n ...(event.attributes\n ? { attributes: cleanAttributes(event.attributes) }\n : {}),\n })),\n links: span.links.map((link) => ({\n ...link,\n ...(link.attributes\n ? { attributes: cleanAttributes(link.attributes) }\n : {}),\n })),\n });\n}\n\nclass ManagedBatchProcessor implements SpanProcessor {\n private readonly processor: BatchSpanProcessor;\n private readonly inFlight = new Set<Promise<void>>();\n private flushPromise: Promise<void> | undefined;\n private closed = false;\n private shutdownPromise: Promise<void> | undefined;\n private exporterShutdownPromise: Promise<void> | undefined;\n private readonly finishers = new Set<() => void>();\n private readonly waiters = new Set<() => void>();\n private readonly shutdownController = new AbortController();\n private underlyingExports = 0;\n private disposed = false;\n readonly counters: Diagnostics = {\n eventsGenerated: 0,\n eventsExported: 0,\n eventsRetried: 0,\n eventsDropped: 0,\n exportFailures: 0,\n queueDepth: 0,\n activeSpans: 0,\n };\n\n constructor(\n private readonly exporter: SpanExporter,\n private readonly maxQueueSize: number,\n batchSize: number,\n interval: number,\n timeout: number,\n private readonly maxConcurrentExports: number,\n private readonly shutdownTimeout: number,\n private readonly sanitize: (span: ReadableSpan) => ReadableSpan,\n private readonly onDiagnostic: CoreOptions[\"onDiagnostic\"],\n private readonly debug: boolean,\n ) {\n this.processor = new BatchSpanProcessor({\n exporter: {\n export: (spans, callback) => {\n let complete!: () => void;\n const pending = new Promise<void>((resolve) => {\n complete = resolve;\n });\n this.inFlight.add(pending);\n let settled = false;\n let queued = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let attempt!: () => void;\n const dequeue = () => {\n if (!queued) return;\n queued = false;\n this.counters.queueDepth -= spans.length;\n };\n const controller = new AbortController();\n const expire = () => {\n controller.abort();\n finish(false, undefined, \"timeout\");\n };\n const finish = (\n success: boolean,\n result?: {\n exportedSpans?: number;\n droppedSpans?: number;\n error?: unknown;\n },\n category?: DiagnosticCategory,\n ) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n this.finishers.delete(expire);\n this.waiters.delete(attempt);\n dequeue();\n const exported = result?.exportedSpans;\n const dropped = result?.droppedSpans;\n const hasCounts =\n Number.isInteger(exported) &&\n Number.isInteger(dropped) &&\n exported! >= 0 &&\n dropped! >= 0 &&\n exported! + dropped! === spans.length;\n this.counters.eventsExported += hasCounts\n ? exported!\n : success\n ? spans.length\n : 0;\n this.counters.eventsDropped += hasCounts\n ? dropped!\n : success\n ? 0\n : spans.length;\n if (!success) {\n this.counters.exportFailures++;\n this.report(\"export\", result?.error, category);\n }\n this.inFlight.delete(pending);\n complete();\n // Failures are accounted for here, never forwarded to OTel's global logger.\n callback({ code: 0 });\n this.wakeWaiter();\n };\n this.finishers.add(expire);\n // BSP can start an export directly in onEnd when the batch fills.\n attempt = () => {\n if (settled) return;\n if (this.disposed) {\n finish(false, undefined, \"shutdown\");\n return;\n }\n if (this.underlyingExports >= this.maxConcurrentExports) {\n this.waiters.add(attempt);\n deadline ??= setTimeout(expire, timeout);\n return;\n }\n this.waiters.delete(attempt);\n dequeue();\n this.underlyingExports++;\n let released = false;\n const release = () => {\n if (released) return;\n released = true;\n this.underlyingExports--;\n this.wakeWaiter();\n };\n try {\n // Standard exporters ignore the optional signal; Eventstream honors it.\n const exporter = this.exporter as SpanExporter & {\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void;\n };\n const result = exporter.export(\n spans,\n (result) => {\n release();\n finish(\n result.code === 0,\n result as typeof result & {\n exportedSpans?: number;\n droppedSpans?: number;\n },\n );\n },\n controller.signal,\n );\n // Also contain exporters incorrectly returning a rejected promise.\n void Promise.resolve(result).catch((error: unknown) => {\n release();\n finish(false, { error });\n });\n } catch (error) {\n release();\n finish(false, { error });\n }\n if (!settled) deadline ??= setTimeout(expire, timeout);\n };\n queueMicrotask(attempt);\n },\n shutdown: async () => {\n await this.waitForExports();\n await this.shutdownExporter();\n },\n },\n maxExportBatchSize: batchSize,\n maxQueueSize,\n scheduledDelayMillis: interval,\n // The callback deadline settles batches before BSP's fallback timeout.\n exportTimeoutMillis: timeout + 1000,\n });\n }\n\n onStart(): void {}\n\n onEnd(span: ReadableSpan): void {\n this.counters.eventsGenerated++;\n if (this.closed || this.counters.queueDepth >= this.maxQueueSize) {\n this.counters.eventsDropped++;\n return;\n }\n try {\n const sanitized = this.sanitize(span);\n this.counters.queueDepth++;\n this.processor.onEnd(sanitized);\n } catch {\n this.counters.eventsDropped++;\n }\n }\n\n forceFlush(): Promise<void> {\n if (this.shutdownPromise) return this.shutdownPromise;\n this.flushPromise ??= Promise.resolve().then(async () => {\n try {\n do {\n await this.processor.forceFlush();\n await this.waitForExports();\n } while (this.counters.queueDepth > 0);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"flush\", error);\n } finally {\n this.flushPromise = undefined;\n }\n });\n return this.flushPromise;\n }\n\n private async waitForExports(): Promise<void> {\n while (this.inFlight.size > 0) await Promise.all(this.inFlight);\n }\n\n private wakeWaiter(): void {\n if (this.underlyingExports >= this.maxConcurrentExports) return;\n const waiter = this.waiters.values().next().value;\n if (!waiter) return;\n this.waiters.delete(waiter);\n queueMicrotask(() => {\n waiter();\n this.wakeWaiter();\n });\n }\n\n shutdown(): Promise<void> {\n this.shutdownPromise ??= (async () => {\n this.closed = true;\n let deadline: ReturnType<typeof setTimeout> | undefined;\n try {\n await Promise.race([\n this.processor.shutdown(),\n new Promise<void>((resolve) => {\n deadline = setTimeout(() => {\n this.counters.exportFailures++;\n this.report(\"shutdown\", undefined, \"timeout\");\n this.shutdownController.abort();\n resolve();\n }, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n } finally {\n clearTimeout(deadline);\n this.disposed = true;\n for (const finish of this.finishers) finish();\n this.counters.eventsDropped += this.counters.queueDepth;\n this.counters.queueDepth = 0;\n // Even when draining times out, initiate cleanup exactly once.\n void this.shutdownExporter();\n }\n })();\n return this.shutdownPromise;\n }\n\n private shutdownExporter(): Promise<void> {\n this.exporterShutdownPromise ??= Promise.resolve()\n .then(() => {\n const exporter = this.exporter as SpanExporter & {\n shutdown(signal?: AbortSignal): Promise<void>;\n };\n return exporter.shutdown(this.shutdownController.signal);\n })\n .catch((error: unknown) => {\n if (!this.disposed && !this.shutdownController.signal.aborted) {\n this.counters.exportFailures++;\n this.report(\"shutdown\", error, \"shutdown\");\n }\n });\n return this.exporterShutdownPromise;\n }\n\n getRetries(): number {\n try {\n const exporter = this.exporter as SpanExporter & {\n getDiagnostics?(): { eventsRetried: number };\n };\n return exporter.getDiagnostics?.().eventsRetried ?? 0;\n } catch {\n return 0;\n }\n }\n\n private report(\n operation: DiagnosticEvent[\"operation\"],\n error: unknown,\n fallback?: DiagnosticCategory,\n ): void {\n const event = diagnosticEvent(operation, classifyError(error, fallback));\n this.counters.lastError = event;\n try {\n void Promise.resolve(this.onDiagnostic?.(event)).catch(() => {});\n } catch {}\n if (this.debug) {\n try {\n console.warn(\n `[ai-observability] ${event.operation}: ${event.category}. ${event.message}`,\n );\n } catch {}\n }\n }\n}\n\nexport function createEngine(options: CoreOptions): Observability {\n const ratio = bounded(options.samplingRatio ?? 1, \"samplingRatio\", 0, 1);\n const maxQueue = bounded(\n options.maxQueueSize ?? 2048,\n \"maxQueueSize\",\n 1,\n 100000,\n );\n const batchSize = bounded(options.batchSize ?? 256, \"batchSize\", 1, maxQueue);\n const interval = bounded(\n options.flushIntervalMs ?? 5000,\n \"flushIntervalMs\",\n 1,\n 3600000,\n );\n const timeout = bounded(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 1,\n 3600000,\n );\n const maxConcurrentExports = bounded(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1,\n 1024,\n );\n const shutdownTimeout = bounded(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 1,\n 3600000,\n );\n const maxActiveSpans = bounded(\n options.maxActiveSpans ?? 4096,\n \"maxActiveSpans\",\n 1,\n 100000,\n );\n for (const [name, value] of Object.entries({\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n maxActiveSpans,\n })) {\n if (!Number.isInteger(value)) throw new Error(`${name} must be an integer`);\n }\n const processor = new ManagedBatchProcessor(\n options.exporter,\n maxQueue,\n batchSize,\n interval,\n timeout,\n maxConcurrentExports,\n shutdownTimeout,\n makeSanitizer(options),\n options.onDiagnostic,\n options.debug ?? false,\n );\n const provider = new TracerProvider({\n resource: resourceFromAttributes({\n ...options.resourceAttributes,\n \"service.name\": options.serviceName ?? \"ai-application\",\n ...(options.serviceVersion\n ? { \"service.version\": options.serviceVersion }\n : {}),\n ...(options.environment\n ? { \"deployment.environment.name\": options.environment }\n : {}),\n }),\n sampler: new ParentBasedSampler({\n root: new TraceIdRatioBasedSampler(ratio),\n }),\n spanProcessors: [processor],\n spanLimits: {\n attributeCountLimit: 64,\n attributeValueLengthLimit: 4096,\n eventCountLimit: 64,\n linkCountLimit: 32,\n attributePerEventCountLimit: 32,\n attributePerLinkCountLimit: 32,\n },\n });\n const tracer = provider.getTracer(\n \"@saguiitay/eventhouse-ai-observability\",\n \"0.2.0\",\n );\n const localContext = new AsyncLocalStorage<Context>();\n const active = new Set<Span>();\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n const engine: Observability = {\n captureContent: options.captureContent ?? false,\n maxActiveSpans,\n startSpan(name, spanOptions = {}) {\n if (closed || active.size >= maxActiveSpans) {\n processor.counters.eventsDropped++;\n return trace.wrapSpanContext(INVALID_SPAN_CONTEXT);\n }\n const { parent, ...otelOptions } = spanOptions;\n const ambient = localContext.getStore() ?? context.active();\n const parentContext = parent\n ? \"spanContext\" in parent\n ? trace.setSpan(ambient, parent)\n : parent\n : ambient;\n const span = tracer.startSpan(name, otelOptions, parentContext);\n if (span.isRecording()) {\n active.add(span);\n const end = span.end.bind(span);\n span.end = (time) => {\n active.delete(span);\n end(time);\n };\n }\n return span;\n },\n withSpan(span, callback) {\n if (closed) return callback();\n const parent =\n localContext.getStore() ?? context.active() ?? ROOT_CONTEXT;\n const current = trace.setSpan(parent, span);\n return localContext.run(current, () => context.with(current, callback));\n },\n flush: () => processor.forceFlush(),\n shutdown() {\n shutdownPromise ??= (async () => {\n closed = true;\n for (const span of active) {\n span.setAttribute(\"observability.incomplete\", true);\n span.end();\n }\n try {\n await provider.shutdown();\n } finally {\n localContext.disable();\n }\n })();\n return shutdownPromise;\n },\n getDiagnostics() {\n return {\n ...processor.counters,\n eventsRetried: processor.getRetries(),\n activeSpans: active.size,\n };\n },\n };\n return engine;\n}\n","export type DiagnosticCategory =\n | \"authentication\"\n | \"network\"\n | \"timeout\"\n | \"throttling\"\n | \"oversized\"\n | \"capacity\"\n | \"shutdown\"\n | \"unknown\";\n\nexport interface DiagnosticEvent {\n readonly operation: \"export\" | \"flush\" | \"shutdown\";\n readonly category: DiagnosticCategory;\n readonly message: string;\n}\n\nconst messages: Record<DiagnosticCategory, string> = {\n authentication:\n \"Check transport credentials and permissions; Eventstream requires producer Send access.\",\n network: \"Check endpoint availability, DNS, and required network egress.\",\n timeout: \"The operation exceeded its deadline; delivery may be uncertain.\",\n throttling: \"The service is throttling; check capacity and reduce load.\",\n oversized:\n \"Reduce span content or attributes to fit the service message limit.\",\n capacity:\n \"The local export bound was reached; check load and exporter health.\",\n shutdown: \"Exporter cleanup did not complete successfully.\",\n unknown: \"Check transport configuration and endpoint health.\",\n};\n\nconst codes = new Map<string | number, DiagnosticCategory>([\n [401, \"authentication\"],\n [403, \"authentication\"],\n [429, \"throttling\"],\n [\"unauthorizedaccess\", \"authentication\"],\n [\"unauthorizederror\", \"authentication\"],\n [\"authenticationerror\", \"authentication\"],\n [\"authenticationfailed\", \"authentication\"],\n [\"amqp:unauthorized-access\", \"authentication\"],\n [\"enotfound\", \"network\"],\n [\"eai_again\", \"network\"],\n [\"econnrefused\", \"network\"],\n [\"econnreset\", \"network\"],\n [\"servicecommunicationerror\", \"network\"],\n [\"serviceunavailableerror\", \"network\"],\n [\"messagingcommunicationerror\", \"network\"],\n [\"connectionlosterror\", \"network\"],\n [\"etimedout\", \"timeout\"],\n [\"timeouterror\", \"timeout\"],\n [\"operationtimeouterror\", \"timeout\"],\n [\"aborterror\", \"timeout\"],\n [\"serverbusyerror\", \"throttling\"],\n [\"servicebusyerror\", \"throttling\"],\n [\"amqp:resource-limit-exceeded\", \"throttling\"],\n]);\nfor (const category of Object.keys(messages) as DiagnosticCategory[])\n codes.set(`eventhouse_${category}`, category);\n\nexport function classifyError(\n error: unknown,\n fallback: DiagnosticCategory = \"unknown\",\n): DiagnosticCategory {\n try {\n for (\n let depth = 0;\n depth < 3 && error && typeof error === \"object\";\n depth++\n ) {\n const current = error as {\n code?: unknown;\n name?: unknown;\n statusCode?: unknown;\n cause?: unknown;\n };\n for (const value of [current.code, current.name, current.statusCode]) {\n const key =\n typeof value === \"number\"\n ? value\n : typeof value === \"string\" && value.length <= 128\n ? value.toLowerCase()\n : undefined;\n const category = key === undefined ? undefined : codes.get(key);\n if (category) return category;\n }\n error = current.cause;\n }\n } catch {\n // Error objects and their getters belong to third-party exporters.\n }\n return fallback;\n}\n\nexport function diagnosticEvent(\n operation: DiagnosticEvent[\"operation\"],\n category: DiagnosticCategory,\n): DiagnosticEvent {\n return Object.freeze({ operation, category, message: messages[category] });\n}\n\nexport function categorizedError(\n category: DiagnosticCategory,\n message: string,\n) {\n return Object.assign(new Error(message), { code: `EVENTHOUSE_${category}` });\n}\n","import { EventHubProducerClient } from \"@azure/event-hubs\";\nimport type { ReadableSpan, SpanExporter } from \"@opentelemetry/sdk-trace\";\nimport { serializeSpan } from \"./serialize.js\";\nimport { categorizedError, classifyError } from \"../diagnostics.js\";\n\nexport { serializeSpan } from \"./serialize.js\";\nexport type { SerializedSpan } from \"./serialize.js\";\n\nexport interface EventstreamExporterOptions {\n connectionString: string;\n entityName?: string;\n maxBatchSizeBytes?: number;\n /** Total deadline for one export, including SDK retries. Defaults to 30000. */\n exportTimeoutMs?: number;\n /** Overall drain/close deadline. Defaults to 30000. */\n shutdownTimeoutMs?: number;\n /** Maximum underlying operations, including aborted operations still pending. Defaults to 4. */\n maxConcurrentExports?: number;\n}\n\nfunction positiveInteger(value: number, name: string, max: number): number {\n if (!Number.isSafeInteger(value) || value < 1 || value > max)\n throw new Error(\n `Eventstream ${name} must be an integer between 1 and ${max}.`,\n );\n return value;\n}\n\nfunction invalidConfiguration(): never {\n throw new Error(\"Invalid Eventstream connection configuration.\");\n}\n\nfunction validateConnection(\n options: EventstreamExporterOptions,\n): string | undefined {\n if (\n typeof options.connectionString !== \"string\" ||\n !options.connectionString.trim()\n ) {\n invalidConfiguration();\n }\n const fields = new Map<string, string>();\n for (const part of options.connectionString.trim().split(\";\")) {\n if (!part.trim()) continue;\n const separator = part.indexOf(\"=\");\n if (separator <= 0) invalidConfiguration();\n const name = part.slice(0, separator).trim().toLowerCase();\n const value = part.slice(separator + 1).trim();\n if (fields.has(name) || !value || /[\\r\\n\\0]/u.test(value))\n invalidConfiguration();\n if (\n ![\n \"endpoint\",\n \"sharedaccesskeyname\",\n \"sharedaccesskey\",\n \"entitypath\",\n ].includes(name)\n ) {\n invalidConfiguration();\n }\n fields.set(name, value);\n }\n if (!fields.has(\"sharedaccesskeyname\") || !fields.has(\"sharedaccesskey\")) {\n invalidConfiguration();\n }\n try {\n const endpoint = new URL(fields.get(\"endpoint\") ?? \"\");\n if (\n endpoint.protocol !== \"sb:\" ||\n !endpoint.hostname ||\n endpoint.username ||\n endpoint.password ||\n endpoint.search ||\n endpoint.hash ||\n (endpoint.pathname !== \"/\" && endpoint.pathname !== \"\")\n )\n invalidConfiguration();\n } catch {\n invalidConfiguration();\n }\n const entityPath = fields.get(\"entitypath\");\n if (\n options.entityName !== undefined &&\n (typeof options.entityName !== \"string\" ||\n !options.entityName.trim() ||\n /[;\\r\\n\\0]/u.test(options.entityName))\n )\n invalidConfiguration();\n const entityName = options.entityName?.trim();\n if (!entityPath && !entityName) invalidConfiguration();\n if (entityPath && entityName && entityPath !== entityName)\n invalidConfiguration();\n if (\n options.maxBatchSizeBytes !== undefined &&\n (!Number.isSafeInteger(options.maxBatchSizeBytes) ||\n options.maxBatchSizeBytes <= 0)\n ) {\n throw new Error(\n \"Eventstream maxBatchSizeBytes must be a positive safe integer.\",\n );\n }\n return entityPath ? undefined : entityName;\n}\n\n/** Sends JSON events to Fabric's Custom endpoint SOURCE using AMQP over TLS. */\nexport class EventstreamExporter implements SpanExporter {\n private readonly producer: EventHubProducerClient;\n private readonly maxBatchSizeBytes: number | undefined;\n private readonly active = new Map<\n AbortController,\n { operation: Promise<void>; expire: () => void }\n >();\n private readonly exportTimeout: number;\n private readonly shutdownTimeout: number;\n private readonly maxConcurrentExports: number;\n private closing = false;\n private shutdownPromise: Promise<void> | undefined;\n private producerClosePromise: Promise<void> | undefined;\n\n constructor(options: EventstreamExporterOptions) {\n const entityName = validateConnection(options);\n this.maxBatchSizeBytes = options.maxBatchSizeBytes;\n this.exportTimeout = positiveInteger(\n options.exportTimeoutMs ?? 30000,\n \"exportTimeoutMs\",\n 3600000,\n );\n this.shutdownTimeout = positiveInteger(\n options.shutdownTimeoutMs ?? 30000,\n \"shutdownTimeoutMs\",\n 3600000,\n );\n this.maxConcurrentExports = positiveInteger(\n options.maxConcurrentExports ?? 4,\n \"maxConcurrentExports\",\n 1024,\n );\n try {\n this.producer = entityName\n ? new EventHubProducerClient(options.connectionString, entityName)\n : new EventHubProducerClient(options.connectionString);\n } catch {\n throw new Error(\"Unable to initialize Eventstream transport.\");\n }\n }\n\n export(\n spans: ReadableSpan[],\n callback: Parameters<SpanExporter[\"export\"]>[1],\n signal?: AbortSignal,\n ): void {\n if (this.closing) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"shutdown\",\n \"Eventstream exporter is shut down.\",\n ),\n }),\n );\n return;\n }\n if (spans.length === 0) {\n queueMicrotask(() => callback({ code: 0 }));\n return;\n }\n if (this.active.size >= this.maxConcurrentExports) {\n queueMicrotask(() =>\n callback({\n code: 1,\n error: categorizedError(\n \"capacity\",\n \"Eventstream export concurrency limit reached.\",\n ),\n }),\n );\n return;\n }\n const controller = new AbortController();\n const progress = { exportedSpans: 0 };\n let settled = false;\n const finish = (failed: boolean, error?: unknown) => {\n if (settled) return;\n settled = true;\n clearTimeout(deadline);\n signal?.removeEventListener(\"abort\", expire);\n const droppedSpans = spans.length - progress.exportedSpans;\n // This optional result extension preserves ordinary SpanExporter consumers.\n const result = {\n code: failed || droppedSpans > 0 ? 1 : 0,\n exportedSpans: progress.exportedSpans,\n droppedSpans,\n ...(failed || droppedSpans > 0\n ? {\n error: categorizedError(\n classifyError(error, failed ? \"unknown\" : \"oversized\"),\n \"Eventstream export failed; events may have been partially delivered.\",\n ),\n }\n : {}),\n };\n callback(result);\n };\n const expire = () => {\n controller.abort();\n finish(\n true,\n categorizedError(\"timeout\", \"Eventstream export deadline expired.\"),\n );\n };\n const deadline = setTimeout(expire, this.exportTimeout);\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) {\n expire();\n return;\n }\n const operation = this.send(spans, controller.signal, progress);\n this.active.set(controller, { operation, expire });\n const complete = (failed: boolean, error?: unknown) => {\n this.active.delete(controller);\n finish(failed, error);\n };\n // Keep the slot until I/O actually settles, even if an SDK ignores abort.\n void operation.then(\n () => complete(false),\n (error: unknown) => complete(true, error),\n );\n }\n\n private async send(\n spans: readonly ReadableSpan[],\n signal: AbortSignal,\n progress: { exportedSpans: number },\n ): Promise<void> {\n const options = {\n abortSignal: signal,\n ...(this.maxBatchSizeBytes === undefined\n ? {}\n : { maxSizeInBytes: this.maxBatchSizeBytes }),\n };\n let batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n const sendBatch = async () => {\n const count = batch.count;\n if (count === 0) return;\n signal.throwIfAborted();\n await this.producer.sendBatch(batch, { abortSignal: signal });\n progress.exportedSpans += count;\n signal.throwIfAborted();\n };\n for (const span of spans) {\n signal.throwIfAborted();\n const event = {\n body: serializeSpan(span),\n contentType: \"application/json\",\n };\n if (batch.tryAdd(event)) continue;\n // A fresh empty batch is authoritative for oversized messages.\n if (batch.count === 0) continue;\n await sendBatch();\n batch = await this.producer.createBatch(options);\n signal.throwIfAborted();\n if (!batch.tryAdd(event)) {\n continue;\n }\n }\n await sendBatch();\n }\n\n shutdown(signal?: AbortSignal): Promise<void> {\n if (!this.shutdownPromise) {\n this.closing = true;\n this.shutdownPromise = this.close(signal);\n }\n return this.shutdownPromise;\n }\n\n private async close(signal?: AbortSignal): Promise<void> {\n let deadline: ReturnType<typeof setTimeout> | undefined;\n let expire: (() => void) | undefined;\n try {\n await Promise.race([\n (async () => {\n await Promise.allSettled(\n [...this.active.values()].map(({ operation }) => operation),\n );\n await this.closeProducer();\n })(),\n new Promise<never>((_resolve, reject) => {\n expire = () => {\n for (const { expire } of this.active.values()) expire();\n void this.closeProducer().catch(() => {});\n reject(categorizedError(\"timeout\", \"Eventstream shutdown failed.\"));\n };\n signal?.addEventListener(\"abort\", expire, { once: true });\n if (signal?.aborted) expire();\n else deadline = setTimeout(expire, this.shutdownTimeout);\n }),\n ]);\n } catch (error) {\n throw categorizedError(\n classifyError(error, \"shutdown\"),\n \"Eventstream shutdown failed.\",\n );\n } finally {\n clearTimeout(deadline);\n if (expire) signal?.removeEventListener(\"abort\", expire);\n this.active.clear();\n }\n }\n\n private closeProducer(): Promise<void> {\n this.producerClosePromise ??= Promise.resolve().then(() =>\n this.producer.close(),\n );\n return this.producerClosePromise;\n }\n}\n","import type { ReadableSpan } from \"@opentelemetry/sdk-trace\";\n\ntype HrTime = ReadableSpan[\"startTime\"];\n\nfunction isoTime(time: HrTime): string {\n return new Date(\n time[0] * 1_000 + Math.floor(time[1] / 1_000_000),\n ).toISOString();\n}\n\nfunction stringAttribute(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\n/** JSON-compatible, framework-neutral Eventstream schema. Times are UTC ISO 8601. */\nexport function serializeSpan(span: ReadableSpan) {\n const context = span.spanContext();\n const resourceAttributes = { ...span.resource.attributes };\n const startTime = isoTime(span.startTime);\n const endTime = isoTime(span.endTime);\n return {\n schemaVersion: \"1.0\" as const,\n timestamp: endTime,\n traceId: context.traceId,\n spanId: context.spanId,\n parentSpanId: span.parentSpanContext?.spanId ?? null,\n spanName: span.name,\n spanKind: span.kind,\n startTime,\n endTime,\n durationMs: span.duration[0] * 1_000 + span.duration[1] / 1_000_000,\n status: span.status.code,\n statusMessage: span.status.message ?? null,\n serviceName: stringAttribute(resourceAttributes[\"service.name\"]),\n serviceVersion: stringAttribute(resourceAttributes[\"service.version\"]),\n environment: stringAttribute(\n resourceAttributes[\"deployment.environment.name\"] ??\n resourceAttributes[\"deployment.environment\"],\n ),\n resourceAttributes,\n spanAttributes: { ...span.attributes },\n events: span.events.map((event) => ({\n name: event.name,\n timestamp: isoTime(event.time),\n attributes: { ...event.attributes },\n droppedAttributesCount: event.droppedAttributesCount ?? 0,\n })),\n links: span.links.map((link) => ({\n traceId: link.context.traceId,\n spanId: link.context.spanId,\n traceFlags: link.context.traceFlags,\n traceState: link.context.traceState?.serialize() ?? null,\n attributes: { ...link.attributes },\n droppedAttributesCount: link.droppedAttributesCount ?? 0,\n })),\n };\n}\n\nexport type SerializedSpan = ReturnType<typeof serializeSpan>;\n","import {\n createEngine,\n type CoreOptions,\n type Observability,\n} from \"./engine.js\";\nimport { EventstreamExporter } from \"./exporters/eventstream.js\";\nimport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\n\nexport type {\n CoreOptions,\n Diagnostics,\n DiagnosticCategory,\n DiagnosticEvent,\n Observability,\n Redactor,\n} from \"./engine.js\";\nexport type { SpanExporter } from \"@opentelemetry/sdk-trace\";\nexport { EventstreamExporter } from \"./exporters/eventstream.js\";\n\nexport interface EventhouseObservabilityOptions extends Omit<\n CoreOptions,\n \"exporter\"\n> {\n connectionString?: string;\n entityName?: string;\n exporter?: SpanExporter;\n maxBatchSizeBytes?: number;\n}\n\nfunction envNumber(name: string): number | undefined {\n const raw = process.env[name];\n if (raw === undefined) return undefined;\n if (raw.trim() === \"\" || !Number.isFinite(Number(raw))) {\n throw new Error(`${name} must be a finite number`);\n }\n return Number(raw);\n}\n\nexport function createObservability(\n options: EventhouseObservabilityOptions = {},\n): Observability {\n if (\"transport\" in options || \"endpoint\" in options || \"headers\" in options)\n throw new Error(\n \"Configure custom transports with exporter; transport, endpoint, and headers options are not supported.\",\n );\n const connectionString =\n options.connectionString ??\n process.env.FABRIC_EVENTSTREAM_CONNECTION_STRING;\n let exporter: SpanExporter;\n if (options.exporter) {\n exporter = options.exporter;\n } else {\n if (!connectionString)\n throw new Error(\n \"Supply a Fabric Eventstream connectionString or a custom SpanExporter.\",\n );\n const entityName =\n options.entityName ?? process.env.FABRIC_EVENTSTREAM_ENTITY_NAME;\n exporter = new EventstreamExporter({\n connectionString,\n ...(entityName ? { entityName } : {}),\n ...(options.maxBatchSizeBytes\n ? { maxBatchSizeBytes: options.maxBatchSizeBytes }\n : {}),\n ...(options.exportTimeoutMs !== undefined\n ? { exportTimeoutMs: options.exportTimeoutMs }\n : {}),\n ...(options.shutdownTimeoutMs !== undefined\n ? { shutdownTimeoutMs: options.shutdownTimeoutMs }\n : {}),\n ...(options.maxConcurrentExports !== undefined\n ? { maxConcurrentExports: options.maxConcurrentExports }\n : {}),\n });\n }\n const serviceName = options.serviceName ?? process.env.OTEL_SERVICE_NAME;\n const serviceVersion =\n options.serviceVersion ?? process.env.OTEL_SERVICE_VERSION;\n const environment = options.environment ?? process.env.DEPLOYMENT_ENVIRONMENT;\n const samplingRatio =\n options.samplingRatio ?? envNumber(\"EVENTHOUSE_SAMPLING_RATIO\");\n const batchSize = options.batchSize ?? envNumber(\"EVENTHOUSE_BATCH_SIZE\");\n const flushIntervalMs =\n options.flushIntervalMs ?? envNumber(\"EVENTHOUSE_FLUSH_INTERVAL_MS\");\n return createEngine({\n ...options,\n exporter,\n ...(serviceName ? { serviceName } : {}),\n ...(serviceVersion ? { serviceVersion } : {}),\n ...(environment ? { environment } : {}),\n ...(samplingRatio !== undefined ? { samplingRatio } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(flushIntervalMs !== undefined ? { flushIntervalMs } : {}),\n });\n}\n"],"mappings":"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","names":["exporter","result","context","expire"]}
|
package/dist/copilot.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createObservability
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XGCHW72B.js";
|
|
4
4
|
|
|
5
5
|
// src/adapters/copilot.ts
|
|
6
6
|
import {
|
|
@@ -223,9 +223,11 @@ function attachCopilot(session, engine, options = {}) {
|
|
|
223
223
|
"gen_ai.usage.output_tokens": usage.outputTokens,
|
|
224
224
|
"gen_ai.usage.cache_read.input_tokens": usage.cacheReadTokens,
|
|
225
225
|
"gen_ai.usage.cache_creation.input_tokens": usage.cacheWriteTokens,
|
|
226
|
-
"copilot.usage.reasoning_tokens": usage.reasoningTokens
|
|
226
|
+
"copilot.usage.reasoning_tokens": usage.reasoningTokens,
|
|
227
|
+
"gen_ai.usage.reasoning.output_tokens": usage.reasoningTokens
|
|
227
228
|
})) {
|
|
228
|
-
if (finite(value)
|
|
229
|
+
if (finite(value) && Number.isSafeInteger(value))
|
|
230
|
+
entry.attributes[field] = value;
|
|
229
231
|
}
|
|
230
232
|
if (usage.responseModel)
|
|
231
233
|
entry.attributes["gen_ai.response.model"] = text(usage.responseModel);
|
package/dist/copilot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/copilot.ts","../src/copilot.ts"],"sourcesContent":["import type { SessionEvent, SessionEventHandler } from \"@github/copilot-sdk\";\nimport {\n SpanKind,\n SpanStatusCode,\n type Attributes,\n type Span,\n} from \"@opentelemetry/api\";\nimport type { Diagnostics, Observability } from \"../engine.js\";\n\n/** Compatible with CopilotSession without requiring its private implementation. */\nexport interface CopilotEventSource {\n readonly sessionId: string;\n on(handler: SessionEventHandler): () => void;\n}\n\nexport interface CopilotObserver {\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nexport interface AttachCopilotOptions {\n /** Defaults to true. Use false when several adapters share an externally owned engine. */\n shutdownEngine?: boolean;\n}\n\ninterface Entry {\n key: string;\n name: string;\n kind: SpanKind;\n attributes: Attributes;\n parentKey?: string;\n start?: number;\n end?: number;\n span?: Span;\n ended?: boolean;\n failed?: string;\n}\n\nconst text = (value: string): string => value.slice(0, 4096);\nconst identifier = (value: string): string => value.slice(0, 256);\nconst finite = (value: number | undefined): value is number =>\n value !== undefined && Number.isFinite(value) && value >= 0;\nconst toolKey = (id: string): string => `tool:${id}`;\nconst spanTypes: Record<string, string> = {\n \"copilot.agent.turn\": \"turn\",\n \"copilot.tool\": \"tool\",\n \"copilot.subagent\": \"subagent\",\n \"copilot.model.request\": \"model_request\",\n};\n// agentId is a namespace, not proof of an execution-parent relationship.\nconst turnKey = (id: string, agentId?: string): string =>\n JSON.stringify([\"turn\", agentId ?? null, id]);\n\n/** Attaches synchronously; event callbacks never perform or await network I/O. */\nexport function attachCopilot(\n session: CopilotEventSource,\n engine: Observability,\n options: AttachCopilotOptions = {},\n): CopilotObserver {\n const capacity = Math.max(1, engine.maxActiveSpans - 1);\n const records = new Map<string, Entry>();\n const open = new Set<Entry>();\n const completed = new Set<string>();\n const waiting = new Map<string, Set<string>>();\n const seen = new Set<string>();\n const usageSeen = new Set<string>();\n const attachedAt = Date.now();\n const root = engine.startSpan(\"copilot.session\", {\n startTime: attachedAt,\n attributes: {\n \"gen_ai.provider.name\": \"github.copilot\",\n \"gen_ai.operation.name\": \"invoke_agent\",\n \"copilot.session.id\": identifier(session.sessionId),\n \"copilot.session.observation_only\": true,\n \"copilot.span.type\": \"session\",\n },\n });\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n\n function remember(set: Set<string>, key: string): boolean {\n if (set.has(key)) return false;\n if (set.size >= Math.max(16, capacity * 2))\n set.delete(set.values().next().value!);\n set.add(key);\n return true;\n }\n\n function timestamp(event: SessionEvent): number {\n const time = Date.parse(event.timestamp);\n return Number.isFinite(time) ? time : Date.now();\n }\n\n function base(event: SessionEvent): Attributes {\n return {\n \"gen_ai.provider.name\": \"github.copilot\",\n \"copilot.session.id\": identifier(session.sessionId),\n ...(event.agentId\n ? { \"copilot.agent.id\": identifier(event.agentId) }\n : {}),\n ...(!Number.isFinite(Date.parse(event.timestamp))\n ? { \"copilot.timestamp.invalid\": true }\n : {}),\n };\n }\n\n function content(attributes: Attributes, key: string, value: unknown): void {\n if (!engine.captureContent || value === undefined) return;\n const encoded = typeof value === \"string\" ? value : JSON.stringify(value);\n if (encoded !== undefined) attributes[key] = text(encoded);\n }\n\n function fail(entry: Entry, errorType: string): void {\n entry.failed = errorType;\n }\n\n function attributeAgent(entry: Entry): void {\n if (entry.attributes[\"gen_ai.agent.name\"] !== undefined || !entry.parentKey)\n return;\n const parent = records.get(entry.parentKey);\n const source = entry.parentKey.startsWith(\"tool:\")\n ? records.get(`subagent:${entry.parentKey.slice(5)}`)\n : parent?.name === \"copilot.agent.turn\"\n ? parent\n : undefined;\n const name = source?.attributes[\"gen_ai.agent.name\"];\n if (typeof name === \"string\") entry.attributes[\"gen_ai.agent.name\"] = name;\n }\n\n function finish(entry: Entry): void {\n if (!entry.span || entry.ended || entry.end === undefined) return;\n attributeAgent(entry);\n if (entry.failed) {\n entry.span.setAttribute(\"error.type\", entry.failed);\n entry.span.setStatus({ code: SpanStatusCode.ERROR });\n } else {\n entry.span.setStatus({ code: SpanStatusCode.OK });\n }\n entry.span.setAttributes(entry.attributes);\n if (entry.start !== undefined && entry.end < entry.start) {\n entry.span.setAttribute(\"copilot.timestamp.reversed\", true);\n }\n entry.span.end(Math.max(entry.start ?? entry.end, entry.end));\n entry.ended = true;\n open.delete(entry);\n completed.add(entry.key);\n }\n\n function removeWait(entry: Entry): void {\n if (!entry.parentKey) return;\n const children = waiting.get(entry.parentKey);\n children?.delete(entry.key);\n if (children?.size === 0) waiting.delete(entry.parentKey);\n }\n\n function materialize(entry: Entry, fallback = false): void {\n const ready = [entry];\n for (let index = 0; index < ready.length; index++) {\n const current = ready[index]!;\n if (current.span || current.start === undefined) continue;\n const parent = current.parentKey\n ? records.get(current.parentKey)?.span\n : root;\n if (!parent && !fallback) {\n let children = waiting.get(current.parentKey!);\n if (!children) waiting.set(current.parentKey!, (children = new Set()));\n children.add(current.key);\n continue;\n }\n removeWait(current);\n if (!parent)\n current.attributes[\"copilot.correlation.missing_parent\"] = true;\n attributeAgent(current);\n current.span = engine.startSpan(current.name, {\n kind: current.kind,\n parent: parent ?? root,\n startTime: current.start,\n attributes: current.attributes,\n });\n finish(current);\n const children = waiting.get(current.key);\n if (children) {\n waiting.delete(current.key);\n for (const key of children) {\n const child = records.get(key);\n if (child) ready.push(child);\n }\n }\n }\n }\n\n function incomplete(entry: Entry, at: number, reason: string): void {\n if (entry.ended) return;\n if (entry.start === undefined) {\n entry.start = entry.end ?? at;\n entry.attributes[\"copilot.lifecycle.missing_start\"] = true;\n }\n if (entry.end === undefined) {\n entry.end = at;\n entry.attributes[\"observability.incomplete\"] = true;\n entry.attributes[\"copilot.lifecycle.end_reason\"] = reason;\n }\n materialize(entry, true);\n finish(entry);\n }\n\n function obtain(\n key: string,\n name: string,\n kind: SpanKind,\n event: SessionEvent,\n ): Entry {\n const existing = records.get(key);\n if (existing) return existing;\n if (records.size >= capacity) {\n const completedKey = completed.values().next().value;\n const victim =\n completedKey === undefined\n ? records.values().next().value!\n : records.get(completedKey)!;\n incomplete(victim, timestamp(event), \"capacity\");\n removeWait(victim);\n records.delete(victim.key);\n completed.delete(victim.key);\n }\n const entry: Entry = {\n key,\n name,\n kind,\n attributes: { ...base(event), \"copilot.span.type\": spanTypes[name] },\n };\n records.set(key, entry);\n open.add(entry);\n return entry;\n }\n\n function start(entry: Entry, event: SessionEvent, parentKey?: string): void {\n if (entry.start !== undefined || entry.ended) return;\n entry.start = timestamp(event);\n if (parentKey) entry.parentKey = parentKey;\n materialize(entry);\n }\n\n function complete(entry: Entry, event: SessionEvent): void {\n if (entry.end !== undefined || entry.ended) return;\n entry.end = timestamp(event);\n finish(entry);\n }\n\n function boundary(\n at: number,\n reason: string,\n errorType?: string,\n agentId?: string,\n ): void {\n for (const entry of open) {\n if (\n entry.ended ||\n (agentId &&\n entry.attributes[\"copilot.agent.id\"] !== identifier(agentId))\n )\n continue;\n if (errorType && entry.end === undefined) fail(entry, errorType);\n incomplete(entry, at, reason);\n }\n }\n\n function request(\n event: Extract<\n SessionEvent,\n { type: \"assistant.usage\" | \"model.call_failure\" }\n >,\n ): void {\n const data = event.data;\n const usage = event.type === \"assistant.usage\" ? event.data : undefined;\n const identity = usage?.accounting\n ? JSON.stringify([\n \"accounting\",\n usage.accounting.sourceSessionId,\n usage.accounting.usageId,\n ])\n : data.apiCallId\n ? JSON.stringify([\n \"request\",\n event.agentId ?? null,\n data.apiCallId,\n event.type,\n ])\n : undefined;\n if (identity && !remember(usageSeen, identity)) return;\n const entry = obtain(\n `request:${event.id}`,\n \"copilot.model.request\",\n SpanKind.CLIENT,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"chat\";\n entry.attributes[\"copilot.usage.scope\"] = \"request\";\n if (data.model) entry.attributes[\"gen_ai.request.model\"] = text(data.model);\n if (data.apiCallId)\n entry.attributes[\"copilot.request.id\"] = identifier(data.apiCallId);\n if (data.parentToolCallId) entry.parentKey = toolKey(data.parentToolCallId);\n const duration =\n event.type === \"assistant.usage\"\n ? event.data.duration\n : event.data.durationMs;\n const end = timestamp(event);\n entry.start = end - (finite(duration) ? duration : 0);\n entry.end = end;\n if (!finite(duration))\n entry.attributes[\"copilot.lifecycle.missing_duration\"] = true;\n if (usage) {\n for (const [field, value] of Object.entries({\n \"gen_ai.usage.input_tokens\": usage.inputTokens,\n \"gen_ai.usage.output_tokens\": usage.outputTokens,\n \"gen_ai.usage.cache_read.input_tokens\": usage.cacheReadTokens,\n \"gen_ai.usage.cache_creation.input_tokens\": usage.cacheWriteTokens,\n \"copilot.usage.reasoning_tokens\": usage.reasoningTokens,\n })) {\n if (finite(value)) entry.attributes[field] = value;\n }\n if (usage.responseModel)\n entry.attributes[\"gen_ai.response.model\"] = text(usage.responseModel);\n } else {\n fail(entry, \"model_call_failure\");\n }\n materialize(entry);\n }\n\n function handle(event: SessionEvent): void {\n if (closed || !remember(seen, event.id)) return;\n switch (event.type) {\n case \"session.start\":\n case \"session.resume\":\n if (event.data.selectedModel)\n root.setAttribute(\n \"gen_ai.request.model\",\n text(event.data.selectedModel),\n );\n break;\n case \"assistant.turn_start\": {\n const entry = obtain(\n turnKey(event.data.turnId, event.agentId),\n \"copilot.agent.turn\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"invoke_agent\";\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n if (event.data.model)\n entry.attributes[\"gen_ai.request.model\"] = text(event.data.model);\n start(\n entry,\n event,\n event.data.parentToolCallId\n ? toolKey(event.data.parentToolCallId)\n : undefined,\n );\n break;\n }\n case \"assistant.turn_end\": {\n const entry = obtain(\n turnKey(event.data.turnId, event.agentId),\n \"copilot.agent.turn\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n if (entry.start === undefined && event.data.parentToolCallId) {\n entry.parentKey = toolKey(event.data.parentToolCallId);\n }\n complete(entry, event);\n break;\n }\n case \"tool.execution_start\": {\n const entry = obtain(\n toolKey(event.data.toolCallId),\n \"copilot.tool\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"execute_tool\";\n entry.attributes[\"gen_ai.tool.name\"] = text(event.data.toolName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n if (event.data.turnId)\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n content(\n entry.attributes,\n \"gen_ai.tool.arguments\",\n event.data.arguments,\n );\n start(\n entry,\n event,\n event.data.turnId\n ? turnKey(event.data.turnId, event.agentId)\n : event.data.parentToolCallId\n ? toolKey(event.data.parentToolCallId)\n : undefined,\n );\n break;\n }\n case \"tool.execution_complete\": {\n const entry = obtain(\n toolKey(event.data.toolCallId),\n \"copilot.tool\",\n SpanKind.INTERNAL,\n event,\n );\n if (entry.end !== undefined || entry.ended) break;\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n entry.attributes[\"copilot.tool.success\"] = event.data.success;\n if (!event.data.success) fail(entry, \"tool_execution_failed\");\n content(\n entry.attributes,\n \"gen_ai.tool.result\",\n event.data.result?.content,\n );\n if (entry.start === undefined) {\n if (event.data.turnId)\n entry.parentKey = turnKey(event.data.turnId, event.agentId);\n else if (event.data.parentToolCallId)\n entry.parentKey = toolKey(event.data.parentToolCallId);\n }\n complete(entry, event);\n break;\n }\n case \"subagent.started\": {\n const entry = obtain(\n `subagent:${event.data.toolCallId}`,\n \"copilot.subagent\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"invoke_agent\";\n entry.attributes[\"gen_ai.agent.name\"] = text(event.data.agentName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n start(entry, event, toolKey(event.data.toolCallId));\n break;\n }\n case \"subagent.completed\":\n case \"subagent.failed\": {\n const entry = obtain(\n `subagent:${event.data.toolCallId}`,\n \"copilot.subagent\",\n SpanKind.INTERNAL,\n event,\n );\n if (entry.end !== undefined || entry.ended) break;\n entry.attributes[\"gen_ai.agent.name\"] = text(event.data.agentName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n if (event.type === \"subagent.failed\") fail(entry, \"subagent_failed\");\n else if (event.data.cancelled) fail(entry, \"cancelled\");\n if (finite(event.data.totalTokens)) {\n entry.attributes[\"copilot.subagent.usage.total_tokens\"] =\n event.data.totalTokens;\n entry.attributes[\"copilot.subagent.usage.scope\"] = \"aggregate\";\n }\n complete(entry, event);\n break;\n }\n case \"assistant.usage\":\n case \"model.call_failure\":\n request(event);\n break;\n case \"user.message\":\n case \"assistant.message\": {\n if (!engine.captureContent) break;\n const attributes = base(event);\n content(\n attributes,\n event.type === \"user.message\"\n ? \"gen_ai.input.messages\"\n : \"gen_ai.output.messages\",\n event.data.content,\n );\n // A message without an explicit turn ID is session content, not a fabricated turn.\n const span = event.data.turnId\n ? records.get(turnKey(event.data.turnId, event.agentId))?.span\n : undefined;\n (span ?? root).addEvent(event.type, attributes, timestamp(event));\n break;\n }\n case \"abort\":\n boundary(timestamp(event), \"abort\", \"cancelled\", event.agentId);\n root.addEvent(\n \"copilot.abort\",\n { \"error.type\": \"cancelled\" },\n timestamp(event),\n );\n break;\n case \"session.error\":\n root.setAttribute(\"error.type\", \"session_error\");\n root.setStatus({ code: SpanStatusCode.ERROR });\n boundary(\n timestamp(event),\n \"session.error\",\n \"session_error\",\n event.agentId,\n );\n break;\n case \"session.idle\":\n boundary(\n timestamp(event),\n \"session.idle\",\n event.data.aborted ? \"cancelled\" : undefined,\n );\n break;\n case \"session.shutdown\":\n if (event.data.shutdownType === \"error\") {\n root.setAttribute(\"error.type\", \"session_error\");\n root.setStatus({ code: SpanStatusCode.ERROR });\n boundary(timestamp(event), \"session.shutdown\", \"session_error\");\n }\n dispose(timestamp(event));\n break;\n }\n }\n\n function safe(callback: () => void): void {\n try {\n callback();\n } catch {\n /* Observability must not affect SDK event delivery. */\n }\n }\n\n let unsubscribe: (() => void) | undefined;\n function dispose(at: number): void {\n if (closed) return;\n closed = true;\n safe(() => unsubscribe?.());\n // One bad span implementation must not prevent cleanup of other active spans.\n for (const entry of open) safe(() => incomplete(entry, at, \"shutdown\"));\n safe(() => root.end(Math.max(attachedAt, at)));\n records.clear();\n open.clear();\n completed.clear();\n waiting.clear();\n seen.clear();\n usageSeen.clear();\n }\n try {\n unsubscribe = session.on((event) => safe(() => handle(event)));\n if (closed) safe(() => unsubscribe?.());\n } catch (error) {\n dispose(Date.now());\n if (options.shutdownEngine !== false)\n safe(() => {\n void engine.shutdown().catch(() => {});\n });\n throw error;\n }\n\n return {\n flush: () => engine.flush(),\n shutdown() {\n if (!shutdownPromise) {\n dispose(Date.now());\n shutdownPromise =\n options.shutdownEngine === false ? engine.flush() : engine.shutdown();\n }\n return shutdownPromise;\n },\n getDiagnostics: () => engine.getDiagnostics(),\n };\n}\n","import { attachCopilot } from \"./adapters/copilot.js\";\nimport {\n createObservability,\n type EventhouseObservabilityOptions,\n} from \"./index.js\";\n\nexport type { EventhouseObservabilityOptions } from \"./index.js\";\n\nexport function observeCopilot(\n session: Parameters<typeof attachCopilot>[0],\n options: EventhouseObservabilityOptions = {},\n): ReturnType<typeof attachCopilot> {\n return attachCopilot(session, createObservability(options));\n}\n"],"mappings":";;;;;AACA;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AAiCP,IAAM,OAAO,CAAC,UAA0B,MAAM,MAAM,GAAG,IAAI;AAC3D,IAAM,aAAa,CAAC,UAA0B,MAAM,MAAM,GAAG,GAAG;AAChE,IAAM,SAAS,CAAC,UACd,UAAU,UAAa,OAAO,SAAS,KAAK,KAAK,SAAS;AAC5D,IAAM,UAAU,CAAC,OAAuB,QAAQ,EAAE;AAClD,IAAM,YAAoC;AAAA,EACxC,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,yBAAyB;AAC3B;AAEA,IAAM,UAAU,CAAC,IAAY,YAC3B,KAAK,UAAU,CAAC,QAAQ,WAAW,MAAM,EAAE,CAAC;AAGvC,SAAS,cACd,SACA,QACA,UAAgC,CAAC,GAChB;AACjB,QAAM,WAAW,KAAK,IAAI,GAAG,OAAO,iBAAiB,CAAC;AACtD,QAAM,UAAU,oBAAI,IAAmB;AACvC,QAAM,OAAO,oBAAI,IAAW;AAC5B,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,UAAU,oBAAI,IAAyB;AAC7C,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,YAAY,oBAAI,IAAY;AAClC,QAAM,aAAa,KAAK,IAAI;AAC5B,QAAM,OAAO,OAAO,UAAU,mBAAmB;AAAA,IAC/C,WAAW;AAAA,IACX,YAAY;AAAA,MACV,wBAAwB;AAAA,MACxB,yBAAyB;AAAA,MACzB,sBAAsB,WAAW,QAAQ,SAAS;AAAA,MAClD,oCAAoC;AAAA,MACpC,qBAAqB;AAAA,IACvB;AAAA,EACF,CAAC;AACD,MAAI,SAAS;AACb,MAAI;AAEJ,WAAS,SAAS,KAAkB,KAAsB;AACxD,QAAI,IAAI,IAAI,GAAG,EAAG,QAAO;AACzB,QAAI,IAAI,QAAQ,KAAK,IAAI,IAAI,WAAW,CAAC;AACvC,UAAI,OAAO,IAAI,OAAO,EAAE,KAAK,EAAE,KAAM;AACvC,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT;AAEA,WAAS,UAAU,OAA6B;AAC9C,UAAM,OAAO,KAAK,MAAM,MAAM,SAAS;AACvC,WAAO,OAAO,SAAS,IAAI,IAAI,OAAO,KAAK,IAAI;AAAA,EACjD;AAEA,WAAS,KAAK,OAAiC;AAC7C,WAAO;AAAA,MACL,wBAAwB;AAAA,MACxB,sBAAsB,WAAW,QAAQ,SAAS;AAAA,MAClD,GAAI,MAAM,UACN,EAAE,oBAAoB,WAAW,MAAM,OAAO,EAAE,IAChD,CAAC;AAAA,MACL,GAAI,CAAC,OAAO,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,IAC5C,EAAE,6BAA6B,KAAK,IACpC,CAAC;AAAA,IACP;AAAA,EACF;AAEA,WAAS,QAAQ,YAAwB,KAAa,OAAsB;AAC1E,QAAI,CAAC,OAAO,kBAAkB,UAAU,OAAW;AACnD,UAAM,UAAU,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;AACxE,QAAI,YAAY,OAAW,YAAW,GAAG,IAAI,KAAK,OAAO;AAAA,EAC3D;AAEA,WAAS,KAAK,OAAc,WAAyB;AACnD,UAAM,SAAS;AAAA,EACjB;AAEA,WAAS,eAAe,OAAoB;AAC1C,QAAI,MAAM,WAAW,mBAAmB,MAAM,UAAa,CAAC,MAAM;AAChE;AACF,UAAM,SAAS,QAAQ,IAAI,MAAM,SAAS;AAC1C,UAAM,SAAS,MAAM,UAAU,WAAW,OAAO,IAC7C,QAAQ,IAAI,YAAY,MAAM,UAAU,MAAM,CAAC,CAAC,EAAE,IAClD,QAAQ,SAAS,uBACf,SACA;AACN,UAAM,OAAO,QAAQ,WAAW,mBAAmB;AACnD,QAAI,OAAO,SAAS,SAAU,OAAM,WAAW,mBAAmB,IAAI;AAAA,EACxE;AAEA,WAAS,OAAO,OAAoB;AAClC,QAAI,CAAC,MAAM,QAAQ,MAAM,SAAS,MAAM,QAAQ,OAAW;AAC3D,mBAAe,KAAK;AACpB,QAAI,MAAM,QAAQ;AAChB,YAAM,KAAK,aAAa,cAAc,MAAM,MAAM;AAClD,YAAM,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;AAAA,IACrD,OAAO;AACL,YAAM,KAAK,UAAU,EAAE,MAAM,eAAe,GAAG,CAAC;AAAA,IAClD;AACA,UAAM,KAAK,cAAc,MAAM,UAAU;AACzC,QAAI,MAAM,UAAU,UAAa,MAAM,MAAM,MAAM,OAAO;AACxD,YAAM,KAAK,aAAa,8BAA8B,IAAI;AAAA,IAC5D;AACA,UAAM,KAAK,IAAI,KAAK,IAAI,MAAM,SAAS,MAAM,KAAK,MAAM,GAAG,CAAC;AAC5D,UAAM,QAAQ;AACd,SAAK,OAAO,KAAK;AACjB,cAAU,IAAI,MAAM,GAAG;AAAA,EACzB;AAEA,WAAS,WAAW,OAAoB;AACtC,QAAI,CAAC,MAAM,UAAW;AACtB,UAAM,WAAW,QAAQ,IAAI,MAAM,SAAS;AAC5C,cAAU,OAAO,MAAM,GAAG;AAC1B,QAAI,UAAU,SAAS,EAAG,SAAQ,OAAO,MAAM,SAAS;AAAA,EAC1D;AAEA,WAAS,YAAY,OAAc,WAAW,OAAa;AACzD,UAAM,QAAQ,CAAC,KAAK;AACpB,aAAS,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;AACjD,YAAM,UAAU,MAAM,KAAK;AAC3B,UAAI,QAAQ,QAAQ,QAAQ,UAAU,OAAW;AACjD,YAAM,SAAS,QAAQ,YACnB,QAAQ,IAAI,QAAQ,SAAS,GAAG,OAChC;AACJ,UAAI,CAAC,UAAU,CAAC,UAAU;AACxB,YAAIA,YAAW,QAAQ,IAAI,QAAQ,SAAU;AAC7C,YAAI,CAACA,UAAU,SAAQ,IAAI,QAAQ,WAAaA,YAAW,oBAAI,IAAI,CAAE;AACrE,QAAAA,UAAS,IAAI,QAAQ,GAAG;AACxB;AAAA,MACF;AACA,iBAAW,OAAO;AAClB,UAAI,CAAC;AACH,gBAAQ,WAAW,oCAAoC,IAAI;AAC7D,qBAAe,OAAO;AACtB,cAAQ,OAAO,OAAO,UAAU,QAAQ,MAAM;AAAA,QAC5C,MAAM,QAAQ;AAAA,QACd,QAAQ,UAAU;AAAA,QAClB,WAAW,QAAQ;AAAA,QACnB,YAAY,QAAQ;AAAA,MACtB,CAAC;AACD,aAAO,OAAO;AACd,YAAM,WAAW,QAAQ,IAAI,QAAQ,GAAG;AACxC,UAAI,UAAU;AACZ,gBAAQ,OAAO,QAAQ,GAAG;AAC1B,mBAAW,OAAO,UAAU;AAC1B,gBAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,cAAI,MAAO,OAAM,KAAK,KAAK;AAAA,QAC7B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,WAAS,WAAW,OAAc,IAAY,QAAsB;AAClE,QAAI,MAAM,MAAO;AACjB,QAAI,MAAM,UAAU,QAAW;AAC7B,YAAM,QAAQ,MAAM,OAAO;AAC3B,YAAM,WAAW,iCAAiC,IAAI;AAAA,IACxD;AACA,QAAI,MAAM,QAAQ,QAAW;AAC3B,YAAM,MAAM;AACZ,YAAM,WAAW,0BAA0B,IAAI;AAC/C,YAAM,WAAW,8BAA8B,IAAI;AAAA,IACrD;AACA,gBAAY,OAAO,IAAI;AACvB,WAAO,KAAK;AAAA,EACd;AAEA,WAAS,OACP,KACA,MACA,MACA,OACO;AACP,UAAM,WAAW,QAAQ,IAAI,GAAG;AAChC,QAAI,SAAU,QAAO;AACrB,QAAI,QAAQ,QAAQ,UAAU;AAC5B,YAAM,eAAe,UAAU,OAAO,EAAE,KAAK,EAAE;AAC/C,YAAM,SACJ,iBAAiB,SACb,QAAQ,OAAO,EAAE,KAAK,EAAE,QACxB,QAAQ,IAAI,YAAY;AAC9B,iBAAW,QAAQ,UAAU,KAAK,GAAG,UAAU;AAC/C,iBAAW,MAAM;AACjB,cAAQ,OAAO,OAAO,GAAG;AACzB,gBAAU,OAAO,OAAO,GAAG;AAAA,IAC7B;AACA,UAAM,QAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY,EAAE,GAAG,KAAK,KAAK,GAAG,qBAAqB,UAAU,IAAI,EAAE;AAAA,IACrE;AACA,YAAQ,IAAI,KAAK,KAAK;AACtB,SAAK,IAAI,KAAK;AACd,WAAO;AAAA,EACT;AAEA,WAAS,MAAM,OAAc,OAAqB,WAA0B;AAC1E,QAAI,MAAM,UAAU,UAAa,MAAM,MAAO;AAC9C,UAAM,QAAQ,UAAU,KAAK;AAC7B,QAAI,UAAW,OAAM,YAAY;AACjC,gBAAY,KAAK;AAAA,EACnB;AAEA,WAAS,SAAS,OAAc,OAA2B;AACzD,QAAI,MAAM,QAAQ,UAAa,MAAM,MAAO;AAC5C,UAAM,MAAM,UAAU,KAAK;AAC3B,WAAO,KAAK;AAAA,EACd;AAEA,WAAS,SACP,IACA,QACA,WACA,SACM;AACN,eAAW,SAAS,MAAM;AACxB,UACE,MAAM,SACL,WACC,MAAM,WAAW,kBAAkB,MAAM,WAAW,OAAO;AAE7D;AACF,UAAI,aAAa,MAAM,QAAQ,OAAW,MAAK,OAAO,SAAS;AAC/D,iBAAW,OAAO,IAAI,MAAM;AAAA,IAC9B;AAAA,EACF;AAEA,WAAS,QACP,OAIM;AACN,UAAM,OAAO,MAAM;AACnB,UAAM,QAAQ,MAAM,SAAS,oBAAoB,MAAM,OAAO;AAC9D,UAAM,WAAW,OAAO,aACpB,KAAK,UAAU;AAAA,MACb;AAAA,MACA,MAAM,WAAW;AAAA,MACjB,MAAM,WAAW;AAAA,IACnB,CAAC,IACD,KAAK,YACH,KAAK,UAAU;AAAA,MACb;AAAA,MACA,MAAM,WAAW;AAAA,MACjB,KAAK;AAAA,MACL,MAAM;AAAA,IACR,CAAC,IACD;AACN,QAAI,YAAY,CAAC,SAAS,WAAW,QAAQ,EAAG;AAChD,UAAM,QAAQ;AAAA,MACZ,WAAW,MAAM,EAAE;AAAA,MACnB;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AACA,UAAM,WAAW,uBAAuB,IAAI;AAC5C,UAAM,WAAW,qBAAqB,IAAI;AAC1C,QAAI,KAAK,MAAO,OAAM,WAAW,sBAAsB,IAAI,KAAK,KAAK,KAAK;AAC1E,QAAI,KAAK;AACP,YAAM,WAAW,oBAAoB,IAAI,WAAW,KAAK,SAAS;AACpE,QAAI,KAAK,iBAAkB,OAAM,YAAY,QAAQ,KAAK,gBAAgB;AAC1E,UAAM,WACJ,MAAM,SAAS,oBACX,MAAM,KAAK,WACX,MAAM,KAAK;AACjB,UAAM,MAAM,UAAU,KAAK;AAC3B,UAAM,QAAQ,OAAO,OAAO,QAAQ,IAAI,WAAW;AACnD,UAAM,MAAM;AACZ,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,WAAW,oCAAoC,IAAI;AAC3D,QAAI,OAAO;AACT,iBAAW,CAAC,OAAO,KAAK,KAAK,OAAO,QAAQ;AAAA,QAC1C,6BAA6B,MAAM;AAAA,QACnC,8BAA8B,MAAM;AAAA,QACpC,wCAAwC,MAAM;AAAA,QAC9C,4CAA4C,MAAM;AAAA,QAClD,kCAAkC,MAAM;AAAA,MAC1C,CAAC,GAAG;AACF,YAAI,OAAO,KAAK,EAAG,OAAM,WAAW,KAAK,IAAI;AAAA,MAC/C;AACA,UAAI,MAAM;AACR,cAAM,WAAW,uBAAuB,IAAI,KAAK,MAAM,aAAa;AAAA,IACxE,OAAO;AACL,WAAK,OAAO,oBAAoB;AAAA,IAClC;AACA,gBAAY,KAAK;AAAA,EACnB;AAEA,WAAS,OAAO,OAA2B;AACzC,QAAI,UAAU,CAAC,SAAS,MAAM,MAAM,EAAE,EAAG;AACzC,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AAAA,MACL,KAAK;AACH,YAAI,MAAM,KAAK;AACb,eAAK;AAAA,YACH;AAAA,YACA,KAAK,MAAM,KAAK,aAAa;AAAA,UAC/B;AACF;AAAA,MACF,KAAK,wBAAwB;AAC3B,cAAM,QAAQ;AAAA,UACZ,QAAQ,MAAM,KAAK,QAAQ,MAAM,OAAO;AAAA,UACxC;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,cAAM,WAAW,uBAAuB,IAAI;AAC5C,cAAM,WAAW,iBAAiB,IAAI,WAAW,MAAM,KAAK,MAAM;AAClE,YAAI,MAAM,KAAK;AACb,gBAAM,WAAW,sBAAsB,IAAI,KAAK,MAAM,KAAK,KAAK;AAClE;AAAA,UACE;AAAA,UACA;AAAA,UACA,MAAM,KAAK,mBACP,QAAQ,MAAM,KAAK,gBAAgB,IACnC;AAAA,QACN;AACA;AAAA,MACF;AAAA,MACA,KAAK,sBAAsB;AACzB,cAAM,QAAQ;AAAA,UACZ,QAAQ,MAAM,KAAK,QAAQ,MAAM,OAAO;AAAA,UACxC;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,cAAM,WAAW,iBAAiB,IAAI,WAAW,MAAM,KAAK,MAAM;AAClE,YAAI,MAAM,UAAU,UAAa,MAAM,KAAK,kBAAkB;AAC5D,gBAAM,YAAY,QAAQ,MAAM,KAAK,gBAAgB;AAAA,QACvD;AACA,iBAAS,OAAO,KAAK;AACrB;AAAA,MACF;AAAA,MACA,KAAK,wBAAwB;AAC3B,cAAM,QAAQ;AAAA,UACZ,QAAQ,MAAM,KAAK,UAAU;AAAA,UAC7B;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,cAAM,WAAW,uBAAuB,IAAI;AAC5C,cAAM,WAAW,kBAAkB,IAAI,KAAK,MAAM,KAAK,QAAQ;AAC/D,cAAM,WAAW,sBAAsB,IAAI;AAAA,UACzC,MAAM,KAAK;AAAA,QACb;AACA,YAAI,MAAM,KAAK;AACb,gBAAM,WAAW,iBAAiB,IAAI,WAAW,MAAM,KAAK,MAAM;AACpE;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA,MAAM,KAAK;AAAA,QACb;AACA;AAAA,UACE;AAAA,UACA;AAAA,UACA,MAAM,KAAK,SACP,QAAQ,MAAM,KAAK,QAAQ,MAAM,OAAO,IACxC,MAAM,KAAK,mBACT,QAAQ,MAAM,KAAK,gBAAgB,IACnC;AAAA,QACR;AACA;AAAA,MACF;AAAA,MACA,KAAK,2BAA2B;AAC9B,cAAM,QAAQ;AAAA,UACZ,QAAQ,MAAM,KAAK,UAAU;AAAA,UAC7B;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,YAAI,MAAM,QAAQ,UAAa,MAAM,MAAO;AAC5C,cAAM,WAAW,sBAAsB,IAAI;AAAA,UACzC,MAAM,KAAK;AAAA,QACb;AACA,cAAM,WAAW,sBAAsB,IAAI,MAAM,KAAK;AACtD,YAAI,CAAC,MAAM,KAAK,QAAS,MAAK,OAAO,uBAAuB;AAC5D;AAAA,UACE,MAAM;AAAA,UACN;AAAA,UACA,MAAM,KAAK,QAAQ;AAAA,QACrB;AACA,YAAI,MAAM,UAAU,QAAW;AAC7B,cAAI,MAAM,KAAK;AACb,kBAAM,YAAY,QAAQ,MAAM,KAAK,QAAQ,MAAM,OAAO;AAAA,mBACnD,MAAM,KAAK;AAClB,kBAAM,YAAY,QAAQ,MAAM,KAAK,gBAAgB;AAAA,QACzD;AACA,iBAAS,OAAO,KAAK;AACrB;AAAA,MACF;AAAA,MACA,KAAK,oBAAoB;AACvB,cAAM,QAAQ;AAAA,UACZ,YAAY,MAAM,KAAK,UAAU;AAAA,UACjC;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,cAAM,WAAW,uBAAuB,IAAI;AAC5C,cAAM,WAAW,mBAAmB,IAAI,KAAK,MAAM,KAAK,SAAS;AACjE,cAAM,WAAW,sBAAsB,IAAI;AAAA,UACzC,MAAM,KAAK;AAAA,QACb;AACA,cAAM,OAAO,OAAO,QAAQ,MAAM,KAAK,UAAU,CAAC;AAClD;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK,mBAAmB;AACtB,cAAM,QAAQ;AAAA,UACZ,YAAY,MAAM,KAAK,UAAU;AAAA,UACjC;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AACA,YAAI,MAAM,QAAQ,UAAa,MAAM,MAAO;AAC5C,cAAM,WAAW,mBAAmB,IAAI,KAAK,MAAM,KAAK,SAAS;AACjE,cAAM,WAAW,sBAAsB,IAAI;AAAA,UACzC,MAAM,KAAK;AAAA,QACb;AACA,YAAI,MAAM,SAAS,kBAAmB,MAAK,OAAO,iBAAiB;AAAA,iBAC1D,MAAM,KAAK,UAAW,MAAK,OAAO,WAAW;AACtD,YAAI,OAAO,MAAM,KAAK,WAAW,GAAG;AAClC,gBAAM,WAAW,qCAAqC,IACpD,MAAM,KAAK;AACb,gBAAM,WAAW,8BAA8B,IAAI;AAAA,QACrD;AACA,iBAAS,OAAO,KAAK;AACrB;AAAA,MACF;AAAA,MACA,KAAK;AAAA,MACL,KAAK;AACH,gBAAQ,KAAK;AACb;AAAA,MACF,KAAK;AAAA,MACL,KAAK,qBAAqB;AACxB,YAAI,CAAC,OAAO,eAAgB;AAC5B,cAAM,aAAa,KAAK,KAAK;AAC7B;AAAA,UACE;AAAA,UACA,MAAM,SAAS,iBACX,0BACA;AAAA,UACJ,MAAM,KAAK;AAAA,QACb;AAEA,cAAM,OAAO,MAAM,KAAK,SACpB,QAAQ,IAAI,QAAQ,MAAM,KAAK,QAAQ,MAAM,OAAO,CAAC,GAAG,OACxD;AACJ,SAAC,QAAQ,MAAM,SAAS,MAAM,MAAM,YAAY,UAAU,KAAK,CAAC;AAChE;AAAA,MACF;AAAA,MACA,KAAK;AACH,iBAAS,UAAU,KAAK,GAAG,SAAS,aAAa,MAAM,OAAO;AAC9D,aAAK;AAAA,UACH;AAAA,UACA,EAAE,cAAc,YAAY;AAAA,UAC5B,UAAU,KAAK;AAAA,QACjB;AACA;AAAA,MACF,KAAK;AACH,aAAK,aAAa,cAAc,eAAe;AAC/C,aAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;AAC7C;AAAA,UACE,UAAU,KAAK;AAAA,UACf;AAAA,UACA;AAAA,UACA,MAAM;AAAA,QACR;AACA;AAAA,MACF,KAAK;AACH;AAAA,UACE,UAAU,KAAK;AAAA,UACf;AAAA,UACA,MAAM,KAAK,UAAU,cAAc;AAAA,QACrC;AACA;AAAA,MACF,KAAK;AACH,YAAI,MAAM,KAAK,iBAAiB,SAAS;AACvC,eAAK,aAAa,cAAc,eAAe;AAC/C,eAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;AAC7C,mBAAS,UAAU,KAAK,GAAG,oBAAoB,eAAe;AAAA,QAChE;AACA,gBAAQ,UAAU,KAAK,CAAC;AACxB;AAAA,IACJ;AAAA,EACF;AAEA,WAAS,KAAK,UAA4B;AACxC,QAAI;AACF,eAAS;AAAA,IACX,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI;AACJ,WAAS,QAAQ,IAAkB;AACjC,QAAI,OAAQ;AACZ,aAAS;AACT,SAAK,MAAM,cAAc,CAAC;AAE1B,eAAW,SAAS,KAAM,MAAK,MAAM,WAAW,OAAO,IAAI,UAAU,CAAC;AACtE,SAAK,MAAM,KAAK,IAAI,KAAK,IAAI,YAAY,EAAE,CAAC,CAAC;AAC7C,YAAQ,MAAM;AACd,SAAK,MAAM;AACX,cAAU,MAAM;AAChB,YAAQ,MAAM;AACd,SAAK,MAAM;AACX,cAAU,MAAM;AAAA,EAClB;AACA,MAAI;AACF,kBAAc,QAAQ,GAAG,CAAC,UAAU,KAAK,MAAM,OAAO,KAAK,CAAC,CAAC;AAC7D,QAAI,OAAQ,MAAK,MAAM,cAAc,CAAC;AAAA,EACxC,SAAS,OAAO;AACd,YAAQ,KAAK,IAAI,CAAC;AAClB,QAAI,QAAQ,mBAAmB;AAC7B,WAAK,MAAM;AACT,aAAK,OAAO,SAAS,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAAA,MACvC,CAAC;AACH,UAAM;AAAA,EACR;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,OAAO,MAAM;AAAA,IAC1B,WAAW;AACT,UAAI,CAAC,iBAAiB;AACpB,gBAAQ,KAAK,IAAI,CAAC;AAClB,0BACE,QAAQ,mBAAmB,QAAQ,OAAO,MAAM,IAAI,OAAO,SAAS;AAAA,MACxE;AACA,aAAO;AAAA,IACT;AAAA,IACA,gBAAgB,MAAM,OAAO,eAAe;AAAA,EAC9C;AACF;;;ACvjBO,SAAS,eACd,SACA,UAA0C,CAAC,GACT;AAClC,SAAO,cAAc,SAAS,oBAAoB,OAAO,CAAC;AAC5D;","names":["children"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/copilot.ts","../src/copilot.ts"],"sourcesContent":["import type { SessionEvent, SessionEventHandler } from \"@github/copilot-sdk\";\nimport {\n SpanKind,\n SpanStatusCode,\n type Attributes,\n type Span,\n} from \"@opentelemetry/api\";\nimport type { Diagnostics, Observability } from \"../engine.js\";\n\n/** Compatible with CopilotSession without requiring its private implementation. */\nexport interface CopilotEventSource {\n readonly sessionId: string;\n on(handler: SessionEventHandler): () => void;\n}\n\nexport interface CopilotObserver {\n flush(): Promise<void>;\n shutdown(): Promise<void>;\n getDiagnostics(): Readonly<Diagnostics>;\n}\n\nexport interface AttachCopilotOptions {\n /** Defaults to true. Use false when several adapters share an externally owned engine. */\n shutdownEngine?: boolean;\n}\n\ninterface Entry {\n key: string;\n name: string;\n kind: SpanKind;\n attributes: Attributes;\n parentKey?: string;\n start?: number;\n end?: number;\n span?: Span;\n ended?: boolean;\n failed?: string;\n}\n\nconst text = (value: string): string => value.slice(0, 4096);\nconst identifier = (value: string): string => value.slice(0, 256);\nconst finite = (value: number | undefined): value is number =>\n value !== undefined && Number.isFinite(value) && value >= 0;\nconst toolKey = (id: string): string => `tool:${id}`;\nconst spanTypes: Record<string, string> = {\n \"copilot.agent.turn\": \"turn\",\n \"copilot.tool\": \"tool\",\n \"copilot.subagent\": \"subagent\",\n \"copilot.model.request\": \"model_request\",\n};\n// agentId is a namespace, not proof of an execution-parent relationship.\nconst turnKey = (id: string, agentId?: string): string =>\n JSON.stringify([\"turn\", agentId ?? null, id]);\n\n/** Attaches synchronously; event callbacks never perform or await network I/O. */\nexport function attachCopilot(\n session: CopilotEventSource,\n engine: Observability,\n options: AttachCopilotOptions = {},\n): CopilotObserver {\n const capacity = Math.max(1, engine.maxActiveSpans - 1);\n const records = new Map<string, Entry>();\n const open = new Set<Entry>();\n const completed = new Set<string>();\n const waiting = new Map<string, Set<string>>();\n const seen = new Set<string>();\n const usageSeen = new Set<string>();\n const attachedAt = Date.now();\n const root = engine.startSpan(\"copilot.session\", {\n startTime: attachedAt,\n attributes: {\n \"gen_ai.provider.name\": \"github.copilot\",\n \"gen_ai.operation.name\": \"invoke_agent\",\n \"copilot.session.id\": identifier(session.sessionId),\n \"copilot.session.observation_only\": true,\n \"copilot.span.type\": \"session\",\n },\n });\n let closed = false;\n let shutdownPromise: Promise<void> | undefined;\n\n function remember(set: Set<string>, key: string): boolean {\n if (set.has(key)) return false;\n if (set.size >= Math.max(16, capacity * 2))\n set.delete(set.values().next().value!);\n set.add(key);\n return true;\n }\n\n function timestamp(event: SessionEvent): number {\n const time = Date.parse(event.timestamp);\n return Number.isFinite(time) ? time : Date.now();\n }\n\n function base(event: SessionEvent): Attributes {\n return {\n \"gen_ai.provider.name\": \"github.copilot\",\n \"copilot.session.id\": identifier(session.sessionId),\n ...(event.agentId\n ? { \"copilot.agent.id\": identifier(event.agentId) }\n : {}),\n ...(!Number.isFinite(Date.parse(event.timestamp))\n ? { \"copilot.timestamp.invalid\": true }\n : {}),\n };\n }\n\n function content(attributes: Attributes, key: string, value: unknown): void {\n if (!engine.captureContent || value === undefined) return;\n const encoded = typeof value === \"string\" ? value : JSON.stringify(value);\n if (encoded !== undefined) attributes[key] = text(encoded);\n }\n\n function fail(entry: Entry, errorType: string): void {\n entry.failed = errorType;\n }\n\n function attributeAgent(entry: Entry): void {\n if (entry.attributes[\"gen_ai.agent.name\"] !== undefined || !entry.parentKey)\n return;\n const parent = records.get(entry.parentKey);\n const source = entry.parentKey.startsWith(\"tool:\")\n ? records.get(`subagent:${entry.parentKey.slice(5)}`)\n : parent?.name === \"copilot.agent.turn\"\n ? parent\n : undefined;\n const name = source?.attributes[\"gen_ai.agent.name\"];\n if (typeof name === \"string\") entry.attributes[\"gen_ai.agent.name\"] = name;\n }\n\n function finish(entry: Entry): void {\n if (!entry.span || entry.ended || entry.end === undefined) return;\n attributeAgent(entry);\n if (entry.failed) {\n entry.span.setAttribute(\"error.type\", entry.failed);\n entry.span.setStatus({ code: SpanStatusCode.ERROR });\n } else {\n entry.span.setStatus({ code: SpanStatusCode.OK });\n }\n entry.span.setAttributes(entry.attributes);\n if (entry.start !== undefined && entry.end < entry.start) {\n entry.span.setAttribute(\"copilot.timestamp.reversed\", true);\n }\n entry.span.end(Math.max(entry.start ?? entry.end, entry.end));\n entry.ended = true;\n open.delete(entry);\n completed.add(entry.key);\n }\n\n function removeWait(entry: Entry): void {\n if (!entry.parentKey) return;\n const children = waiting.get(entry.parentKey);\n children?.delete(entry.key);\n if (children?.size === 0) waiting.delete(entry.parentKey);\n }\n\n function materialize(entry: Entry, fallback = false): void {\n const ready = [entry];\n for (let index = 0; index < ready.length; index++) {\n const current = ready[index]!;\n if (current.span || current.start === undefined) continue;\n const parent = current.parentKey\n ? records.get(current.parentKey)?.span\n : root;\n if (!parent && !fallback) {\n let children = waiting.get(current.parentKey!);\n if (!children) waiting.set(current.parentKey!, (children = new Set()));\n children.add(current.key);\n continue;\n }\n removeWait(current);\n if (!parent)\n current.attributes[\"copilot.correlation.missing_parent\"] = true;\n attributeAgent(current);\n current.span = engine.startSpan(current.name, {\n kind: current.kind,\n parent: parent ?? root,\n startTime: current.start,\n attributes: current.attributes,\n });\n finish(current);\n const children = waiting.get(current.key);\n if (children) {\n waiting.delete(current.key);\n for (const key of children) {\n const child = records.get(key);\n if (child) ready.push(child);\n }\n }\n }\n }\n\n function incomplete(entry: Entry, at: number, reason: string): void {\n if (entry.ended) return;\n if (entry.start === undefined) {\n entry.start = entry.end ?? at;\n entry.attributes[\"copilot.lifecycle.missing_start\"] = true;\n }\n if (entry.end === undefined) {\n entry.end = at;\n entry.attributes[\"observability.incomplete\"] = true;\n entry.attributes[\"copilot.lifecycle.end_reason\"] = reason;\n }\n materialize(entry, true);\n finish(entry);\n }\n\n function obtain(\n key: string,\n name: string,\n kind: SpanKind,\n event: SessionEvent,\n ): Entry {\n const existing = records.get(key);\n if (existing) return existing;\n if (records.size >= capacity) {\n const completedKey = completed.values().next().value;\n const victim =\n completedKey === undefined\n ? records.values().next().value!\n : records.get(completedKey)!;\n incomplete(victim, timestamp(event), \"capacity\");\n removeWait(victim);\n records.delete(victim.key);\n completed.delete(victim.key);\n }\n const entry: Entry = {\n key,\n name,\n kind,\n attributes: { ...base(event), \"copilot.span.type\": spanTypes[name] },\n };\n records.set(key, entry);\n open.add(entry);\n return entry;\n }\n\n function start(entry: Entry, event: SessionEvent, parentKey?: string): void {\n if (entry.start !== undefined || entry.ended) return;\n entry.start = timestamp(event);\n if (parentKey) entry.parentKey = parentKey;\n materialize(entry);\n }\n\n function complete(entry: Entry, event: SessionEvent): void {\n if (entry.end !== undefined || entry.ended) return;\n entry.end = timestamp(event);\n finish(entry);\n }\n\n function boundary(\n at: number,\n reason: string,\n errorType?: string,\n agentId?: string,\n ): void {\n for (const entry of open) {\n if (\n entry.ended ||\n (agentId &&\n entry.attributes[\"copilot.agent.id\"] !== identifier(agentId))\n )\n continue;\n if (errorType && entry.end === undefined) fail(entry, errorType);\n incomplete(entry, at, reason);\n }\n }\n\n function request(\n event: Extract<\n SessionEvent,\n { type: \"assistant.usage\" | \"model.call_failure\" }\n >,\n ): void {\n const data = event.data;\n const usage = event.type === \"assistant.usage\" ? event.data : undefined;\n const identity = usage?.accounting\n ? JSON.stringify([\n \"accounting\",\n usage.accounting.sourceSessionId,\n usage.accounting.usageId,\n ])\n : data.apiCallId\n ? JSON.stringify([\n \"request\",\n event.agentId ?? null,\n data.apiCallId,\n event.type,\n ])\n : undefined;\n if (identity && !remember(usageSeen, identity)) return;\n const entry = obtain(\n `request:${event.id}`,\n \"copilot.model.request\",\n SpanKind.CLIENT,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"chat\";\n entry.attributes[\"copilot.usage.scope\"] = \"request\";\n if (data.model) entry.attributes[\"gen_ai.request.model\"] = text(data.model);\n if (data.apiCallId)\n entry.attributes[\"copilot.request.id\"] = identifier(data.apiCallId);\n if (data.parentToolCallId) entry.parentKey = toolKey(data.parentToolCallId);\n const duration =\n event.type === \"assistant.usage\"\n ? event.data.duration\n : event.data.durationMs;\n const end = timestamp(event);\n entry.start = end - (finite(duration) ? duration : 0);\n entry.end = end;\n if (!finite(duration))\n entry.attributes[\"copilot.lifecycle.missing_duration\"] = true;\n if (usage) {\n for (const [field, value] of Object.entries({\n \"gen_ai.usage.input_tokens\": usage.inputTokens,\n \"gen_ai.usage.output_tokens\": usage.outputTokens,\n \"gen_ai.usage.cache_read.input_tokens\": usage.cacheReadTokens,\n \"gen_ai.usage.cache_creation.input_tokens\": usage.cacheWriteTokens,\n \"copilot.usage.reasoning_tokens\": usage.reasoningTokens,\n \"gen_ai.usage.reasoning.output_tokens\": usage.reasoningTokens,\n })) {\n if (finite(value) && Number.isSafeInteger(value))\n entry.attributes[field] = value;\n }\n if (usage.responseModel)\n entry.attributes[\"gen_ai.response.model\"] = text(usage.responseModel);\n } else {\n fail(entry, \"model_call_failure\");\n }\n materialize(entry);\n }\n\n function handle(event: SessionEvent): void {\n if (closed || !remember(seen, event.id)) return;\n switch (event.type) {\n case \"session.start\":\n case \"session.resume\":\n if (event.data.selectedModel)\n root.setAttribute(\n \"gen_ai.request.model\",\n text(event.data.selectedModel),\n );\n break;\n case \"assistant.turn_start\": {\n const entry = obtain(\n turnKey(event.data.turnId, event.agentId),\n \"copilot.agent.turn\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"invoke_agent\";\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n if (event.data.model)\n entry.attributes[\"gen_ai.request.model\"] = text(event.data.model);\n start(\n entry,\n event,\n event.data.parentToolCallId\n ? toolKey(event.data.parentToolCallId)\n : undefined,\n );\n break;\n }\n case \"assistant.turn_end\": {\n const entry = obtain(\n turnKey(event.data.turnId, event.agentId),\n \"copilot.agent.turn\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n if (entry.start === undefined && event.data.parentToolCallId) {\n entry.parentKey = toolKey(event.data.parentToolCallId);\n }\n complete(entry, event);\n break;\n }\n case \"tool.execution_start\": {\n const entry = obtain(\n toolKey(event.data.toolCallId),\n \"copilot.tool\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"execute_tool\";\n entry.attributes[\"gen_ai.tool.name\"] = text(event.data.toolName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n if (event.data.turnId)\n entry.attributes[\"copilot.turn.id\"] = identifier(event.data.turnId);\n content(\n entry.attributes,\n \"gen_ai.tool.arguments\",\n event.data.arguments,\n );\n start(\n entry,\n event,\n event.data.turnId\n ? turnKey(event.data.turnId, event.agentId)\n : event.data.parentToolCallId\n ? toolKey(event.data.parentToolCallId)\n : undefined,\n );\n break;\n }\n case \"tool.execution_complete\": {\n const entry = obtain(\n toolKey(event.data.toolCallId),\n \"copilot.tool\",\n SpanKind.INTERNAL,\n event,\n );\n if (entry.end !== undefined || entry.ended) break;\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n entry.attributes[\"copilot.tool.success\"] = event.data.success;\n if (!event.data.success) fail(entry, \"tool_execution_failed\");\n content(\n entry.attributes,\n \"gen_ai.tool.result\",\n event.data.result?.content,\n );\n if (entry.start === undefined) {\n if (event.data.turnId)\n entry.parentKey = turnKey(event.data.turnId, event.agentId);\n else if (event.data.parentToolCallId)\n entry.parentKey = toolKey(event.data.parentToolCallId);\n }\n complete(entry, event);\n break;\n }\n case \"subagent.started\": {\n const entry = obtain(\n `subagent:${event.data.toolCallId}`,\n \"copilot.subagent\",\n SpanKind.INTERNAL,\n event,\n );\n entry.attributes[\"gen_ai.operation.name\"] = \"invoke_agent\";\n entry.attributes[\"gen_ai.agent.name\"] = text(event.data.agentName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n start(entry, event, toolKey(event.data.toolCallId));\n break;\n }\n case \"subagent.completed\":\n case \"subagent.failed\": {\n const entry = obtain(\n `subagent:${event.data.toolCallId}`,\n \"copilot.subagent\",\n SpanKind.INTERNAL,\n event,\n );\n if (entry.end !== undefined || entry.ended) break;\n entry.attributes[\"gen_ai.agent.name\"] = text(event.data.agentName);\n entry.attributes[\"copilot.tool.call_id\"] = identifier(\n event.data.toolCallId,\n );\n if (event.type === \"subagent.failed\") fail(entry, \"subagent_failed\");\n else if (event.data.cancelled) fail(entry, \"cancelled\");\n if (finite(event.data.totalTokens)) {\n entry.attributes[\"copilot.subagent.usage.total_tokens\"] =\n event.data.totalTokens;\n entry.attributes[\"copilot.subagent.usage.scope\"] = \"aggregate\";\n }\n complete(entry, event);\n break;\n }\n case \"assistant.usage\":\n case \"model.call_failure\":\n request(event);\n break;\n case \"user.message\":\n case \"assistant.message\": {\n if (!engine.captureContent) break;\n const attributes = base(event);\n content(\n attributes,\n event.type === \"user.message\"\n ? \"gen_ai.input.messages\"\n : \"gen_ai.output.messages\",\n event.data.content,\n );\n // A message without an explicit turn ID is session content, not a fabricated turn.\n const span = event.data.turnId\n ? records.get(turnKey(event.data.turnId, event.agentId))?.span\n : undefined;\n (span ?? root).addEvent(event.type, attributes, timestamp(event));\n break;\n }\n case \"abort\":\n boundary(timestamp(event), \"abort\", \"cancelled\", event.agentId);\n root.addEvent(\n \"copilot.abort\",\n { \"error.type\": \"cancelled\" },\n timestamp(event),\n );\n break;\n case \"session.error\":\n root.setAttribute(\"error.type\", \"session_error\");\n root.setStatus({ code: SpanStatusCode.ERROR });\n boundary(\n timestamp(event),\n \"session.error\",\n \"session_error\",\n event.agentId,\n );\n break;\n case \"session.idle\":\n boundary(\n timestamp(event),\n \"session.idle\",\n event.data.aborted ? \"cancelled\" : undefined,\n );\n break;\n case \"session.shutdown\":\n if (event.data.shutdownType === \"error\") {\n root.setAttribute(\"error.type\", \"session_error\");\n root.setStatus({ code: SpanStatusCode.ERROR });\n boundary(timestamp(event), \"session.shutdown\", \"session_error\");\n }\n dispose(timestamp(event));\n break;\n }\n }\n\n function safe(callback: () => void): void {\n try {\n callback();\n } catch {\n /* Observability must not affect SDK event delivery. */\n }\n }\n\n let unsubscribe: (() => void) | undefined;\n function dispose(at: number): void {\n if (closed) return;\n closed = true;\n safe(() => unsubscribe?.());\n // One bad span implementation must not prevent cleanup of other active spans.\n for (const entry of open) safe(() => incomplete(entry, at, \"shutdown\"));\n safe(() => root.end(Math.max(attachedAt, at)));\n records.clear();\n open.clear();\n completed.clear();\n waiting.clear();\n seen.clear();\n usageSeen.clear();\n }\n try {\n unsubscribe = session.on((event) => safe(() => handle(event)));\n if (closed) safe(() => unsubscribe?.());\n } catch (error) {\n dispose(Date.now());\n if (options.shutdownEngine !== false)\n safe(() => {\n void engine.shutdown().catch(() => {});\n });\n throw error;\n }\n\n return {\n flush: () => engine.flush(),\n shutdown() {\n if (!shutdownPromise) {\n dispose(Date.now());\n shutdownPromise =\n options.shutdownEngine === false ? engine.flush() : engine.shutdown();\n }\n return shutdownPromise;\n },\n getDiagnostics: () => engine.getDiagnostics(),\n };\n}\n","import { attachCopilot } from \"./adapters/copilot.js\";\nimport {\n createObservability,\n type EventhouseObservabilityOptions,\n} from \"./index.js\";\n\nexport type { EventhouseObservabilityOptions } from \"./index.js\";\n\nexport function observeCopilot(\n session: Parameters<typeof attachCopilot>[0],\n options: EventhouseObservabilityOptions = {},\n): ReturnType<typeof attachCopilot> {\n return attachCopilot(session, createObservability(options));\n}\n"],"mappings":"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","names":["children"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { type CoreOptions, type Observability } from "./engine.js";
|
|
2
2
|
import type { SpanExporter } from "@opentelemetry/sdk-trace";
|
|
3
|
-
export { createEngine, redactSecrets } from "./engine.js";
|
|
4
3
|
export type { CoreOptions, Diagnostics, DiagnosticCategory, DiagnosticEvent, Observability, Redactor, } from "./engine.js";
|
|
5
4
|
export type { SpanExporter } from "@opentelemetry/sdk-trace";
|
|
6
|
-
export { EventstreamExporter
|
|
7
|
-
export { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
5
|
+
export { EventstreamExporter } from "./exporters/eventstream.js";
|
|
8
6
|
export interface EventhouseObservabilityOptions extends Omit<CoreOptions, "exporter"> {
|
|
9
7
|
connectionString?: string;
|
|
10
8
|
entityName?: string;
|
|
11
|
-
transport?: "eventstream" | "otlp";
|
|
12
9
|
exporter?: SpanExporter;
|
|
13
|
-
endpoint?: string;
|
|
14
|
-
headers?: Record<string, string>;
|
|
15
10
|
maxBatchSizeBytes?: number;
|
|
16
11
|
}
|
|
17
12
|
export declare function createObservability(options?: EventhouseObservabilityOptions): Observability;
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EventstreamExporter,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
createObservability,
|
|
6
|
-
redactSecrets,
|
|
7
|
-
serializeSpan
|
|
8
|
-
} from "./chunk-XQFUPGYU.js";
|
|
3
|
+
createObservability
|
|
4
|
+
} from "./chunk-XGCHW72B.js";
|
|
9
5
|
export {
|
|
10
6
|
EventstreamExporter,
|
|
11
|
-
|
|
12
|
-
createEngine,
|
|
13
|
-
createObservability,
|
|
14
|
-
redactSecrets,
|
|
15
|
-
serializeSpan
|
|
7
|
+
createObservability
|
|
16
8
|
};
|
|
17
9
|
//# sourceMappingURL=index.js.map
|
package/dist/openai.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type OpenAI from "openai";
|
|
2
|
+
import { type OpenAIAttachOptions, type OpenAIObserver } from "./adapters/openai.js";
|
|
3
|
+
import { type EventhouseObservabilityOptions, type Observability } from "./index.js";
|
|
4
|
+
export { attachOpenAI } from "./adapters/openai.js";
|
|
5
|
+
export type { OpenAIAttachOptions, OpenAIObserver } from "./adapters/openai.js";
|
|
6
|
+
export type OpenAIObservabilityOptions = OpenAIAttachOptions & ((EventhouseObservabilityOptions & {
|
|
7
|
+
engine?: never;
|
|
8
|
+
}) | {
|
|
9
|
+
engine: Observability;
|
|
10
|
+
});
|
|
11
|
+
/** Newly constructed engines are owned; supplied engines are external by default. */
|
|
12
|
+
export declare function observeOpenAI<T extends OpenAI>(client: T, options?: OpenAIObservabilityOptions): OpenAIObserver<T>;
|