agentfootprint 2.8.3 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ /**
3
+ * otelObservability — OpenTelemetry distributed-tracing adapter.
4
+ *
5
+ * Ships every agentfootprint event as OpenTelemetry spans + log
6
+ * records via a consumer-supplied OTel API. Same hierarchical
7
+ * mapping as the X-Ray adapter, but the destination is whichever
8
+ * OTel-compat backend the consumer's SDK exports to:
9
+ *
10
+ * - **Honeycomb** (OTLP/HTTP)
11
+ * - **Grafana Cloud / Tempo / Mimir** (OTLP)
12
+ * - **AWS Distro for OTel** → AWS X-Ray (alternative to xrayObservability)
13
+ * - **Datadog APM** (OTLP endpoint)
14
+ * - **Splunk Observability Cloud** (OTLP)
15
+ * - **New Relic** (OTLP endpoint)
16
+ * - **Lightstep / ServiceNow Cloud Observability** (OTLP)
17
+ * - any custom OTel collector / processor pipeline
18
+ *
19
+ * Subpath: `agentfootprint/observability-providers`
20
+ * Peer dep: `@opentelemetry/api` (OPTIONAL — installed only when
21
+ * this adapter is used. The consumer ALSO installs the
22
+ * OTel SDK + exporter of their choice — that's the BYO
23
+ * contract that makes this adapter backend-agnostic.).
24
+ *
25
+ * **Why BYO SDK:** OTel's SDK is heavyweight and exporter-specific
26
+ * (each backend has its own exporter package). Forcing a particular
27
+ * exporter would defeat the "OTel is portable" guarantee. Consumers
28
+ * configure the SDK + exporter once at app startup; we just speak
29
+ * the typed OTel API.
30
+ *
31
+ * Mapping:
32
+ *
33
+ * agent.turn_start ↦ start root span (one trace per turn)
34
+ * agent.turn_end ↦ end root span
35
+ * agent.iteration_start ↦ start child span under root
36
+ * agent.iteration_end ↦ end iteration span
37
+ * stream.llm_start ↦ start child span (model call)
38
+ * stream.llm_end ↦ end llm span
39
+ * stream.tool_start ↦ start child span (tool call)
40
+ * stream.tool_end ↦ end tool span (with `error: true` if errored)
41
+ * cost.tick ↦ setAttribute on topmost active span
42
+ *
43
+ * @example Basic — Honeycomb via OTLP
44
+ * ```ts
45
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
46
+ * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
47
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
48
+ * import { trace } from '@opentelemetry/api';
49
+ * import { otelObservability } from 'agentfootprint/observability-providers';
50
+ *
51
+ * // Set up OTel ONCE at app startup.
52
+ * const provider = new NodeTracerProvider();
53
+ * provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter({
54
+ * url: 'https://api.honeycomb.io/v1/traces',
55
+ * headers: { 'x-honeycomb-team': process.env.HONEYCOMB_KEY },
56
+ * })));
57
+ * provider.register();
58
+ *
59
+ * agent.enable.observability({
60
+ * strategy: otelObservability({
61
+ * serviceName: 'my-agent',
62
+ * // tracer optional — defaults to trace.getTracer('agentfootprint').
63
+ * }),
64
+ * });
65
+ * ```
66
+ *
67
+ * @example Test injection
68
+ * ```ts
69
+ * otelObservability({
70
+ * serviceName: 'test',
71
+ * tracer: mockTracer, // anything matching the OTel Tracer interface
72
+ * });
73
+ * ```
74
+ */
75
+ Object.defineProperty(exports, "__esModule", { value: true });
76
+ exports.otelObservability = void 0;
77
+ const lazyRequire_js_1 = require("../../lib/lazyRequire.js");
78
+ // ─── Strategy factory ────────────────────────────────────────────────
79
+ function otelObservability(opts) {
80
+ if (!opts.serviceName) {
81
+ throw new TypeError(`[otelObservability] \`serviceName\` is required. ` +
82
+ `Pass an identifier visible in your OTel backend's service map, e.g. 'my-agent-prod'.`);
83
+ }
84
+ const sampleRate = opts.sampleRate ?? 1;
85
+ // Lazy-resolve tracer if not injected. Defer the API import until
86
+ // first event so consumers who don't actually fire events (no agent
87
+ // run yet) don't even hit the OTel API surface.
88
+ let tracer = opts.tracer;
89
+ let otelApi;
90
+ function ensureTracer() {
91
+ if (tracer)
92
+ return tracer;
93
+ if (!otelApi) {
94
+ try {
95
+ otelApi = (0, lazyRequire_js_1.lazyRequire)('@opentelemetry/api');
96
+ }
97
+ catch {
98
+ throw new Error('otelObservability requires the `@opentelemetry/api` peer dependency.\n' +
99
+ ' Install: npm install @opentelemetry/api\n' +
100
+ ' Plus an OTel SDK + exporter for your backend (e.g.,\n' +
101
+ ' `@opentelemetry/sdk-trace-node` + `@opentelemetry/exporter-trace-otlp-http`).\n' +
102
+ ' Or pass `tracer` for test injection.');
103
+ }
104
+ }
105
+ if (!otelApi.trace?.getTracer) {
106
+ throw new Error('otelObservability: `@opentelemetry/api` is installed but `trace.getTracer` not found. Update the package.');
107
+ }
108
+ tracer = otelApi.trace.getTracer('agentfootprint');
109
+ return tracer;
110
+ }
111
+ // Per-turn state — same pattern as xrayObservability. Events for
112
+ // multiple in-flight turns interleave correctly because we key by
113
+ // `runId` from the event payload.
114
+ const activeTurns = new Map();
115
+ let stopped = false;
116
+ let onErrorHook;
117
+ function pushSpan(turnState, name, attrs) {
118
+ // OTel parent-context wiring: we capture the parent in a context
119
+ // and start the new span under it. (For BYO SDK setups, the
120
+ // `trace.setSpan` + `context.with` pattern is canonical. For
121
+ // the test-injected tracer path, we just pass the parent as
122
+ // implicit context.)
123
+ const parent = turnState.stack[turnState.stack.length - 1]?.span;
124
+ let ctx;
125
+ if (parent && otelApi?.trace?.setSpan && otelApi?.context?.active) {
126
+ ctx = otelApi.trace.setSpan(otelApi.context.active(), parent);
127
+ }
128
+ const span = ensureTracer().startSpan(name, attrs ? { attributes: attrs } : undefined, ctx);
129
+ turnState.stack.push({ name, span });
130
+ return span;
131
+ }
132
+ function popSpan(turnState, expectedName) {
133
+ let idx = turnState.stack.length - 1;
134
+ if (expectedName) {
135
+ while (idx >= 0 && turnState.stack[idx].name !== expectedName)
136
+ idx--;
137
+ }
138
+ if (idx < 0)
139
+ return undefined;
140
+ return turnState.stack.splice(idx, 1)[0].span;
141
+ }
142
+ function endSpan(span, opts) {
143
+ if (opts?.error) {
144
+ const code = otelApi?.SpanStatusCode?.ERROR ?? 2;
145
+ try {
146
+ span.setStatus({ code });
147
+ }
148
+ catch {
149
+ /* mock tracers may not implement setStatus — ignore */
150
+ }
151
+ }
152
+ span.end();
153
+ }
154
+ // ─── Event-to-span dispatch ────────────────────────────────────────
155
+ function handleEvent(event) {
156
+ if (stopped)
157
+ return;
158
+ const runId = event.payload?.runId;
159
+ if (!runId)
160
+ return; // Events without a turn anchor — skip.
161
+ switch (event.type) {
162
+ case 'agentfootprint.agent.turn_start': {
163
+ const sampled = sampleRate >= 1 || Math.random() < sampleRate;
164
+ const turnState = { stack: [], sampled };
165
+ activeTurns.set(runId, turnState);
166
+ if (sampled)
167
+ pushSpan(turnState, opts.serviceName, { 'service.name': opts.serviceName });
168
+ break;
169
+ }
170
+ case 'agentfootprint.agent.turn_end': {
171
+ const t = activeTurns.get(runId);
172
+ if (!t)
173
+ break;
174
+ // Defensive: end everything still on the stack.
175
+ while (t.stack.length > 0) {
176
+ const span = popSpan(t);
177
+ if (span)
178
+ endSpan(span);
179
+ }
180
+ activeTurns.delete(runId);
181
+ break;
182
+ }
183
+ case 'agentfootprint.agent.iteration_start': {
184
+ const t = activeTurns.get(runId);
185
+ if (t?.sampled) {
186
+ const iteration = event.payload.iteration;
187
+ pushSpan(t, `iteration:${iteration ?? '?'}`, {
188
+ ...(typeof iteration === 'number' && { 'iteration.number': iteration }),
189
+ });
190
+ }
191
+ break;
192
+ }
193
+ case 'agentfootprint.agent.iteration_end': {
194
+ const t = activeTurns.get(runId);
195
+ if (t?.sampled) {
196
+ const span = popSpan(t);
197
+ if (span)
198
+ endSpan(span);
199
+ }
200
+ break;
201
+ }
202
+ case 'agentfootprint.stream.llm_start': {
203
+ const t = activeTurns.get(runId);
204
+ if (!t?.sampled)
205
+ break;
206
+ const model = event.payload.model;
207
+ pushSpan(t, 'llm', model ? { 'gen_ai.request.model': model } : undefined);
208
+ break;
209
+ }
210
+ case 'agentfootprint.stream.llm_end': {
211
+ const t = activeTurns.get(runId);
212
+ if (!t?.sampled)
213
+ break;
214
+ const span = popSpan(t, 'llm');
215
+ if (span)
216
+ endSpan(span);
217
+ break;
218
+ }
219
+ case 'agentfootprint.stream.tool_start': {
220
+ const t = activeTurns.get(runId);
221
+ if (!t?.sampled)
222
+ break;
223
+ const toolName = event.payload.toolName ?? 'tool';
224
+ pushSpan(t, `tool:${toolName}`, { 'tool.name': toolName });
225
+ break;
226
+ }
227
+ case 'agentfootprint.stream.tool_end': {
228
+ const t = activeTurns.get(runId);
229
+ if (!t?.sampled)
230
+ break;
231
+ const toolName = event.payload.toolName;
232
+ const errored = event.payload.error !== undefined;
233
+ const span = popSpan(t, toolName ? `tool:${toolName}` : undefined);
234
+ if (span)
235
+ endSpan(span, { error: errored });
236
+ break;
237
+ }
238
+ // Other events — annotate the topmost active span.
239
+ default: {
240
+ const t = activeTurns.get(runId);
241
+ const top = t?.stack[t.stack.length - 1]?.span;
242
+ if (!t?.sampled || !top)
243
+ break;
244
+ // Cost ticks are particularly valuable as attributes.
245
+ if (event.type === 'agentfootprint.cost.tick') {
246
+ const p = event.payload;
247
+ if (typeof p.cumulativeCostUsd === 'number') {
248
+ try {
249
+ top.setAttribute('cost.cumulative_usd', p.cumulativeCostUsd);
250
+ }
251
+ catch {
252
+ /* ignore */
253
+ }
254
+ }
255
+ }
256
+ break;
257
+ }
258
+ }
259
+ }
260
+ return {
261
+ name: 'otel',
262
+ capabilities: { events: true, traces: true },
263
+ exportEvent: handleEvent,
264
+ flush() {
265
+ // OTel SDKs handle their own flushing (the consumer-configured
266
+ // SpanProcessor's `forceFlush()`). We don't cross that boundary
267
+ // here — calling `provider.forceFlush()` is the consumer's
268
+ // responsibility on shutdown. Documented in the README.
269
+ },
270
+ stop() {
271
+ stopped = true;
272
+ // Defensive: end any spans the agent loop didn't close.
273
+ for (const [, t] of activeTurns) {
274
+ while (t.stack.length > 0) {
275
+ const span = popSpan(t);
276
+ if (span)
277
+ endSpan(span);
278
+ }
279
+ }
280
+ activeTurns.clear();
281
+ },
282
+ _onError(err, event) {
283
+ onErrorHook =
284
+ onErrorHook ??
285
+ ((e) => {
286
+ // eslint-disable-next-line no-console
287
+ console.error(`[otelObservability] error:`, e.message);
288
+ });
289
+ onErrorHook(err, event);
290
+ },
291
+ };
292
+ }
293
+ exports.otelObservability = otelObservability;
294
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../../src/adapters/observability/otel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,290 @@
1
+ /**
2
+ * otelObservability — OpenTelemetry distributed-tracing adapter.
3
+ *
4
+ * Ships every agentfootprint event as OpenTelemetry spans + log
5
+ * records via a consumer-supplied OTel API. Same hierarchical
6
+ * mapping as the X-Ray adapter, but the destination is whichever
7
+ * OTel-compat backend the consumer's SDK exports to:
8
+ *
9
+ * - **Honeycomb** (OTLP/HTTP)
10
+ * - **Grafana Cloud / Tempo / Mimir** (OTLP)
11
+ * - **AWS Distro for OTel** → AWS X-Ray (alternative to xrayObservability)
12
+ * - **Datadog APM** (OTLP endpoint)
13
+ * - **Splunk Observability Cloud** (OTLP)
14
+ * - **New Relic** (OTLP endpoint)
15
+ * - **Lightstep / ServiceNow Cloud Observability** (OTLP)
16
+ * - any custom OTel collector / processor pipeline
17
+ *
18
+ * Subpath: `agentfootprint/observability-providers`
19
+ * Peer dep: `@opentelemetry/api` (OPTIONAL — installed only when
20
+ * this adapter is used. The consumer ALSO installs the
21
+ * OTel SDK + exporter of their choice — that's the BYO
22
+ * contract that makes this adapter backend-agnostic.).
23
+ *
24
+ * **Why BYO SDK:** OTel's SDK is heavyweight and exporter-specific
25
+ * (each backend has its own exporter package). Forcing a particular
26
+ * exporter would defeat the "OTel is portable" guarantee. Consumers
27
+ * configure the SDK + exporter once at app startup; we just speak
28
+ * the typed OTel API.
29
+ *
30
+ * Mapping:
31
+ *
32
+ * agent.turn_start ↦ start root span (one trace per turn)
33
+ * agent.turn_end ↦ end root span
34
+ * agent.iteration_start ↦ start child span under root
35
+ * agent.iteration_end ↦ end iteration span
36
+ * stream.llm_start ↦ start child span (model call)
37
+ * stream.llm_end ↦ end llm span
38
+ * stream.tool_start ↦ start child span (tool call)
39
+ * stream.tool_end ↦ end tool span (with `error: true` if errored)
40
+ * cost.tick ↦ setAttribute on topmost active span
41
+ *
42
+ * @example Basic — Honeycomb via OTLP
43
+ * ```ts
44
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
45
+ * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
46
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
47
+ * import { trace } from '@opentelemetry/api';
48
+ * import { otelObservability } from 'agentfootprint/observability-providers';
49
+ *
50
+ * // Set up OTel ONCE at app startup.
51
+ * const provider = new NodeTracerProvider();
52
+ * provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter({
53
+ * url: 'https://api.honeycomb.io/v1/traces',
54
+ * headers: { 'x-honeycomb-team': process.env.HONEYCOMB_KEY },
55
+ * })));
56
+ * provider.register();
57
+ *
58
+ * agent.enable.observability({
59
+ * strategy: otelObservability({
60
+ * serviceName: 'my-agent',
61
+ * // tracer optional — defaults to trace.getTracer('agentfootprint').
62
+ * }),
63
+ * });
64
+ * ```
65
+ *
66
+ * @example Test injection
67
+ * ```ts
68
+ * otelObservability({
69
+ * serviceName: 'test',
70
+ * tracer: mockTracer, // anything matching the OTel Tracer interface
71
+ * });
72
+ * ```
73
+ */
74
+ import { lazyRequire } from '../../lib/lazyRequire.js';
75
+ // ─── Strategy factory ────────────────────────────────────────────────
76
+ export function otelObservability(opts) {
77
+ if (!opts.serviceName) {
78
+ throw new TypeError(`[otelObservability] \`serviceName\` is required. ` +
79
+ `Pass an identifier visible in your OTel backend's service map, e.g. 'my-agent-prod'.`);
80
+ }
81
+ const sampleRate = opts.sampleRate ?? 1;
82
+ // Lazy-resolve tracer if not injected. Defer the API import until
83
+ // first event so consumers who don't actually fire events (no agent
84
+ // run yet) don't even hit the OTel API surface.
85
+ let tracer = opts.tracer;
86
+ let otelApi;
87
+ function ensureTracer() {
88
+ if (tracer)
89
+ return tracer;
90
+ if (!otelApi) {
91
+ try {
92
+ otelApi = lazyRequire('@opentelemetry/api');
93
+ }
94
+ catch {
95
+ throw new Error('otelObservability requires the `@opentelemetry/api` peer dependency.\n' +
96
+ ' Install: npm install @opentelemetry/api\n' +
97
+ ' Plus an OTel SDK + exporter for your backend (e.g.,\n' +
98
+ ' `@opentelemetry/sdk-trace-node` + `@opentelemetry/exporter-trace-otlp-http`).\n' +
99
+ ' Or pass `tracer` for test injection.');
100
+ }
101
+ }
102
+ if (!otelApi.trace?.getTracer) {
103
+ throw new Error('otelObservability: `@opentelemetry/api` is installed but `trace.getTracer` not found. Update the package.');
104
+ }
105
+ tracer = otelApi.trace.getTracer('agentfootprint');
106
+ return tracer;
107
+ }
108
+ // Per-turn state — same pattern as xrayObservability. Events for
109
+ // multiple in-flight turns interleave correctly because we key by
110
+ // `runId` from the event payload.
111
+ const activeTurns = new Map();
112
+ let stopped = false;
113
+ let onErrorHook;
114
+ function pushSpan(turnState, name, attrs) {
115
+ // OTel parent-context wiring: we capture the parent in a context
116
+ // and start the new span under it. (For BYO SDK setups, the
117
+ // `trace.setSpan` + `context.with` pattern is canonical. For
118
+ // the test-injected tracer path, we just pass the parent as
119
+ // implicit context.)
120
+ const parent = turnState.stack[turnState.stack.length - 1]?.span;
121
+ let ctx;
122
+ if (parent && otelApi?.trace?.setSpan && otelApi?.context?.active) {
123
+ ctx = otelApi.trace.setSpan(otelApi.context.active(), parent);
124
+ }
125
+ const span = ensureTracer().startSpan(name, attrs ? { attributes: attrs } : undefined, ctx);
126
+ turnState.stack.push({ name, span });
127
+ return span;
128
+ }
129
+ function popSpan(turnState, expectedName) {
130
+ let idx = turnState.stack.length - 1;
131
+ if (expectedName) {
132
+ while (idx >= 0 && turnState.stack[idx].name !== expectedName)
133
+ idx--;
134
+ }
135
+ if (idx < 0)
136
+ return undefined;
137
+ return turnState.stack.splice(idx, 1)[0].span;
138
+ }
139
+ function endSpan(span, opts) {
140
+ if (opts?.error) {
141
+ const code = otelApi?.SpanStatusCode?.ERROR ?? 2;
142
+ try {
143
+ span.setStatus({ code });
144
+ }
145
+ catch {
146
+ /* mock tracers may not implement setStatus — ignore */
147
+ }
148
+ }
149
+ span.end();
150
+ }
151
+ // ─── Event-to-span dispatch ────────────────────────────────────────
152
+ function handleEvent(event) {
153
+ if (stopped)
154
+ return;
155
+ const runId = event.payload?.runId;
156
+ if (!runId)
157
+ return; // Events without a turn anchor — skip.
158
+ switch (event.type) {
159
+ case 'agentfootprint.agent.turn_start': {
160
+ const sampled = sampleRate >= 1 || Math.random() < sampleRate;
161
+ const turnState = { stack: [], sampled };
162
+ activeTurns.set(runId, turnState);
163
+ if (sampled)
164
+ pushSpan(turnState, opts.serviceName, { 'service.name': opts.serviceName });
165
+ break;
166
+ }
167
+ case 'agentfootprint.agent.turn_end': {
168
+ const t = activeTurns.get(runId);
169
+ if (!t)
170
+ break;
171
+ // Defensive: end everything still on the stack.
172
+ while (t.stack.length > 0) {
173
+ const span = popSpan(t);
174
+ if (span)
175
+ endSpan(span);
176
+ }
177
+ activeTurns.delete(runId);
178
+ break;
179
+ }
180
+ case 'agentfootprint.agent.iteration_start': {
181
+ const t = activeTurns.get(runId);
182
+ if (t?.sampled) {
183
+ const iteration = event.payload.iteration;
184
+ pushSpan(t, `iteration:${iteration ?? '?'}`, {
185
+ ...(typeof iteration === 'number' && { 'iteration.number': iteration }),
186
+ });
187
+ }
188
+ break;
189
+ }
190
+ case 'agentfootprint.agent.iteration_end': {
191
+ const t = activeTurns.get(runId);
192
+ if (t?.sampled) {
193
+ const span = popSpan(t);
194
+ if (span)
195
+ endSpan(span);
196
+ }
197
+ break;
198
+ }
199
+ case 'agentfootprint.stream.llm_start': {
200
+ const t = activeTurns.get(runId);
201
+ if (!t?.sampled)
202
+ break;
203
+ const model = event.payload.model;
204
+ pushSpan(t, 'llm', model ? { 'gen_ai.request.model': model } : undefined);
205
+ break;
206
+ }
207
+ case 'agentfootprint.stream.llm_end': {
208
+ const t = activeTurns.get(runId);
209
+ if (!t?.sampled)
210
+ break;
211
+ const span = popSpan(t, 'llm');
212
+ if (span)
213
+ endSpan(span);
214
+ break;
215
+ }
216
+ case 'agentfootprint.stream.tool_start': {
217
+ const t = activeTurns.get(runId);
218
+ if (!t?.sampled)
219
+ break;
220
+ const toolName = event.payload.toolName ?? 'tool';
221
+ pushSpan(t, `tool:${toolName}`, { 'tool.name': toolName });
222
+ break;
223
+ }
224
+ case 'agentfootprint.stream.tool_end': {
225
+ const t = activeTurns.get(runId);
226
+ if (!t?.sampled)
227
+ break;
228
+ const toolName = event.payload.toolName;
229
+ const errored = event.payload.error !== undefined;
230
+ const span = popSpan(t, toolName ? `tool:${toolName}` : undefined);
231
+ if (span)
232
+ endSpan(span, { error: errored });
233
+ break;
234
+ }
235
+ // Other events — annotate the topmost active span.
236
+ default: {
237
+ const t = activeTurns.get(runId);
238
+ const top = t?.stack[t.stack.length - 1]?.span;
239
+ if (!t?.sampled || !top)
240
+ break;
241
+ // Cost ticks are particularly valuable as attributes.
242
+ if (event.type === 'agentfootprint.cost.tick') {
243
+ const p = event.payload;
244
+ if (typeof p.cumulativeCostUsd === 'number') {
245
+ try {
246
+ top.setAttribute('cost.cumulative_usd', p.cumulativeCostUsd);
247
+ }
248
+ catch {
249
+ /* ignore */
250
+ }
251
+ }
252
+ }
253
+ break;
254
+ }
255
+ }
256
+ }
257
+ return {
258
+ name: 'otel',
259
+ capabilities: { events: true, traces: true },
260
+ exportEvent: handleEvent,
261
+ flush() {
262
+ // OTel SDKs handle their own flushing (the consumer-configured
263
+ // SpanProcessor's `forceFlush()`). We don't cross that boundary
264
+ // here — calling `provider.forceFlush()` is the consumer's
265
+ // responsibility on shutdown. Documented in the README.
266
+ },
267
+ stop() {
268
+ stopped = true;
269
+ // Defensive: end any spans the agent loop didn't close.
270
+ for (const [, t] of activeTurns) {
271
+ while (t.stack.length > 0) {
272
+ const span = popSpan(t);
273
+ if (span)
274
+ endSpan(span);
275
+ }
276
+ }
277
+ activeTurns.clear();
278
+ },
279
+ _onError(err, event) {
280
+ onErrorHook =
281
+ onErrorHook ??
282
+ ((e) => {
283
+ // eslint-disable-next-line no-console
284
+ console.error(`[otelObservability] error:`, e.message);
285
+ });
286
+ onErrorHook(err, event);
287
+ },
288
+ };
289
+ }
290
+ //# sourceMappingURL=otel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.js","sourceRoot":"","sources":["../../../../src/adapters/observability/otel.ts"],"names":[],"mappings":"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"}
@@ -29,11 +29,17 @@
29
29
  * Roadmap:
