@ai-agent-forge/plugin-observability 0.85.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 @@
1
+ {"version":3,"file":"observability.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * First-party observability plugin: a per-session bounded event journal over\n * the draft lifecycle catalog plus a deterministic problem-report exporter.\n *\n * Extracted from the host's `src/plugins/observability.ts` (D-075 S4, second\n * B-class batch). The plugin is an ordinary capability-plugin citizen: it\n * subscribes through `api.lifecycle.registerObserve`, persists reports through\n * `api.output` when the host declares the `output-artifacts` feature, and\n * never touches host internals. Every payload that leaves the journal through\n * a problem report is pushed through the host output serializer redaction\n * channel, so internal field keys are replaced at any depth before anything\n * is exported.\n *\n * Event definitions are host-owned: the host's bootstrap lifecycle plugin\n * defines every catalog event before capability plugins load, and this plugin\n * registers observers by `{ id, version }` reference only (see\n * `./event-ids.ts`). A host that has not defined a subscribed event gets a\n * structured registration failure instead of a silent empty subscription.\n */\n\nimport { appendFileSync } from \"node:fs\";\nimport type {\n\tCapabilityAPI,\n\tDisposableRegistration,\n\tLifecycleEvent,\n\tLoggerRecord,\n\tMetricsCancelLatencySampledV1,\n\tMetricsMemoryRecallSampledV1,\n\tMetricsNotSampledV1,\n\tMetricsSnapshotV1,\n\tMetricsTokensSampledV1,\n\tObservabilityExportSinkV1,\n\tObservabilityHostAdapterV1,\n\tObservabilityJournalEntryV1,\n\tObservabilityJournalStatsV1,\n\tObservabilityLogLevel,\n\tObservabilityMetricsOptions,\n\tObservabilityPlugin,\n\tObservabilityQueryFilterV1,\n\tObservabilityTraceTimelineV1,\n\tProblemReportV1,\n\tTraceRecordV1,\n\tTraceSinkOptionsV1,\n} from \"@agent-forge/plugin-sdk\";\nimport {\n\tAGENT_SETTLED_EVENT_ID,\n\tAGENT_TASK_SETTLED_EVENT_ID,\n\tCATALOG_EVENT_VERSION,\n\tINPUT_RECEIVED_EVENT_ID,\n\tMODEL_SELECT_EVENT_ID,\n\tMODEL_STREAM_EVENT_ID,\n\tOPERATION_END_EVENT_ID,\n\tPLUGIN_DISPOSE_EVENT_ID,\n\tPLUGIN_READY_EVENT_ID,\n\tSESSION_AUTO_RETRY_EVENT_ID,\n\tSESSION_COMPACTION_COMMIT_EVENT_ID,\n\tSESSION_COMPACTION_DECISION_EVENT_ID,\n\tSESSION_COMPACTION_FAILED_EVENT_ID,\n\tSESSION_CONTEXT_REPLACED_EVENT_ID,\n\tSESSION_END_EVENT_ID,\n\tSESSION_RELOAD_EVENT_ID,\n\tSESSION_START_EVENT_ID,\n\tTOOL_CALL_EVENT_ID,\n\tTOOL_COMMIT_EVENT_ID,\n\tTOOL_EXECUTE_EVENT_ID,\n\tTOOL_EXECUTION_START_EVENT_ID,\n\tTOOL_GATE_BLOCKED_EVENT_ID,\n\tTOOL_RESULT_EVENT_ID,\n\tTOOL_RESULT_RAW_EVENT_ID,\n\tTURN_END_EVENT_ID,\n\tTURN_START_EVENT_ID,\n\tUI_PROMPT_END_EVENT_ID,\n\tUI_PROMPT_START_EVENT_ID,\n} from \"./event-ids.ts\";\nimport { createOtlpTraceExportSink } from \"./otlp-exporter.ts\";\nimport {\n\tcreateHostOutputSerializer,\n\ttype HostOutputSerializerContextV1,\n\ttype HostOutputSerializerV1,\n} from \"./output-serializer.ts\";\n\n/** The plugin's public behavior face re-exported for consumers of this module. */\nexport type { ObservabilityPlugin } from \"@agent-forge/plugin-sdk\";\n\nexport const OBSERVABILITY_PLUGIN_ID = \"agent-forge.observability\";\nexport const DEFAULT_JOURNAL_MAX_ENTRIES = 2000;\nexport const DEFAULT_PROBLEM_REPORT_TAIL_SIZE = 50;\nexport const PROBLEM_REPORT_OPERATION_ID = \"agent-forge.observability/problem-report\";\nconst REDACTION_POLICY_VERSION = \"agent-forge.observability@1\";\n/** The builtin memory capability's recall tool; its executions feed the hit rate. */\nexport const MEMORY_RECALL_TOOL_NAME = \"memory_recall\";\n\n/** Default `maxStringChars` for trace payload snapshots (design §4.3). */\nexport const DEFAULT_TRACE_MAX_STRING_CHARS = 16_000;\n/** Default snapshot budget: 384 KiB, strictly below the 512 KiB record budget (design §4.3). */\nexport const DEFAULT_TRACE_MAX_SNAPSHOT_BYTES = 393_216;\n/** Hard per-record budget; the write-path guard of last resort (design §4.2/§4.3). */\nexport const TRACE_RECORD_MAX_BYTES = 524_288;\n/** Args/result summaries inside `tool.span` data are bounded to ~2 KiB each. */\nexport const TRACE_TOOL_SUMMARY_MAX_CHARS = 2_048;\n/**\n * Upper bound per in-flight span-state table (`pendingTurns`, `toolSpans`,\n * `streams`, result-diff pairs). Bounded by design: entries are keyed by\n * in-flight ids and deleted on pairing, but a crash or a lost terminal event\n * would otherwise leak them — past the bound the oldest unpaired entry is\n * evicted FIFO (first key in Map insertion order).\n */\nexport const TRACE_SPAN_STATE_MAX_ENTRIES = 256;\n/** Serialized leaves below this size never pay for their own redaction placeholder. */\nconst TRACE_SNAPSHOT_MIN_REDACTABLE_BYTES = 64;\nconst TRACE_SCHEMA_V1 = \"agent-forge/trace.v1\";\nconst TRACE_SINK_FAILURE_STAGE = \"observability.trace.sink-failure\";\n\n/** Trace-sink injection: host adapter plus optional snapshot bounds (design §4.4). */\nexport interface ObservabilityTraceConfig {\n\treadonly adapter: ObservabilityHostAdapterV1;\n\treadonly options?: TraceSinkOptionsV1;\n\t/**\n\t * Host-injected telemetry export sinks (design §8 seam): every finalized\n\t * trace record is handed to each sink synchronously; sink failures are\n\t * isolated and never break the file sink or event delivery.\n\t */\n\treadonly exportSinks?: readonly ObservabilityExportSinkV1[];\n}\n\nexport interface ObservabilityPluginOptions {\n\t/** Maximum retained journal entries; oldest entries are dropped first. */\n\treadonly maxEntries?: number;\n\t/** Injected clock; must be provided wherever determinism is required. */\n\treadonly now?: () => number;\n\t/** Number of trailing journal entries embedded in a problem report. */\n\treadonly tailSize?: number;\n\t/**\n\t * Trace-file sink (design §4). Omitted keeps the plugin trace-free: no\n\t * adapter calls, no file, journal and problem-report behavior unchanged.\n\t */\n\treadonly trace?: ObservabilityTraceConfig;\n}\n\nexport interface ObservabilityJournalOptions {\n\treadonly maxEntries?: number;\n\treadonly now?: () => number;\n}\n\nexport interface ObservabilityJournal {\n\tappendEvent(event: LifecycleEvent<unknown>): ObservabilityJournalEntryV1 | null;\n\tquery(filter?: ObservabilityQueryFilterV1): readonly ObservabilityJournalEntryV1[];\n\texplainTrace(traceId: string): ObservabilityTraceTimelineV1;\n\tgetMetrics(options?: ObservabilityMetricsOptions): MetricsSnapshotV1;\n\tstats(): ObservabilityJournalStatsV1;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction assertPositiveSafeInteger(value: number, label: string): void {\n\tif (!Number.isSafeInteger(value) || value < 1) throw new Error(`${label} must be a positive safe integer`);\n}\n\nfunction assertNonEmptyString(value: string, label: string): void {\n\tif (typeof value !== \"string\" || value.trim() === \"\") throw new Error(`${label} must be a non-empty string`);\n}\n\nfunction firstTextContent(data: Record<string, unknown>): string | undefined {\n\tconst content = data.content;\n\tif (!Array.isArray(content)) return undefined;\n\tfor (const item of content) {\n\t\tif (isRecord(item) && item.type === \"text\" && typeof item.text === \"string\") return item.text;\n\t}\n\treturn undefined;\n}\n\nfunction extractSessionId(data: unknown): string | null {\n\tif (!isRecord(data) || typeof data.sessionId !== \"string\" || data.sessionId === \"\") return null;\n\treturn data.sessionId;\n}\n\nfunction deriveLevel(stage: string, data: unknown): ObservabilityLogLevel {\n\tif (!isRecord(data)) return \"info\";\n\tif (stage === MODEL_STREAM_EVENT_ID) return isRecord(data.error) ? \"error\" : \"info\";\n\tif (stage === OPERATION_END_EVENT_ID) {\n\t\tif (data.status === \"failed\") return \"error\";\n\t\treturn data.status === \"cancelled\" ? \"warn\" : \"info\";\n\t}\n\tif (stage === PLUGIN_DISPOSE_EVENT_ID) return data.status === \"failed\" ? \"error\" : \"info\";\n\tif (data.isError === true) return \"error\";\n\treturn \"info\";\n}\n\nfunction buildSummary(stage: string, data: unknown): string {\n\tif (!isRecord(data)) return stage;\n\tconst isError = data.isError === true;\n\tswitch (stage) {\n\t\tcase MODEL_STREAM_EVENT_ID:\n\t\t\treturn `${String(data.phase)} ${String(data.event)}`;\n\t\tcase TOOL_CALL_EVENT_ID:\n\t\t\treturn `call ${String(data.toolName)}`;\n\t\tcase TOOL_EXECUTE_EVENT_ID:\n\t\t\treturn `execute ${String(data.toolName)}${isError ? \" (error)\" : \"\"}`;\n\t\tcase TOOL_RESULT_RAW_EVENT_ID:\n\t\tcase TOOL_RESULT_EVENT_ID:\n\t\t\treturn `result ${String(data.toolName)}${isError ? \" (error)\" : \"\"}`;\n\t\tcase TOOL_COMMIT_EVENT_ID:\n\t\t\treturn `commit ${String(data.toolName)}${isError ? \" (error)\" : \"\"}`;\n\t\tcase OPERATION_END_EVENT_ID:\n\t\t\treturn `${String(data.operationKind)} ${String(data.status)}`;\n\t\tcase PLUGIN_READY_EVENT_ID:\n\t\t\treturn `ready ${String(data.pluginId)}`;\n\t\tcase PLUGIN_DISPOSE_EVENT_ID:\n\t\t\treturn `disposed ${String(data.pluginId)} (${String(data.status)})`;\n\t\tcase SESSION_RELOAD_EVENT_ID:\n\t\t\treturn `generation ${String(data.generation)}`;\n\t\tcase SESSION_CONTEXT_REPLACED_EVENT_ID:\n\t\t\treturn `context replaced (${String(data.reason)})`;\n\t\tdefault:\n\t\t\treturn stage;\n\t}\n}\n\ninterface ExtractedErrorInfo {\n\treadonly code: string;\n\treadonly message: string;\n\treadonly phase?: string;\n}\n\nfunction extractErrorInfo(entry: ObservabilityJournalEntryV1): ExtractedErrorInfo | null {\n\tconst data = entry.data;\n\t// v8 ignore next -- error 级条目的 data 恒为对象(deriveLevel 已保证)\n\tif (!isRecord(data)) return null;\n\tconst phase = typeof data.phase === \"string\" && data.phase !== \"\" ? data.phase : undefined;\n\tif (isRecord(data.error) && typeof data.error.code === \"string\" && typeof data.error.message === \"string\") {\n\t\treturn { code: data.error.code, message: data.error.message, ...(phase === undefined ? {} : { phase }) };\n\t}\n\tif (data.status === \"failed\") {\n\t\tconst message = typeof data.errorMessage === \"string\" ? data.errorMessage : entry.summary;\n\t\treturn { code: \"operation.failed\", message, ...(phase === undefined ? {} : { phase }) };\n\t}\n\tif (data.isError === true) {\n\t\tconst message = firstTextContent(data) ?? entry.summary;\n\t\treturn { code: \"tool.failed\", message, ...(phase === undefined ? {} : { phase }) };\n\t}\n\treturn null;\n}\n\n/** Deterministic JSON: sorted object keys, no whitespace, stable scalars. */\nfunction canonicalJson(value: unknown): string {\n\tif (value === null) return \"null\";\n\tif (typeof value === \"string\") return JSON.stringify(value);\n\tif (typeof value === \"number\") return Number.isFinite(value) ? String(value) : \"null\";\n\tif (typeof value === \"boolean\") return String(value);\n\tif (Array.isArray(value)) return `[${value.map(canonicalJson).join(\",\")}]`;\n\t// v8 ignore next -- 报告体仅由 JSON-safe 字段构成,不可序列化分支不可达\n\tif (isRecord(value)) {\n\t\tconst keys = Object.keys(value)\n\t\t\t.filter((key) => value[key] !== undefined)\n\t\t\t.sort();\n\t\treturn `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(\",\")}}`;\n\t}\n\tthrow new Error(`Value is not JSON-serializable: ${typeof value}`);\n}\n\n/** FNV-1a 32-bit over the UTF-8 bytes of the input, rendered as 8 hex chars. */\nexport function fnv1a32Hex(input: string): string {\n\tlet hash = 0x811c9dc5;\n\tfor (const byte of new TextEncoder().encode(input)) {\n\t\thash ^= byte;\n\t\thash = Math.imul(hash, 0x01000193);\n\t}\n\treturn (hash >>> 0).toString(16).padStart(8, \"0\");\n}\n\n/**\n * Bounded ring journal with drop-oldest eviction and a replay guard: a\n * lifecycle event id already seen is ignored, so redelivery stays idempotent.\n * The replay window matches the ring bound — evicted events may be re-recorded.\n */\nexport function createObservabilityJournal(options: ObservabilityJournalOptions = {}): ObservabilityJournal {\n\tconst maxEntries = options.maxEntries ?? DEFAULT_JOURNAL_MAX_ENTRIES;\n\tassertPositiveSafeInteger(maxEntries, \"Journal maxEntries\");\n\tconst now = options.now ?? (() => Date.now());\n\tconst entries: ObservabilityJournalEntryV1[] = [];\n\tconst seenEventIds = new Set<string>();\n\tconst seenOrder: string[] = [];\n\tlet sequence = 0;\n\tlet dropped = 0;\n\n\tconst filterEntries = (filter: ObservabilityQueryFilterV1 | undefined): readonly ObservabilityJournalEntryV1[] => {\n\t\tif (filter === undefined) return entries;\n\t\tif (filter.limit !== undefined) assertPositiveSafeInteger(filter.limit, \"Query limit\");\n\t\tconst filtered = entries.filter(\n\t\t\t(entry) =>\n\t\t\t\t(filter.sessionId === undefined || entry.sessionId === filter.sessionId) &&\n\t\t\t\t(filter.stage === undefined || entry.stage === filter.stage) &&\n\t\t\t\t(filter.level === undefined || entry.level === filter.level) &&\n\t\t\t\t(filter.traceId === undefined || entry.traceId === filter.traceId),\n\t\t);\n\t\treturn filter.limit === undefined ? filtered : filtered.slice(-filter.limit);\n\t};\n\n\treturn {\n\t\tappendEvent(event) {\n\t\t\tassertNonEmptyString(event.id, \"Lifecycle event id\");\n\t\t\tif (seenEventIds.has(event.id)) return null;\n\t\t\tseenEventIds.add(event.id);\n\t\t\tseenOrder.push(event.id);\n\t\t\tconst entry: ObservabilityJournalEntryV1 = Object.freeze({\n\t\t\t\tsequence: ++sequence,\n\t\t\t\tat: now(),\n\t\t\t\tsessionId: extractSessionId(event.data),\n\t\t\t\tstage: event.type,\n\t\t\t\tlevel: deriveLevel(event.type, event.data),\n\t\t\t\t...(event.correlationId === undefined ? {} : { traceId: event.correlationId }),\n\t\t\t\tsummary: buildSummary(event.type, event.data),\n\t\t\t\t...(event.data === undefined ? {} : { data: event.data }),\n\t\t\t});\n\t\t\tentries.push(entry);\n\t\t\twhile (entries.length > maxEntries) {\n\t\t\t\tentries.shift();\n\t\t\t\tconst evicted = seenOrder.shift();\n\t\t\t\t// v8 ignore next -- seenOrder 与 entries 同步增删,evicted 不会有 undefined\n\t\t\t\tif (evicted !== undefined) seenEventIds.delete(evicted);\n\t\t\t\tdropped += 1;\n\t\t\t}\n\t\t\treturn entry;\n\t\t},\n\t\tquery: (filter) => [...filterEntries(filter)],\n\t\texplainTrace(traceId) {\n\t\t\tassertNonEmptyString(traceId, \"Trace id\");\n\t\t\tlet previous: number | null = null;\n\t\t\tconst steps = entries\n\t\t\t\t.filter((entry) => entry.traceId === traceId)\n\t\t\t\t.map((entry) => {\n\t\t\t\t\tconst durationMs = previous === null ? null : entry.at - previous;\n\t\t\t\t\tprevious = entry.at;\n\t\t\t\t\treturn Object.freeze({ entry, durationMs });\n\t\t\t\t});\n\t\t\treturn { traceId, steps: Object.freeze(steps) };\n\t\t},\n\t\tgetMetrics: (options) => buildMetricsSnapshot(entries, options),\n\t\tstats: () => ({ size: entries.length, dropped }),\n\t};\n}\n\n/**\n * Linear-interpolated percentile (R-7): position `(n - 1) * ratio` between the\n * sorted order statistics. Returns `null` for an empty sample.\n */\nexport function percentile(values: readonly number[], ratio: number): number | null {\n\tif (!Number.isFinite(ratio) || ratio < 0 || ratio > 1) {\n\t\tthrow new Error(\"Percentile ratio must be a number between 0 and 1\");\n\t}\n\tif (values.length === 0) return null;\n\tconst sorted = [...values].sort((a, b) => a - b);\n\tconst position = (sorted.length - 1) * ratio;\n\tconst lower = Math.floor(position);\n\tconst upper = Math.ceil(position);\n\tif (lower === upper) return sorted[lower];\n\treturn sorted[lower] + (sorted[upper] - sorted[lower]) * (position - lower);\n}\n\nconst notSampled = (reason: string): MetricsNotSampledV1 => ({ status: \"not_sampled\", reason });\n\n/** The journal carries no standalone cancel event: `operation.end(cancelled)` is itself the turn's terminal fact. */\nconst CANCEL_LATENCY_NOT_SAMPLED = notSampled(\n\t\"journal records no standalone cancel signal event; operation.end(cancelled) is itself the terminal event\",\n);\n/** The lifecycle catalog defines no usage/token-bearing event for the journal to subscribe to. */\nconst TOKENS_NOT_SAMPLED = notSampled(\"lifecycle catalog defines no usage/token cost event for the journal to record\");\n\nconst isCancelledOperationEnd = (entry: ObservabilityJournalEntryV1): boolean =>\n\tentry.stage === OPERATION_END_EVENT_ID && isRecord(entry.data) && entry.data.status === \"cancelled\";\n\ninterface TurnGroupV1 {\n\treadonly traceId: string;\n\treadonly entries: readonly ObservabilityJournalEntryV1[];\n\t/** Sequence of the group's last entry; the window keeps the trailing groups. */\n\treadonly lastSequence: number;\n}\n\n/**\n * Groups journal entries by their correlationId into turn groups ordered by\n * their last entry's sequence, then keeps only the trailing `windowTurns`\n * groups (all groups when the bound is undefined).\n */\nfunction selectTurnWindow(\n\tentries: readonly ObservabilityJournalEntryV1[],\n\twindowTurns: number | undefined,\n): readonly TurnGroupV1[] {\n\tconst groups = new Map<string, ObservabilityJournalEntryV1[]>();\n\tfor (const entry of entries) {\n\t\tif (entry.traceId === undefined) continue;\n\t\tconst group = groups.get(entry.traceId);\n\t\tif (group === undefined) groups.set(entry.traceId, [entry]);\n\t\telse group.push(entry);\n\t}\n\tconst ordered: TurnGroupV1[] = [...groups].map(([traceId, group]) => ({\n\t\ttraceId,\n\t\tentries: group,\n\t\tlastSequence: group[group.length - 1].sequence,\n\t}));\n\tordered.sort((a, b) => a.lastSequence - b.lastSequence);\n\treturn windowTurns === undefined ? ordered : ordered.slice(-windowTurns);\n}\n\n/**\n * Aggregates a deterministic product-metrics snapshot from journal entries.\n * Read-only: the entries are consumed as-is, so journal recording behavior is\n * untouched and export-side redaction cannot affect any count.\n *\n * Metric rulings over the lifecycle catalog (v1):\n * - A turn is a correlationId group. It succeeds when it contains a\n * `model.stream` entry (assistant output) and no error-level entry and no\n * `operation.end(cancelled)` terminal; duration is last.at - first.at.\n * - Tool execution is counted once per `tool.execute` entry (the settled\n * invocation; execute/result.raw/result/commit would multiply-count one call).\n * - Cancel latency is not sampled: the catalog has no standalone cancel event\n * among the journal's subscriptions, and `operation.end(cancelled)` is itself\n * the terminal event, so the cancel-to-terminal delay is always zero-by-construction.\n * - Tokens are not sampled: no usage/token event exists in the catalog.\n * - Memory recall hit: a `memory_recall` `tool.execute` whose `isError` is false\n * with non-empty `content`.\n */\nexport function buildMetricsSnapshot(\n\tentries: readonly ObservabilityJournalEntryV1[],\n\toptions: ObservabilityMetricsOptions = {},\n): MetricsSnapshotV1 {\n\tconst windowTurns = options.windowTurns;\n\tif (windowTurns !== undefined) {\n\t\tassertPositiveSafeInteger(windowTurns, \"Window turns\");\n\t}\n\tconst groups = selectTurnWindow(entries, windowTurns);\n\tconst windowEntries = groups.flatMap((group) => group.entries);\n\n\tconst firstAt = windowEntries[0]?.at ?? null;\n\tconst lastAt = windowEntries.at(-1)?.at ?? null;\n\n\tconst turnDurations: number[] = [];\n\tlet successCount = 0;\n\tfor (const group of groups) {\n\t\tconst first = group.entries[0];\n\t\tconst last = group.entries[group.entries.length - 1];\n\t\tturnDurations.push(last.at - first.at);\n\t\tconst hasAssistantOutput = group.entries.some((entry) => entry.stage === MODEL_STREAM_EVENT_ID);\n\t\tconst hasErrorLevel = group.entries.some((entry) => entry.level === \"error\");\n\t\tconst hasCancelledTerminal = group.entries.some(isCancelledOperationEnd);\n\t\tif (hasAssistantOutput && !hasErrorLevel && !hasCancelledTerminal) successCount += 1;\n\t}\n\n\tlet toolCalls = 0;\n\tlet toolErrors = 0;\n\tconst errorsByTool = new Map<string, number>();\n\tfor (const entry of windowEntries) {\n\t\tif (entry.stage !== TOOL_EXECUTE_EVENT_ID) continue;\n\t\ttoolCalls += 1;\n\t\tif (!isRecord(entry.data) || entry.data.isError !== true) continue;\n\t\ttoolErrors += 1;\n\t\tconst toolName = typeof entry.data.toolName === \"string\" ? entry.data.toolName : \"unknown\";\n\t\terrorsByTool.set(toolName, (errorsByTool.get(toolName) ?? 0) + 1);\n\t}\n\tconst topErrors = [...errorsByTool]\n\t\t.map(([toolName, errors]) => ({ toolName, errors }))\n\t\t.sort((a, b) => b.errors - a.errors || (a.toolName < b.toolName ? -1 : 1));\n\n\tlet recallCalls = 0;\n\tlet recallHits = 0;\n\tfor (const entry of windowEntries) {\n\t\tif (entry.stage !== TOOL_EXECUTE_EVENT_ID) continue;\n\t\tif (!isRecord(entry.data) || entry.data.toolName !== MEMORY_RECALL_TOOL_NAME) continue;\n\t\trecallCalls += 1;\n\t\tif (entry.data.isError !== true && Array.isArray(entry.data.content) && entry.data.content.length > 0) {\n\t\t\trecallHits += 1;\n\t\t}\n\t}\n\tconst memoryRecall: MetricsMemoryRecallSampledV1 | MetricsNotSampledV1 =\n\t\trecallCalls === 0\n\t\t\t? notSampled(\"no memory_recall tool executions in the window\")\n\t\t\t: { status: \"sampled\", calls: recallCalls, hits: recallHits, hitRate: recallHits / recallCalls };\n\n\tconst cancelLatencyMs: MetricsCancelLatencySampledV1 | MetricsNotSampledV1 = CANCEL_LATENCY_NOT_SAMPLED;\n\tconst tokens: MetricsTokensSampledV1 | MetricsNotSampledV1 = TOKENS_NOT_SAMPLED;\n\n\treturn Object.freeze({\n\t\tversion: 1,\n\t\twindow: Object.freeze({\n\t\t\twindowTurns: windowTurns ?? null,\n\t\t\tsampledTurns: groups.length,\n\t\t\tfirstAt,\n\t\t\tlastAt,\n\t\t}),\n\t\tturns: Object.freeze({\n\t\t\tcount: groups.length,\n\t\t\tsuccessCount,\n\t\t\tsuccessRate: groups.length === 0 ? null : successCount / groups.length,\n\t\t\tp50DurationMs: percentile(turnDurations, 0.5),\n\t\t\tp95DurationMs: percentile(turnDurations, 0.95),\n\t\t}),\n\t\ttools: Object.freeze({\n\t\t\tcalls: toolCalls,\n\t\t\terrors: toolErrors,\n\t\t\terrorRate: toolCalls === 0 ? null : toolErrors / toolCalls,\n\t\t\ttopErrors: Object.freeze(topErrors),\n\t\t}),\n\t\tcancelLatencyMs,\n\t\ttokens,\n\t\tmemoryRecall,\n\t});\n}\n\n/**\n * Bounded, redacted snapshot of an arbitrary JSON tree (design §4.3):\n * image-like content collapses to `{ redacted: \"image\", approxBytes }`\n * placeholders, strings over `maxStringChars` truncate with a\n * `…[truncated N chars]` suffix, and — when the serialized snapshot exceeds\n * `maxSnapshotBytes` — string leaves degrade largest-first to\n * `{ redacted: \"truncated\", approxBytes }` placeholders until it fits.\n * Structure, ordering, roles, and scalars are preserved; the function is pure\n * and total (cycles and non-serializable values become explicit placeholders).\n */\nexport function redactProviderPayloadSnapshot(\n\tpayload: unknown,\n\tlimits: { readonly maxStringChars: number; readonly maxSnapshotBytes: number },\n): unknown {\n\tconst redacted = redactTree(payload, limits, new Set<object>());\n\treturn enforceSnapshotBudget(redacted, limits.maxSnapshotBytes);\n}\n\ninterface RedactLimits {\n\treadonly maxStringChars: number;\n\treadonly maxSnapshotBytes: number;\n}\n\nconst truncationSuffix = (originalLength: number, keptLength: number): string =>\n\t`…[truncated ${originalLength - keptLength} chars]`;\n\n/** Best-effort serialized byte size; non-serializable values fall back to their string form. */\nfunction approxBytesOf(value: unknown): number {\n\ttry {\n\t\tconst serialized = JSON.stringify(value);\n\t\tif (serialized !== undefined) return Buffer.byteLength(serialized, \"utf8\");\n\t} catch {\n\t\t// fall through to the string form below\n\t}\n\treturn Buffer.byteLength(String(value), \"utf8\");\n}\n\nfunction isImageLikeContent(value: Record<string, unknown>): boolean {\n\tif (value.type === \"image\" || value.type === \"image_url\") return true;\n\tconst image = value.image;\n\tif (typeof image === \"string\" || isRecord(image)) return true;\n\tif (typeof value.base64 === \"string\") return true;\n\tconst imageUrl = value.image_url;\n\tif (typeof imageUrl === \"string\" || isRecord(imageUrl)) return true;\n\t// Google-family adapters inline images as {inlineData:{mimeType,data}} /\n\t// {inline_data:{mime_type,data}}; both carry raw base64 and must collapse.\n\tif (isRecord(value.inlineData) || isRecord(value.inline_data)) return true;\n\treturn false;\n}\n\nfunction redactTree(value: unknown, limits: RedactLimits, seen: Set<object>): unknown {\n\tif (typeof value === \"string\") {\n\t\tif (value.length > limits.maxStringChars) {\n\t\t\treturn `${value.slice(0, limits.maxStringChars)}${truncationSuffix(value.length, limits.maxStringChars)}`;\n\t\t}\n\t\treturn value;\n\t}\n\tif (Array.isArray(value)) {\n\t\tif (seen.has(value)) return { redacted: \"circular\" };\n\t\tseen.add(value);\n\t\ttry {\n\t\t\treturn value.map((item) => redactTree(item, limits, seen));\n\t\t} finally {\n\t\t\tseen.delete(value);\n\t\t}\n\t}\n\tif (!isRecord(value)) return value;\n\tif (seen.has(value)) return { redacted: \"circular\" };\n\tseen.add(value);\n\ttry {\n\t\tif (isImageLikeContent(value)) {\n\t\t\treturn { redacted: \"image\", approxBytes: approxBytesOf(value) };\n\t\t}\n\t\tconst out: Record<string, unknown> = {};\n\t\tfor (const [key, entry] of Object.entries(value)) {\n\t\t\tif (entry === undefined) continue;\n\t\t\tout[key] = redactTree(entry, limits, seen);\n\t\t}\n\t\treturn out;\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\ninterface SnapshotLeaf {\n\t/** Object.entries yields string keys, which index arrays equivalently at runtime. */\n\treadonly parent: Record<string, unknown>;\n\treadonly key: string;\n\treadonly size: number;\n}\n\n/** Collects string leaves at any depth, keeping parent references for replacement. */\nfunction collectStringLeaves(value: unknown, seen: Set<object>, out: SnapshotLeaf[]): void {\n\tif (typeof value === \"string\" || !isRecordLikeContainer(value)) return;\n\tif (seen.has(value)) return;\n\tseen.add(value);\n\ttry {\n\t\tconst parent = value as Record<string, unknown>;\n\t\tfor (const [key, entry] of Object.entries(parent)) {\n\t\t\tif (typeof entry === \"string\") {\n\t\t\t\tconst size = Buffer.byteLength(entry, \"utf8\");\n\t\t\t\tif (size >= TRACE_SNAPSHOT_MIN_REDACTABLE_BYTES) {\n\t\t\t\t\tout.push({ parent, key, size });\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcollectStringLeaves(entry, seen, out);\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tseen.delete(value);\n\t}\n}\n\nfunction isRecordLikeContainer(value: unknown): value is Record<string, unknown> | unknown[] {\n\treturn value !== null && typeof value === \"object\";\n}\n\n/**\n * Degrades the largest string leaves to `{ redacted: \"truncated\", approxBytes }`\n * placeholders until the snapshot fits `maxSnapshotBytes`. Roots that already\n * fit pass through untouched; residuals fall through to the record-level guard.\n */\nfunction enforceSnapshotBudget(root: unknown, maxSnapshotBytes: number): unknown {\n\tlet total = approxBytesOf(root);\n\tif (total <= maxSnapshotBytes) return root;\n\tconst leaves: SnapshotLeaf[] = [];\n\tcollectStringLeaves(root, new Set<object>(), leaves);\n\t// Stable sort (ES2019+): equal sizes keep deterministic walk order.\n\tleaves.sort((a, b) => b.size - a.size);\n\tfor (const leaf of leaves) {\n\t\tif (total <= maxSnapshotBytes) break;\n\t\tconst placeholder = { redacted: \"truncated\", approxBytes: leaf.size };\n\t\tleaf.parent[leaf.key] = placeholder;\n\t\ttotal -= leaf.size - approxBytesOf(placeholder);\n\t}\n\treturn root;\n}\n\n/** Trace record with the envelope fields still open; the sink assigns v/schema/seq/t. */\ntype TraceRecordDraftV1 = Omit<TraceRecordV1, \"v\" | \"schema\" | \"seq\" | \"t\">;\n\n/**\n * Last-resort write guard (design §4.3): when a serialized record exceeds the\n * 512 KiB hard budget, its `data` collapses to a record-level truncation\n * marker. Normal traffic never reaches this — the snapshot budget (384 KiB) is\n * strictly below it.\n */\nfunction enforceRecordBudget(record: TraceRecordV1): TraceRecordV1 {\n\tconst serialized = JSON.stringify(record);\n\tif (serialized !== undefined && Buffer.byteLength(serialized, \"utf8\") <= TRACE_RECORD_MAX_BYTES) return record;\n\treturn { ...record, data: { truncated: true, approxBytes: approxBytesOf(record.data) } };\n}\n\n/**\n * Bounded args/result summary for `tool.span` data (≤ ~2 KiB each): values\n * that serialize within the bound stay structured, larger ones keep only a\n * truncated serialization.\n */\nfunction boundedJsonSummary(value: unknown, maxChars: number): unknown {\n\ttry {\n\t\tconst serialized = JSON.stringify(value);\n\t\tif (serialized === undefined) return String(value);\n\t\tif (Buffer.byteLength(serialized, \"utf8\") <= maxChars) return value;\n\t\treturn `${serialized.slice(0, maxChars)}${truncationSuffix(serialized.length, maxChars)}`;\n\t} catch (error) {\n\t\treturn `[unserializable: ${error instanceof Error ? error.message : String(error)}]`;\n\t}\n}\n\n/**\n * Upper bound on retained stack lines for a mirrored Error value; the same\n * bound the host logger applies to a logged cause (core/logger.ts).\n */\nconst MIRROR_ERROR_STACK_MAX_LINES = 10;\n\n/**\n * Error-aware bounded serialization for the `plugin.log` mirror, with the same\n * cause-bounding semantics as the host logger: an `Error` value becomes\n * `{ name, message, stack: first 10 lines }` — plain JSON serialization would\n * collapse it to `{}` because Errors own no enumerable properties — while every\n * other value keeps the existing bounded JSON behavior. Errors nested inside\n * objects/arrays are replaced at any depth, cycle-safe.\n */\nfunction errorAwareBoundedJsonSummary(value: unknown, maxChars: number): unknown {\n\tconst replaceErrors = (input: unknown, seen: Set<object>): unknown => {\n\t\tif (input instanceof Error) {\n\t\t\tconst stackLines = input.stack?.split(\"\\n\");\n\t\t\tconst stack =\n\t\t\t\tstackLines === undefined ? undefined : stackLines.slice(0, MIRROR_ERROR_STACK_MAX_LINES).join(\"\\n\");\n\t\t\treturn { name: input.name, message: input.message, ...(stack === undefined ? {} : { stack }) };\n\t\t}\n\t\tif (Array.isArray(input) || isRecord(input)) {\n\t\t\tif (seen.has(input)) return { redacted: \"circular\" };\n\t\t\tseen.add(input);\n\t\t\ttry {\n\t\t\t\treturn Array.isArray(input)\n\t\t\t\t\t? input.map((item) => replaceErrors(item, seen))\n\t\t\t\t\t: Object.fromEntries(Object.entries(input).map(([key, entry]) => [key, replaceErrors(entry, seen)]));\n\t\t\t} finally {\n\t\t\t\tseen.delete(input);\n\t\t\t}\n\t\t}\n\t\treturn input;\n\t};\n\treturn boundedJsonSummary(replaceErrors(value, new Set<object>()), maxChars);\n}\n\ninterface TurnSpanStart {\n\treadonly startedAt: number;\n}\n\ninterface ToolSpanState {\n\tstartedAt?: number;\n\ttoolName: string;\n\targs?: unknown;\n\tresult?: unknown;\n\t/** Set by tool.gate.blocked before the commit projection; keys stay absent on a normal call. */\n\tblocked?: boolean;\n\tblockReason?: string;\n}\n\n/**\n * First-party delegation tool names whose `tool.span` record gains a\n * structured child-session reference (design §4.6 父子关联行): `subagent_run`'s\n * foreground projection parses `tasks[].sessionId`, `subagent_result`'s a\n * top-level `sessionId`. Third-party delegation tools are deliberately not\n * auto-covered — they can build their own collector over the same public\n * lifecycle subscription face.\n */\nconst DELEGATION_TOOL_NAMES: ReadonlySet<string> = new Set([\"subagent_run\", \"subagent_result\"]);\n\ninterface ChildSessionReference {\n\treadonly childSessionId: string;\n\treadonly childSessionCount: number;\n}\n\nfunction firstTextOfContent(content: unknown): string | undefined {\n\tif (!Array.isArray(content)) return undefined;\n\tfor (const item of content) {\n\t\tif (isRecord(item) && item.type === \"text\" && typeof item.text === \"string\") return item.text;\n\t}\n\treturn undefined;\n}\n\n/**\n * Extracts the structured child-session reference from an untruncated\n * delegation tool result: the projection JSON inside the raw `tool.execute`\n * content is parsed — never the 2 KiB bounded display summary. Shape stays\n * stable across task counts: `childSessionId` is always the first extracted\n * session id and `childSessionCount` the number of session ids extracted\n * (1 for `subagent_result`). Unparsable results, unknown tool names, or\n * projections without a session id yield undefined — the keys stay absent,\n * never fabricated.\n */\nfunction extractChildSessionReference(toolName: string, result: unknown): ChildSessionReference | undefined {\n\tif (!DELEGATION_TOOL_NAMES.has(toolName)) return undefined;\n\tconst text = firstTextOfContent(result);\n\tif (text === undefined) return undefined;\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(text);\n\t} catch {\n\t\treturn undefined;\n\t}\n\tif (!isRecord(parsed)) return undefined;\n\tif (toolName === \"subagent_result\") {\n\t\tif (typeof parsed.sessionId !== \"string\" || parsed.sessionId === \"\") return undefined;\n\t\treturn { childSessionId: parsed.sessionId, childSessionCount: 1 };\n\t}\n\tconst tasks = parsed.tasks;\n\tif (!Array.isArray(tasks)) return undefined;\n\tconst sessionIds: string[] = [];\n\tfor (const task of tasks) {\n\t\tif (isRecord(task) && typeof task.sessionId === \"string\" && task.sessionId !== \"\") {\n\t\t\tsessionIds.push(task.sessionId);\n\t\t}\n\t}\n\tif (sessionIds.length === 0) return undefined;\n\treturn { childSessionId: sessionIds[0], childSessionCount: sessionIds.length };\n}\n\ninterface StreamTiming {\n\tstartedAt?: number;\n\tfirstDeltaAt?: number;\n}\n\ninterface TraceSink {\n\tonEvent(event: LifecycleEvent<unknown>): void;\n\tcaptureProviderPayload(payload: unknown, model: unknown): void;\n\tmirrorPluginLog(record: LoggerRecord): void;\n\t/** Best-effort export-sink flush (fire-and-forget); never throws. */\n\tflush(): void;\n}\n\n/**\n * Trace-file sink over `agent-forge/trace.v1` (design §4). Records are\n * appended one JSON line at a time, flushed per write; `seq` restarts at 1\n * whenever the host resolves a different path. Write failures never throw:\n * the first failure of a streak reports through `adapter.onSinkFailure` plus a\n * journal error entry, later consecutive failures only count.\n */\nfunction createTraceSink(\n\tadapter: ObservabilityHostAdapterV1,\n\toptions: TraceSinkOptionsV1,\n\tnow: () => number,\n\treportSinkError: (error: unknown) => void,\n\texportSinks: readonly ObservabilityExportSinkV1[],\n): TraceSink {\n\tconst maxStringChars = options.maxStringChars ?? DEFAULT_TRACE_MAX_STRING_CHARS;\n\tconst maxSnapshotBytes = options.maxSnapshotBytes ?? DEFAULT_TRACE_MAX_SNAPSHOT_BYTES;\n\tassertPositiveSafeInteger(maxStringChars, \"Trace maxStringChars\");\n\tassertPositiveSafeInteger(maxSnapshotBytes, \"Trace maxSnapshotBytes\");\n\tconst limits: RedactLimits = { maxStringChars, maxSnapshotBytes };\n\n\t// Telemetry export seam (design §8): host-injected sinks plus the OTLP\n\t// exporter when configured. Sink failures are isolated per sink and never\n\t// reach event delivery or the file sink.\n\tconst sinks: readonly ObservabilityExportSinkV1[] = [\n\t\t...exportSinks,\n\t\t...(options.otlp === undefined\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\tcreateOtlpTraceExportSink({\n\t\t\t\t\t\t...options.otlp,\n\t\t\t\t\t\tonFailure: (error) => {\n\t\t\t\t\t\t\treportSinkError(error);\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t]),\n\t];\n\tconst feedExportSinks = (record: TraceRecordV1): void => {\n\t\tfor (const sink of sinks) {\n\t\t\ttry {\n\t\t\t\tsink.onTraceRecord(record);\n\t\t\t} catch {\n\t\t\t\t// isolated: a broken export sink must not break the file sink\n\t\t\t}\n\t\t}\n\t};\n\tconst flushExportSinks = (reason: string): void => {\n\t\tfor (const sink of sinks) {\n\t\t\ttry {\n\t\t\t\tvoid sink.flush(reason).catch(() => {});\n\t\t\t} catch {\n\t\t\t\t// isolated\n\t\t\t}\n\t\t}\n\t};\n\n\tlet seq = 0;\n\tlet currentPath: string | null = null;\n\tlet failing = false;\n\n\tconst emitRecord = (draft: TraceRecordDraftV1): void => {\n\t\tconst path = adapter.getTraceFilePath();\n\t\tif (path === null) return;\n\t\ttry {\n\t\t\tif (path !== currentPath) {\n\t\t\t\tcurrentPath = path;\n\t\t\t\tseq = 0;\n\t\t\t}\n\t\t\tconst record: TraceRecordV1 = enforceRecordBudget({\n\t\t\t\tv: 1,\n\t\t\t\tschema: TRACE_SCHEMA_V1,\n\t\t\t\tseq: seq + 1,\n\t\t\t\tt: now(),\n\t\t\t\t...draft,\n\t\t\t});\n\t\t\tfeedExportSinks(record);\n\t\t\tappendFileSync(path, `${JSON.stringify(record)}\\n`, \"utf8\");\n\t\t\tseq += 1;\n\t\t\tfailing = false;\n\t\t} catch (error) {\n\t\t\t// Rate-limited failure handling (design §4.4): report the first\n\t\t\t// failure of a streak, stay silent on consecutive ones, never throw.\n\t\t\tif (!failing) {\n\t\t\t\tfailing = true;\n\t\t\t\ttry {\n\t\t\t\t\tadapter.onSinkFailure(error);\n\t\t\t\t} catch {\n\t\t\t\t\t// sink-failure reporting must never break event delivery\n\t\t\t\t}\n\t\t\t\treportSinkError(error);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst boundedData = (data: unknown): unknown => redactProviderPayloadSnapshot(data, limits);\n\n\tconst emitFromEvent = (event: LifecycleEvent<unknown>, draft: TraceRecordDraftV1): void => {\n\t\temitRecord({\n\t\t\t...(event.correlationId === undefined ? {} : { traceId: event.correlationId }),\n\t\t\t...draft,\n\t\t});\n\t};\n\n\tconst pendingTurns = new Map<string, TurnSpanStart>();\n\tconst toolSpans = new Map<string, ToolSpanState>();\n\tconst streams = new Map<string, StreamTiming>();\n\t/** One captured side per toolCallId for the result-diff self-check. */\n\tconst resultDiffPairs = new Map<string, { raw?: string; final?: string }>();\n\t/** toolCallIds whose pairing already emitted a diff record; guards idempotence. */\n\tconst resultDiffSeen = new Map<string, true>();\n\n\t/**\n\t * Bounded-by-design insertion: past `TRACE_SPAN_STATE_MAX_ENTRIES` the\n\t * oldest unpaired entry (first key in Map insertion order) is evicted FIFO.\n\t */\n\tconst setTracked = <T>(map: Map<string, T>, key: string, value: T): void => {\n\t\tmap.set(key, value);\n\t\twhile (map.size > TRACE_SPAN_STATE_MAX_ENTRIES) {\n\t\t\tconst oldest = map.keys().next();\n\t\t\t// v8 ignore next -- 循环条件保证 map 非空,第一个 key 必存在\n\t\t\tif (oldest.done !== true) map.delete(oldest.value);\n\t\t}\n\t};\n\n\tconst turnKey = (event: LifecycleEvent<unknown>): string => {\n\t\tif (event.correlationId !== undefined) return `c:${event.correlationId}`;\n\t\tconst data = isRecord(event.data) ? event.data : {};\n\t\tconst sessionId = typeof data.sessionId === \"string\" ? data.sessionId : \"\";\n\t\tconst turnIndex = typeof data.turnIndex === \"number\" ? data.turnIndex : \"\";\n\t\treturn `t:${sessionId}:${turnIndex}`;\n\t};\n\n\tconst usageToGenAi = (usage: unknown): Record<string, number> | undefined => {\n\t\tif (!isRecord(usage)) return undefined;\n\t\tconst mapped: Record<string, number> = {};\n\t\tconst fields: readonly [string, string][] = [\n\t\t\t[\"input\", \"gen_ai.usage.input_tokens\"],\n\t\t\t[\"output\", \"gen_ai.usage.output_tokens\"],\n\t\t\t[\"cacheRead\", \"gen_ai.usage.cache_read_tokens\"],\n\t\t\t[\"cacheWrite\", \"gen_ai.usage.cache_write_tokens\"],\n\t\t\t[\"totalTokens\", \"gen_ai.usage.total_tokens\"],\n\t\t];\n\t\tfor (const [source, target] of fields) {\n\t\t\tconst value = usage[source];\n\t\t\tif (typeof value === \"number\" && Number.isFinite(value)) mapped[target] = value;\n\t\t}\n\t\tconst cost = usage.cost;\n\t\tif (isRecord(cost) && typeof cost.total === \"number\" && Number.isFinite(cost.total)) {\n\t\t\tmapped[\"gen_ai.usage.cost\"] = cost.total;\n\t\t}\n\t\treturn Object.keys(mapped).length > 0 ? mapped : undefined;\n\t};\n\n\tconst emitGenericLifecycle = (event: LifecycleEvent<unknown>): void => {\n\t\temitFromEvent(event, {\n\t\t\tkind: \"lifecycle\",\n\t\t\tlevel: deriveLevel(event.type, event.data),\n\t\t\tdata: boundedData({ event: event.type, data: event.data }),\n\t\t});\n\t};\n\n\t/**\n\t * Result-diff self-check (design §4.2 `decision` row): captures one side of\n\t * the `tool.result.raw@1` → `tool.result@1` pairing for a toolCallId. Once\n\t * both sides arrived, their bounded serializations are compared and a\n\t * mismatch emits one `decision` record with `{toolCallId, rawBytes,\n\t * finalBytes}`.\n\t *\n\t * Record semantics: \"the final output differs from the tool's raw output\".\n\t * Legacy result hooks and image normalization also contribute to a\n\t * difference, so this is deliberately not a transform attribution. The\n\t * comparison reuses the 2 KiB bounded summary; both byte sizes refer to\n\t * those bounded serializations.\n\t *\n\t * Idempotence: a toolCallId whose pairing already emitted a `decision`\n\t * record is remembered (bounded, FIFO-evicted like the other span-state\n\t * tables); later raw/final deliveries for the same toolCallId are skipped\n\t * outright, so duplicate events can never trigger a second comparison or a\n\t * second record.\n\t */\n\tconst recordResultDiffSide = (side: \"raw\" | \"final\", event: LifecycleEvent<unknown>): void => {\n\t\tconst data = isRecord(event.data) ? event.data : {};\n\t\tconst toolCallId = data.toolCallId;\n\t\tif (typeof toolCallId !== \"string\") return;\n\t\tif (resultDiffSeen.has(toolCallId)) return;\n\t\tconst content = side === \"raw\" ? data.content : isRecord(data.message) ? data.message.content : undefined;\n\t\tif (!Array.isArray(content)) return; // a side that cannot be serialized is never fabricated\n\t\tconst serialized = JSON.stringify(boundedJsonSummary(content, TRACE_TOOL_SUMMARY_MAX_CHARS));\n\t\tif (serialized === undefined) return;\n\t\tconst pair = resultDiffPairs.get(toolCallId) ?? {};\n\t\tpair[side] = serialized;\n\t\tsetTracked(resultDiffPairs, toolCallId, pair);\n\t\tif (pair.raw === undefined || pair.final === undefined) return;\n\t\tresultDiffPairs.delete(toolCallId);\n\t\tif (pair.raw === pair.final) return;\n\t\tsetTracked(resultDiffSeen, toolCallId, true);\n\t\temitFromEvent(event, {\n\t\t\tkind: \"decision\",\n\t\t\tlevel: \"info\",\n\t\t\tdata: {\n\t\t\t\ttoolCallId,\n\t\t\t\trawBytes: Buffer.byteLength(pair.raw, \"utf8\"),\n\t\t\t\tfinalBytes: Buffer.byteLength(pair.final, \"utf8\"),\n\t\t\t},\n\t\t});\n\t};\n\n\tconst handleEvent = (event: LifecycleEvent<unknown>): void => {\n\t\tconst data = isRecord(event.data) ? event.data : {};\n\t\tswitch (event.type) {\n\t\t\tcase SESSION_START_EVENT_ID: {\n\t\t\t\t// Session-level parent linkage (design §4.2 session.start row):\n\t\t\t\t// the session-header facts arrive through the host adapter; an\n\t\t\t\t// adapter without a getter — or an unset header field — keeps\n\t\t\t\t// the previous record shape (no parentSessionId/parentTraceId\n\t\t\t\t// key, never null).\n\t\t\t\tconst parentSessionId = adapter.getParentAgentSessionId?.();\n\t\t\t\tconst parentTraceId = adapter.getParentTraceId?.();\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"session.start\",\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\t...data,\n\t\t\t\t\t\t...(parentSessionId === undefined ? {} : { parentSessionId }),\n\t\t\t\t\t\t...(parentTraceId === undefined ? {} : { parentTraceId }),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SESSION_END_EVENT_ID:\n\t\t\t\t// The session.end fact stays in the trace file (lifecycle record);\n\t\t\t\t// the export sinks get their final flush beside it (design §8).\n\t\t\t\temitGenericLifecycle(event);\n\t\t\t\tflushExportSinks(\"session.end\");\n\t\t\t\treturn;\n\t\t\tcase TURN_START_EVENT_ID:\n\t\t\t\tsetTracked(pendingTurns, turnKey(event), { startedAt: now() });\n\t\t\t\treturn;\n\t\t\tcase TURN_END_EVENT_ID: {\n\t\t\t\tconst key = turnKey(event);\n\t\t\t\tconst pending = pendingTurns.get(key);\n\t\t\t\tif (pending === undefined) return; // unpaired span: no record (crash leaves gaps by design)\n\t\t\t\tpendingTurns.delete(key);\n\t\t\t\tconst endedAt = now();\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"turn.span\",\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tdur: Math.max(0, endedAt - pending.startedAt),\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\t...(typeof data.sessionId === \"string\" ? { sessionId: data.sessionId } : {}),\n\t\t\t\t\t\t...(typeof data.turnIndex === \"number\" ? { turnIndex: data.turnIndex } : {}),\n\t\t\t\t\t\t...(typeof data.messageCount === \"number\" ? { messageCount: data.messageCount } : {}),\n\t\t\t\t\t\t// 回合级偏离结果(第 4 期):completed 回合省键,从不虚构。\n\t\t\t\t\t\t...(typeof data.outcome === \"string\" ? { outcome: data.outcome } : {}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase TOOL_EXECUTION_START_EVENT_ID: {\n\t\t\t\tif (typeof data.toolCallId !== \"string\") return;\n\t\t\t\tconst span = toolSpans.get(data.toolCallId) ?? { toolName: \"unknown\" };\n\t\t\t\tsetTracked(toolSpans, data.toolCallId, {\n\t\t\t\t\t...span,\n\t\t\t\t\ttoolName: typeof data.toolName === \"string\" ? data.toolName : span.toolName,\n\t\t\t\t\tstartedAt: now(),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase TOOL_CALL_EVENT_ID:\n\t\t\tcase TOOL_EXECUTE_EVENT_ID: {\n\t\t\t\t// Args/result capture only; the span record is emitted on commit.\n\t\t\t\tif (typeof data.toolCallId !== \"string\") return;\n\t\t\t\tconst span = toolSpans.get(data.toolCallId) ?? {\n\t\t\t\t\ttoolName: typeof data.toolName === \"string\" ? data.toolName : \"unknown\",\n\t\t\t\t};\n\t\t\t\tsetTracked(toolSpans, data.toolCallId, {\n\t\t\t\t\t...span,\n\t\t\t\t\t...(data.input !== undefined ? { args: data.input } : {}),\n\t\t\t\t\t...(event.type === TOOL_EXECUTE_EVENT_ID && data.content !== undefined ? { result: data.content } : {}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase TOOL_GATE_BLOCKED_EVENT_ID: {\n\t\t\t\t// 拦截归因(第 4 期):仅当该 callId 的 span state 已存在时写入\n\t\t\t\t// blocked 标记;state 缺席即忽略,不照 TOOL_CALL/TOOL_EXECUTION_START\n\t\t\t\t// 的缺席建 state 先例(防伪造 callId 占用 256 FIFO 淘汰窗口)。\n\t\t\t\tif (typeof data.toolCallId !== \"string\") return;\n\t\t\t\tconst span = toolSpans.get(data.toolCallId);\n\t\t\t\tif (span !== undefined) {\n\t\t\t\t\tspan.blocked = true;\n\t\t\t\t\tif (typeof data.reason === \"string\" && data.reason !== \"\") span.blockReason = data.reason;\n\t\t\t\t}\n\t\t\t\temitGenericLifecycle(event);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase TOOL_COMMIT_EVENT_ID: {\n\t\t\t\tif (typeof data.toolCallId !== \"string\") return;\n\t\t\t\tconst span = toolSpans.get(data.toolCallId);\n\t\t\t\tif (span === undefined || span.startedAt === undefined) return; // unpaired span: no record\n\t\t\t\ttoolSpans.delete(data.toolCallId);\n\t\t\t\tconst isError = data.isError === true;\n\t\t\t\tconst endedAt = now();\n\t\t\t\tconst toolName = typeof data.toolName === \"string\" ? data.toolName : span.toolName;\n\t\t\t\t// 父侧结构化子会话引用(第 4 期,design §4.6):仅识别第一方委派工具,\n\t\t\t\t// 从未截断的 tool.execute content 解析(非 2KiB 展示文本);提取失败省键。\n\t\t\t\tconst childSession = extractChildSessionReference(toolName, span.result);\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"tool.span\",\n\t\t\t\t\tlevel: isError ? \"error\" : \"info\",\n\t\t\t\t\tdur: Math.max(0, endedAt - span.startedAt),\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\tcallId: data.toolCallId,\n\t\t\t\t\t\ttoolName,\n\t\t\t\t\t\tisError,\n\t\t\t\t\t\t// 拦截归因(第 4 期):span state 标记过 blocked 才投影;reason\n\t\t\t\t\t\t// 未标记则省 blockReason 键,正常调用两键都不出现。\n\t\t\t\t\t\t...(span.blocked === true ? { blocked: true } : {}),\n\t\t\t\t\t\t...(span.blocked === true && span.blockReason !== undefined ? { blockReason: span.blockReason } : {}),\n\t\t\t\t\t\t...(childSession === undefined ? {} : { childSessionId: childSession.childSessionId }),\n\t\t\t\t\t\t...(childSession === undefined ? {} : { childSessionCount: childSession.childSessionCount }),\n\t\t\t\t\t\t...(span.args !== undefined\n\t\t\t\t\t\t\t? { args: boundedJsonSummary(span.args, TRACE_TOOL_SUMMARY_MAX_CHARS) }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t...(span.result !== undefined\n\t\t\t\t\t\t\t? { result: boundedJsonSummary(span.result, TRACE_TOOL_SUMMARY_MAX_CHARS) }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase MODEL_STREAM_EVENT_ID: {\n\t\t\t\tconst streamId = typeof data.streamId === \"string\" ? data.streamId : null;\n\t\t\t\tif (streamId === null) return;\n\t\t\t\tconst eventName = data.event;\n\t\t\t\tif (eventName === \"start\") {\n\t\t\t\t\tsetTracked(streams, streamId, { startedAt: now() });\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (data.terminal !== true) {\n\t\t\t\t\tif (typeof eventName === \"string\" && eventName.endsWith(\"_delta\")) {\n\t\t\t\t\t\tconst timing = streams.get(streamId);\n\t\t\t\t\t\tif (timing !== undefined && timing.firstDeltaAt === undefined) timing.firstDeltaAt = now();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst timing = streams.get(streamId);\n\t\t\t\tstreams.delete(streamId);\n\t\t\t\tconst streamEndedAt = now();\n\t\t\t\tconst partial = isRecord(data.partial) ? data.partial : undefined;\n\t\t\t\tconst usage = usageToGenAi(partial?.usage);\n\t\t\t\tconst isErrorEvent = eventName === \"error\";\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"llm.response\",\n\t\t\t\t\tlevel: isErrorEvent ? \"error\" : \"info\",\n\t\t\t\t\t...(timing?.startedAt !== undefined ? { dur: Math.max(0, streamEndedAt - timing.startedAt) } : {}),\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\tstreamId,\n\t\t\t\t\t\t...(typeof partial?.stopReason === \"string\" ? { stopReason: partial.stopReason } : {}),\n\t\t\t\t\t\t...(usage !== undefined ? usage : {}),\n\t\t\t\t\t\t...(timing?.startedAt !== undefined && timing.firstDeltaAt !== undefined\n\t\t\t\t\t\t\t? { ttftMs: Math.max(0, timing.firstDeltaAt - timing.startedAt) }\n\t\t\t\t\t\t\t: {}),\n\t\t\t\t\t\t...(isErrorEvent ? { error: boundedData(data.error) } : {}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase SESSION_AUTO_RETRY_EVENT_ID:\n\t\t\tcase SESSION_COMPACTION_DECISION_EVENT_ID:\n\t\t\t\t// Retry/compaction decisions: validated event data passes through\n\t\t\t\t// the bounded redaction channel verbatim; absent optional fields\n\t\t\t\t// (threshold triplet) stay absent — never fabricated.\n\t\t\t\temitFromEvent(event, { kind: \"decision\", level: \"info\", data: boundedData(event.data) });\n\t\t\t\treturn;\n\t\t\tcase SESSION_COMPACTION_FAILED_EVENT_ID:\n\t\t\t\t// A genuinely failed compaction is a real failure terminal, not a\n\t\t\t\t// decision: records as `error` with the reason/errorMessage facts.\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"error\",\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\t...(typeof data.reason === \"string\" ? { reason: data.reason } : {}),\n\t\t\t\t\t\t...(typeof data.errorMessage === \"string\" ? { errorMessage: data.errorMessage } : {}),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\tcase SESSION_COMPACTION_COMMIT_EVENT_ID: {\n\t\t\t\t// Whitelist projection: summary and other long-text fields stay out\n\t\t\t\t// of the trace record on purpose (design §4.2 decision row).\n\t\t\t\temitFromEvent(event, {\n\t\t\t\t\tkind: \"decision\",\n\t\t\t\t\tlevel: \"info\",\n\t\t\t\t\tdata: boundedData({\n\t\t\t\t\t\t...(typeof data.entryId === \"string\" ? { entryId: data.entryId } : {}),\n\t\t\t\t\t\t...(typeof data.reason === \"string\" ? { reason: data.reason } : {}),\n\t\t\t\t\t\t...(typeof data.tokensBefore === \"number\" ? { tokensBefore: data.tokensBefore } : {}),\n\t\t\t\t\t\t...(data.usage === undefined ? {} : { usage: data.usage }),\n\t\t\t\t\t}),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase TOOL_RESULT_RAW_EVENT_ID:\n\t\t\t\temitGenericLifecycle(event);\n\t\t\t\trecordResultDiffSide(\"raw\", event);\n\t\t\t\treturn;\n\t\t\tcase TOOL_RESULT_EVENT_ID:\n\t\t\t\temitGenericLifecycle(event);\n\t\t\t\trecordResultDiffSide(\"final\", event);\n\t\t\t\treturn;\n\t\t\tcase OPERATION_END_EVENT_ID:\n\t\t\tcase PLUGIN_DISPOSE_EVENT_ID: {\n\t\t\t\tif (data.status === \"failed\") {\n\t\t\t\t\t// Captured error terminal: the `error` kind records the failure fact.\n\t\t\t\t\temitFromEvent(event, {\n\t\t\t\t\t\tkind: \"error\",\n\t\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\t\tdata: boundedData({ source: event.type, ...data }),\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\temitGenericLifecycle(event);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\temitGenericLifecycle(event);\n\t\t}\n\t};\n\n\treturn {\n\t\tflush: () => flushExportSinks(\"dispose\"),\n\t\tonEvent(event) {\n\t\t\ttry {\n\t\t\t\thandleEvent(event);\n\t\t\t} catch {\n\t\t\t\t// Trace collection must never break event delivery (design §4.4).\n\t\t\t}\n\t\t},\n\t\tcaptureProviderPayload(payload, model) {\n\t\t\tconst source = isRecord(payload) ? payload : {};\n\t\t\tconst tools = source.tools;\n\t\t\tconst messages = source.messages;\n\t\t\t// Both wire shapes are accepted: Anthropic lists tools flat\n\t\t\t// (`tools[].name`), openai-completions nests them under\n\t\t\t// `tools[].function.name`; only string names are collected.\n\t\t\tconst toolNames = Array.isArray(tools)\n\t\t\t\t? tools\n\t\t\t\t\t\t.map((tool) => {\n\t\t\t\t\t\t\tif (!isRecord(tool)) return null;\n\t\t\t\t\t\t\tif (typeof tool.name === \"string\") return tool.name;\n\t\t\t\t\t\t\tconst fn = tool.function;\n\t\t\t\t\t\t\treturn isRecord(fn) && typeof fn.name === \"string\" ? fn.name : null;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter((name): name is string => name !== null)\n\t\t\t\t: undefined;\n\t\t\tconst system = source.system;\n\t\t\tlet systemPromptChars: number | undefined;\n\t\t\tif (typeof system === \"string\") {\n\t\t\t\tsystemPromptChars = system.length;\n\t\t\t} else if (Array.isArray(system)) {\n\t\t\t\tlet total = 0;\n\t\t\t\tlet found = false;\n\t\t\t\tfor (const block of system) {\n\t\t\t\t\tif (isRecord(block) && typeof block.text === \"string\") {\n\t\t\t\t\t\ttotal += block.text.length;\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (found) systemPromptChars = total;\n\t\t\t}\n\t\t\tif (systemPromptChars === undefined && Array.isArray(messages)) {\n\t\t\t\t// openai-completions wire shape: the system prompt rides as\n\t\t\t\t// system-role messages instead of a top-level `system` field.\n\t\t\t\tlet total = 0;\n\t\t\t\tlet found = false;\n\t\t\t\tfor (const message of messages) {\n\t\t\t\t\tif (!isRecord(message) || message.role !== \"system\") continue;\n\t\t\t\t\tconst content = message.content;\n\t\t\t\t\tif (typeof content === \"string\") {\n\t\t\t\t\t\ttotal += content.length;\n\t\t\t\t\t\tfound = true;\n\t\t\t\t\t} else if (Array.isArray(content)) {\n\t\t\t\t\t\tfor (const part of content) {\n\t\t\t\t\t\t\tif (isRecord(part) && typeof part.text === \"string\") {\n\t\t\t\t\t\t\t\ttotal += part.text.length;\n\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (found) systemPromptChars = total;\n\t\t\t}\n\t\t\tconst data: Record<string, unknown> = {\n\t\t\t\t...(typeof model === \"string\" ? { \"gen_ai.request.model\": model } : {}),\n\t\t\t\t...(systemPromptChars === undefined ? {} : { systemPromptChars }),\n\t\t\t\t...(Array.isArray(messages) ? { messageCount: messages.length } : {}),\n\t\t\t\t...(toolNames === undefined ? {} : { toolNames }),\n\t\t\t\tpayload: redactProviderPayloadSnapshot(payload, limits),\n\t\t\t};\n\t\t\t// Emitted immediately: the payload is final before the request is\n\t\t\t// sent, so \"written\" means \"was about to be sent\" even under a crash\n\t\t\t// (design §4.2 llm.request row). traceId comes from the turn in\n\t\t\t// flight; an adapter without the getter keeps the phase-1 shape\n\t\t\t// (no traceId field).\n\t\t\tconst traceId = adapter.getTurnCorrelationId?.();\n\t\t\temitRecord({\n\t\t\t\t...(traceId === undefined ? {} : { traceId }),\n\t\t\t\tkind: \"llm.request\",\n\t\t\t\tlevel: \"info\",\n\t\t\t\tdata,\n\t\t\t});\n\t\t},\n\t\tmirrorPluginLog(record) {\n\t\t\t// Self-recursion guard (design §4.4): never call api.logger on this\n\t\t\t// path — the host forwards logger output into here, so a logger call\n\t\t\t// would loop. Trace-append only; emitRecord never throws.\n\t\t\tconst traceId = adapter.getTurnCorrelationId?.();\n\t\t\temitRecord({\n\t\t\t\t...(traceId === undefined ? {} : { traceId }),\n\t\t\t\tkind: \"plugin.log\",\n\t\t\t\t// debug maps to the envelope's info floor; data.level keeps the\n\t\t\t\t// record's own level verbatim.\n\t\t\t\tlevel: record.level === \"warn\" ? \"warn\" : record.level === \"error\" ? \"error\" : \"info\",\n\t\t\t\tdata: {\n\t\t\t\t\tpluginId: record.pluginId,\n\t\t\t\t\tlevel: record.level,\n\t\t\t\t\tmessage: record.message,\n\t\t\t\t\t...(record.fields === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { fields: errorAwareBoundedJsonSummary(record.fields, TRACE_TOOL_SUMMARY_MAX_CHARS) }),\n\t\t\t\t\t...(record.cause === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { cause: errorAwareBoundedJsonSummary(record.cause, TRACE_TOOL_SUMMARY_MAX_CHARS) }),\n\t\t\t\t},\n\t\t\t});\n\t\t},\n\t};\n}\n\n/**\n * Events the journal records; the ids come from the shared lifecycle catalog\n * (see `./event-ids.ts`). The trace sink consumes the same deliveries but\n * never changes this set. The host defines these events before capability\n * plugins load; the plugin only holds the `{ id, version }` reference.\n */\nconst observedEventIds: readonly { readonly id: string; readonly version: number }[] = [\n\t{ id: MODEL_STREAM_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_CALL_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_EXECUTE_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_RESULT_RAW_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_RESULT_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_COMMIT_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: OPERATION_END_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: PLUGIN_READY_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: PLUGIN_DISPOSE_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_RELOAD_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_CONTEXT_REPLACED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n];\n\n/**\n * Trace-only subscriptions (design §4.4): span-pairing, session/agent facts,\n * and the decision/compaction attribution events the trace sink needs but the\n * journal must not record, so journal and problem-report behavior stays\n * byte-identical with or without tracing. Each event id keeps exactly one\n * registration; these are additional ids, not a parallel subscription\n * mechanism. Registered only when a trace adapter is injected. The phase-4\n * additions close the coverage-matrix gaps (design §4.6): session.end@1,\n * agent.task.settled@1, and the prompt/input boundary events.\n */\nconst traceOnlyObservedEventIds: readonly { readonly id: string; readonly version: number }[] = [\n\t{ id: SESSION_START_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TURN_START_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TURN_END_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: TOOL_EXECUTION_START_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: MODEL_SELECT_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: AGENT_SETTLED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_AUTO_RETRY_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_COMPACTION_DECISION_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_COMPACTION_FAILED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_COMPACTION_COMMIT_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: SESSION_END_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: AGENT_TASK_SETTLED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t// 拦截归因(第 4 期):block 短路观察事实;handleEvent 专门 case 标记\n\t// span state 后走 emitGenericLifecycle。\n\t{ id: TOOL_GATE_BLOCKED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t// 纯订阅缺口闭合(第 4 期,design §4.6):用户提示边界与输入到达;均经\n\t// handleEvent 的 default 分支走 emitGenericLifecycle(kind=\"lifecycle\")。\n\t{ id: UI_PROMPT_START_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: UI_PROMPT_END_EVENT_ID, version: CATALOG_EVENT_VERSION },\n\t{ id: INPUT_RECEIVED_EVENT_ID, version: CATALOG_EVENT_VERSION },\n];\n\nfunction createRedactionContext(): HostOutputSerializerContextV1 {\n\treturn { surface: \"cli-text\", policyVersion: REDACTION_POLICY_VERSION, inspectorAuthorized: false };\n}\n\nfunction sortedCounts(\n\tentries: readonly ObservabilityJournalEntryV1[],\n\tpick: (entry: ObservabilityJournalEntryV1) => string,\n): Record<string, number> {\n\tconst counts: Record<string, number> = {};\n\tfor (const entry of entries) {\n\t\tconst key = pick(entry);\n\t\tcounts[key] = (counts[key] ?? 0) + 1;\n\t}\n\tconst sorted: Record<string, number> = {};\n\tfor (const key of Object.keys(counts).sort()) sorted[key] = counts[key];\n\treturn sorted;\n}\n\nexport interface ProblemReportBuildInput {\n\treadonly journal: ObservabilityJournal;\n\treadonly now: () => number;\n\treadonly tailSize: number;\n\treadonly serializer: HostOutputSerializerV1;\n\treadonly sessionId: string;\n\treadonly reason: string;\n}\n\n/**\n * Builds a deterministic problem report from the journal. Every payload is\n * rendered through the host output serializer redaction channel, and the whole\n * report body goes through a second whole-document pass, so internal field\n * keys cannot survive at any depth.\n */\nexport function buildProblemReport(input: ProblemReportBuildInput): ProblemReportV1 {\n\tassertNonEmptyString(input.sessionId, \"Report sessionId\");\n\tassertNonEmptyString(input.reason, \"Report reason\");\n\tif (!Number.isSafeInteger(input.tailSize) || input.tailSize < 0) {\n\t\tthrow new Error(\"Report tailSize must be a non-negative safe integer\");\n\t}\n\tconst redactionContext = createRedactionContext();\n\tconst sessionEntries = input.journal.query({ sessionId: input.sessionId });\n\tlet redactionApplied = false;\n\tconst projectPayload = (payload: unknown): string => {\n\t\tconst projection = input.serializer.project({ data: payload }, redactionContext);\n\t\tif (projection.redactions !== undefined) redactionApplied = true;\n\t\treturn projection.text;\n\t};\n\n\tconst lastErrorEntry = [...sessionEntries].reverse().find((entry) => entry.level === \"error\") ?? null;\n\tconst lastErrorDetail = lastErrorEntry === null ? null : extractErrorInfo(lastErrorEntry);\n\tconst lastError =\n\t\tlastErrorEntry === null || lastErrorDetail === null\n\t\t\t? null\n\t\t\t: Object.freeze({\n\t\t\t\t\tsequence: lastErrorEntry.sequence,\n\t\t\t\t\tat: lastErrorEntry.at,\n\t\t\t\t\tstage: lastErrorEntry.stage,\n\t\t\t\t\t...(lastErrorDetail.phase === undefined ? {} : { phase: lastErrorDetail.phase }),\n\t\t\t\t\ttraceId: lastErrorEntry.traceId ?? null,\n\t\t\t\t\tcode: lastErrorDetail.code,\n\t\t\t\t\tmessage: lastErrorDetail.message,\n\t\t\t\t});\n\n\tconst tail = sessionEntries.slice(-input.tailSize).map((entry) =>\n\t\tObject.freeze({\n\t\t\tsequence: entry.sequence,\n\t\t\tat: entry.at,\n\t\t\tstage: entry.stage,\n\t\t\tlevel: entry.level,\n\t\t\ttraceId: entry.traceId ?? null,\n\t\t\tsummary: entry.summary,\n\t\t\t...(entry.data === undefined ? {} : { data: projectPayload(entry.data) }),\n\t\t}),\n\t);\n\n\tconst draft: Omit<ProblemReportV1, \"reportId\" | \"redactionApplied\" | \"projection\"> = {\n\t\tversion: 1,\n\t\tcreatedAt: input.now(),\n\t\treason: input.reason,\n\t\tsession: Object.freeze({\n\t\t\tsessionId: input.sessionId,\n\t\t\tentryCount: sessionEntries.length,\n\t\t\tfirstSequence: sessionEntries[0]?.sequence ?? null,\n\t\t\tlastSequence: sessionEntries[sessionEntries.length - 1]?.sequence ?? null,\n\t\t}),\n\t\tlastError,\n\t\tjournalTail: tail,\n\t\tcounts: Object.freeze({\n\t\t\tbyStage: sortedCounts(sessionEntries, (entry) => entry.stage),\n\t\t\tbyLevel: sortedCounts(sessionEntries, (entry) => entry.level),\n\t\t}),\n\t\tdropped: input.journal.stats().dropped,\n\t};\n\n\t// Whole-report redaction pass: the exporter output may only ever carry\n\t// allowlisted field names, at any depth, even if a future report field\n\t// starts colliding with an internal key.\n\tconst wholeReportProjection = input.serializer.project(draft, redactionContext);\n\t// v8 ignore next -- 报告体字段名不含内部键;二遍脱敏是防未来字段冲突的前瞻防御\n\tif (wholeReportProjection.redactions !== undefined) redactionApplied = true;\n\tconst body: Omit<ProblemReportV1, \"reportId\"> = {\n\t\t...draft,\n\t\tredactionApplied,\n\t\tprojection: Object.freeze({ surface: redactionContext.surface, text: wholeReportProjection.text }),\n\t};\n\tconst reportId = fnv1a32Hex(canonicalJson(body));\n\treturn Object.freeze({ ...body, reportId });\n}\n\n/**\n * Creates the observability plugin on top of a public capability API.\n * Returns the journal facade, the deterministic problem-report exporter, and\n * — when a trace adapter is injected — the trace sink (design §4).\n */\nexport function createObservabilityPlugin(\n\tapi: CapabilityAPI,\n\toptions: ObservabilityPluginOptions = {},\n): ObservabilityPlugin {\n\tconst maxEntries = options.maxEntries ?? DEFAULT_JOURNAL_MAX_ENTRIES;\n\tconst tailSize = options.tailSize ?? DEFAULT_PROBLEM_REPORT_TAIL_SIZE;\n\tassertPositiveSafeInteger(tailSize, \"Report tailSize\");\n\tconst now = options.now ?? (() => Date.now());\n\tconst journal = createObservabilityJournal({ maxEntries, now });\n\tconst serializer = createHostOutputSerializer();\n\n\tlet sinkFailureSequence = 0;\n\tconst reportSinkError = (error: unknown): void => {\n\t\tsinkFailureSequence += 1;\n\t\t// Synthetic journal entry (not a catalog event): keeps the failure\n\t\t// visible to problem reports without touching the lifecycle directory.\n\t\tjournal.appendEvent({\n\t\t\tid: `${OBSERVABILITY_PLUGIN_ID}/trace-sink-failure/${sinkFailureSequence}`,\n\t\t\tdeliveryId: `trace-sink-failure-${sinkFailureSequence}`,\n\t\t\ttype: TRACE_SINK_FAILURE_STAGE,\n\t\t\tversion: 1,\n\t\t\tphase: \"committed\",\n\t\t\tsource: OBSERVABILITY_PLUGIN_ID,\n\t\t\ttimestamp: now(),\n\t\t\t// `isError` drives the journal's generic error-level derivation; the\n\t\t\t// `error` envelope feeds the problem report's last-error extraction.\n\t\t\tdata: {\n\t\t\t\tisError: true,\n\t\t\t\terror: { code: \"trace.sink.failed\", message: error instanceof Error ? error.message : String(error) },\n\t\t\t},\n\t\t});\n\t};\n\n\tconst traceConfig = options.trace;\n\tconst trace =\n\t\ttraceConfig === undefined\n\t\t\t? undefined\n\t\t\t: createTraceSink(\n\t\t\t\t\ttraceConfig.adapter,\n\t\t\t\t\ttraceConfig.options ?? {},\n\t\t\t\t\tnow,\n\t\t\t\t\treportSinkError,\n\t\t\t\t\ttraceConfig.exportSinks ?? [],\n\t\t\t\t);\n\n\tconst record = (event: LifecycleEvent<unknown>): void => {\n\t\tjournal.appendEvent(event);\n\t\ttrace?.onEvent(event);\n\t};\n\n\tconst registrations: DisposableRegistration[] = [];\n\tfor (const binding of observedEventIds) {\n\t\tregistrations.push(api.lifecycle.registerObserve<unknown>(binding.id, record, binding.version));\n\t}\n\tif (trace !== undefined) {\n\t\tfor (const binding of traceOnlyObservedEventIds) {\n\t\t\tregistrations.push(\n\t\t\t\tapi.lifecycle.registerObserve<unknown>(binding.id, (event) => trace.onEvent(event), binding.version),\n\t\t\t);\n\t\t}\n\t}\n\n\tconst exportProblemReport = async (input: {\n\t\treadonly sessionId: string;\n\t\treadonly reason: string;\n\t}): Promise<ProblemReportV1> => {\n\t\tconst report = buildProblemReport({\n\t\t\tjournal,\n\t\t\tnow,\n\t\t\ttailSize,\n\t\t\tserializer,\n\t\t\tsessionId: input.sessionId,\n\t\t\treason: input.reason,\n\t\t});\n\n\t\t// Artifact persistence uses only the public OutputArtifactAPI. When the\n\t\t// host did not declare the `output-artifacts` feature, api.output is\n\t\t// undefined and the report object alone is returned; reaching the host\n\t\t// artifact store through any other path is not allowed here.\n\t\tif (api.output === undefined) return report;\n\t\tconst ref = await api.output.put({\n\t\t\tsessionId: input.sessionId,\n\t\t\toperationId: PROBLEM_REPORT_OPERATION_ID,\n\t\t\tkind: \"problem-report\",\n\t\t\tmediaType: \"application/json\",\n\t\t\ttruncated: false,\n\t\t\tdata: new TextEncoder().encode(canonicalJson(report)),\n\t\t});\n\t\treturn Object.freeze({ ...report, artifact: Object.freeze({ ...ref }) });\n\t};\n\n\treturn {\n\t\tid: OBSERVABILITY_PLUGIN_ID,\n\t\tquery: (filter) => journal.query(filter),\n\t\texplainTrace: (traceId) => journal.explainTrace(traceId),\n\t\tgetMetrics: (options) => journal.getMetrics(options),\n\t\tstats: () => journal.stats(),\n\t\texportProblemReport,\n\t\tcaptureProviderPayload: (payload, model) => trace?.captureProviderPayload(payload, model),\n\t\tmirrorPluginLog: (record) => trace?.mirrorPluginLog(record),\n\t\tdispose: () => {\n\t\t\ttrace?.flush();\n\t\t\tconst failures: unknown[] = [];\n\t\t\tfor (const registration of registrations) {\n\t\t\t\ttry {\n\t\t\t\t\tregistration.dispose();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tfailures.push(error);\n\t\t\t\t}\n\t\t\t}\n\t\t\tregistrations.length = 0;\n\t\t\tif (failures.length === 1) throw failures[0];\n\t\t\tif (failures.length > 1) throw new AggregateError(failures, \"Observability plugin disposal failed\");\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OTLP/HTTP+JSON trace export sink for the first-party observability plugin
3
+ * (design §8 telemetry export seam). Implements `ObservabilityExportSinkV1`
4
+ * over plain `fetch` — no OpenTelemetry SDK dependency; the wire payload is
5
+ * the spec's JSON encoding of `ExportTraceServiceRequest`.
6
+ *
7
+ * Mapping (registered, design §8): one OTLP trace per turn correlation id.
8
+ * Span-bearing records export as spans (`turn.span` root, `llm.response` and
9
+ * `tool.span` parented under it); record kinds without a closed duration
10
+ * (`session.start`, `llm.request`, `lifecycle`, `error`, `decision`,
11
+ * `plugin.log`) and records without a trace id are not exported — the local
12
+ * `agent-forge/trace.v1` file keeps full fidelity. OTel ids are derived
13
+ * deterministically (SHA-256) from the correlation id so parent/child linkage
14
+ * is reproducible across runs and processes.
15
+ *
16
+ * Failure domain: export failures never throw — the first failure of a streak
17
+ * reports through `onFailure`, the batch is retained for the next flush and
18
+ * oldest spans drop (counted) once the cap is hit.
19
+ */
20
+ import type { ObservabilityExportSinkV1, TraceRecordV1 } from "@agent-forge/plugin-sdk";
21
+ export declare const OTLP_DEFAULT_TIMEOUT_MS = 5000;
22
+ export declare const OTLP_DEFAULT_FLUSH_THRESHOLD = 64;
23
+ export declare const OTLP_MAX_BUFFERED_SPANS = 1024;
24
+ /** Deterministic 32-hex OTLP trace id derived from a turn correlation id. */
25
+ export declare function deriveOtlpTraceId(correlationId: string): string;
26
+ /** Deterministic 16-hex OTLP span id derived from the trace id plus span discriminator. */
27
+ export declare function deriveOtlpSpanId(correlationId: string, discriminator: string): string;
28
+ /** Epoch-ms to OTLP unix-nano string via BigInt (number math loses precision above 2^53). */
29
+ export declare function epochMsToUnixNano(ms: number): string;
30
+ /** Normalized trace ingest URL: base URL + signal path unless already present. */
31
+ export declare function resolveOtlpTracesUrl(endpoint: string): string;
32
+ export interface OtlpExportSinkOptions {
33
+ readonly endpoint: string;
34
+ readonly timeoutMs?: number;
35
+ readonly flushThreshold?: number;
36
+ readonly fetchImpl?: (url: string, init: {
37
+ method: "POST";
38
+ headers: {
39
+ "content-type": string;
40
+ };
41
+ body: string;
42
+ signal: AbortSignal;
43
+ }) => Promise<{
44
+ ok: boolean;
45
+ status: number;
46
+ }>;
47
+ /** Failure channel: first failure of a streak, plus drop notifications. */
48
+ readonly onFailure?: (error: Error) => void;
49
+ }
50
+ export declare function createOtlpTraceExportSink(options: OtlpExportSinkOptions): ObservabilityExportSinkV1;
51
+ /** Type guard helper used by the plugin wiring: is a record span-exportable at all. */
52
+ export declare function isOtlpSpanRecord(record: TraceRecordV1): boolean;
53
+ //# sourceMappingURL=otlp-exporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-exporter.d.ts","sourceRoot":"","sources":["../src/otlp-exporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAExF,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAC7C,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,uBAAuB,OAAQ,CAAC;AAG7C,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAErF;AAED,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAEpD;AAgGD,kFAAkF;AAClF,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,SAAS,CAAC,EAAE,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE;YAAE,cAAc,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,CAAA;KAAE,KAC5F,OAAO,CAAC;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC5C;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,qBAAqB,GAAG,yBAAyB,CA+EnG;AASD,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAE/D","sourcesContent":["/**\n * OTLP/HTTP+JSON trace export sink for the first-party observability plugin\n * (design §8 telemetry export seam). Implements `ObservabilityExportSinkV1`\n * over plain `fetch` — no OpenTelemetry SDK dependency; the wire payload is\n * the spec's JSON encoding of `ExportTraceServiceRequest`.\n *\n * Mapping (registered, design §8): one OTLP trace per turn correlation id.\n * Span-bearing records export as spans (`turn.span` root, `llm.response` and\n * `tool.span` parented under it); record kinds without a closed duration\n * (`session.start`, `llm.request`, `lifecycle`, `error`, `decision`,\n * `plugin.log`) and records without a trace id are not exported — the local\n * `agent-forge/trace.v1` file keeps full fidelity. OTel ids are derived\n * deterministically (SHA-256) from the correlation id so parent/child linkage\n * is reproducible across runs and processes.\n *\n * Failure domain: export failures never throw — the first failure of a streak\n * reports through `onFailure`, the batch is retained for the next flush and\n * oldest spans drop (counted) once the cap is hit.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { ObservabilityExportSinkV1, TraceRecordV1 } from \"@agent-forge/plugin-sdk\";\n\nexport const OTLP_DEFAULT_TIMEOUT_MS = 5_000;\nexport const OTLP_DEFAULT_FLUSH_THRESHOLD = 64;\nexport const OTLP_MAX_BUFFERED_SPANS = 1_024;\nconst OTLP_SIGNAL_PATH = \"/v1/traces\";\n\n/** Deterministic 32-hex OTLP trace id derived from a turn correlation id. */\nexport function deriveOtlpTraceId(correlationId: string): string {\n\treturn createHash(\"sha256\").update(correlationId, \"utf8\").digest(\"hex\").slice(0, 32);\n}\n\n/** Deterministic 16-hex OTLP span id derived from the trace id plus span discriminator. */\nexport function deriveOtlpSpanId(correlationId: string, discriminator: string): string {\n\treturn createHash(\"sha256\").update(`${correlationId}|${discriminator}`, \"utf8\").digest(\"hex\").slice(0, 16);\n}\n\n/** Epoch-ms to OTLP unix-nano string via BigInt (number math loses precision above 2^53). */\nexport function epochMsToUnixNano(ms: number): string {\n\treturn (BigInt(Math.max(0, Math.trunc(ms))) * 1_000_000n).toString();\n}\n\ninterface OtlpAttribute {\n\treadonly key: string;\n\treadonly value: { readonly stringValue: string } | { readonly intValue: string } | { readonly boolValue: boolean };\n}\n\ninterface OtlpSpan {\n\treadonly traceId: string;\n\treadonly spanId: string;\n\treadonly parentSpanId?: string;\n\treadonly name: string;\n\treadonly kind: string;\n\treadonly startTimeUnixNano: string;\n\treadonly endTimeUnixNano: string;\n\treadonly attributes?: readonly OtlpAttribute[];\n\treadonly status: { readonly code: string };\n}\n\nfunction attr(key: string, value: string | number | boolean): OtlpAttribute {\n\tif (typeof value === \"number\") {\n\t\treturn Number.isSafeInteger(value)\n\t\t\t? { key, value: { intValue: String(value) } }\n\t\t\t: { key, value: { stringValue: String(value) } };\n\t}\n\tif (typeof value === \"boolean\") return { key, value: { boolValue: value } };\n\treturn { key, value: { stringValue: value } };\n}\n\n/** Shallow primitive-valued fields of the record's bounded data become span attributes. */\nfunction attributesFromData(data: unknown, limit = 32): OtlpAttribute[] {\n\tif (typeof data !== \"object\" || data === null) return [];\n\tconst out: OtlpAttribute[] = [];\n\tfor (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n\t\tif (out.length >= limit) break;\n\t\tif (typeof value === \"string\" && value.length > 0) out.push(attr(key, value.slice(0, 512)));\n\t\telse if (typeof value === \"number\" && Number.isFinite(value)) out.push(attr(key, value));\n\t\telse if (typeof value === \"boolean\") out.push(attr(key, value));\n\t}\n\treturn out;\n}\n\nfunction spanFromRecord(record: TraceRecordV1): OtlpSpan | null {\n\tconst dur = record.dur;\n\tconst traceId = record.traceId;\n\tif (dur === undefined || traceId === undefined) return null;\n\n\tconst traceHex = deriveOtlpTraceId(traceId);\n\tconst endTime = epochMsToUnixNano(record.t);\n\tconst startTime = epochMsToUnixNano(record.t - dur);\n\tconst status = { code: record.level === \"error\" ? \"STATUS_CODE_ERROR\" : \"STATUS_CODE_OK\" };\n\tconst data = record.data;\n\tconst base = { traceId: traceHex, startTimeUnixNano: startTime, endTimeUnixNano: endTime, status };\n\n\tif (record.kind === \"turn.span\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: \"agent.turn\",\n\t\t\tkind: \"SPAN_KIND_INTERNAL\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\tif (record.kind === \"llm.response\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, \"llm.response\"),\n\t\t\tparentSpanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: \"agent.llm\",\n\t\t\tkind: \"SPAN_KIND_CLIENT\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\tif (record.kind === \"tool.span\") {\n\t\tconst callId = (\n\t\t\ttypeof (data as Record<string, unknown> | undefined)?.callId === \"string\"\n\t\t\t\t? (data as Record<string, unknown>).callId\n\t\t\t\t: \"\"\n\t\t) as string;\n\t\tconst toolName = (\n\t\t\ttypeof (data as Record<string, unknown> | undefined)?.toolName === \"string\"\n\t\t\t\t? (data as Record<string, unknown>).toolName\n\t\t\t\t: \"\"\n\t\t) as string;\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, `tool.span|${callId}`),\n\t\t\tparentSpanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: toolName.length > 0 ? `agent.tool:${toolName}` : \"agent.tool\",\n\t\t\tkind: \"SPAN_KIND_INTERNAL\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\treturn null;\n}\n\n/** Normalized trace ingest URL: base URL + signal path unless already present. */\nexport function resolveOtlpTracesUrl(endpoint: string): string {\n\tconst trimmed = endpoint.replace(/\\/+$/, \"\");\n\treturn trimmed.endsWith(OTLP_SIGNAL_PATH) ? trimmed : `${trimmed}${OTLP_SIGNAL_PATH}`;\n}\n\nexport interface OtlpExportSinkOptions {\n\treadonly endpoint: string;\n\treadonly timeoutMs?: number;\n\treadonly flushThreshold?: number;\n\treadonly fetchImpl?: (\n\t\turl: string,\n\t\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n\t) => Promise<{ ok: boolean; status: number }>;\n\t/** Failure channel: first failure of a streak, plus drop notifications. */\n\treadonly onFailure?: (error: Error) => void;\n}\n\nexport function createOtlpTraceExportSink(options: OtlpExportSinkOptions): ObservabilityExportSinkV1 {\n\tconst timeoutMs = options.timeoutMs ?? OTLP_DEFAULT_TIMEOUT_MS;\n\tconst flushThreshold = options.flushThreshold ?? OTLP_DEFAULT_FLUSH_THRESHOLD;\n\tconst url = resolveOtlpTracesUrl(options.endpoint);\n\tconst fetchImpl = options.fetchImpl ?? defaultFetch;\n\n\tlet buffer: OtlpSpan[] = [];\n\tlet dropped = 0;\n\tlet failing = false;\n\tlet inFlight: Promise<void> = Promise.resolve();\n\n\tfunction reportFailure(error: Error): void {\n\t\tif (failing) return;\n\t\tfailing = true;\n\t\ttry {\n\t\t\toptions.onFailure?.(error);\n\t\t} catch {\n\t\t\t// failure reporting must never break the sink\n\t\t}\n\t}\n\n\tasync function deliver(reason: string): Promise<void> {\n\t\tif (buffer.length === 0) return;\n\t\tconst batch = buffer;\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst body = JSON.stringify({\n\t\t\t\tresourceSpans: [\n\t\t\t\t\t{\n\t\t\t\t\t\tresource: { attributes: [attr(\"service.name\", \"agent-forge\")] },\n\t\t\t\t\t\tscopeSpans: [{ scope: { name: \"agent-forge.observability\", version: \"trace.v1\" }, spans: batch }],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst response = await fetchImpl(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\t\tbody,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\treportFailure(new Error(`OTLP export failed (reason=${reason}): HTTP ${response.status}`));\n\t\t\t\tdropOverflow();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfailing = false;\n\t\t\tbuffer = buffer.slice(batch.length);\n\t\t} catch (error) {\n\t\t\treportFailure(error instanceof Error ? error : new Error(String(error)));\n\t\t\tdropOverflow();\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tfunction dropOverflow(): void {\n\t\tif (buffer.length <= OTLP_MAX_BUFFERED_SPANS) return;\n\t\tconst excess = buffer.length - OTLP_MAX_BUFFERED_SPANS;\n\t\tbuffer = buffer.slice(excess);\n\t\tdropped += excess;\n\t\treportFailure(new Error(`OTLP export buffer overflow: dropped ${excess} spans (total dropped ${dropped})`));\n\t}\n\n\tfunction flush(reason: string): Promise<void> {\n\t\tconst run = inFlight.then(() => deliver(reason));\n\t\tinFlight = run.catch(() => {});\n\t\treturn run;\n\t}\n\n\treturn {\n\t\tonTraceRecord: (record) => {\n\t\t\tconst span = spanFromRecord(record);\n\t\t\tif (span === null) return;\n\t\t\tbuffer.push(span);\n\t\t\tif (buffer.length >= flushThreshold) void flush(\"threshold\");\n\t\t},\n\t\tflush,\n\t};\n}\n\nfunction defaultFetch(\n\turl: string,\n\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n): Promise<{ ok: boolean; status: number }> {\n\treturn fetch(url, init) as unknown as Promise<{ ok: boolean; status: number }>;\n}\n\n/** Type guard helper used by the plugin wiring: is a record span-exportable at all. */\nexport function isOtlpSpanRecord(record: TraceRecordV1): boolean {\n\treturn spanFromRecord(record) !== null;\n}\n"]}
@@ -0,0 +1,206 @@
1
+ /**
2
+ * OTLP/HTTP+JSON trace export sink for the first-party observability plugin
3
+ * (design §8 telemetry export seam). Implements `ObservabilityExportSinkV1`
4
+ * over plain `fetch` — no OpenTelemetry SDK dependency; the wire payload is
5
+ * the spec's JSON encoding of `ExportTraceServiceRequest`.
6
+ *
7
+ * Mapping (registered, design §8): one OTLP trace per turn correlation id.
8
+ * Span-bearing records export as spans (`turn.span` root, `llm.response` and
9
+ * `tool.span` parented under it); record kinds without a closed duration
10
+ * (`session.start`, `llm.request`, `lifecycle`, `error`, `decision`,
11
+ * `plugin.log`) and records without a trace id are not exported — the local
12
+ * `agent-forge/trace.v1` file keeps full fidelity. OTel ids are derived
13
+ * deterministically (SHA-256) from the correlation id so parent/child linkage
14
+ * is reproducible across runs and processes.
15
+ *
16
+ * Failure domain: export failures never throw — the first failure of a streak
17
+ * reports through `onFailure`, the batch is retained for the next flush and
18
+ * oldest spans drop (counted) once the cap is hit.
19
+ */
20
+ import { createHash } from "node:crypto";
21
+ export const OTLP_DEFAULT_TIMEOUT_MS = 5_000;
22
+ export const OTLP_DEFAULT_FLUSH_THRESHOLD = 64;
23
+ export const OTLP_MAX_BUFFERED_SPANS = 1_024;
24
+ const OTLP_SIGNAL_PATH = "/v1/traces";
25
+ /** Deterministic 32-hex OTLP trace id derived from a turn correlation id. */
26
+ export function deriveOtlpTraceId(correlationId) {
27
+ return createHash("sha256").update(correlationId, "utf8").digest("hex").slice(0, 32);
28
+ }
29
+ /** Deterministic 16-hex OTLP span id derived from the trace id plus span discriminator. */
30
+ export function deriveOtlpSpanId(correlationId, discriminator) {
31
+ return createHash("sha256").update(`${correlationId}|${discriminator}`, "utf8").digest("hex").slice(0, 16);
32
+ }
33
+ /** Epoch-ms to OTLP unix-nano string via BigInt (number math loses precision above 2^53). */
34
+ export function epochMsToUnixNano(ms) {
35
+ return (BigInt(Math.max(0, Math.trunc(ms))) * 1000000n).toString();
36
+ }
37
+ function attr(key, value) {
38
+ if (typeof value === "number") {
39
+ return Number.isSafeInteger(value)
40
+ ? { key, value: { intValue: String(value) } }
41
+ : { key, value: { stringValue: String(value) } };
42
+ }
43
+ if (typeof value === "boolean")
44
+ return { key, value: { boolValue: value } };
45
+ return { key, value: { stringValue: value } };
46
+ }
47
+ /** Shallow primitive-valued fields of the record's bounded data become span attributes. */
48
+ function attributesFromData(data, limit = 32) {
49
+ if (typeof data !== "object" || data === null)
50
+ return [];
51
+ const out = [];
52
+ for (const [key, value] of Object.entries(data)) {
53
+ if (out.length >= limit)
54
+ break;
55
+ if (typeof value === "string" && value.length > 0)
56
+ out.push(attr(key, value.slice(0, 512)));
57
+ else if (typeof value === "number" && Number.isFinite(value))
58
+ out.push(attr(key, value));
59
+ else if (typeof value === "boolean")
60
+ out.push(attr(key, value));
61
+ }
62
+ return out;
63
+ }
64
+ function spanFromRecord(record) {
65
+ const dur = record.dur;
66
+ const traceId = record.traceId;
67
+ if (dur === undefined || traceId === undefined)
68
+ return null;
69
+ const traceHex = deriveOtlpTraceId(traceId);
70
+ const endTime = epochMsToUnixNano(record.t);
71
+ const startTime = epochMsToUnixNano(record.t - dur);
72
+ const status = { code: record.level === "error" ? "STATUS_CODE_ERROR" : "STATUS_CODE_OK" };
73
+ const data = record.data;
74
+ const base = { traceId: traceHex, startTimeUnixNano: startTime, endTimeUnixNano: endTime, status };
75
+ if (record.kind === "turn.span") {
76
+ return {
77
+ ...base,
78
+ spanId: deriveOtlpSpanId(traceId, "turn.span"),
79
+ name: "agent.turn",
80
+ kind: "SPAN_KIND_INTERNAL",
81
+ attributes: attributesFromData(data),
82
+ };
83
+ }
84
+ if (record.kind === "llm.response") {
85
+ return {
86
+ ...base,
87
+ spanId: deriveOtlpSpanId(traceId, "llm.response"),
88
+ parentSpanId: deriveOtlpSpanId(traceId, "turn.span"),
89
+ name: "agent.llm",
90
+ kind: "SPAN_KIND_CLIENT",
91
+ attributes: attributesFromData(data),
92
+ };
93
+ }
94
+ if (record.kind === "tool.span") {
95
+ const callId = (typeof data?.callId === "string"
96
+ ? data.callId
97
+ : "");
98
+ const toolName = (typeof data?.toolName === "string"
99
+ ? data.toolName
100
+ : "");
101
+ return {
102
+ ...base,
103
+ spanId: deriveOtlpSpanId(traceId, `tool.span|${callId}`),
104
+ parentSpanId: deriveOtlpSpanId(traceId, "turn.span"),
105
+ name: toolName.length > 0 ? `agent.tool:${toolName}` : "agent.tool",
106
+ kind: "SPAN_KIND_INTERNAL",
107
+ attributes: attributesFromData(data),
108
+ };
109
+ }
110
+ return null;
111
+ }
112
+ /** Normalized trace ingest URL: base URL + signal path unless already present. */
113
+ export function resolveOtlpTracesUrl(endpoint) {
114
+ const trimmed = endpoint.replace(/\/+$/, "");
115
+ return trimmed.endsWith(OTLP_SIGNAL_PATH) ? trimmed : `${trimmed}${OTLP_SIGNAL_PATH}`;
116
+ }
117
+ export function createOtlpTraceExportSink(options) {
118
+ const timeoutMs = options.timeoutMs ?? OTLP_DEFAULT_TIMEOUT_MS;
119
+ const flushThreshold = options.flushThreshold ?? OTLP_DEFAULT_FLUSH_THRESHOLD;
120
+ const url = resolveOtlpTracesUrl(options.endpoint);
121
+ const fetchImpl = options.fetchImpl ?? defaultFetch;
122
+ let buffer = [];
123
+ let dropped = 0;
124
+ let failing = false;
125
+ let inFlight = Promise.resolve();
126
+ function reportFailure(error) {
127
+ if (failing)
128
+ return;
129
+ failing = true;
130
+ try {
131
+ options.onFailure?.(error);
132
+ }
133
+ catch {
134
+ // failure reporting must never break the sink
135
+ }
136
+ }
137
+ async function deliver(reason) {
138
+ if (buffer.length === 0)
139
+ return;
140
+ const batch = buffer;
141
+ const controller = new AbortController();
142
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
143
+ try {
144
+ const body = JSON.stringify({
145
+ resourceSpans: [
146
+ {
147
+ resource: { attributes: [attr("service.name", "agent-forge")] },
148
+ scopeSpans: [{ scope: { name: "agent-forge.observability", version: "trace.v1" }, spans: batch }],
149
+ },
150
+ ],
151
+ });
152
+ const response = await fetchImpl(url, {
153
+ method: "POST",
154
+ headers: { "content-type": "application/json" },
155
+ body,
156
+ signal: controller.signal,
157
+ });
158
+ if (!response.ok) {
159
+ reportFailure(new Error(`OTLP export failed (reason=${reason}): HTTP ${response.status}`));
160
+ dropOverflow();
161
+ return;
162
+ }
163
+ failing = false;
164
+ buffer = buffer.slice(batch.length);
165
+ }
166
+ catch (error) {
167
+ reportFailure(error instanceof Error ? error : new Error(String(error)));
168
+ dropOverflow();
169
+ }
170
+ finally {
171
+ clearTimeout(timer);
172
+ }
173
+ }
174
+ function dropOverflow() {
175
+ if (buffer.length <= OTLP_MAX_BUFFERED_SPANS)
176
+ return;
177
+ const excess = buffer.length - OTLP_MAX_BUFFERED_SPANS;
178
+ buffer = buffer.slice(excess);
179
+ dropped += excess;
180
+ reportFailure(new Error(`OTLP export buffer overflow: dropped ${excess} spans (total dropped ${dropped})`));
181
+ }
182
+ function flush(reason) {
183
+ const run = inFlight.then(() => deliver(reason));
184
+ inFlight = run.catch(() => { });
185
+ return run;
186
+ }
187
+ return {
188
+ onTraceRecord: (record) => {
189
+ const span = spanFromRecord(record);
190
+ if (span === null)
191
+ return;
192
+ buffer.push(span);
193
+ if (buffer.length >= flushThreshold)
194
+ void flush("threshold");
195
+ },
196
+ flush,
197
+ };
198
+ }
199
+ function defaultFetch(url, init) {
200
+ return fetch(url, init);
201
+ }
202
+ /** Type guard helper used by the plugin wiring: is a record span-exportable at all. */
203
+ export function isOtlpSpanRecord(record) {
204
+ return spanFromRecord(record) !== null;
205
+ }
206
+ //# sourceMappingURL=otlp-exporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otlp-exporter.js","sourceRoot":"","sources":["../src/otlp-exporter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * OTLP/HTTP+JSON trace export sink for the first-party observability plugin\n * (design §8 telemetry export seam). Implements `ObservabilityExportSinkV1`\n * over plain `fetch` — no OpenTelemetry SDK dependency; the wire payload is\n * the spec's JSON encoding of `ExportTraceServiceRequest`.\n *\n * Mapping (registered, design §8): one OTLP trace per turn correlation id.\n * Span-bearing records export as spans (`turn.span` root, `llm.response` and\n * `tool.span` parented under it); record kinds without a closed duration\n * (`session.start`, `llm.request`, `lifecycle`, `error`, `decision`,\n * `plugin.log`) and records without a trace id are not exported — the local\n * `agent-forge/trace.v1` file keeps full fidelity. OTel ids are derived\n * deterministically (SHA-256) from the correlation id so parent/child linkage\n * is reproducible across runs and processes.\n *\n * Failure domain: export failures never throw — the first failure of a streak\n * reports through `onFailure`, the batch is retained for the next flush and\n * oldest spans drop (counted) once the cap is hit.\n */\n\nimport { createHash } from \"node:crypto\";\nimport type { ObservabilityExportSinkV1, TraceRecordV1 } from \"@agent-forge/plugin-sdk\";\n\nexport const OTLP_DEFAULT_TIMEOUT_MS = 5_000;\nexport const OTLP_DEFAULT_FLUSH_THRESHOLD = 64;\nexport const OTLP_MAX_BUFFERED_SPANS = 1_024;\nconst OTLP_SIGNAL_PATH = \"/v1/traces\";\n\n/** Deterministic 32-hex OTLP trace id derived from a turn correlation id. */\nexport function deriveOtlpTraceId(correlationId: string): string {\n\treturn createHash(\"sha256\").update(correlationId, \"utf8\").digest(\"hex\").slice(0, 32);\n}\n\n/** Deterministic 16-hex OTLP span id derived from the trace id plus span discriminator. */\nexport function deriveOtlpSpanId(correlationId: string, discriminator: string): string {\n\treturn createHash(\"sha256\").update(`${correlationId}|${discriminator}`, \"utf8\").digest(\"hex\").slice(0, 16);\n}\n\n/** Epoch-ms to OTLP unix-nano string via BigInt (number math loses precision above 2^53). */\nexport function epochMsToUnixNano(ms: number): string {\n\treturn (BigInt(Math.max(0, Math.trunc(ms))) * 1_000_000n).toString();\n}\n\ninterface OtlpAttribute {\n\treadonly key: string;\n\treadonly value: { readonly stringValue: string } | { readonly intValue: string } | { readonly boolValue: boolean };\n}\n\ninterface OtlpSpan {\n\treadonly traceId: string;\n\treadonly spanId: string;\n\treadonly parentSpanId?: string;\n\treadonly name: string;\n\treadonly kind: string;\n\treadonly startTimeUnixNano: string;\n\treadonly endTimeUnixNano: string;\n\treadonly attributes?: readonly OtlpAttribute[];\n\treadonly status: { readonly code: string };\n}\n\nfunction attr(key: string, value: string | number | boolean): OtlpAttribute {\n\tif (typeof value === \"number\") {\n\t\treturn Number.isSafeInteger(value)\n\t\t\t? { key, value: { intValue: String(value) } }\n\t\t\t: { key, value: { stringValue: String(value) } };\n\t}\n\tif (typeof value === \"boolean\") return { key, value: { boolValue: value } };\n\treturn { key, value: { stringValue: value } };\n}\n\n/** Shallow primitive-valued fields of the record's bounded data become span attributes. */\nfunction attributesFromData(data: unknown, limit = 32): OtlpAttribute[] {\n\tif (typeof data !== \"object\" || data === null) return [];\n\tconst out: OtlpAttribute[] = [];\n\tfor (const [key, value] of Object.entries(data as Record<string, unknown>)) {\n\t\tif (out.length >= limit) break;\n\t\tif (typeof value === \"string\" && value.length > 0) out.push(attr(key, value.slice(0, 512)));\n\t\telse if (typeof value === \"number\" && Number.isFinite(value)) out.push(attr(key, value));\n\t\telse if (typeof value === \"boolean\") out.push(attr(key, value));\n\t}\n\treturn out;\n}\n\nfunction spanFromRecord(record: TraceRecordV1): OtlpSpan | null {\n\tconst dur = record.dur;\n\tconst traceId = record.traceId;\n\tif (dur === undefined || traceId === undefined) return null;\n\n\tconst traceHex = deriveOtlpTraceId(traceId);\n\tconst endTime = epochMsToUnixNano(record.t);\n\tconst startTime = epochMsToUnixNano(record.t - dur);\n\tconst status = { code: record.level === \"error\" ? \"STATUS_CODE_ERROR\" : \"STATUS_CODE_OK\" };\n\tconst data = record.data;\n\tconst base = { traceId: traceHex, startTimeUnixNano: startTime, endTimeUnixNano: endTime, status };\n\n\tif (record.kind === \"turn.span\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: \"agent.turn\",\n\t\t\tkind: \"SPAN_KIND_INTERNAL\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\tif (record.kind === \"llm.response\") {\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, \"llm.response\"),\n\t\t\tparentSpanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: \"agent.llm\",\n\t\t\tkind: \"SPAN_KIND_CLIENT\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\tif (record.kind === \"tool.span\") {\n\t\tconst callId = (\n\t\t\ttypeof (data as Record<string, unknown> | undefined)?.callId === \"string\"\n\t\t\t\t? (data as Record<string, unknown>).callId\n\t\t\t\t: \"\"\n\t\t) as string;\n\t\tconst toolName = (\n\t\t\ttypeof (data as Record<string, unknown> | undefined)?.toolName === \"string\"\n\t\t\t\t? (data as Record<string, unknown>).toolName\n\t\t\t\t: \"\"\n\t\t) as string;\n\t\treturn {\n\t\t\t...base,\n\t\t\tspanId: deriveOtlpSpanId(traceId, `tool.span|${callId}`),\n\t\t\tparentSpanId: deriveOtlpSpanId(traceId, \"turn.span\"),\n\t\t\tname: toolName.length > 0 ? `agent.tool:${toolName}` : \"agent.tool\",\n\t\t\tkind: \"SPAN_KIND_INTERNAL\",\n\t\t\tattributes: attributesFromData(data),\n\t\t};\n\t}\n\treturn null;\n}\n\n/** Normalized trace ingest URL: base URL + signal path unless already present. */\nexport function resolveOtlpTracesUrl(endpoint: string): string {\n\tconst trimmed = endpoint.replace(/\\/+$/, \"\");\n\treturn trimmed.endsWith(OTLP_SIGNAL_PATH) ? trimmed : `${trimmed}${OTLP_SIGNAL_PATH}`;\n}\n\nexport interface OtlpExportSinkOptions {\n\treadonly endpoint: string;\n\treadonly timeoutMs?: number;\n\treadonly flushThreshold?: number;\n\treadonly fetchImpl?: (\n\t\turl: string,\n\t\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n\t) => Promise<{ ok: boolean; status: number }>;\n\t/** Failure channel: first failure of a streak, plus drop notifications. */\n\treadonly onFailure?: (error: Error) => void;\n}\n\nexport function createOtlpTraceExportSink(options: OtlpExportSinkOptions): ObservabilityExportSinkV1 {\n\tconst timeoutMs = options.timeoutMs ?? OTLP_DEFAULT_TIMEOUT_MS;\n\tconst flushThreshold = options.flushThreshold ?? OTLP_DEFAULT_FLUSH_THRESHOLD;\n\tconst url = resolveOtlpTracesUrl(options.endpoint);\n\tconst fetchImpl = options.fetchImpl ?? defaultFetch;\n\n\tlet buffer: OtlpSpan[] = [];\n\tlet dropped = 0;\n\tlet failing = false;\n\tlet inFlight: Promise<void> = Promise.resolve();\n\n\tfunction reportFailure(error: Error): void {\n\t\tif (failing) return;\n\t\tfailing = true;\n\t\ttry {\n\t\t\toptions.onFailure?.(error);\n\t\t} catch {\n\t\t\t// failure reporting must never break the sink\n\t\t}\n\t}\n\n\tasync function deliver(reason: string): Promise<void> {\n\t\tif (buffer.length === 0) return;\n\t\tconst batch = buffer;\n\t\tconst controller = new AbortController();\n\t\tconst timer = setTimeout(() => controller.abort(), timeoutMs);\n\t\ttry {\n\t\t\tconst body = JSON.stringify({\n\t\t\t\tresourceSpans: [\n\t\t\t\t\t{\n\t\t\t\t\t\tresource: { attributes: [attr(\"service.name\", \"agent-forge\")] },\n\t\t\t\t\t\tscopeSpans: [{ scope: { name: \"agent-forge.observability\", version: \"trace.v1\" }, spans: batch }],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t});\n\t\t\tconst response = await fetchImpl(url, {\n\t\t\t\tmethod: \"POST\",\n\t\t\t\theaders: { \"content-type\": \"application/json\" },\n\t\t\t\tbody,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tif (!response.ok) {\n\t\t\t\treportFailure(new Error(`OTLP export failed (reason=${reason}): HTTP ${response.status}`));\n\t\t\t\tdropOverflow();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfailing = false;\n\t\t\tbuffer = buffer.slice(batch.length);\n\t\t} catch (error) {\n\t\t\treportFailure(error instanceof Error ? error : new Error(String(error)));\n\t\t\tdropOverflow();\n\t\t} finally {\n\t\t\tclearTimeout(timer);\n\t\t}\n\t}\n\n\tfunction dropOverflow(): void {\n\t\tif (buffer.length <= OTLP_MAX_BUFFERED_SPANS) return;\n\t\tconst excess = buffer.length - OTLP_MAX_BUFFERED_SPANS;\n\t\tbuffer = buffer.slice(excess);\n\t\tdropped += excess;\n\t\treportFailure(new Error(`OTLP export buffer overflow: dropped ${excess} spans (total dropped ${dropped})`));\n\t}\n\n\tfunction flush(reason: string): Promise<void> {\n\t\tconst run = inFlight.then(() => deliver(reason));\n\t\tinFlight = run.catch(() => {});\n\t\treturn run;\n\t}\n\n\treturn {\n\t\tonTraceRecord: (record) => {\n\t\t\tconst span = spanFromRecord(record);\n\t\t\tif (span === null) return;\n\t\t\tbuffer.push(span);\n\t\t\tif (buffer.length >= flushThreshold) void flush(\"threshold\");\n\t\t},\n\t\tflush,\n\t};\n}\n\nfunction defaultFetch(\n\turl: string,\n\tinit: { method: \"POST\"; headers: { \"content-type\": string }; body: string; signal: AbortSignal },\n): Promise<{ ok: boolean; status: number }> {\n\treturn fetch(url, init) as unknown as Promise<{ ok: boolean; status: number }>;\n}\n\n/** Type guard helper used by the plugin wiring: is a record span-exportable at all. */\nexport function isOtlpSpanRecord(record: TraceRecordV1): boolean {\n\treturn spanFromRecord(record) !== null;\n}\n"]}