@nagi-js/otel 0.1.1-rc.10 → 0.1.1-rc.13

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/dist/index.js CHANGED
@@ -116,8 +116,10 @@ function otelHooks(opts = {}) {
116
116
  function endStepSpanOk(event, span) {
117
117
  const k = stepKey(event.runId, event.stepId, event.attempt);
118
118
  const startedAt = stepStartTimes.get(k);
119
- const durationMs = event.kind === "match" && startedAt ? event.at.getTime() - startedAt.getTime() : event.durationMs;
120
- span.setAttribute("nagi.step.duration_ms", durationMs);
119
+ const durationMs = event.durationMs ?? (startedAt ? event.at.getTime() - startedAt.getTime() : void 0);
120
+ if (durationMs !== void 0) {
121
+ span.setAttribute("nagi.step.duration_ms", durationMs);
122
+ }
121
123
  span.end(event.at);
122
124
  }
123
125
  function endStepSpanErr(span, error, endAt) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/compose.ts","../src/context.ts","../src/hooks.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n FlowCompleteEvent,\n FlowErrorEvent,\n FlowHooks,\n FlowStartEvent,\n SignalReceivedEvent,\n SignalSentEvent,\n StepCompleteEvent,\n StepErrorEvent,\n StepRetryEvent,\n StepStartEvent,\n} from \"@nagi-js/core\";\n\nexport function composeHooks(...hooks: readonly FlowHooks[]): FlowHooks {\n const result: {\n onFlowStart?: (event: FlowStartEvent) => Promise<void>;\n onFlowComplete?: (event: FlowCompleteEvent) => Promise<void>;\n onFlowError?: (event: FlowErrorEvent) => Promise<void>;\n onStepStart?: (event: StepStartEvent) => Promise<void>;\n onStepComplete?: (event: StepCompleteEvent) => Promise<void>;\n onStepError?: (event: StepErrorEvent) => Promise<void>;\n onStepRetry?: (event: StepRetryEvent) => Promise<void>;\n onSignalSent?: (event: SignalSentEvent) => Promise<void>;\n onSignalReceived?: (event: SignalReceivedEvent) => Promise<void>;\n } = {};\n\n const fs = pick(hooks, \"onFlowStart\");\n if (fs.length > 0) result.onFlowStart = fanout(\"onFlowStart\", fs);\n\n const fc = pick(hooks, \"onFlowComplete\");\n if (fc.length > 0) result.onFlowComplete = fanout(\"onFlowComplete\", fc);\n\n const fe = pick(hooks, \"onFlowError\");\n if (fe.length > 0) result.onFlowError = fanout(\"onFlowError\", fe);\n\n const ss = pick(hooks, \"onStepStart\");\n if (ss.length > 0) result.onStepStart = fanout(\"onStepStart\", ss);\n\n const sc = pick(hooks, \"onStepComplete\");\n if (sc.length > 0) result.onStepComplete = fanout(\"onStepComplete\", sc);\n\n const se = pick(hooks, \"onStepError\");\n if (se.length > 0) result.onStepError = fanout(\"onStepError\", se);\n\n const sr = pick(hooks, \"onStepRetry\");\n if (sr.length > 0) result.onStepRetry = fanout(\"onStepRetry\", sr);\n\n const sigS = pick(hooks, \"onSignalSent\");\n if (sigS.length > 0) result.onSignalSent = fanout(\"onSignalSent\", sigS);\n\n const sigR = pick(hooks, \"onSignalReceived\");\n if (sigR.length > 0)\n result.onSignalReceived = fanout(\"onSignalReceived\", sigR);\n\n return result;\n}\n\nfunction pick<K extends keyof FlowHooks>(\n hooks: readonly FlowHooks[],\n name: K,\n): Array<NonNullable<FlowHooks[K]>> {\n const out: Array<NonNullable<FlowHooks[K]>> = [];\n for (const h of hooks) {\n const fn = h[name];\n if (fn !== undefined) out.push(fn);\n }\n return out;\n}\n\nfunction fanout<E>(\n name: string,\n subs: ReadonlyArray<(event: E) => void | Promise<void>>,\n): (event: E) => Promise<void> {\n return async (event: E) => {\n for (const fn of subs) {\n try {\n await fn(event);\n } catch (err) {\n console.error(\n `[@nagi-js/otel] composeHooks: ${name} subscriber threw`,\n err,\n );\n }\n }\n };\n}\n","import type { AttemptNumber, RunId, StepCtx, StepId } from \"@nagi-js/core\";\nimport type { Span } from \"@opentelemetry/api\";\n\nconst SEP = \"\\x1f\";\n\nexport function stepKey(\n runId: RunId,\n stepId: StepId,\n attempt: AttemptNumber,\n): string {\n return `${runId}${SEP}${stepId}${SEP}${attempt}`;\n}\n\nexport const stepSpanRegistry = new Map<string, Span>();\n\nexport function getStepSpan(\n ctx: Pick<StepCtx<unknown>, \"runId\" | \"stepId\" | \"attempt\">,\n): Span | undefined {\n return stepSpanRegistry.get(stepKey(ctx.runId, ctx.stepId, ctx.attempt));\n}\n","import type {\n AttemptNumber,\n FlowCompleteEvent,\n FlowErrorEvent,\n FlowHooks,\n FlowStartEvent,\n RunId,\n SerializedError,\n SignalReceivedEvent,\n StepCompleteEvent,\n StepErrorEvent,\n StepEvent,\n StepId,\n StepRetryEvent,\n StepStartEvent,\n} from \"@nagi-js/core\";\nimport {\n type Attributes,\n type Context,\n context,\n type Span,\n SpanKind,\n SpanStatusCode,\n type Tracer,\n trace,\n} from \"@opentelemetry/api\";\nimport { stepKey, stepSpanRegistry } from \"./context\";\n\nconst TRACER_NAME = \"@nagi-js/otel\";\nconst TRACER_VERSION = \"0.0.0\";\n\nconst DEFAULT_FLOW_PREFIX = \"flow\";\nconst DEFAULT_STEP_PREFIX = \"step\";\n\nexport interface OtelHooksOpts {\n readonly tracer?: Tracer;\n readonly spanNamePrefix?: { readonly flow?: string; readonly step?: string };\n readonly defaultAttributes?: Attributes;\n}\n\nexport function otelHooks(opts: OtelHooksOpts = {}): FlowHooks {\n const tracer: Tracer =\n opts.tracer ?? trace.getTracer(TRACER_NAME, TRACER_VERSION);\n const flowPrefix = opts.spanNamePrefix?.flow ?? DEFAULT_FLOW_PREFIX;\n const stepPrefix = opts.spanNamePrefix?.step ?? DEFAULT_STEP_PREFIX;\n const baseAttrs: Attributes = opts.defaultAttributes ?? {};\n\n const flowCtxs = new Map<RunId, Context>();\n const stepStartTimes = new Map<string, Date>();\n\n function withGuard<E>(\n name: string,\n fn: (event: E) => void,\n ): (event: E) => void {\n return (event: E) => {\n try {\n fn(event);\n } catch (err) {\n console.error(`[@nagi-js/otel] ${name} hook failed`, err);\n }\n };\n }\n\n function flowAttrs(event: {\n readonly runId: RunId;\n readonly flowId: string;\n }): Attributes {\n return {\n ...baseAttrs,\n \"nagi.flow.id\": event.flowId,\n \"nagi.run.id\": event.runId,\n };\n }\n\n function stepAttrs(event: StepEvent): Attributes {\n return {\n ...flowAttrs(event),\n \"nagi.step.id\": event.stepId,\n \"nagi.step.attempt\": event.attempt,\n \"nagi.step.kind\": event.kind,\n };\n }\n\n function startStepSpan(event: StepStartEvent): Span {\n const parentCtx = flowCtxs.get(event.runId) ?? context.active();\n return tracer.startSpan(\n `${stepPrefix} ${event.stepId}`,\n {\n kind: SpanKind.INTERNAL,\n startTime: event.at,\n attributes: stepAttrs(event),\n },\n parentCtx,\n );\n }\n\n function resolveParentContext(event: FlowStartEvent): Context {\n if (!event.parent) return context.active();\n const stepSpan = stepSpanRegistry.get(\n stepKey(event.parent.runId, event.parent.stepId, event.parent.attempt),\n );\n if (stepSpan) return trace.setSpan(context.active(), stepSpan);\n const parentFlowCtx = flowCtxs.get(event.parent.runId);\n if (parentFlowCtx) return parentFlowCtx;\n return context.active();\n }\n\n function endStepSpanOk(event: StepCompleteEvent, span: Span): void {\n const k = stepKey(event.runId, event.stepId, event.attempt);\n const startedAt = stepStartTimes.get(k);\n const durationMs =\n event.kind === \"match\" && startedAt\n ? event.at.getTime() - startedAt.getTime()\n : event.durationMs;\n span.setAttribute(\"nagi.step.duration_ms\", durationMs);\n span.end(event.at);\n }\n\n function endStepSpanErr(\n span: Span,\n error: SerializedError,\n endAt: Date,\n ): void {\n span.recordException(toError(error));\n span.setAttribute(\"error.type\", error.name);\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.end(endAt);\n }\n\n function consumeStepSpan(\n runId: RunId,\n stepId: StepId,\n attempt: AttemptNumber,\n ): Span | undefined {\n const k = stepKey(runId, stepId, attempt);\n const span = stepSpanRegistry.get(k);\n stepSpanRegistry.delete(k);\n stepStartTimes.delete(k);\n return span;\n }\n\n return {\n onFlowStart: withGuard<FlowStartEvent>(\"onFlowStart\", (event) => {\n const parentCtx = resolveParentContext(event);\n const attrs: Attributes = { ...flowAttrs(event) };\n if (event.parent) {\n attrs[\"nagi.parent.run.id\"] = event.parent.runId;\n attrs[\"nagi.parent.step.id\"] = event.parent.stepId;\n attrs[\"nagi.parent.step.attempt\"] = event.parent.attempt;\n }\n const span = tracer.startSpan(\n `${flowPrefix} ${event.flowId}`,\n {\n kind: SpanKind.INTERNAL,\n startTime: event.at,\n attributes: attrs,\n },\n parentCtx,\n );\n flowCtxs.set(event.runId, trace.setSpan(context.active(), span));\n }),\n\n onFlowComplete: withGuard<FlowCompleteEvent>(\"onFlowComplete\", (event) => {\n const ctx = flowCtxs.get(event.runId);\n flowCtxs.delete(event.runId);\n const span = ctx ? trace.getSpan(ctx) : undefined;\n span?.end(event.at);\n }),\n\n onFlowError: withGuard<FlowErrorEvent>(\"onFlowError\", (event) => {\n const ctx = flowCtxs.get(event.runId);\n flowCtxs.delete(event.runId);\n const span = ctx ? trace.getSpan(ctx) : undefined;\n if (span) endStepSpanErr(span, event.error, event.at);\n }),\n\n onStepStart: withGuard<StepStartEvent>(\"onStepStart\", (event) => {\n const span = startStepSpan(event);\n const k = stepKey(event.runId, event.stepId, event.attempt);\n stepSpanRegistry.set(k, span);\n stepStartTimes.set(k, event.at);\n }),\n\n onStepComplete: withGuard<StepCompleteEvent>(\"onStepComplete\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanOk(event, span);\n }),\n\n onStepError: withGuard<StepErrorEvent>(\"onStepError\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanErr(span, event.error, event.at);\n }),\n\n onStepRetry: withGuard<StepRetryEvent>(\"onStepRetry\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanErr(span, event.error, event.at);\n\n const flowCtx = flowCtxs.get(event.runId);\n const flowSpan = flowCtx ? trace.getSpan(flowCtx) : undefined;\n flowSpan?.addEvent(\n \"nagi.retry.scheduled\",\n {\n \"nagi.step.id\": event.stepId,\n \"nagi.step.attempt\": event.attempt,\n \"nagi.next_attempt_at\": event.nextAttemptAt.toISOString(),\n },\n event.at,\n );\n }),\n\n onSignalReceived: withGuard<SignalReceivedEvent>(\n \"onSignalReceived\",\n (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (!span) return;\n span.addEvent(\n \"nagi.signal.received\",\n { \"nagi.signal.payload_present\": event.payload !== null },\n event.at,\n );\n span.setAttribute(\"nagi.step.duration_ms\", 0);\n span.end(event.at);\n },\n ),\n };\n}\n\nfunction toError(err: SerializedError): Error {\n const e = new Error(err.message);\n e.name = err.name;\n if (err.stack !== undefined) e.stack = err.stack;\n return e;\n}\n"]}