30
30
  * - agentcoreObservability ← v2.8.1
31
31
  * - cloudwatchObservability ← v2.8.2
32
- * - xrayObservability ← v2.8.3 (this release)
33
- * - otelObservability ← v2.9.x
34
- * - datadogObservability ← v2.9.x
32
+ * - xrayObservability ← v2.8.3
33
+ * - otelObservability ← v2.9.0 (this release)
34
+ *
35
+ * Note: `datadogObservability` was on the v2.9 roadmap, but Datadog
36
+ * APM accepts OTLP — point your OTel SDK at Datadog's OTLP endpoint
37
+ * and `otelObservability` covers the Datadog use case. We'll ship a
38
+ * dedicated `dd-trace`-based adapter only if real-world feedback
39
+ * demands the native Datadog APM client.
35
40
  */
36
41
  export { agentcoreObservability, } from './adapters/observability/agentcore.js';
37
42
  export { cloudwatchObservability, } from './adapters/observability/cloudwatch.js';
38
43
  export { xrayObservability, } from './adapters/observability/xray.js';
44
+ export { otelObservability, } from './adapters/observability/otel.js';
39
45
  //# sourceMappingURL=observability-providers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"observability-providers.js","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EACL,sBAAsB,GAEvB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,GAExB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,GAGlB,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"observability-providers.js","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,sBAAsB,GAEvB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,GAExB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,GAGlB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,GAKlB,MAAM,kCAAkC,CAAC"}
