@alvin0/ai-agent-sdk-observability-node 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 alvin0 (chaulamdinhai) <chaulamdinhai@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,65 @@
1
+ # @alvin0/ai-agent-sdk-observability-node
2
+
3
+ Runtime: **Node 22.12+**.
4
+
5
+ ```sh
6
+ pnpm add @alvin0/ai-agent-sdk-core @alvin0/ai-agent-sdk-observability-node
7
+ ```
8
+
9
+ Node-only durable observation journal and explicit lifecycle/diagnostic helpers.
10
+ The journal root is always caller-supplied. Records use checksum-framed JSONL,
11
+ private directory/file modes, unique segments, atomic acknowledgment cursors,
12
+ bounded retention, and strict corruption recovery.
13
+
14
+ Exact provider-wire diagnostics are a separate high-risk capability and refuse
15
+ construction unless both `content: 'full'` and `allowWireBodies: true` are set.
16
+ Nothing installs process lifecycle handlers automatically.
17
+
18
+ For normal runtime composition, use the inert `jsonlObservationExporter()`
19
+ factory. Filesystem resources are acquired only when `createAgentRuntime()`
20
+ calls its `ready()` lifecycle boundary:
21
+
22
+ ```ts
23
+ import { createAgentRuntime } from '@alvin0/ai-agent-sdk-core'
24
+ import {
25
+ jsonlObservationExporter,
26
+ recoverRuntimeObservationJournal,
27
+ } from '@alvin0/ai-agent-sdk-observability-node'
28
+
29
+ const runtime = await createAgentRuntime({
30
+ providers: [provider],
31
+ observability: {
32
+ mode: 'reliable',
33
+ exporters: [{
34
+ exporter: jsonlObservationExporter({
35
+ rootDir: './observations',
36
+ mode: 'reliable',
37
+ }),
38
+ ownership: 'owned',
39
+ requirement: 'required',
40
+ boundary: 'local-durable',
41
+ }],
42
+ },
43
+ })
44
+
45
+ await runtime.close()
46
+ const recovered = await recoverRuntimeObservationJournal('./observations')
47
+ ```
48
+
49
+ The runtime adapter persists privacy-filtered events and atomic terminal run
50
+ records in `runtime-delivery/`, and acknowledges their IDs separately. The
51
+ caller still closes the runtime explicitly; an owned exporter is closed by the
52
+ runtime after all active runs settle. `recoverRuntimeObservationJournal()`
53
+ verifies checksums and returns both event and terminal-run records from this
54
+ recommended format; `recoverJournal()` remains the advanced legacy-journal
55
+ recovery API.
56
+
57
+ Composition: `runtime.observability.exporters`. Lifecycle:
58
+ `explicit-owned-or-borrowed`; normal JSONL composition selects owned local
59
+ durability, while advanced hosts may retain a borrowed exporter explicitly.
60
+
61
+ Use `@alvin0/ai-agent-sdk-observability-node/journal` when only durable journal and
62
+ lifecycle APIs are needed, or `@alvin0/ai-agent-sdk-observability-node/diagnostic` for
63
+ the separately gated exact-wire capability. That diagnostic route exports
64
+ `createDailyJsonlRequestLogger()` and `combineProviderRequestLoggers()` for
65
+ provider request-logger slots. The root entry re-exports both.
@@ -0,0 +1,44 @@
1
+ import { JsonValue, ObservationContentPolicy } from "@alvin0/ai-agent-sdk-core/observability";
2
+ //#region src/diagnostic/wire-logger.d.ts
3
+ interface ProviderWireLogRecord {
4
+ readonly schemaVersion: 1;
5
+ readonly type: string;
6
+ readonly provider: string;
7
+ readonly timestamp: string;
8
+ readonly [key: string]: JsonValue;
9
+ }
10
+ interface ProviderWireLogger {
11
+ (record: ProviderWireLogRecord): Promise<void>;
12
+ shutdown(): Promise<void>;
13
+ }
14
+ interface DiagnosticWireLoggerOptions {
15
+ readonly rootDir: string;
16
+ readonly content: ObservationContentPolicy;
17
+ readonly allowWireBodies: boolean;
18
+ readonly now?: () => Date;
19
+ }
20
+ /** Create an exact-wire logger only after two explicit high-risk opt-ins. */
21
+ declare function createDiagnosticWireLogger(options: DiagnosticWireLoggerOptions): ProviderWireLogger;
22
+ //#endregion
23
+ //#region src/diagnostic/request-logger.d.ts
24
+ /** Minimum structural input accepted from an HTTP provider request logger. */
25
+ interface ProviderRequestLogLike {
26
+ readonly provider: string;
27
+ readonly timestamp: string;
28
+ }
29
+ interface DailyJsonlRequestLoggerOptions {
30
+ readonly rootDir?: string;
31
+ readonly content: 'full';
32
+ readonly allowWireBodies: true;
33
+ readonly now?: () => Date;
34
+ /** @deprecated Unique diagnostic files always use a UTC date. */
35
+ readonly calendar?: 'local' | 'utc';
36
+ }
37
+ type DailyJsonlRequestLogger = ((record: ProviderRequestLogLike) => Promise<void>) & Pick<ProviderWireLogger, 'shutdown'>;
38
+ /** Compatibility-shaped exact request logger hosted by the Node diagnostic capability. */
39
+ declare function createDailyJsonlRequestLogger(options: DailyJsonlRequestLoggerOptions): DailyJsonlRequestLogger;
40
+ /** Fan one exact request record out to independent caller-owned log sinks. */
41
+ declare function combineProviderRequestLoggers<RecordType extends ProviderRequestLogLike>(...loggers: readonly ((record: RecordType) => Promise<void> | void)[]): (record: RecordType) => Promise<void>;
42
+ //#endregion
43
+ export { createDailyJsonlRequestLogger as a, ProviderWireLogger as c, combineProviderRequestLoggers as i, createDiagnosticWireLogger as l, DailyJsonlRequestLoggerOptions as n, DiagnosticWireLoggerOptions as o, ProviderRequestLogLike as r, ProviderWireLogRecord as s, DailyJsonlRequestLogger as t };
44
+ //# sourceMappingURL=diagnostic-B0r2HLqz.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-B0r2HLqz.d.mts","names":[],"sources":["../src/diagnostic/wire-logger.ts","../src/diagnostic/request-logger.ts"],"mappings":";;UAMiB;WACN;WACA;WACA;WACA;YACC,cAAc;;UAGT;GACd,QAAQ,wBAAwB;EACjC,YAAY;;UAGG;WACN;WACA,SAAS;WACT;WACA,YAAY;;;iBASP,2BAA2B,SAAS,8BAA8B;;;;UCzBjE;WACN;WACA;;UAGM;WACN;WACA;WACA;WACA,YAAY;;WAEZ;;KAGC,4BACT,QAAQ,2BAA2B,iBAClC,KAAK;;iBAGO,8BACd,SAAS,iCACR;;iBAea,8BAA8B,mBAAmB,2BAC5D,oBAAoB,QAAQ,eAAe,2BAC5C,QAAQ,eAAe"}
@@ -0,0 +1,80 @@
1
+ import { n as ensureSafeRoot, r as openExclusiveFile } from "./safe-filesystem-CbOPNSoN.mjs";
2
+ import { randomBytes } from "node:crypto";
3
+ import { join, resolve } from "node:path";
4
+
5
+ //#region src/diagnostic/wire-logger.ts
6
+ function providerSegment(value) {
7
+ const safe = value.replace(/[^A-Za-z0-9._-]/g, "_").replace(/^\.+/, "_");
8
+ return safe.length === 0 ? "_unknown" : safe;
9
+ }
10
+ /** Create an exact-wire logger only after two explicit high-risk opt-ins. */
11
+ function createDiagnosticWireLogger(options) {
12
+ if (options?.content !== "full" || options.allowWireBodies !== true) throw new TypeError("wire diagnostics require content: 'full' and allowWireBodies: true");
13
+ const rootInput = resolve(options.rootDir);
14
+ const handles = /* @__PURE__ */ new Map();
15
+ let tail = Promise.resolve();
16
+ let closed = false;
17
+ const handleFor = (provider) => {
18
+ const segment = providerSegment(provider);
19
+ const existing = handles.get(segment);
20
+ if (existing !== void 0) return existing;
21
+ const pending = (async () => {
22
+ const root = await ensureSafeRoot(join(rootInput, segment, "wire"));
23
+ const day = (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString().slice(0, 10);
24
+ return await openExclusiveFile(root, `${day}-${process.pid}-${randomBytes(8).toString("hex")}.wire.jsonl`);
25
+ })();
26
+ handles.set(segment, pending);
27
+ return pending;
28
+ };
29
+ const logger = (async (record) => {
30
+ if (closed) throw new TypeError("wire diagnostic logger is closed");
31
+ const write = tail.then(async () => {
32
+ await (await handleFor(record.provider)).writeFile(`${JSON.stringify({
33
+ ...record,
34
+ timestamp: (options.now?.() ?? /* @__PURE__ */ new Date()).toISOString()
35
+ })}\n`, "utf8");
36
+ });
37
+ tail = write.catch(() => void 0);
38
+ await write;
39
+ });
40
+ logger.shutdown = async () => {
41
+ if (closed) return;
42
+ closed = true;
43
+ await tail;
44
+ for (const handle of await Promise.all(handles.values())) {
45
+ await handle.datasync();
46
+ await handle.close();
47
+ }
48
+ };
49
+ return logger;
50
+ }
51
+
52
+ //#endregion
53
+ //#region src/diagnostic/request-logger.ts
54
+ /** Compatibility-shaped exact request logger hosted by the Node diagnostic capability. */
55
+ function createDailyJsonlRequestLogger(options) {
56
+ const wire = createDiagnosticWireLogger({
57
+ rootDir: options.rootDir ?? ".providers",
58
+ content: options.content,
59
+ allowWireBodies: options.allowWireBodies,
60
+ ...options.now === void 0 ? {} : { now: options.now }
61
+ });
62
+ const logger = (async (record) => {
63
+ await wire(record);
64
+ });
65
+ logger.shutdown = () => wire.shutdown();
66
+ return logger;
67
+ }
68
+ /** Fan one exact request record out to independent caller-owned log sinks. */
69
+ function combineProviderRequestLoggers(...loggers) {
70
+ const sinks = Object.freeze([...loggers]);
71
+ return async (record) => {
72
+ await Promise.all(sinks.map(async (logger) => {
73
+ await logger(record);
74
+ }));
75
+ };
76
+ }
77
+
78
+ //#endregion
79
+ export { createDailyJsonlRequestLogger as n, createDiagnosticWireLogger as r, combineProviderRequestLoggers as t };
80
+ //# sourceMappingURL=diagnostic-Cf6AKmxT.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-Cf6AKmxT.mjs","names":[],"sources":["../src/diagnostic/wire-logger.ts","../src/diagnostic/request-logger.ts"],"sourcesContent":["import { randomBytes } from 'node:crypto'\nimport type { FileHandle } from 'node:fs/promises'\nimport { join, resolve } from 'node:path'\nimport type { JsonValue, ObservationContentPolicy } from '@alvin0/ai-agent-sdk-core/observability'\nimport { ensureSafeRoot, openExclusiveFile } from '../common/safe-filesystem.ts'\n\nexport interface ProviderWireLogRecord {\n readonly schemaVersion: 1\n readonly type: string\n readonly provider: string\n readonly timestamp: string\n readonly [key: string]: JsonValue\n}\n\nexport interface ProviderWireLogger {\n (record: ProviderWireLogRecord): Promise<void>\n shutdown(): Promise<void>\n}\n\nexport interface DiagnosticWireLoggerOptions {\n readonly rootDir: string\n readonly content: ObservationContentPolicy\n readonly allowWireBodies: boolean\n readonly now?: () => Date\n}\n\nfunction providerSegment(value: string): string {\n const safe = value.replace(/[^A-Za-z0-9._-]/g, '_').replace(/^\\.+/, '_')\n return safe.length === 0 ? '_unknown' : safe\n}\n\n/** Create an exact-wire logger only after two explicit high-risk opt-ins. */\nexport function createDiagnosticWireLogger(options: DiagnosticWireLoggerOptions): ProviderWireLogger {\n if (options?.content !== 'full' || options.allowWireBodies !== true) {\n throw new TypeError(\"wire diagnostics require content: 'full' and allowWireBodies: true\")\n }\n const rootInput = resolve(options.rootDir)\n const handles = new Map<string, Promise<FileHandle>>()\n let tail: Promise<void> = Promise.resolve()\n let closed = false\n const handleFor = (provider: string): Promise<FileHandle> => {\n const segment = providerSegment(provider)\n const existing = handles.get(segment)\n if (existing !== undefined) return existing\n const pending = (async () => {\n const root = await ensureSafeRoot(join(rootInput, segment, 'wire'))\n const day = (options.now?.() ?? new Date()).toISOString().slice(0, 10)\n return await openExclusiveFile(root, `${day}-${process.pid}-${randomBytes(8).toString('hex')}.wire.jsonl`)\n })()\n handles.set(segment, pending)\n return pending\n }\n const logger = (async (record: ProviderWireLogRecord) => {\n if (closed) throw new TypeError('wire diagnostic logger is closed')\n const write = tail.then(async () => {\n const handle = await handleFor(record.provider)\n await handle.writeFile(\n `${JSON.stringify({ ...record, timestamp: (options.now?.() ?? new Date()).toISOString() })}\\n`,\n 'utf8',\n )\n })\n tail = write.catch(() => undefined)\n await write\n }) as ProviderWireLogger\n logger.shutdown = async () => {\n if (closed) return\n closed = true\n await tail\n for (const handle of await Promise.all(handles.values())) {\n await handle.datasync()\n await handle.close()\n }\n }\n return logger\n}\n","import {\n createDiagnosticWireLogger,\n type ProviderWireLogRecord,\n type ProviderWireLogger,\n} from './wire-logger.ts'\n\n/** Minimum structural input accepted from an HTTP provider request logger. */\nexport interface ProviderRequestLogLike {\n readonly provider: string\n readonly timestamp: string\n}\n\nexport interface DailyJsonlRequestLoggerOptions {\n readonly rootDir?: string\n readonly content: 'full'\n readonly allowWireBodies: true\n readonly now?: () => Date\n /** @deprecated Unique diagnostic files always use a UTC date. */\n readonly calendar?: 'local' | 'utc'\n}\n\nexport type DailyJsonlRequestLogger = (\n (record: ProviderRequestLogLike) => Promise<void>\n) & Pick<ProviderWireLogger, 'shutdown'>\n\n/** Compatibility-shaped exact request logger hosted by the Node diagnostic capability. */\nexport function createDailyJsonlRequestLogger(\n options: DailyJsonlRequestLoggerOptions,\n): DailyJsonlRequestLogger {\n const wire = createDiagnosticWireLogger({\n rootDir: options.rootDir ?? '.providers',\n content: options.content,\n allowWireBodies: options.allowWireBodies,\n ...(options.now === undefined ? {} : { now: options.now }),\n })\n const logger = (async (record: ProviderRequestLogLike): Promise<void> => {\n await wire(record as ProviderWireLogRecord)\n }) as DailyJsonlRequestLogger\n logger.shutdown = () => wire.shutdown()\n return logger\n}\n\n/** Fan one exact request record out to independent caller-owned log sinks. */\nexport function combineProviderRequestLoggers<RecordType extends ProviderRequestLogLike>(\n ...loggers: readonly ((record: RecordType) => Promise<void> | void)[]\n): (record: RecordType) => Promise<void> {\n const sinks = Object.freeze([...loggers])\n return async record => {\n await Promise.all(sinks.map(async logger => { await logger(record) }))\n }\n}\n"],"mappings":";;;;;AA0BA,SAAS,gBAAgB,OAAuB;CAC9C,MAAM,OAAO,MAAM,QAAQ,oBAAoB,GAAG,CAAC,CAAC,QAAQ,QAAQ,GAAG;CACvE,OAAO,KAAK,WAAW,IAAI,aAAa;AAC1C;;AAGA,SAAgB,2BAA2B,SAA0D;CACnG,IAAI,SAAS,YAAY,UAAU,QAAQ,oBAAoB,MAC7D,MAAM,IAAI,UAAU,oEAAoE;CAE1F,MAAM,YAAY,QAAQ,QAAQ,OAAO;CACzC,MAAM,0BAAU,IAAI,IAAiC;CACrD,IAAI,OAAsB,QAAQ,QAAQ;CAC1C,IAAI,SAAS;CACb,MAAM,aAAa,aAA0C;EAC3D,MAAM,UAAU,gBAAgB,QAAQ;EACxC,MAAM,WAAW,QAAQ,IAAI,OAAO;EACpC,IAAI,aAAa,QAAW,OAAO;EACnC,MAAM,WAAW,YAAY;GAC3B,MAAM,OAAO,MAAM,eAAe,KAAK,WAAW,SAAS,MAAM,CAAC;GAClE,MAAM,OAAO,QAAQ,MAAM,qBAAK,IAAI,KAAK,EAAC,CAAE,YAAY,CAAC,CAAC,MAAM,GAAG,EAAE;GACrE,OAAO,MAAM,kBAAkB,MAAM,GAAG,IAAI,GAAG,QAAQ,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,YAAY;EAC3G,EAAC,CAAE;EACH,QAAQ,IAAI,SAAS,OAAO;EAC5B,OAAO;CACT;CACA,MAAM,UAAU,OAAO,WAAkC;EACvD,IAAI,QAAQ,MAAM,IAAI,UAAU,kCAAkC;EAClE,MAAM,QAAQ,KAAK,KAAK,YAAY;GAElC,OAAM,MADe,UAAU,OAAO,QAAQ,EAClC,CAAC,UACX,GAAG,KAAK,UAAU;IAAE,GAAG;IAAQ,YAAY,QAAQ,MAAM,qBAAK,IAAI,KAAK,EAAC,CAAE,YAAY;GAAE,CAAC,EAAE,KAC3F,MACF;EACF,CAAC;EACD,OAAO,MAAM,YAAY,MAAS;EAClC,MAAM;CACR;CACA,OAAO,WAAW,YAAY;EAC5B,IAAI,QAAQ;EACZ,SAAS;EACT,MAAM;EACN,KAAK,MAAM,UAAU,MAAM,QAAQ,IAAI,QAAQ,OAAO,CAAC,GAAG;GACxD,MAAM,OAAO,SAAS;GACtB,MAAM,OAAO,MAAM;EACrB;CACF;CACA,OAAO;AACT;;;;;AChDA,SAAgB,8BACd,SACyB;CACzB,MAAM,OAAO,2BAA2B;EACtC,SAAS,QAAQ,WAAW;EAC5B,SAAS,QAAQ;EACjB,iBAAiB,QAAQ;EACzB,GAAI,QAAQ,QAAQ,SAAY,CAAC,IAAI,EAAE,KAAK,QAAQ,IAAI;CAC1D,CAAC;CACD,MAAM,UAAU,OAAO,WAAkD;EACvE,MAAM,KAAK,MAA+B;CAC5C;CACA,OAAO,iBAAiB,KAAK,SAAS;CACtC,OAAO;AACT;;AAGA,SAAgB,8BACd,GAAG,SACoC;CACvC,MAAM,QAAQ,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC;CACxC,OAAO,OAAM,WAAU;EACrB,MAAM,QAAQ,IAAI,MAAM,IAAI,OAAM,WAAU;GAAE,MAAM,OAAO,MAAM;EAAE,CAAC,CAAC;CACvE;AACF"}
@@ -0,0 +1,2 @@
1
+ import { a as createDailyJsonlRequestLogger, c as ProviderWireLogger, i as combineProviderRequestLoggers, l as createDiagnosticWireLogger, n as DailyJsonlRequestLoggerOptions, o as DiagnosticWireLoggerOptions, r as ProviderRequestLogLike, s as ProviderWireLogRecord, t as DailyJsonlRequestLogger } from "./diagnostic-B0r2HLqz.mjs";
2
+ export { type DailyJsonlRequestLogger, type DailyJsonlRequestLoggerOptions, type DiagnosticWireLoggerOptions, type ProviderRequestLogLike, type ProviderWireLogRecord, type ProviderWireLogger, combineProviderRequestLoggers, createDailyJsonlRequestLogger, createDiagnosticWireLogger };
@@ -0,0 +1,3 @@
1
+ import { n as createDailyJsonlRequestLogger, r as createDiagnosticWireLogger, t as combineProviderRequestLoggers } from "./diagnostic-Cf6AKmxT.mjs";
2
+
3
+ export { combineProviderRequestLoggers, createDailyJsonlRequestLogger, createDiagnosticWireLogger };
@@ -0,0 +1,3 @@
1
+ import { a as createDailyJsonlRequestLogger, c as ProviderWireLogger, i as combineProviderRequestLoggers, l as createDiagnosticWireLogger, n as DailyJsonlRequestLoggerOptions, o as DiagnosticWireLoggerOptions, r as ProviderRequestLogLike, s as ProviderWireLogRecord, t as DailyJsonlRequestLogger } from "./diagnostic-B0r2HLqz.mjs";
2
+ import { _ as JsonlObservationJournalOptions, a as NodeLifecycleTarget, c as recoverRuntimeObservationJournal, d as JournalRecoveryRecord, f as JournalRecoveryResult, g as JournalDurabilityMode, h as recoverJournal, i as NodeLifecycleOptions, l as RuntimeJournalRecoveryResult, m as JsonlObservationJournalExporter, n as NodeObservationError, o as installNodeObservabilityLifecycle, p as JournalStats, r as NodeObservationErrorCode, s as jsonlObservationExporter, t as NODE_OBSERVATION_ERROR_CODES, u as RuntimeJournalRecord } from "./journal-export-BMfSC4Z6.mjs";
3
+ export { type DailyJsonlRequestLogger, type DailyJsonlRequestLoggerOptions, type DiagnosticWireLoggerOptions, type JournalDurabilityMode, type JournalRecoveryRecord, type JournalRecoveryResult, type JournalStats, JsonlObservationJournalExporter, type JsonlObservationJournalOptions, NODE_OBSERVATION_ERROR_CODES, type NodeLifecycleOptions, type NodeLifecycleTarget, NodeObservationError, type NodeObservationErrorCode, type ProviderRequestLogLike, type ProviderWireLogRecord, type ProviderWireLogger, type RuntimeJournalRecord as RuntimeJournalRecoveryRecord, type RuntimeJournalRecoveryResult, combineProviderRequestLoggers, createDailyJsonlRequestLogger, createDiagnosticWireLogger, installNodeObservabilityLifecycle, jsonlObservationExporter, recoverJournal, recoverRuntimeObservationJournal };
package/dist/index.mjs ADDED
@@ -0,0 +1,5 @@
1
+ import { a as recoverJournal, i as JsonlObservationJournalExporter, n as jsonlObservationExporter, r as recoverRuntimeObservationJournal, t as installNodeObservabilityLifecycle } from "./journal-export-HAdAQxLv.mjs";
2
+ import { a as NodeObservationError, i as NODE_OBSERVATION_ERROR_CODES } from "./safe-filesystem-CbOPNSoN.mjs";
3
+ import { n as createDailyJsonlRequestLogger, r as createDiagnosticWireLogger, t as combineProviderRequestLoggers } from "./diagnostic-Cf6AKmxT.mjs";
4
+
5
+ export { JsonlObservationJournalExporter, NODE_OBSERVATION_ERROR_CODES, NodeObservationError, combineProviderRequestLoggers, createDailyJsonlRequestLogger, createDiagnosticWireLogger, installNodeObservabilityLifecycle, jsonlObservationExporter, recoverJournal, recoverRuntimeObservationJournal };
@@ -0,0 +1,125 @@
1
+ import { ObservationBoundary, ObservationEvent } from "@alvin0/ai-agent-sdk-core";
2
+ import { ExportAck, Observability, ObservationBatch, ObservationExportItem, ObservationExporter, ObservationExporterPlugin } from "@alvin0/ai-agent-sdk-core/observability";
3
+ //#region src/journal/types.d.ts
4
+ type JournalDurabilityMode = 'operational' | 'reliable' | 'audit';
5
+ interface JsonlObservationJournalOptions {
6
+ readonly id?: string;
7
+ readonly rootDir: string;
8
+ readonly mode: JournalDurabilityMode;
9
+ readonly maxSegmentBytes?: number;
10
+ readonly maxRetainedBytes?: number;
11
+ readonly acknowledgedRetentionMs?: number;
12
+ readonly syncIntervalMs?: number;
13
+ readonly syncRecordCount?: number;
14
+ readonly now?: () => Date;
15
+ readonly segmentId?: () => string;
16
+ }
17
+ //#endregion
18
+ //#region src/journal.d.ts
19
+ interface JournalRecoveryRecord {
20
+ readonly segment: string;
21
+ readonly line: number;
22
+ readonly event: ObservationEvent;
23
+ readonly payloadJson: string;
24
+ }
25
+ interface JournalRecoveryResult {
26
+ readonly records: readonly JournalRecoveryRecord[];
27
+ readonly quarantinedSegments: readonly string[];
28
+ readonly truncatedSegments: readonly string[];
29
+ }
30
+ interface JournalStats {
31
+ readonly segmentCount: number;
32
+ readonly retainedBytes: number;
33
+ readonly unacknowledgedEvents: number;
34
+ readonly currentSegment?: string;
35
+ }
36
+ /** Append-only Node journal whose local durability is measured with fdatasync. */
37
+ declare class JsonlObservationJournalExporter implements ObservationExporter {
38
+ readonly id: string;
39
+ readonly supportedBoundaries: readonly ObservationBoundary[];
40
+ private readonly options;
41
+ private readonly rootPromise;
42
+ private current;
43
+ private writeTail;
44
+ private readonly pendingStages;
45
+ private readonly batchEvents;
46
+ private readonly acknowledged;
47
+ private syncTimer;
48
+ private unsyncedRecords;
49
+ private unsyncedCritical;
50
+ private closing;
51
+ constructor(options: JsonlObservationJournalOptions);
52
+ ready(): Promise<void>;
53
+ stage(event: ObservationEvent): Promise<void>;
54
+ export(batch: ObservationBatch, signal: AbortSignal): Promise<ExportAck>;
55
+ acknowledgeBatch(batchId: string): Promise<number>;
56
+ acknowledgeEvents(eventIds: readonly string[]): Promise<void>;
57
+ recover(): Promise<JournalRecoveryResult>;
58
+ cleanup(): Promise<void>;
59
+ private cleanupNow;
60
+ stats(): Promise<JournalStats>;
61
+ shutdown(_signal: AbortSignal): Promise<void>;
62
+ private initialize;
63
+ private enqueueWrite;
64
+ private openSegment;
65
+ private rotateIfNeeded;
66
+ private scheduleReliableSync;
67
+ private syncCurrent;
68
+ private ensureCapacity;
69
+ private loadCursor;
70
+ private persistCursor;
71
+ }
72
+ declare function recoverJournal(rootInput: string): Promise<JournalRecoveryResult>;
73
+ //#endregion
74
+ //#region src/journal/runtime-frame.d.ts
75
+ type RuntimeFrameKind = 'event' | 'run-terminal-record';
76
+ interface RuntimeJournalRecord {
77
+ readonly segment: string;
78
+ readonly line: number;
79
+ readonly kind: RuntimeFrameKind;
80
+ readonly id: string;
81
+ readonly key: string;
82
+ readonly item: ObservationExportItem;
83
+ readonly payloadJson: string;
84
+ }
85
+ //#endregion
86
+ //#region src/journal/runtime-store.d.ts
87
+ interface RuntimeJournalRecoveryResult {
88
+ readonly records: readonly RuntimeJournalRecord[];
89
+ readonly truncatedSegments: readonly string[];
90
+ readonly quarantinedSegments: readonly string[];
91
+ }
92
+ //#endregion
93
+ //#region src/journal/runtime-exporter.d.ts
94
+ /** Recommended runtime adapter. The advanced marker-free journal remains independent. */
95
+ declare function jsonlObservationExporter(options: JsonlObservationJournalOptions): ObservationExporterPlugin;
96
+ /** Verify and recover records written by the recommended runtime exporter. */
97
+ declare function recoverRuntimeObservationJournal(rootDir: string): Promise<RuntimeJournalRecoveryResult>;
98
+ //#endregion
99
+ //#region src/lifecycle.d.ts
100
+ interface NodeLifecycleTarget {
101
+ on(event: 'beforeExit' | 'SIGINT' | 'SIGTERM', listener: () => void): unknown;
102
+ off(event: 'beforeExit' | 'SIGINT' | 'SIGTERM', listener: () => void): unknown;
103
+ }
104
+ interface NodeLifecycleOptions {
105
+ readonly target?: NodeLifecycleTarget;
106
+ readonly signals?: readonly ('SIGINT' | 'SIGTERM')[];
107
+ readonly onFailure?: (error: unknown) => void;
108
+ }
109
+ /** Install opt-in Node shutdown triggers and return an idempotent disposer. */
110
+ declare function installNodeObservabilityLifecycle(observation: Pick<Observability, 'shutdown'>, options?: NodeLifecycleOptions): () => void;
111
+ //#endregion
112
+ //#region src/common/errors.d.ts
113
+ declare const NODE_OBSERVATION_ERROR_CODES: Readonly<{
114
+ readonly corrupt: 'OBSERVABILITY_JOURNAL_CORRUPT';
115
+ readonly io: 'OBSERVABILITY_JOURNAL_IO';
116
+ }>;
117
+ type NodeObservationErrorCode = typeof NODE_OBSERVATION_ERROR_CODES[keyof typeof NODE_OBSERVATION_ERROR_CODES];
118
+ declare class NodeObservationError extends Error {
119
+ readonly name = "NodeObservationError";
120
+ readonly code: NodeObservationErrorCode;
121
+ constructor(code: NodeObservationErrorCode, message: string, options?: ErrorOptions);
122
+ }
123
+ //#endregion
124
+ export { JsonlObservationJournalOptions as _, NodeLifecycleTarget as a, recoverRuntimeObservationJournal as c, JournalRecoveryRecord as d, JournalRecoveryResult as f, JournalDurabilityMode as g, recoverJournal as h, NodeLifecycleOptions as i, RuntimeJournalRecoveryResult as l, JsonlObservationJournalExporter as m, NodeObservationError as n, installNodeObservabilityLifecycle as o, JournalStats as p, NodeObservationErrorCode as r, jsonlObservationExporter as s, NODE_OBSERVATION_ERROR_CODES as t, RuntimeJournalRecord as u };
125
+ //# sourceMappingURL=journal-export-BMfSC4Z6.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal-export-BMfSC4Z6.d.mts","names":[],"sources":["../src/journal/types.ts","../src/journal.ts","../src/journal/runtime-frame.ts","../src/journal/runtime-store.ts","../src/journal/runtime-exporter.ts","../src/lifecycle.ts","../src/common/errors.ts"],"mappings":";;;KAAY;UAEK;WACN;WACA;WACA,MAAM;WACN;WACA;WACA;WACA;WACA;WACA,YAAY;WACZ;;;;UCqBM;WACN;WACA;WACA,OAAO;WACP;;UAGM;WACN,kBAAkB;WAClB;WACA;;UAGM;WACN;WACA;WACA;WACA;;;cA8BE,2CAA2C;WAC7C;WACA,8BAA8B;mBACtB;mBAEA;UACT;UACA;mBACS;mBACA;mBACA;UACT;UACA;UACA;UACA;EAER,YAAY,SAAS;EAsBf,SAAS;EAIf,MAAM,OAAO,mBAAmB;EAgC1B,OAAO,OAAO,kBAAkB,QAAQ,cAAc,QAAQ;EAmB9D,iBAAiB,kBAAkB;EAQnC,kBAAkB,8BAA8B;EAkBhD,WAAW,QAAQ;EASnB,WAAW;UAMH;EAqCR,SAAS,QAAQ;EAmBjB,SAAS,SAAS,cAAc;UAYxB;UAQN;UAMM;UASA;UAcN;UAeM;UAOA;UAkBA;UAwBA;;iBAYM,eAAe,oBAAoB,QAAQ;;;KCvYrD;UAEK;WACN;WACA;WACA,MAAM;WACN;WACA;WACA,MAAM;WACN;;;;UCkCM;WACN,kBAAkB;WAClB;WACA;;;;;iBC5BK,yBACd,SAAS,iCACR;;iBAoCmB,iCACpB,kBACC,QAAQ;;;UC5DM;EACf,GAAG,4CAA4C;EAC/C,IAAI,4CAA4C;;UAGjC;WACN,SAAS;WACT;WACA,aAAa;;;iBAIR,kCACd,aAAa,KAAK,4BAClB,UAAS;;;cChBE,8BAA4B;WAC9B;WACL;;KAGM,kCAAkC,0CAA0C;cAE3E,6BAA6B;WACtB;WACT,MAAM;EAEf,YAAY,MAAM,0BAA0B,iBAAiB,UAAU"}