network-ai 5.5.7 → 5.5.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INTEGRATION_GUIDE.md +2 -2
- package/README.md +9 -4
- package/bin/cli.ts +5 -1
- package/dist/adapters/adapter-registry.d.ts +26 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -1
- package/dist/adapters/adapter-registry.js +93 -8
- package/dist/adapters/adapter-registry.js.map +1 -1
- package/dist/adapters/streaming-base-adapter.d.ts +6 -0
- package/dist/adapters/streaming-base-adapter.d.ts.map +1 -1
- package/dist/adapters/streaming-base-adapter.js +6 -0
- package/dist/adapters/streaming-base-adapter.js.map +1 -1
- package/dist/bin/cli.js +6 -1
- package/dist/bin/cli.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-runtime.d.ts +9 -0
- package/dist/lib/agent-runtime.d.ts.map +1 -1
- package/dist/lib/agent-runtime.js +7 -0
- package/dist/lib/agent-runtime.js.map +1 -1
- package/dist/lib/auth-guardian.d.ts +7 -0
- package/dist/lib/auth-guardian.d.ts.map +1 -1
- package/dist/lib/auth-guardian.js +7 -0
- package/dist/lib/auth-guardian.js.map +1 -1
- package/dist/lib/circuit-breaker.d.ts +93 -0
- package/dist/lib/circuit-breaker.d.ts.map +1 -0
- package/dist/lib/circuit-breaker.js +164 -0
- package/dist/lib/circuit-breaker.js.map +1 -0
- package/dist/lib/env-manager.d.ts +10 -2
- package/dist/lib/env-manager.d.ts.map +1 -1
- package/dist/lib/env-manager.js +19 -1
- package/dist/lib/env-manager.js.map +1 -1
- package/dist/lib/federated-budget.d.ts.map +1 -1
- package/dist/lib/federated-budget.js +3 -2
- package/dist/lib/federated-budget.js.map +1 -1
- package/dist/lib/locked-blackboard.d.ts +61 -0
- package/dist/lib/locked-blackboard.d.ts.map +1 -1
- package/dist/lib/locked-blackboard.js +166 -0
- package/dist/lib/locked-blackboard.js.map +1 -1
- package/dist/lib/phase-pipeline.d.ts +13 -1
- package/dist/lib/phase-pipeline.d.ts.map +1 -1
- package/dist/lib/phase-pipeline.js +12 -2
- package/dist/lib/phase-pipeline.js.map +1 -1
- package/dist/lib/telemetry-provider.d.ts +166 -0
- package/dist/lib/telemetry-provider.d.ts.map +1 -0
- package/dist/lib/telemetry-provider.js +207 -0
- package/dist/lib/telemetry-provider.js.map +1 -0
- package/package.json +3 -3
- package/types/agent-adapter.d.ts +4 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry Provider — BYOT (Bring Your Own Telemetry) abstraction.
|
|
3
|
+
*
|
|
4
|
+
* Defines a minimal interface over distributed tracing providers such as
|
|
5
|
+
* OpenTelemetry, Datadog APM, Honeycomb, etc. Network-AI core never imports
|
|
6
|
+
* a concrete telemetry SDK — only this interface — preserving the zero-
|
|
7
|
+
* dependency BYOC design.
|
|
8
|
+
*
|
|
9
|
+
* ## Wiring into adapter lifecycle hooks
|
|
10
|
+
*
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createOtelHooks, CapturingTelemetryProvider } from 'network-ai';
|
|
13
|
+
* import { AdapterHookManager } from 'network-ai';
|
|
14
|
+
*
|
|
15
|
+
* const provider = new CapturingTelemetryProvider(); // or your own impl
|
|
16
|
+
* const hookManager = new AdapterHookManager();
|
|
17
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* ## Implementing for OpenTelemetry
|
|
21
|
+
*
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import { trace, SpanStatusCode } from '@opentelemetry/api';
|
|
24
|
+
* import type { ITelemetryProvider, SpanAttributes } from 'network-ai';
|
|
25
|
+
*
|
|
26
|
+
* class OtelProvider implements ITelemetryProvider {
|
|
27
|
+
* private tracer = trace.getTracer('network-ai');
|
|
28
|
+
* private spans = new Map<string, Span>();
|
|
29
|
+
*
|
|
30
|
+
* startSpan(name: string, attrs: SpanAttributes = {}): string {
|
|
31
|
+
* const span = this.tracer.startSpan(name, { attributes: attrs as Attributes });
|
|
32
|
+
* const id = `span_${Date.now()}`;
|
|
33
|
+
* this.spans.set(id, span);
|
|
34
|
+
* return id;
|
|
35
|
+
* }
|
|
36
|
+
* endSpan(id: string, status: 'ok' | 'error'): void {
|
|
37
|
+
* const span = this.spans.get(id);
|
|
38
|
+
* if (!span) return;
|
|
39
|
+
* span.setStatus({ code: status === 'ok' ? SpanStatusCode.OK : SpanStatusCode.ERROR });
|
|
40
|
+
* span.end();
|
|
41
|
+
* this.spans.delete(id);
|
|
42
|
+
* }
|
|
43
|
+
* recordEvent(id: string, name: string, attrs: SpanAttributes = {}): void {
|
|
44
|
+
* this.spans.get(id)?.addEvent(name, attrs as Attributes);
|
|
45
|
+
* }
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
import type { ExecutionHook } from './adapter-hooks';
|
|
50
|
+
/**
|
|
51
|
+
* Flat attribute bag for span and event annotations.
|
|
52
|
+
* Values must be serialisable primitives for cross-backend compatibility.
|
|
53
|
+
*/
|
|
54
|
+
export interface SpanAttributes {
|
|
55
|
+
[key: string]: string | number | boolean | undefined;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* A span captured by `CapturingTelemetryProvider` — use in tests to assert
|
|
59
|
+
* on emitted traces.
|
|
60
|
+
*/
|
|
61
|
+
export interface CapturedSpan {
|
|
62
|
+
spanId: string;
|
|
63
|
+
name: string;
|
|
64
|
+
attributes: SpanAttributes;
|
|
65
|
+
startedAt: number;
|
|
66
|
+
endedAt?: number;
|
|
67
|
+
status?: 'ok' | 'error';
|
|
68
|
+
events: Array<{
|
|
69
|
+
name: string;
|
|
70
|
+
attributes: SpanAttributes;
|
|
71
|
+
ts: number;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Minimal telemetry abstraction. Implement this interface to plug any
|
|
76
|
+
* tracing backend into Network-AI without adding runtime dependencies.
|
|
77
|
+
*
|
|
78
|
+
* **Contract:** all methods are synchronous or fire-and-forget.
|
|
79
|
+
* Implementations **must not throw** — catch and handle internally.
|
|
80
|
+
*/
|
|
81
|
+
export interface ITelemetryProvider {
|
|
82
|
+
/**
|
|
83
|
+
* Start a new span.
|
|
84
|
+
* @param name Human-readable operation name (e.g. `'adapter.execute'`).
|
|
85
|
+
* @param attributes Initial span attributes.
|
|
86
|
+
* @returns Opaque spanId — pass to `endSpan` / `recordEvent`.
|
|
87
|
+
*/
|
|
88
|
+
startSpan(name: string, attributes?: SpanAttributes): string;
|
|
89
|
+
/**
|
|
90
|
+
* End a span with a final status.
|
|
91
|
+
* @param spanId Value returned by `startSpan`.
|
|
92
|
+
* @param status `'ok'` for success, `'error'` for failure.
|
|
93
|
+
* @param attributes Additional attributes to attach at close time.
|
|
94
|
+
*/
|
|
95
|
+
endSpan(spanId: string, status: 'ok' | 'error', attributes?: SpanAttributes): void;
|
|
96
|
+
/**
|
|
97
|
+
* Record a point-in-time event within an active span.
|
|
98
|
+
* @param spanId Value returned by `startSpan`.
|
|
99
|
+
* @param name Event name (e.g. `'blackboard.commit'`).
|
|
100
|
+
* @param attributes Event annotations.
|
|
101
|
+
*/
|
|
102
|
+
recordEvent(spanId: string, name: string, attributes?: SpanAttributes): void;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* No-op implementation. Used as the default when no telemetry provider is
|
|
106
|
+
* supplied so the instrumentation path compiles to a handful of dead calls
|
|
107
|
+
* that the JIT eliminates.
|
|
108
|
+
*/
|
|
109
|
+
export declare class NullTelemetryProvider implements ITelemetryProvider {
|
|
110
|
+
/** @inheritdoc */
|
|
111
|
+
startSpan(_name: string, _attributes?: SpanAttributes): string;
|
|
112
|
+
/** @inheritdoc */
|
|
113
|
+
endSpan(_spanId: string, _status: 'ok' | 'error', _attributes?: SpanAttributes): void;
|
|
114
|
+
/** @inheritdoc */
|
|
115
|
+
recordEvent(_spanId: string, _name: string, _attributes?: SpanAttributes): void;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* In-memory provider that stores every span and event for test assertions.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const provider = new CapturingTelemetryProvider();
|
|
123
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
124
|
+
*
|
|
125
|
+
* await registry.executeAgent('agent:foo', payload, ctx);
|
|
126
|
+
*
|
|
127
|
+
* const span = provider.spans.find(s => s.name === 'adapter.execute');
|
|
128
|
+
* expect(span?.status).toBe('ok');
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export declare class CapturingTelemetryProvider implements ITelemetryProvider {
|
|
132
|
+
/** All spans created since construction or last `clear()`. */
|
|
133
|
+
readonly spans: CapturedSpan[];
|
|
134
|
+
private counter;
|
|
135
|
+
/** @inheritdoc */
|
|
136
|
+
startSpan(name: string, attributes?: SpanAttributes): string;
|
|
137
|
+
/** @inheritdoc */
|
|
138
|
+
endSpan(spanId: string, status: 'ok' | 'error', attributes?: SpanAttributes): void;
|
|
139
|
+
/** @inheritdoc */
|
|
140
|
+
recordEvent(spanId: string, name: string, attributes?: SpanAttributes): void;
|
|
141
|
+
/** Clear all captured data and reset span counter. */
|
|
142
|
+
clear(): void;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Create a set of `ExecutionHook` objects that emit traces to `provider`.
|
|
146
|
+
*
|
|
147
|
+
* Register the returned hooks with an `AdapterHookManager`:
|
|
148
|
+
* ```typescript
|
|
149
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* Three hooks are created — one per `HookPhase`:
|
|
153
|
+
* - `otel:beforeExecute` — calls `provider.startSpan('adapter.execute', {...})`
|
|
154
|
+
* - `otel:afterExecute` — calls `provider.endSpan(spanId, 'ok')`
|
|
155
|
+
* - `otel:onError` — calls `provider.endSpan(spanId, 'error')`
|
|
156
|
+
*
|
|
157
|
+
* Each hook has `priority: 100` so it runs before most user-defined hooks.
|
|
158
|
+
* The spanId is stored in `ctx.metadata._otelSpanId` for downstream hooks
|
|
159
|
+
* that wish to add their own `recordEvent` calls.
|
|
160
|
+
*
|
|
161
|
+
* **Permission check semantics:** `beforeExecute` fires once when execution
|
|
162
|
+
* begins — not per streaming chunk — matching the documented "once at start"
|
|
163
|
+
* semantics of `StreamingBaseAdapter`.
|
|
164
|
+
*/
|
|
165
|
+
export declare function createOtelHooks(provider: ITelemetryProvider): ExecutionHook[];
|
|
166
|
+
//# sourceMappingURL=telemetry-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-provider.d.ts","sourceRoot":"","sources":["../../lib/telemetry-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,iBAAiB,CAAC;AAMlE;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACtD;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,cAAc,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,GAAG,MAAM,CAAC;IAE7D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO,EAAE,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAEnF;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;CAC9E;AAMD;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,kBAAkB;IAC9D,kBAAkB;IAClB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,MAAM;IAC9D,kBAAkB;IAClB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,GAAG,OAAO,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,IAAI;IACrF,kBAAkB;IAClB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,cAAc,GAAG,IAAI;CAChF;AAMD;;;;;;;;;;;;;GAaG;AACH,qBAAa,0BAA2B,YAAW,kBAAkB;IACnE,8DAA8D;IAC9D,QAAQ,CAAC,KAAK,EAAE,YAAY,EAAE,CAAM;IACpC,OAAO,CAAC,OAAO,CAAK;IAEpB,kBAAkB;IAClB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,cAAmB,GAAG,MAAM;IAMhE,kBAAkB;IAClB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAG,OAAO,EAAE,UAAU,GAAE,cAAmB,GAAG,IAAI;IAQtF,kBAAkB;IAClB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,GAAE,cAAmB,GAAG,IAAI;IAMhF,sDAAsD;IACtD,KAAK,IAAI,IAAI;CAId;AASD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,aAAa,EAAE,CAyD7E"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Telemetry Provider — BYOT (Bring Your Own Telemetry) abstraction.
|
|
4
|
+
*
|
|
5
|
+
* Defines a minimal interface over distributed tracing providers such as
|
|
6
|
+
* OpenTelemetry, Datadog APM, Honeycomb, etc. Network-AI core never imports
|
|
7
|
+
* a concrete telemetry SDK — only this interface — preserving the zero-
|
|
8
|
+
* dependency BYOC design.
|
|
9
|
+
*
|
|
10
|
+
* ## Wiring into adapter lifecycle hooks
|
|
11
|
+
*
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { createOtelHooks, CapturingTelemetryProvider } from 'network-ai';
|
|
14
|
+
* import { AdapterHookManager } from 'network-ai';
|
|
15
|
+
*
|
|
16
|
+
* const provider = new CapturingTelemetryProvider(); // or your own impl
|
|
17
|
+
* const hookManager = new AdapterHookManager();
|
|
18
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* ## Implementing for OpenTelemetry
|
|
22
|
+
*
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { trace, SpanStatusCode } from '@opentelemetry/api';
|
|
25
|
+
* import type { ITelemetryProvider, SpanAttributes } from 'network-ai';
|
|
26
|
+
*
|
|
27
|
+
* class OtelProvider implements ITelemetryProvider {
|
|
28
|
+
* private tracer = trace.getTracer('network-ai');
|
|
29
|
+
* private spans = new Map<string, Span>();
|
|
30
|
+
*
|
|
31
|
+
* startSpan(name: string, attrs: SpanAttributes = {}): string {
|
|
32
|
+
* const span = this.tracer.startSpan(name, { attributes: attrs as Attributes });
|
|
33
|
+
* const id = `span_${Date.now()}`;
|
|
34
|
+
* this.spans.set(id, span);
|
|
35
|
+
* return id;
|
|
36
|
+
* }
|
|
37
|
+
* endSpan(id: string, status: 'ok' | 'error'): void {
|
|
38
|
+
* const span = this.spans.get(id);
|
|
39
|
+
* if (!span) return;
|
|
40
|
+
* span.setStatus({ code: status === 'ok' ? SpanStatusCode.OK : SpanStatusCode.ERROR });
|
|
41
|
+
* span.end();
|
|
42
|
+
* this.spans.delete(id);
|
|
43
|
+
* }
|
|
44
|
+
* recordEvent(id: string, name: string, attrs: SpanAttributes = {}): void {
|
|
45
|
+
* this.spans.get(id)?.addEvent(name, attrs as Attributes);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
51
|
+
exports.CapturingTelemetryProvider = exports.NullTelemetryProvider = void 0;
|
|
52
|
+
exports.createOtelHooks = createOtelHooks;
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// NULL PROVIDER (default — zero overhead when no telemetry is configured)
|
|
55
|
+
// ============================================================================
|
|
56
|
+
/**
|
|
57
|
+
* No-op implementation. Used as the default when no telemetry provider is
|
|
58
|
+
* supplied so the instrumentation path compiles to a handful of dead calls
|
|
59
|
+
* that the JIT eliminates.
|
|
60
|
+
*/
|
|
61
|
+
class NullTelemetryProvider {
|
|
62
|
+
/** @inheritdoc */
|
|
63
|
+
startSpan(_name, _attributes) { return ''; }
|
|
64
|
+
/** @inheritdoc */
|
|
65
|
+
endSpan(_spanId, _status, _attributes) { }
|
|
66
|
+
/** @inheritdoc */
|
|
67
|
+
recordEvent(_spanId, _name, _attributes) { }
|
|
68
|
+
}
|
|
69
|
+
exports.NullTelemetryProvider = NullTelemetryProvider;
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// CAPTURING PROVIDER (for testing)
|
|
72
|
+
// ============================================================================
|
|
73
|
+
/**
|
|
74
|
+
* In-memory provider that stores every span and event for test assertions.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const provider = new CapturingTelemetryProvider();
|
|
79
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
80
|
+
*
|
|
81
|
+
* await registry.executeAgent('agent:foo', payload, ctx);
|
|
82
|
+
*
|
|
83
|
+
* const span = provider.spans.find(s => s.name === 'adapter.execute');
|
|
84
|
+
* expect(span?.status).toBe('ok');
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
class CapturingTelemetryProvider {
|
|
88
|
+
/** All spans created since construction or last `clear()`. */
|
|
89
|
+
spans = [];
|
|
90
|
+
counter = 0;
|
|
91
|
+
/** @inheritdoc */
|
|
92
|
+
startSpan(name, attributes = {}) {
|
|
93
|
+
const spanId = `span_${++this.counter}`;
|
|
94
|
+
this.spans.push({ spanId, name, attributes: { ...attributes }, startedAt: Date.now(), events: [] });
|
|
95
|
+
return spanId;
|
|
96
|
+
}
|
|
97
|
+
/** @inheritdoc */
|
|
98
|
+
endSpan(spanId, status, attributes = {}) {
|
|
99
|
+
const span = this.spans.find(s => s.spanId === spanId);
|
|
100
|
+
if (!span)
|
|
101
|
+
return;
|
|
102
|
+
span.endedAt = Date.now();
|
|
103
|
+
span.status = status;
|
|
104
|
+
Object.assign(span.attributes, attributes);
|
|
105
|
+
}
|
|
106
|
+
/** @inheritdoc */
|
|
107
|
+
recordEvent(spanId, name, attributes = {}) {
|
|
108
|
+
const span = this.spans.find(s => s.spanId === spanId);
|
|
109
|
+
if (!span)
|
|
110
|
+
return;
|
|
111
|
+
span.events.push({ name, attributes: { ...attributes }, ts: Date.now() });
|
|
112
|
+
}
|
|
113
|
+
/** Clear all captured data and reset span counter. */
|
|
114
|
+
clear() {
|
|
115
|
+
this.spans.length = 0;
|
|
116
|
+
this.counter = 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.CapturingTelemetryProvider = CapturingTelemetryProvider;
|
|
120
|
+
// ============================================================================
|
|
121
|
+
// HOOK FACTORY
|
|
122
|
+
// ============================================================================
|
|
123
|
+
/** Metadata key used to propagate spanId through `HookContext`. @internal */
|
|
124
|
+
const SPAN_ID_META_KEY = '_otelSpanId';
|
|
125
|
+
/**
|
|
126
|
+
* Create a set of `ExecutionHook` objects that emit traces to `provider`.
|
|
127
|
+
*
|
|
128
|
+
* Register the returned hooks with an `AdapterHookManager`:
|
|
129
|
+
* ```typescript
|
|
130
|
+
* createOtelHooks(provider).forEach(h => hookManager.register(h));
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* Three hooks are created — one per `HookPhase`:
|
|
134
|
+
* - `otel:beforeExecute` — calls `provider.startSpan('adapter.execute', {...})`
|
|
135
|
+
* - `otel:afterExecute` — calls `provider.endSpan(spanId, 'ok')`
|
|
136
|
+
* - `otel:onError` — calls `provider.endSpan(spanId, 'error')`
|
|
137
|
+
*
|
|
138
|
+
* Each hook has `priority: 100` so it runs before most user-defined hooks.
|
|
139
|
+
* The spanId is stored in `ctx.metadata._otelSpanId` for downstream hooks
|
|
140
|
+
* that wish to add their own `recordEvent` calls.
|
|
141
|
+
*
|
|
142
|
+
* **Permission check semantics:** `beforeExecute` fires once when execution
|
|
143
|
+
* begins — not per streaming chunk — matching the documented "once at start"
|
|
144
|
+
* semantics of `StreamingBaseAdapter`.
|
|
145
|
+
*/
|
|
146
|
+
function createOtelHooks(provider) {
|
|
147
|
+
return [
|
|
148
|
+
{
|
|
149
|
+
name: 'otel:beforeExecute',
|
|
150
|
+
phase: 'beforeExecute',
|
|
151
|
+
priority: 100,
|
|
152
|
+
handler(ctx) {
|
|
153
|
+
try {
|
|
154
|
+
const spanId = provider.startSpan('adapter.execute', {
|
|
155
|
+
agentId: ctx.agentId,
|
|
156
|
+
action: ctx.payload.action ?? '',
|
|
157
|
+
depth: ctx.depth,
|
|
158
|
+
});
|
|
159
|
+
ctx.metadata[SPAN_ID_META_KEY] = spanId;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Telemetry must never break execution
|
|
163
|
+
}
|
|
164
|
+
return ctx;
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'otel:afterExecute',
|
|
169
|
+
phase: 'afterExecute',
|
|
170
|
+
priority: 100,
|
|
171
|
+
handler(ctx) {
|
|
172
|
+
try {
|
|
173
|
+
const spanId = ctx.metadata[SPAN_ID_META_KEY];
|
|
174
|
+
if (spanId) {
|
|
175
|
+
provider.endSpan(spanId, 'ok', {
|
|
176
|
+
success: ctx.result?.success === true,
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// no-op
|
|
182
|
+
}
|
|
183
|
+
return ctx;
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'otel:onError',
|
|
188
|
+
phase: 'onError',
|
|
189
|
+
priority: 100,
|
|
190
|
+
handler(ctx) {
|
|
191
|
+
try {
|
|
192
|
+
const spanId = ctx.metadata[SPAN_ID_META_KEY];
|
|
193
|
+
if (spanId) {
|
|
194
|
+
provider.endSpan(spanId, 'error', {
|
|
195
|
+
errorMessage: ctx.error?.message ?? 'unknown',
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// no-op
|
|
201
|
+
}
|
|
202
|
+
return ctx;
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=telemetry-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-provider.js","sourceRoot":"","sources":["../../lib/telemetry-provider.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "network-ai",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.9",
|
|
4
4
|
"description": "AI agent orchestration framework for TypeScript/Node.js - 29 adapters (LangChain, AutoGen, CrewAI, OpenAI Assistants, LlamaIndex, Semantic Kernel, Haystack, DSPy, Agno, MCP, OpenClaw, A2A, Codex, MiniMax, NemoClaw, APS, Copilot, LangGraph, Anthropic Computer Use, OpenAI Agents SDK, Vertex AI, Pydantic AI, Browser Agent, Hermes, Orchestrator, RLM + streaming variants). Built-in CLI, security, swarm intelligence, real-time streaming, and agentic workflow patterns.",
|
|
5
5
|
"homepage": "https://network-ai.org",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -102,9 +102,9 @@
|
|
|
102
102
|
"python": ">=3.9"
|
|
103
103
|
},
|
|
104
104
|
"devDependencies": {
|
|
105
|
-
"@types/node": "^25.
|
|
105
|
+
"@types/node": "^25.9.0",
|
|
106
106
|
"dotenv": "^17.4.2",
|
|
107
|
-
"openai": "^6.
|
|
107
|
+
"openai": "^6.38.0",
|
|
108
108
|
"ts-node": "^10.9.2",
|
|
109
109
|
"typescript": "^6.0.3"
|
|
110
110
|
},
|
package/types/agent-adapter.d.ts
CHANGED
|
@@ -238,7 +238,10 @@ export type AdapterEventType =
|
|
|
238
238
|
| 'agent:execution:retry'
|
|
239
239
|
| 'agent:execution:fallback'
|
|
240
240
|
| 'agent:discovered'
|
|
241
|
-
| 'agent:unavailable'
|
|
241
|
+
| 'agent:unavailable'
|
|
242
|
+
| 'circuit:open'
|
|
243
|
+
| 'circuit:half-open'
|
|
244
|
+
| 'circuit:close';
|
|
242
245
|
|
|
243
246
|
export interface AdapterEvent {
|
|
244
247
|
type: AdapterEventType;
|