@@ -30,16 +30,23 @@
30
30
  * Roadmap:
31
31
  * - agentcoreObservability ← v2.8.1
32
32
  * - cloudwatchObservability ← v2.8.2
33
- * - xrayObservability ← v2.8.3 (this release)
34
- * - otelObservability ← v2.9.x
35
- * - datadogObservability ← v2.9.x
33
+ * - xrayObservability ← v2.8.3
34
+ * - otelObservability ← v2.9.0 (this release)
35
+ *
36
+ * Note: `datadogObservability` was on the v2.9 roadmap, but Datadog
37
+ * APM accepts OTLP — point your OTel SDK at Datadog's OTLP endpoint
38
+ * and `otelObservability` covers the Datadog use case. We'll ship a
39
+ * dedicated `dd-trace`-based adapter only if real-world feedback
40
+ * demands the native Datadog APM client.
36
41
  */
37
42
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.xrayObservability = exports.cloudwatchObservability = exports.agentcoreObservability = void 0;
43
+ exports.otelObservability = exports.xrayObservability = exports.cloudwatchObservability = exports.agentcoreObservability = void 0;
39
44
  var agentcore_js_1 = require("./adapters/observability/agentcore.js");
40
45
  Object.defineProperty(exports, "agentcoreObservability", { enumerable: true, get: function () { return agentcore_js_1.agentcoreObservability; } });