1
+ {"version":3,"sources":["../src/compose.ts","../src/context.ts","../src/hooks.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n FlowCompleteEvent,\n FlowErrorEvent,\n FlowHooks,\n FlowStartEvent,\n SignalReceivedEvent,\n SignalSentEvent,\n StepCompleteEvent,\n StepErrorEvent,\n StepRetryEvent,\n StepStartEvent,\n} from \"@nagi-js/core\";\n\nexport function composeHooks(...hooks: readonly FlowHooks[]): FlowHooks {\n const result: {\n onFlowStart?: (event: FlowStartEvent) => Promise<void>;\n onFlowComplete?: (event: FlowCompleteEvent) => Promise<void>;\n onFlowError?: (event: FlowErrorEvent) => Promise<void>;\n onStepStart?: (event: StepStartEvent) => Promise<void>;\n onStepComplete?: (event: StepCompleteEvent) => Promise<void>;\n onStepError?: (event: StepErrorEvent) => Promise<void>;\n onStepRetry?: (event: StepRetryEvent) => Promise<void>;\n onSignalSent?: (event: SignalSentEvent) => Promise<void>;\n onSignalReceived?: (event: SignalReceivedEvent) => Promise<void>;\n } = {};\n\n const fs = pick(hooks, \"onFlowStart\");\n if (fs.length > 0) result.onFlowStart = fanout(\"onFlowStart\", fs);\n\n const fc = pick(hooks, \"onFlowComplete\");\n if (fc.length > 0) result.onFlowComplete = fanout(\"onFlowComplete\", fc);\n\n const fe = pick(hooks, \"onFlowError\");\n if (fe.length > 0) result.onFlowError = fanout(\"onFlowError\", fe);\n\n const ss = pick(hooks, \"onStepStart\");\n if (ss.length > 0) result.onStepStart = fanout(\"onStepStart\", ss);\n\n const sc = pick(hooks, \"onStepComplete\");\n if (sc.length > 0) result.onStepComplete = fanout(\"onStepComplete\", sc);\n\n const se = pick(hooks, \"onStepError\");\n if (se.length > 0) result.onStepError = fanout(\"onStepError\", se);\n\n const sr = pick(hooks, \"onStepRetry\");\n if (sr.length > 0) result.onStepRetry = fanout(\"onStepRetry\", sr);\n\n const sigS = pick(hooks, \"onSignalSent\");\n if (sigS.length > 0) result.onSignalSent = fanout(\"onSignalSent\", sigS);\n\n const sigR = pick(hooks, \"onSignalReceived\");\n if (sigR.length > 0)\n result.onSignalReceived = fanout(\"onSignalReceived\", sigR);\n\n return result;\n}\n\nfunction pick<K extends keyof FlowHooks>(\n hooks: readonly FlowHooks[],\n name: K,\n): Array<NonNullable<FlowHooks[K]>> {\n const out: Array<NonNullable<FlowHooks[K]>> = [];\n for (const h of hooks) {\n const fn = h[name];\n if (fn !== undefined) out.push(fn);\n }\n return out;\n}\n\nfunction fanout<E>(\n name: string,\n subs: ReadonlyArray<(event: E) => void | Promise<void>>,\n): (event: E) => Promise<void> {\n return async (event: E) => {\n for (const fn of subs) {\n try {\n await fn(event);\n } catch (err) {\n console.error(\n `[@nagi-js/otel] composeHooks: ${name} subscriber threw`,\n err,\n );\n }\n }\n };\n}\n","import type { AttemptNumber, RunId, StepCtx, StepId } from \"@nagi-js/core\";\nimport type { Span } from \"@opentelemetry/api\";\n\nconst SEP = \"\\x1f\";\n\nexport function stepKey(\n runId: RunId,\n stepId: StepId,\n attempt: AttemptNumber,\n): string {\n return `${runId}${SEP}${stepId}${SEP}${attempt}`;\n}\n\nexport const stepSpanRegistry = new Map<string, Span>();\n\nexport function getStepSpan(\n ctx: Pick<StepCtx<unknown>, \"runId\" | \"stepId\" | \"attempt\">,\n): Span | undefined {\n return stepSpanRegistry.get(stepKey(ctx.runId, ctx.stepId, ctx.attempt));\n}\n","import type {\n AttemptNumber,\n FlowCompleteEvent,\n FlowErrorEvent,\n FlowHooks,\n FlowStartEvent,\n RunId,\n SerializedError,\n SignalReceivedEvent,\n StepCompleteEvent,\n StepErrorEvent,\n StepEvent,\n StepId,\n StepRetryEvent,\n StepStartEvent,\n} from \"@nagi-js/core\";\nimport {\n type Attributes,\n type Context,\n context,\n type Span,\n SpanKind,\n SpanStatusCode,\n type Tracer,\n trace,\n} from \"@opentelemetry/api\";\nimport { stepKey, stepSpanRegistry } from \"./context\";\n\nconst TRACER_NAME = \"@nagi-js/otel\";\nconst TRACER_VERSION = \"0.0.0\";\n\nconst DEFAULT_FLOW_PREFIX = \"flow\";\nconst DEFAULT_STEP_PREFIX = \"step\";\n\nexport interface OtelHooksOpts {\n readonly tracer?: Tracer;\n readonly spanNamePrefix?: { readonly flow?: string; readonly step?: string };\n readonly defaultAttributes?: Attributes;\n}\n\nexport function otelHooks(opts: OtelHooksOpts = {}): FlowHooks {\n const tracer: Tracer =\n opts.tracer ?? trace.getTracer(TRACER_NAME, TRACER_VERSION);\n const flowPrefix = opts.spanNamePrefix?.flow ?? DEFAULT_FLOW_PREFIX;\n const stepPrefix = opts.spanNamePrefix?.step ?? DEFAULT_STEP_PREFIX;\n const baseAttrs: Attributes = opts.defaultAttributes ?? {};\n\n const flowCtxs = new Map<RunId, Context>();\n const stepStartTimes = new Map<string, Date>();\n\n function withGuard<E>(\n name: string,\n fn: (event: E) => void,\n ): (event: E) => void {\n return (event: E) => {\n try {\n fn(event);\n } catch (err) {\n console.error(`[@nagi-js/otel] ${name} hook failed`, err);\n }\n };\n }\n\n function flowAttrs(event: {\n readonly runId: RunId;\n readonly flowId: string;\n }): Attributes {\n return {\n ...baseAttrs,\n \"nagi.flow.id\": event.flowId,\n \"nagi.run.id\": event.runId,\n };\n }\n\n function stepAttrs(event: StepEvent): Attributes {\n return {\n ...flowAttrs(event),\n \"nagi.step.id\": event.stepId,\n \"nagi.step.attempt\": event.attempt,\n \"nagi.step.kind\": event.kind,\n };\n }\n\n function startStepSpan(event: StepStartEvent): Span {\n const parentCtx = flowCtxs.get(event.runId) ?? context.active();\n return tracer.startSpan(\n `${stepPrefix} ${event.stepId}`,\n {\n kind: SpanKind.INTERNAL,\n startTime: event.at,\n attributes: stepAttrs(event),\n },\n parentCtx,\n );\n }\n\n function resolveParentContext(event: FlowStartEvent): Context {\n if (!event.parent) return context.active();\n const stepSpan = stepSpanRegistry.get(\n stepKey(event.parent.runId, event.parent.stepId, event.parent.attempt),\n );\n if (stepSpan) return trace.setSpan(context.active(), stepSpan);\n const parentFlowCtx = flowCtxs.get(event.parent.runId);\n if (parentFlowCtx) return parentFlowCtx;\n return context.active();\n }\n\n function endStepSpanOk(event: StepCompleteEvent, span: Span): void {\n const k = stepKey(event.runId, event.stepId, event.attempt);\n const startedAt = stepStartTimes.get(k);\n // match/subflow completions carry no durationMs; recompute from the span's\n // start, and omit the attribute entirely if even that is unavailable.\n const durationMs =\n event.durationMs ??\n (startedAt ? event.at.getTime() - startedAt.getTime() : undefined);\n if (durationMs !== undefined) {\n span.setAttribute(\"nagi.step.duration_ms\", durationMs);\n }\n span.end(event.at);\n }\n\n function endStepSpanErr(\n span: Span,\n error: SerializedError,\n endAt: Date,\n ): void {\n span.recordException(toError(error));\n span.setAttribute(\"error.type\", error.name);\n span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });\n span.end(endAt);\n }\n\n function consumeStepSpan(\n runId: RunId,\n stepId: StepId,\n attempt: AttemptNumber,\n ): Span | undefined {\n const k = stepKey(runId, stepId, attempt);\n const span = stepSpanRegistry.get(k);\n stepSpanRegistry.delete(k);\n stepStartTimes.delete(k);\n return span;\n }\n\n return {\n onFlowStart: withGuard<FlowStartEvent>(\"onFlowStart\", (event) => {\n const parentCtx = resolveParentContext(event);\n const attrs: Attributes = { ...flowAttrs(event) };\n if (event.parent) {\n attrs[\"nagi.parent.run.id\"] = event.parent.runId;\n attrs[\"nagi.parent.step.id\"] = event.parent.stepId;\n attrs[\"nagi.parent.step.attempt\"] = event.parent.attempt;\n }\n const span = tracer.startSpan(\n `${flowPrefix} ${event.flowId}`,\n {\n kind: SpanKind.INTERNAL,\n startTime: event.at,\n attributes: attrs,\n },\n parentCtx,\n );\n flowCtxs.set(event.runId, trace.setSpan(context.active(), span));\n }),\n\n onFlowComplete: withGuard<FlowCompleteEvent>(\"onFlowComplete\", (event) => {\n const ctx = flowCtxs.get(event.runId);\n flowCtxs.delete(event.runId);\n const span = ctx ? trace.getSpan(ctx) : undefined;\n span?.end(event.at);\n }),\n\n onFlowError: withGuard<FlowErrorEvent>(\"onFlowError\", (event) => {\n const ctx = flowCtxs.get(event.runId);\n flowCtxs.delete(event.runId);\n const span = ctx ? trace.getSpan(ctx) : undefined;\n if (span) endStepSpanErr(span, event.error, event.at);\n }),\n\n onStepStart: withGuard<StepStartEvent>(\"onStepStart\", (event) => {\n const span = startStepSpan(event);\n const k = stepKey(event.runId, event.stepId, event.attempt);\n stepSpanRegistry.set(k, span);\n stepStartTimes.set(k, event.at);\n }),\n\n onStepComplete: withGuard<StepCompleteEvent>(\"onStepComplete\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanOk(event, span);\n }),\n\n onStepError: withGuard<StepErrorEvent>(\"onStepError\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanErr(span, event.error, event.at);\n }),\n\n onStepRetry: withGuard<StepRetryEvent>(\"onStepRetry\", (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (span) endStepSpanErr(span, event.error, event.at);\n\n const flowCtx = flowCtxs.get(event.runId);\n const flowSpan = flowCtx ? trace.getSpan(flowCtx) : undefined;\n flowSpan?.addEvent(\n \"nagi.retry.scheduled\",\n {\n \"nagi.step.id\": event.stepId,\n \"nagi.step.attempt\": event.attempt,\n \"nagi.next_attempt_at\": event.nextAttemptAt.toISOString(),\n },\n event.at,\n );\n }),\n\n onSignalReceived: withGuard<SignalReceivedEvent>(\n \"onSignalReceived\",\n (event) => {\n const span = consumeStepSpan(event.runId, event.stepId, event.attempt);\n if (!span) return;\n span.addEvent(\n \"nagi.signal.received\",\n { \"nagi.signal.payload_present\": event.payload !== null },\n event.at,\n );\n span.setAttribute(\"nagi.step.duration_ms\", 0);\n span.end(event.at);\n },\n ),\n };\n}\n\nfunction toError(err: SerializedError): Error {\n const e = new Error(err.message);\n e.name = err.name;\n if (err.stack !== undefined) e.stack = err.stack;\n return e;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nagi-js/otel",
3
- "version": "0.1.1-rc.10",
3
+ "version": "0.1.1-rc.13",
4
4
  "description": "OpenTelemetry hooks adapter for nagi.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,7 +35,7 @@
35
35
  "LICENSE"
36
36
  ],
37
37
  "dependencies": {
38
- "@nagi-js/core": "0.1.1-rc.10"
38
+ "@nagi-js/core": "0.1.1-rc.13"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "@opentelemetry/api": "^1.9.0"