@hazeljs/observability 0.7.9 → 0.8.1

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 CHANGED
@@ -93,14 +93,15 @@ class AIService {
93
93
  The observability package follows the A2A (Agent-to-Agent) and OTel specifications to ensure your traces are compatible with the broader ecosystem.
94
94
 
95
95
  <MermaidDiagram chart={`graph TD
96
- A["@Trace() Decorator"] --> B["Observability Service"]
97
- B --> C["OpenTelemetry Provider"]
98
- C --> D["OTLP Exporter"]
99
- D --> E["Observability Platform<br/>(Jaeger, Honeycomb, Datadog)"]
100
-
96
+ A["@Trace() Decorator"] --> B["Observability Service"]
97
+ B --> C["OpenTelemetry Provider"]
98
+ C --> D["OTLP Exporter"]
99
+ D --> E["Observability Platform<br/>(Jaeger, Honeycomb, Datadog)"]
100
+
101
101
  style A fill:#3b82f6,color:#fff
102
102
  style B fill:#6366f1,color:#fff
103
103
  style C fill:#10b981,color:#fff
104
+
104
105
  `} />
105
106
 
106
107
  ## API Reference
@@ -109,11 +110,7 @@ The observability package follows the A2A (Agent-to-Agent) and OTel specificatio
109
110
 
110
111
  ```typescript
111
112
  class OpenTelemetryProvider {
112
- constructor(config: {
113
- serviceName: string;
114
- endpoint?: string;
115
- headers?: Record<string, string>;
116
- });
113
+ constructor(config: { serviceName: string; endpoint?: string; headers?: Record<string, string> });
117
114
  initialize(): void;
118
115
  shutdown(): Promise<void>;
119
116
  }
@@ -126,6 +123,7 @@ class OpenTelemetryProvider {
126
123
  ```
127
124
 
128
125
  **TraceOptions:**
126
+
129
127
  - `attributes`: Static attributes to add to the span.
130
128
  - `captureArgs`: Whether to capture method arguments (default: `false`).
131
129
  - `captureResult`: Whether to capture method return value (default: `false`).
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Tracing Decorator (@Trace)
3
+ * Automatically wraps a class method inside an OpenTelemetry Span for detailed observability.
4
+ *
5
+ * @param spanName Custom name for the span. Defaults to the method name.
6
+ */
7
+ export declare function Trace(spanName?: string): MethodDecorator;
8
+ //# sourceMappingURL=trace.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/trace.decorator.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,CAoDxD"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Trace = Trace;
4
+ const api_1 = require("@opentelemetry/api");
5
+ /**
6
+ * Tracing Decorator (@Trace)
7
+ * Automatically wraps a class method inside an OpenTelemetry Span for detailed observability.
8
+ *
9
+ * @param spanName Custom name for the span. Defaults to the method name.
10
+ */
11
+ function Trace(spanName) {
12
+ return (target, propertyKey, descriptor) => {
13
+ const originalMethod = descriptor.value;
14
+ if (typeof originalMethod !== 'function')
15
+ return descriptor;
16
+ const methodName = String(propertyKey);
17
+ const resolvedSpanName = spanName || methodName;
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
+ descriptor.value = function (...args) {
20
+ const tracer = api_1.trace.getTracer('hazeljs');
21
+ return tracer.startActiveSpan(resolvedSpanName, (span) => {
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ const handleError = (error) => {
24
+ span.recordException(error);
25
+ span.setStatus({
26
+ code: api_1.SpanStatusCode.ERROR,
27
+ message: error instanceof Error ? error.message : String(error),
28
+ });
29
+ span.end();
30
+ throw error;
31
+ };
32
+ try {
33
+ span.setAttribute('code.function', methodName);
34
+ // Execute original logic
35
+ const result = originalMethod.apply(this, args);
36
+ if (result instanceof Promise) {
37
+ return result
38
+ .then((res) => {
39
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
40
+ span.end();
41
+ return res;
42
+ })
43
+ .catch(handleError);
44
+ }
45
+ span.setStatus({ code: api_1.SpanStatusCode.OK });
46
+ span.end();
47
+ return result;
48
+ }
49
+ catch (error) {
50
+ return handleError(error);
51
+ }
52
+ });
53
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
+ };
55
+ return descriptor;
56
+ };
57
+ }
@@ -0,0 +1,4 @@
1
+ export * from './types';
2
+ export * from './opentelemetry.provider';
3
+ export * from './decorators/trace.decorator';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./opentelemetry.provider"), exports);
19
+ __exportStar(require("./decorators/trace.decorator"), exports);
@@ -0,0 +1,28 @@
1
+ import { Tracer } from '@opentelemetry/api';
2
+ import { ObservabilityProvider, ObservabilityConfig } from './types';
3
+ /**
4
+ * OpenTelemetry implementation of the ObservabilityProvider
5
+ */
6
+ export declare class OpenTelemetryProvider implements ObservabilityProvider {
7
+ private config;
8
+ private provider;
9
+ private exporter?;
10
+ constructor(config: ObservabilityConfig);
11
+ /**
12
+ * Start tracking observability metrics
13
+ */
14
+ start(): Promise<void>;
15
+ /**
16
+ * Stop operations gracefully, ensuring spans flush
17
+ */
18
+ stop(): Promise<void>;
19
+ /**
20
+ * Retrieves a named tracer
21
+ */
22
+ getTracer(name: string): Tracer;
23
+ /**
24
+ * Tracking LLM cost allows the agent runtime to dynamically emit span metrics or print usage statistics
25
+ */
26
+ trackCost(model: string, promptTokens: number, completionTokens: number): void;
27
+ }
28
+ //# sourceMappingURL=opentelemetry.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opentelemetry.provider.d.ts","sourceRoot":"","sources":["../src/opentelemetry.provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAKnD,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAErE;;GAEG;AACH,qBAAa,qBAAsB,YAAW,qBAAqB;IACjE,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,QAAQ,CAAC,CAAoB;gBAEzB,MAAM,EAAE,mBAAmB;IAqBvC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;CAS/E"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenTelemetryProvider = void 0;
4
+ /* eslint-disable no-console */
5
+ const api_1 = require("@opentelemetry/api");
6
+ const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
7
+ const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
8
+ const resources_1 = require("@opentelemetry/resources");
9
+ const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
10
+ /**
11
+ * OpenTelemetry implementation of the ObservabilityProvider
12
+ */
13
+ class OpenTelemetryProvider {
14
+ constructor(config) {
15
+ this.config = config;
16
+ const resource = (0, resources_1.resourceFromAttributes)({
17
+ [semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: config.serviceName,
18
+ });
19
+ const spanProcessors = [];
20
+ if (config.otlpEndpoint) {
21
+ this.exporter = new exporter_trace_otlp_http_1.OTLPTraceExporter({
22
+ url: config.otlpEndpoint,
23
+ });
24
+ spanProcessors.push(new sdk_trace_node_1.BatchSpanProcessor(this.exporter));
25
+ }
26
+ this.provider = new sdk_trace_node_1.NodeTracerProvider({
27
+ resource,
28
+ ...(spanProcessors.length > 0 ? { spanProcessors } : {}),
29
+ });
30
+ }
31
+ /**
32
+ * Start tracking observability metrics
33
+ */
34
+ async start() {
35
+ // Register provider globally so trace decorators can pick it up
36
+ this.provider.register();
37
+ console.log(`[Observability] Started tracing service ${this.config.serviceName}`);
38
+ }
39
+ /**
40
+ * Stop operations gracefully, ensuring spans flush
41
+ */
42
+ async stop() {
43
+ try {
44
+ await this.provider.shutdown();
45
+ if (this.exporter) {
46
+ await this.exporter.shutdown();
47
+ }
48
+ console.log(`[Observability] Stopped tracing service ${this.config.serviceName}`);
49
+ }
50
+ catch (e) {
51
+ console.error('[Observability] Failed to shutdown opentelemetry gracefully', e);
52
+ }
53
+ }
54
+ /**
55
+ * Retrieves a named tracer
56
+ */
57
+ getTracer(name) {
58
+ return api_1.trace.getTracer(name);
59
+ }
60
+ /**
61
+ * Tracking LLM cost allows the agent runtime to dynamically emit span metrics or print usage statistics
62
+ */
63
+ trackCost(model, promptTokens, completionTokens) {
64
+ const activeSpan = api_1.trace.getActiveSpan();
65
+ if (activeSpan) {
66
+ activeSpan.setAttribute('llm.model', model);
67
+ activeSpan.setAttribute('llm.usage.prompt_tokens', promptTokens);
68
+ activeSpan.setAttribute('llm.usage.completion_tokens', completionTokens);
69
+ activeSpan.setAttribute('llm.usage.total_tokens', promptTokens + completionTokens);
70
+ }
71
+ }
72
+ }
73
+ exports.OpenTelemetryProvider = OpenTelemetryProvider;
@@ -0,0 +1,37 @@
1
+ import { Tracer } from '@opentelemetry/api';
2
+ /**
3
+ * Interface for tracking and reporting observability metrics
4
+ */
5
+ export interface ObservabilityProvider {
6
+ /**
7
+ * Initializes the tracing provider setup (e.g., OpenTelemetry NodeSDK)
8
+ */
9
+ start(): Promise<void>;
10
+ /**
11
+ * Stops and flushes the tracing provider setup
12
+ */
13
+ stop(): Promise<void>;
14
+ /**
15
+ * Retrieves the tracer
16
+ */
17
+ getTracer(name: string): Tracer;
18
+ /**
19
+ * Tracks LLM cost metrics
20
+ * @param model Model name (e.g., 'gpt-4o')
21
+ * @param promptTokens Number of tokens in the prompt
22
+ * @param completionTokens Number of tokens in the completion
23
+ */
24
+ trackCost(model: string, promptTokens: number, completionTokens: number): void;
25
+ }
26
+ /**
27
+ * Represents the configuration properties to setup tracing
28
+ */
29
+ export interface ObservabilityConfig {
30
+ /** The service name to appear in tracing tools (e.g. 'agent-runtime') */
31
+ serviceName: string;
32
+ /** Otlp GRPC/HTTP exporter endpoint (e.g., Datadog, Jaeger, Zipkin) */
33
+ otlpEndpoint?: string;
34
+ /** Whether to log prompts directly to the spans (false by default for privacy) */
35
+ logPrompts?: boolean;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAEhC;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CAChF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kFAAkF;IAClF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazeljs/observability",
3
- "version": "0.7.9",
3
+ "version": "0.8.1",
4
4
  "description": "Unified observability, OpenTelemetry tracing, and LLM cost tracking for HazelJS agents and flows",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -48,5 +48,5 @@
48
48
  "url": "https://github.com/hazeljs/hazel-js/issues"
49
49
  },
50
50
  "homepage": "https://hazeljs.ai",
51
- "gitHead": "28c21c509aeca3bf2d0878fbee737d906b654c67"
51
+ "gitHead": "8b7685d1250c4622f25d83992f58e13a59bb3dba"
52
52
  }