opik-otel 2.0.19

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/README.md ADDED
@@ -0,0 +1,59 @@
1
+ # Opik OpenTelemetry Integration
2
+
3
+ [![npm version](https://img.shields.io/npm/v/opik-otel.svg)](https://www.npmjs.com/package/opik-otel)
4
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/comet-ml/opik/blob/main/LICENSE)
5
+
6
+ Bridge [OpenTelemetry](https://opentelemetry.io/) traces produced by your services into [Opik](https://www.comet.com/docs/opik/) so spans land under the correct Opik trace and parent span.
7
+
8
+ ## Features
9
+
10
+ - 🔗 **`attachToParent`** — read `opik_trace_id` / `opik_parent_span_id` HTTP headers and stamp the matching attributes on an OpenTelemetry boundary span
11
+ - 🌳 **`OpikSpanProcessor`** — propagate Opik IDs down an entire OTel subtree so descendants of the boundary span are linked to the same Opik trace and chain of parents
12
+ - 🧰 **Header constants & types** — `OPIK_TRACE_ID`, `OPIK_SPAN_ID`, `OPIK_PARENT_SPAN_ID`, `OpikDistributedTraceAttributes`
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ # npm
18
+ npm install opik-otel
19
+
20
+ # yarn
21
+ yarn add opik-otel
22
+
23
+ # pnpm
24
+ pnpm add opik-otel
25
+ ```
26
+
27
+ ### Requirements
28
+
29
+ - Node.js ≥ 18
30
+ - `@opentelemetry/api` ≥ 1.9
31
+ - `@opentelemetry/sdk-trace-base` ≥ 1.30 (or v2)
32
+ - Opik SDK (`opik` peer dependency)
33
+
34
+ ## Quick Start
35
+
36
+ ```typescript
37
+ import { trace } from "@opentelemetry/api";
38
+ import {
39
+ BasicTracerProvider,
40
+ BatchSpanProcessor,
41
+ } from "@opentelemetry/sdk-trace-base";
42
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
43
+ import { attachToParent, OpikSpanProcessor } from "opik-otel";
44
+
45
+ const provider = new BasicTracerProvider();
46
+ provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter()));
47
+ provider.addSpanProcessor(new OpikSpanProcessor());
48
+ provider.register();
49
+
50
+ const tracer = trace.getTracer("my-service");
51
+
52
+ // On every incoming request:
53
+ const span = tracer.startSpan("server-span");
54
+ attachToParent(span, request.headers);
55
+ // ... handle the request; descendant spans inherit Opik IDs automatically
56
+ span.end();
57
+ ```
58
+
59
+ See the Opik documentation on [distributed traces with OpenTelemetry](https://www.comet.com/docs/opik/tracing/advanced/log_distributed_traces#distributed-traces-with-a-remote-service-using-opentelemetry) for the full client/server pattern.
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ 'use strict';var opik=require('opik'),uuid=require('uuid'),api=require('@opentelemetry/api');var o="opik.trace_id",s="opik.span_id",p="opik.parent_span_id";var u=class{constructor(e,t){this.opikTraceId=e,this.opikParentSpanId=t;}asAttributes(){let e={[o]:this.opikTraceId};return this.opikParentSpanId!==void 0&&(e[p]=this.opikParentSpanId),e}};var I="opik_trace_id",l="opik_parent_span_id",d=r=>typeof r!="string"||!uuid.validate(r)?false:uuid.version(r)===7;function k(r,e){let t=e.toLowerCase();if(typeof r[Symbol.iterator]=="function"){for(let[n,a]of r)if(n.toLowerCase()===t)return a;return}let i=r;for(let[n,a]of Object.entries(i))if(n.toLowerCase()===t)return Array.isArray(a)?a[0]:a}function O(r){var i,n;let e=(i=k(r,I))==null?void 0:i.trim(),t=((n=k(r,l))==null?void 0:n.trim())||void 0;return e?d(e)?(t!==void 0&&!d(t)&&(opik.logger.warn(`Opik distributed trace header '${l}' is not a valid UUIDv7; ignoring parent span id.`),t=void 0),new u(e,t)):(opik.logger.warn(`Opik distributed trace header '${I}' is not a valid UUIDv7; skipping distributed trace processing.`),null):(t!==void 0&&opik.logger.warn(`Opik distributed trace header '${I}' is missing while '${l}' is provided; skipping distributed trace processing.`),null)}function x(r,e){let t=O(e);if(t===null)return false;let i=t.asAttributes();return i[s]=opik.generateId(),r.setAttributes(i),true}function N(r){var m,A,S;let e=api.trace.getSpan(r);if(e&&"attributes"in e){let b=(m=e.attributes)!=null?m:{},f=b[o],g=b[s];if(f!==void 0||g!==void 0)if(!d(f))opik.logger.warn(`Parent span attribute '${o}' is missing or not a valid UUIDv7: ${JSON.stringify(f)}; ignoring inherited Opik context.`);else if(!d(g))opik.logger.warn(`Parent span attribute '${s}' is missing or not a valid UUIDv7: ${JSON.stringify(g)}; ignoring inherited Opik context.`);else return {traceId:f,parentSpanId:g}}let t=api.propagation.getBaggage(r),i=(A=t==null?void 0:t.getEntry(o))==null?void 0:A.value;if(i===void 0)return;if(!d(i)){opik.logger.warn(`Baggage value for '${o}' is not a valid UUIDv7: ${JSON.stringify(i)}; ignoring.`);return}let n=(S=t==null?void 0:t.getEntry(s))==null?void 0:S.value,a;return n===void 0?a=void 0:d(n)?a=n:(opik.logger.warn(`Baggage value for '${s}' is not a valid UUIDv7: ${JSON.stringify(n)}; attaching to '${o}' without a parent span id.`),a=void 0),{traceId:i,parentSpanId:a}}var P=class{onStart(e,t){let i=N(t);if(i)try{e.setAttribute(o,i.traceId),e.setAttribute(s,opik.generateId()),i.parentSpanId!==void 0&&e.setAttribute(p,i.parentSpanId);}catch(n){opik.logger.debug("OpikSpanProcessor.onStart failed:",n);}}onEnd(){}async forceFlush(){}async shutdown(){}};exports.OPIK_PARENT_SPAN_ID=p;exports.OPIK_SPAN_ID=s;exports.OPIK_TRACE_ID=o;exports.OpikDistributedTraceAttributes=u;exports.OpikSpanProcessor=P;exports.attachToParent=x;exports.extractOpikDistributedTraceAttributes=O;
@@ -0,0 +1,114 @@
1
+ import { Span, Context } from '@opentelemetry/api';
2
+ import { SpanProcessor } from '@opentelemetry/sdk-trace-base';
3
+
4
+ /**
5
+ * Represents distributed trace attributes for the OPIK tracing system.
6
+ *
7
+ * This class provides a structured way to handle distributed trace attributes,
8
+ * specifically the trace ID and parent span ID. It exposes a method to convert
9
+ * those attributes into a plain object suitable for use as OpenTelemetry span
10
+ * attributes.
11
+ */
12
+ declare class OpikDistributedTraceAttributes {
13
+ private readonly opikTraceId;
14
+ private readonly opikParentSpanId?;
15
+ /**
16
+ * @param opikTraceId The unique identifier for the trace.
17
+ * @param opikParentSpanId The identifier for the parent span in the trace,
18
+ * or undefined if this is the root span.
19
+ */
20
+ constructor(opikTraceId: string, opikParentSpanId?: string);
21
+ /**
22
+ * Converts the distributed trace attributes into a plain object suitable
23
+ * for OpenTelemetry `Span.setAttributes`.
24
+ */
25
+ asAttributes(): Record<string, string>;
26
+ }
27
+
28
+ /**
29
+ * Minimal structural type for an OpenTelemetry `Span`. Only the
30
+ * `setAttributes` method is required for distributed-trace propagation, so we
31
+ * avoid taking a runtime dependency on `@opentelemetry/api`. Any object that
32
+ * implements this method — including `import("@opentelemetry/api").Span` — is
33
+ * accepted.
34
+ */
35
+ interface OpenTelemetrySpanLike {
36
+ setAttributes(attributes: Record<string, string>): unknown;
37
+ }
38
+ /**
39
+ * Headers carrying Opik distributed trace context. Accepts both plain
40
+ * dictionaries and any iterable of `[name, value]` pairs (e.g. the WHATWG
41
+ * `Headers` object).
42
+ */
43
+ type HttpHeadersLike = Record<string, string | string[] | undefined> | Iterable<[string, string]>;
44
+ /**
45
+ * Extracts Opik distributed trace attributes from HTTP headers.
46
+ *
47
+ * Reads `opik_trace_id` and the optional `opik_parent_span_id` headers
48
+ * (case-insensitive). Values are trimmed; if `opik_trace_id` is missing,
49
+ * empty, whitespace-only, or not a valid UUID the function logs a warning
50
+ * (when invalid, or when `opik_parent_span_id` was provided without a
51
+ * `opik_trace_id`) and returns `null`. If `opik_parent_span_id` is present
52
+ * but not a valid UUID it is dropped with a warning and the trace is still
53
+ * attached using the valid `opik_trace_id`.
54
+ */
55
+ declare function extractOpikDistributedTraceAttributes(httpHeaders: HttpHeadersLike): OpikDistributedTraceAttributes | null;
56
+ /**
57
+ * Attaches an Opik distributed trace parent to the provided OpenTelemetry
58
+ * span by extracting trace context from HTTP headers and setting the
59
+ * corresponding span attributes.
60
+ *
61
+ * @returns `true` if headers were found and attributes were set, `false`
62
+ * otherwise.
63
+ */
64
+ declare function attachToParent(span: OpenTelemetrySpanLike, httpHeaders: HttpHeadersLike): boolean;
65
+
66
+ /**
67
+ * OTel `SpanProcessor` that propagates Opik IDs down an attached subtree.
68
+ *
69
+ * `attachToParent` only sets `opik.trace_id` / `opik.parent_span_id` /
70
+ * `opik.span_id` on the *boundary* OTel span. Children created inside that
71
+ * span inherit OTel context but not those attributes, so without this
72
+ * processor descendants would be orphaned in a synthetic Opik trace by the
73
+ * backend.
74
+ *
75
+ * On every span start this processor inspects the parent OTel span (and OTel
76
+ * baggage, for cross-process boundaries). If the parent already carries
77
+ * `opik.trace_id` + `opik.span_id`, it mints a fresh `opik.span_id` for the
78
+ * new span and threads the parent's value as `opik.parent_span_id`. The
79
+ * backend `OpenTelemetryMapper` fast path then uses these UUIDs verbatim.
80
+ *
81
+ * Spans whose parent has no Opik attributes (and no baggage) are left
82
+ * untouched, so today's SHA-256 + Redis path still applies — the processor
83
+ * only kicks in for attached subtrees originating from `attachToParent`.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
88
+ * import { OpikSpanProcessor } from "opik-otel";
89
+ *
90
+ * const provider = new BasicTracerProvider();
91
+ * provider.addSpanProcessor(new OpikSpanProcessor());
92
+ * // ... add your exporter processor as well
93
+ * ```
94
+ */
95
+ declare class OpikSpanProcessor implements SpanProcessor {
96
+ onStart(span: Span, parentContext: Context): void;
97
+ onEnd(): void;
98
+ forceFlush(): Promise<void>;
99
+ shutdown(): Promise<void>;
100
+ }
101
+
102
+ /**
103
+ * Canonical OTel attribute keys for Opik distributed tracing.
104
+ *
105
+ * These are the attribute names set on OpenTelemetry spans (and read by the
106
+ * Opik backend's `OpenTelemetryMapper`). They mirror the constants in
107
+ * `GeneralMappingRules.java` on the backend side and `attributes.py` in the
108
+ * Python SDK.
109
+ */
110
+ declare const OPIK_TRACE_ID = "opik.trace_id";
111
+ declare const OPIK_SPAN_ID = "opik.span_id";
112
+ declare const OPIK_PARENT_SPAN_ID = "opik.parent_span_id";
113
+
114
+ export { type HttpHeadersLike, OPIK_PARENT_SPAN_ID, OPIK_SPAN_ID, OPIK_TRACE_ID, type OpenTelemetrySpanLike, OpikDistributedTraceAttributes, OpikSpanProcessor, attachToParent, extractOpikDistributedTraceAttributes };
@@ -0,0 +1,114 @@
1
+ import { Span, Context } from '@opentelemetry/api';
2
+ import { SpanProcessor } from '@opentelemetry/sdk-trace-base';
3
+
4
+ /**
5
+ * Represents distributed trace attributes for the OPIK tracing system.
6
+ *
7
+ * This class provides a structured way to handle distributed trace attributes,
8
+ * specifically the trace ID and parent span ID. It exposes a method to convert
9
+ * those attributes into a plain object suitable for use as OpenTelemetry span
10
+ * attributes.
11
+ */
12
+ declare class OpikDistributedTraceAttributes {
13
+ private readonly opikTraceId;
14
+ private readonly opikParentSpanId?;
15
+ /**
16
+ * @param opikTraceId The unique identifier for the trace.
17
+ * @param opikParentSpanId The identifier for the parent span in the trace,
18
+ * or undefined if this is the root span.
19
+ */
20
+ constructor(opikTraceId: string, opikParentSpanId?: string);
21
+ /**
22
+ * Converts the distributed trace attributes into a plain object suitable
23
+ * for OpenTelemetry `Span.setAttributes`.
24
+ */
25
+ asAttributes(): Record<string, string>;
26
+ }
27
+
28
+ /**
29
+ * Minimal structural type for an OpenTelemetry `Span`. Only the
30
+ * `setAttributes` method is required for distributed-trace propagation, so we
31
+ * avoid taking a runtime dependency on `@opentelemetry/api`. Any object that
32
+ * implements this method — including `import("@opentelemetry/api").Span` — is
33
+ * accepted.
34
+ */
35
+ interface OpenTelemetrySpanLike {
36
+ setAttributes(attributes: Record<string, string>): unknown;
37
+ }
38
+ /**
39
+ * Headers carrying Opik distributed trace context. Accepts both plain
40
+ * dictionaries and any iterable of `[name, value]` pairs (e.g. the WHATWG
41
+ * `Headers` object).
42
+ */
43
+ type HttpHeadersLike = Record<string, string | string[] | undefined> | Iterable<[string, string]>;
44
+ /**
45
+ * Extracts Opik distributed trace attributes from HTTP headers.
46
+ *
47
+ * Reads `opik_trace_id` and the optional `opik_parent_span_id` headers
48
+ * (case-insensitive). Values are trimmed; if `opik_trace_id` is missing,
49
+ * empty, whitespace-only, or not a valid UUID the function logs a warning
50
+ * (when invalid, or when `opik_parent_span_id` was provided without a
51
+ * `opik_trace_id`) and returns `null`. If `opik_parent_span_id` is present
52
+ * but not a valid UUID it is dropped with a warning and the trace is still
53
+ * attached using the valid `opik_trace_id`.
54
+ */
55
+ declare function extractOpikDistributedTraceAttributes(httpHeaders: HttpHeadersLike): OpikDistributedTraceAttributes | null;
56
+ /**
57
+ * Attaches an Opik distributed trace parent to the provided OpenTelemetry
58
+ * span by extracting trace context from HTTP headers and setting the
59
+ * corresponding span attributes.
60
+ *
61
+ * @returns `true` if headers were found and attributes were set, `false`
62
+ * otherwise.
63
+ */
64
+ declare function attachToParent(span: OpenTelemetrySpanLike, httpHeaders: HttpHeadersLike): boolean;
65
+
66
+ /**
67
+ * OTel `SpanProcessor` that propagates Opik IDs down an attached subtree.
68
+ *
69
+ * `attachToParent` only sets `opik.trace_id` / `opik.parent_span_id` /
70
+ * `opik.span_id` on the *boundary* OTel span. Children created inside that
71
+ * span inherit OTel context but not those attributes, so without this
72
+ * processor descendants would be orphaned in a synthetic Opik trace by the
73
+ * backend.
74
+ *
75
+ * On every span start this processor inspects the parent OTel span (and OTel
76
+ * baggage, for cross-process boundaries). If the parent already carries
77
+ * `opik.trace_id` + `opik.span_id`, it mints a fresh `opik.span_id` for the
78
+ * new span and threads the parent's value as `opik.parent_span_id`. The
79
+ * backend `OpenTelemetryMapper` fast path then uses these UUIDs verbatim.
80
+ *
81
+ * Spans whose parent has no Opik attributes (and no baggage) are left
82
+ * untouched, so today's SHA-256 + Redis path still applies — the processor
83
+ * only kicks in for attached subtrees originating from `attachToParent`.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
88
+ * import { OpikSpanProcessor } from "opik-otel";
89
+ *
90
+ * const provider = new BasicTracerProvider();
91
+ * provider.addSpanProcessor(new OpikSpanProcessor());
92
+ * // ... add your exporter processor as well
93
+ * ```
94
+ */
95
+ declare class OpikSpanProcessor implements SpanProcessor {
96
+ onStart(span: Span, parentContext: Context): void;
97
+ onEnd(): void;
98
+ forceFlush(): Promise<void>;
99
+ shutdown(): Promise<void>;
100
+ }
101
+
102
+ /**
103
+ * Canonical OTel attribute keys for Opik distributed tracing.
104
+ *
105
+ * These are the attribute names set on OpenTelemetry spans (and read by the
106
+ * Opik backend's `OpenTelemetryMapper`). They mirror the constants in
107
+ * `GeneralMappingRules.java` on the backend side and `attributes.py` in the
108
+ * Python SDK.
109
+ */
110
+ declare const OPIK_TRACE_ID = "opik.trace_id";
111
+ declare const OPIK_SPAN_ID = "opik.span_id";
112
+ declare const OPIK_PARENT_SPAN_ID = "opik.parent_span_id";
113
+
114
+ export { type HttpHeadersLike, OPIK_PARENT_SPAN_ID, OPIK_SPAN_ID, OPIK_TRACE_ID, type OpenTelemetrySpanLike, OpikDistributedTraceAttributes, OpikSpanProcessor, attachToParent, extractOpikDistributedTraceAttributes };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import {logger,generateId}from'opik';import {validate,version}from'uuid';import {trace,propagation}from'@opentelemetry/api';var o="opik.trace_id",s="opik.span_id",p="opik.parent_span_id";var u=class{constructor(e,t){this.opikTraceId=e,this.opikParentSpanId=t;}asAttributes(){let e={[o]:this.opikTraceId};return this.opikParentSpanId!==void 0&&(e[p]=this.opikParentSpanId),e}};var I="opik_trace_id",l="opik_parent_span_id",d=r=>typeof r!="string"||!validate(r)?false:version(r)===7;function k(r,e){let t=e.toLowerCase();if(typeof r[Symbol.iterator]=="function"){for(let[n,a]of r)if(n.toLowerCase()===t)return a;return}let i=r;for(let[n,a]of Object.entries(i))if(n.toLowerCase()===t)return Array.isArray(a)?a[0]:a}function O(r){var i,n;let e=(i=k(r,I))==null?void 0:i.trim(),t=((n=k(r,l))==null?void 0:n.trim())||void 0;return e?d(e)?(t!==void 0&&!d(t)&&(logger.warn(`Opik distributed trace header '${l}' is not a valid UUIDv7; ignoring parent span id.`),t=void 0),new u(e,t)):(logger.warn(`Opik distributed trace header '${I}' is not a valid UUIDv7; skipping distributed trace processing.`),null):(t!==void 0&&logger.warn(`Opik distributed trace header '${I}' is missing while '${l}' is provided; skipping distributed trace processing.`),null)}function x(r,e){let t=O(e);if(t===null)return false;let i=t.asAttributes();return i[s]=generateId(),r.setAttributes(i),true}function N(r){var m,A,S;let e=trace.getSpan(r);if(e&&"attributes"in e){let b=(m=e.attributes)!=null?m:{},f=b[o],g=b[s];if(f!==void 0||g!==void 0)if(!d(f))logger.warn(`Parent span attribute '${o}' is missing or not a valid UUIDv7: ${JSON.stringify(f)}; ignoring inherited Opik context.`);else if(!d(g))logger.warn(`Parent span attribute '${s}' is missing or not a valid UUIDv7: ${JSON.stringify(g)}; ignoring inherited Opik context.`);else return {traceId:f,parentSpanId:g}}let t=propagation.getBaggage(r),i=(A=t==null?void 0:t.getEntry(o))==null?void 0:A.value;if(i===void 0)return;if(!d(i)){logger.warn(`Baggage value for '${o}' is not a valid UUIDv7: ${JSON.stringify(i)}; ignoring.`);return}let n=(S=t==null?void 0:t.getEntry(s))==null?void 0:S.value,a;return n===void 0?a=void 0:d(n)?a=n:(logger.warn(`Baggage value for '${s}' is not a valid UUIDv7: ${JSON.stringify(n)}; attaching to '${o}' without a parent span id.`),a=void 0),{traceId:i,parentSpanId:a}}var P=class{onStart(e,t){let i=N(t);if(i)try{e.setAttribute(o,i.traceId),e.setAttribute(s,generateId()),i.parentSpanId!==void 0&&e.setAttribute(p,i.parentSpanId);}catch(n){logger.debug("OpikSpanProcessor.onStart failed:",n);}}onEnd(){}async forceFlush(){}async shutdown(){}};export{p as OPIK_PARENT_SPAN_ID,s as OPIK_SPAN_ID,o as OPIK_TRACE_ID,u as OpikDistributedTraceAttributes,P as OpikSpanProcessor,x as attachToParent,O as extractOpikDistributedTraceAttributes};
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "opik-otel",
3
+ "description": "Opik TypeScript and JavaScript SDK integration with OpenTelemetry",
4
+ "version": "2.0.19",
5
+ "engines": {
6
+ "node": ">=18"
7
+ },
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/comet-ml/opik.git",
11
+ "directory": "sdks/typescript/src/opik/integrations/opik-otel"
12
+ },
13
+ "homepage": "https://www.comet.com/docs/opik/",
14
+ "author": {
15
+ "name": "Comet",
16
+ "email": "support@comet.com",
17
+ "url": "https://github.com/comet-ml"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/comet-ml/opik/issues",
21
+ "email": "support@comet.com"
22
+ },
23
+ "license": "Apache-2.0",
24
+ "keywords": [
25
+ "opik",
26
+ "opentelemetry",
27
+ "otel",
28
+ "tracing",
29
+ "distributed-tracing",
30
+ "sdk",
31
+ "javascript",
32
+ "javascript-sdk",
33
+ "typescript",
34
+ "typescript-sdk",
35
+ "comet"
36
+ ],
37
+ "exports": {
38
+ "./package.json": "./package.json",
39
+ ".": {
40
+ "types": "./dist/index.d.ts",
41
+ "import": "./dist/index.js",
42
+ "require": "./dist/index.cjs"
43
+ }
44
+ },
45
+ "main": "dist/index.cjs",
46
+ "module": "dist/index.js",
47
+ "types": "dist/index.d.ts",
48
+ "type": "module",
49
+ "scripts": {
50
+ "build": "tsup",
51
+ "watch": "tsup --watch",
52
+ "lint": "eslint '**/*.{ts,tsx}'",
53
+ "typecheck": "tsc --noEmit",
54
+ "format": "prettier --write 'src/**/*.{ts,tsx,js,jsx,json,md}'",
55
+ "test": "vitest run"
56
+ },
57
+ "files": [
58
+ "dist/**/*",
59
+ "README.md"
60
+ ],
61
+ "peerDependencies": {
62
+ "@opentelemetry/api": "^1.9.0",
63
+ "@opentelemetry/sdk-trace-base": "^1.30.0 || ^2.0.0",
64
+ "opik": "^2.0.15"
65
+ },
66
+ "dependencies": {
67
+ "uuid": "^11.0.3"
68
+ },
69
+ "devDependencies": {
70
+ "@eslint/js": "^9.20.0",
71
+ "@opentelemetry/api": "^1.9.0",
72
+ "@opentelemetry/sdk-trace-base": "^2.7.0",
73
+ "@types/uuid": "^10.0.0",
74
+ "eslint": "^9.34.0",
75
+ "globals": "^15.14.0",
76
+ "prettier": "^3.6.2",
77
+ "tsup": "^8.5.0",
78
+ "typescript": "^5.9.2",
79
+ "typescript-eslint": "^8.42.0",
80
+ "vitest": "^3.0.5"
81
+ }
82
+ }