41
46
  var cloudwatch_js_1 = require("./adapters/observability/cloudwatch.js");
42
47
  Object.defineProperty(exports, "cloudwatchObservability", { enumerable: true, get: function () { return cloudwatch_js_1.cloudwatchObservability; } });
43
48
  var xray_js_1 = require("./adapters/observability/xray.js");
44
49
  Object.defineProperty(exports, "xrayObservability", { enumerable: true, get: function () { return xray_js_1.xrayObservability; } });
50
+ var otel_js_1 = require("./adapters/observability/otel.js");
51
+ Object.defineProperty(exports, "otelObservability", { enumerable: true, get: function () { return otel_js_1.otelObservability; } });
45
52
  //# sourceMappingURL=observability-providers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"observability-providers.js","sourceRoot":"","sources":["../src/observability-providers.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;AAEH,sEAG+C;AAF7C,sHAAA,sBAAsB,OAAA;AAGxB,wEAGgD;AAF9C,wHAAA,uBAAuB,OAAA;AAGzB,4DAI0C;AAHxC,4GAAA,iBAAiB,OAAA"}
1
+ {"version":3,"file":"observability-providers.js","sourceRoot":"","sources":["../src/observability-providers.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;;;AAEH,sEAG+C;AAF7C,sHAAA,sBAAsB,OAAA;AAGxB,wEAGgD;AAF9C,wHAAA,uBAAuB,OAAA;AAGzB,4DAI0C;AAHxC,4GAAA,iBAAiB,OAAA;AAInB,4DAM0C;AALxC,4GAAA,iBAAiB,OAAA"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * otelObservability — OpenTelemetry distributed-tracing adapter.
3
+ *
4
+ * Ships every agentfootprint event as OpenTelemetry spans + log
5
+ * records via a consumer-supplied OTel API. Same hierarchical
6
+ * mapping as the X-Ray adapter, but the destination is whichever
7
+ * OTel-compat backend the consumer's SDK exports to:
8
+ *
9
+ * - **Honeycomb** (OTLP/HTTP)
10
+ * - **Grafana Cloud / Tempo / Mimir** (OTLP)
11
+ * - **AWS Distro for OTel** → AWS X-Ray (alternative to xrayObservability)
12
+ * - **Datadog APM** (OTLP endpoint)
13
+ * - **Splunk Observability Cloud** (OTLP)
14
+ * - **New Relic** (OTLP endpoint)
15
+ * - **Lightstep / ServiceNow Cloud Observability** (OTLP)
16
+ * - any custom OTel collector / processor pipeline
17
+ *
18
+ * Subpath: `agentfootprint/observability-providers`
19
+ * Peer dep: `@opentelemetry/api` (OPTIONAL — installed only when
20
+ * this adapter is used. The consumer ALSO installs the
21
+ * OTel SDK + exporter of their choice — that's the BYO
22
+ * contract that makes this adapter backend-agnostic.).
23
+ *
24
+ * **Why BYO SDK:** OTel's SDK is heavyweight and exporter-specific
25
+ * (each backend has its own exporter package). Forcing a particular
26
+ * exporter would defeat the "OTel is portable" guarantee. Consumers
27
+ * configure the SDK + exporter once at app startup; we just speak
28
+ * the typed OTel API.
29
+ *
30
+ * Mapping:
31
+ *
32
+ * agent.turn_start ↦ start root span (one trace per turn)
33
+ * agent.turn_end ↦ end root span
34
+ * agent.iteration_start ↦ start child span under root
35
+ * agent.iteration_end ↦ end iteration span
36
+ * stream.llm_start ↦ start child span (model call)
37
+ * stream.llm_end ↦ end llm span
38
+ * stream.tool_start ↦ start child span (tool call)
39
+ * stream.tool_end ↦ end tool span (with `error: true` if errored)
40
+ * cost.tick ↦ setAttribute on topmost active span
41
+ *
42
+ * @example Basic — Honeycomb via OTLP
43
+ * ```ts
44
+ * import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
45
+ * import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
46
+ * import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base';
47
+ * import { trace } from '@opentelemetry/api';
48
+ * import { otelObservability } from 'agentfootprint/observability-providers';
49
+ *
50
+ * // Set up OTel ONCE at app startup.
51
+ * const provider = new NodeTracerProvider();
52
+ * provider.addSpanProcessor(new BatchSpanProcessor(new OTLPTraceExporter({
53
+ * url: 'https://api.honeycomb.io/v1/traces',
54
+ * headers: { 'x-honeycomb-team': process.env.HONEYCOMB_KEY },
55
+ * })));
56
+ * provider.register();
57
+ *
58
+ * agent.enable.observability({
59
+ * strategy: otelObservability({
60
+ * serviceName: 'my-agent',
61
+ * // tracer optional — defaults to trace.getTracer('agentfootprint').
62
+ * }),
63
+ * });
64
+ * ```
65
+ *
66
+ * @example Test injection
67
+ * ```ts
68
+ * otelObservability({
69
+ * serviceName: 'test',
70
+ * tracer: mockTracer, // anything matching the OTel Tracer interface
71
+ * });
72
+ * ```
73
+ */
74
+ import type { ObservabilityStrategy } from '../../strategies/types.js';
75
+ export interface OtelObservabilityOptions {
76
+ /** Service name on every emitted span. Surfaces in your OTel
77
+ * backend's service map. Required. */
78
+ readonly serviceName: string;
79
+ /** OTel Tracer to use. Defaults to
80
+ * `trace.getTracer('agentfootprint', AGENTFOOTPRINT_VERSION)`
81
+ * (where `trace` is the lazy-imported `@opentelemetry/api`). */
82
+ readonly tracer?: OtelTracerLike;
83
+ /** 0..1 — sample rate for turn-level spans. Default `1.0`.
84
+ * Sampling decisions are normally an OTel SDK concern (via
85
+ * `Sampler`); this option is a per-strategy override for cases
86
+ * where the consumer wants agentfootprint to drop spans BEFORE
87
+ * they reach the SDK (e.g., aggressive cost control). */
88
+ readonly sampleRate?: number;
89
+ }
90
+ /** Subset of `@opentelemetry/api`'s `Tracer` we depend on. */
91
+ export interface OtelTracerLike {
92
+ startSpan(name: string, options?: OtelSpanOptions, context?: unknown): OtelSpanLike;
93
+ }
94
+ /** Subset of `@opentelemetry/api`'s `SpanOptions`. */
95
+ export interface OtelSpanOptions {
96
+ attributes?: Record<string, string | number | boolean>;
97
+ startTime?: number;
98
+ kind?: number;
99
+ }
100
+ /** Subset of `@opentelemetry/api`'s `Span` we depend on. */
101
+ export interface OtelSpanLike {
102
+ setAttribute(key: string, value: string | number | boolean): unknown;
103
+ setStatus(status: {
104
+ code: number;
105
+ message?: string;
106
+ }): unknown;
107
+ end(endTime?: number): void;
108
+ spanContext(): {
109
+ traceId: string;
110
+ spanId: string;
111
+ traceFlags: number;
112
+ };
113
+ }
114
+ export declare function otelObservability(opts: OtelObservabilityOptions): ObservabilityStrategy;
115
+ //# sourceMappingURL=otel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/otel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwEG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAIvE,MAAM,WAAW,wBAAwB;IACvC;2CACuC;IACvC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;qEAEiE;IACjE,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IACjC;;;;8DAI0D;IAC1D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAID,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;CACrF;AAED,sDAAsD;AACtD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACrE,SAAS,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/D,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CACxE;AAgBD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA0OvF"}
@@ -29,11 +29,17 @@
29
29
  * Roadmap:
30
30
  * - agentcoreObservability ← v2.8.1
31
31
  * - cloudwatchObservability ← v2.8.2
32
- * - xrayObservability ← v2.8.3 (this release)
33
- * - otelObservability ← v2.9.x
34
- * - datadogObservability ← v2.9.x
32
+ * - xrayObservability ← v2.8.3
33
+ * - otelObservability ← v2.9.0 (this release)
34
+ *
35
+ * Note: `datadogObservability` was on the v2.9 roadmap, but Datadog
36
+ * APM accepts OTLP — point your OTel SDK at Datadog's OTLP endpoint
37
+ * and `otelObservability` covers the Datadog use case. We'll ship a
38
+ * dedicated `dd-trace`-based adapter only if real-world feedback
39
+ * demands the native Datadog APM client.
35
40
  */
36
41
  export { agentcoreObservability, type AgentcoreObservabilityOptions, } from './adapters/observability/agentcore.js';
37
42
  export { cloudwatchObservability, type CloudwatchObservabilityOptions, } from './adapters/observability/cloudwatch.js';
38
43
  export { xrayObservability, type XrayObservabilityOptions, type XRayLikeClient, } from './adapters/observability/xray.js';
44
+ export { otelObservability, type OtelObservabilityOptions, type OtelTracerLike, type OtelSpanLike, type OtelSpanOptions, } from './adapters/observability/otel.js';
39
45
  //# sourceMappingURL=observability-providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfootprint",
3
- "version": "2.8.3",
3
+ "version": "2.9.0",
4
4
  "description": "The explainable agent framework — build AI agents you can explain, audit, and trust. Built on footprintjs.",
5
5
  "license": "MIT",
6
6
  "author": "Sanjay Krishna Anbalagan",
@@ -173,6 +173,7 @@
173
173
  "@aws-sdk/client-cloudwatch-logs": "*",
174
174
  "@aws-sdk/client-xray": "*",
175
175
  "@modelcontextprotocol/sdk": "*",
176
+ "@opentelemetry/api": "*",
176
177
  "footprintjs": ">=4.17.1",
177
178
  "ioredis": "*",
178
179
  "openai": "*",
@@ -200,6 +201,9 @@
200
201
  "@modelcontextprotocol/sdk": {
201
202
  "optional": true
202
203
  },
204
+ "@opentelemetry/api": {
205
+ "optional": true
206
+ },
203
207
  "ioredis": {
204
208
  "optional": true
205
209
  },