agentfootprint 9.7.0 → 9.8.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,146 @@
1
+ /**
2
+ * fileObservability — the typed event stream, one JSON line per event, in a
3
+ * local file.
4
+ *
5
+ * The sink for the shop that has no collector. Every other adapter in this
6
+ * folder ships somewhere: CloudWatch, X-Ray, an OTLP endpoint. A great many
7
+ * on-premises deployments have none of those — they have a directory, a log
8
+ * shipper (Filebeat, Fluent Bit, Vector, `promtail`, `journald`, or a person
9
+ * with `grep`), and a rule that nothing leaves the network. NDJSON on disk is
10
+ * the format all of those already read, so the sink is the file.
11
+ *
12
+ * Zero dependencies: `node:fs`, lazily required at construction so merely
13
+ * importing `agentfootprint/observe` stays browser-safe (this factory is
14
+ * Node-only; calling it in a browser throws by name).
15
+ *
16
+ * ## The line
17
+ *
18
+ * One `JSON.stringify(event)` per line, newline-terminated, appended in
19
+ * dispatch order — the SAME envelope `cloudwatchObservability` puts in a log
20
+ * event, so a query written against one reads the other:
21
+ *
22
+ * ```jsonl
23
+ * {"type":"agentfootprint.agent.turn_start","payload":{…},"meta":{"runId":"…","sessionId":"…"}}
24
+ * {"type":"agentfootprint.stream.tool_end","payload":{…},"meta":{…}}
25
+ * ```
26
+ *
27
+ * Nothing is summarized, bounded or redacted on the way out. **A payload that
28
+ * must not be on that disk must not reach this strategy** — narrow it with
29
+ * `eventTypes` / `tier` / `sampleRate`, or apply a footprintjs
30
+ * `RedactionPolicy` upstream, exactly as with every other sink. (For a bounded
31
+ * record by construction, `auditExport({ payloadMode: 'bounded' })` is the
32
+ * adapter that does that job.)
33
+ *
34
+ * ## Buffered, not synchronous
35
+ *
36
+ * `exportEvent` is sync and never touches the disk: it serializes, buffers, and
37
+ * returns. Batches are appended asynchronously on a size trigger
38
+ * (`maxBufferEvents` / `maxBufferBytes`), on a timer (`flushIntervalMs`), and on
39
+ * `flush()`. A hard kill therefore loses at most the buffer — the price of not
40
+ * making telemetry a term in agent-loop latency. Call `flush()` (or
41
+ * `agent.shutdown()`, which does) at process end; see the 8.12.0 lifecycle laws
42
+ * on {@link BaseStrategy.flush}.
43
+ *
44
+ * ## Rotation is ONE generation, and that is deliberate
45
+ *
46
+ * With `maxBytes` set, a batch that would push the file past the ceiling first
47
+ * renames it to `<path>.1` — **replacing any previous `.1`** — and starts a
48
+ * fresh file. That is the whole policy. There is no `.2`, no compression, no
49
+ * time-based schedule, no cross-process coordination (two processes writing one
50
+ * file each keep their own byte count and will both rotate it). It exists so an
51
+ * unattended agent cannot fill a disk, and for nothing else: **retention is a
52
+ * log-management daemon's job**, and `logrotate` with `copytruncate`, Fluent Bit,
53
+ * or a systemd timer will do it properly. Omit `maxBytes` — the default — and
54
+ * this adapter never renames anything, which is the right choice when a real
55
+ * rotator already owns the file.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * import { fileObservability } from 'agentfootprint/observe';
60
+ *
61
+ * const telemetry = agent.enable.observability({
62
+ * strategy: fileObservability({
63
+ * path: '/var/log/agentfootprint/events.ndjson',
64
+ * maxBytes: 64 * 1024 * 1024, // safety ceiling; logrotate owns retention
65
+ * }),
66
+ * });
67
+ *
68
+ * // … run …
69
+ * await agent.shutdown(); // flushes + stops everything enabled
70
+ * ```
71
+ */
72
+ import type { AgentfootprintEvent, AgentfootprintEventType } from '../../events/registry.js';
73
+ import type { ObservabilityStrategy } from '../../strategies/types.js';
74
+ export interface FileObservabilityOptions {
75
+ /** Absolute or relative path to the NDJSON file. **Required.** Its parent
76
+ * directories are created (`recursive`) and the file itself is claimed at
77
+ * construction, so an unwritable path fails where you wrote it rather than
78
+ * at the first event — the only moment a caller is still watching. */
79
+ readonly path: string;
80
+ /** Rotation ceiling in bytes. Omitted → **never rotates** (the right choice
81
+ * when `logrotate` or a shipper already owns the file). Set → a batch that
82
+ * would cross the ceiling first renames the file to `<path>.1`, replacing
83
+ * any previous `.1`, and starts fresh. ONE generation, no compression, no
84
+ * cross-process coordination — see the note in this module's docstring. */
85
+ readonly maxBytes?: number;
86
+ /** Max events buffered before a forced append. Default 100. */
87
+ readonly maxBufferEvents?: number;
88
+ /** Max buffered payload bytes (UTF-8) before a forced append. Default 65536
89
+ * (64 KB) — a local write is cheap, so this is far larger than the network
90
+ * adapters' 10 KB. */
91
+ readonly maxBufferBytes?: number;
92
+ /** Forced-append interval when traffic is sparse, in ms. Default 1000.
93
+ * `0` disables the timer — only size triggers and `flush()` write. */
94
+ readonly flushIntervalMs?: number;
95
+ /** Narrow what lands on the disk. Becomes the strategy's
96
+ * {@link ObservabilityStrategy.relevantEventTypes}, so the dispatcher does
97
+ * not even forward the rest — the filter costs nothing at the hot path.
98
+ * Omitted → every event the `tier` lets through is written. */
99
+ readonly eventTypes?: readonly AgentfootprintEventType[];
100
+ /**
101
+ * Where delivery failures go — a full disk, a revoked permission, a path
102
+ * whose directory was removed under a long-running process.
103
+ *
104
+ * Same law as the network adapters (8.11.0): **telemetry that fails
105
+ * invisibly is indistinguishable from telemetry that works.** Unhandled,
106
+ * failures reach a rate-limited `console.error`. The batch that failed is
107
+ * dropped, never requeued, so a disk that has been full for an hour cannot
108
+ * grow the buffer without bound.
109
+ */
110
+ readonly onError?: (error: Error, event?: AgentfootprintEvent) => void;
111
+ /** Test seam — inject a filesystem. Bypasses `node:fs` entirely, which is
112
+ * also what lets the rotation policy be asserted without a real disk. */
113
+ readonly _fs?: FileSinkFs;
114
+ }
115
+ /**
116
+ * The slice of the filesystem this adapter touches — five calls, named by what
117
+ * the adapter uses them FOR rather than by their `node:fs` signatures.
118
+ *
119
+ * Sync members run once, at construction; the append path is async so the agent
120
+ * loop never waits on a disk.
121
+ */
122
+ export interface FileSinkFs {
123
+ /** Create the log file's parent directory chain. */
124
+ mkdirSync(dir: string, options: {
125
+ readonly recursive: boolean;
126
+ }): void;
127
+ /** Claim the file at construction. This is the writability refusal: an
128
+ * unwritable path throws HERE, with the caller still on the stack. */
129
+ appendFileSync(file: string, data: string): void;
130
+ /** Current size, so the rotation counter starts from what is already there
131
+ * rather than from zero on every restart. */
132
+ statSync(file: string): {
133
+ readonly size: number;
134
+ };
135
+ /** Append one batch of NDJSON lines. */
136
+ appendFile(file: string, data: string): Promise<void>;
137
+ /** Rotate: `<path>` → `<path>.1`, replacing any previous `.1`. */
138
+ rename(from: string, to: string): Promise<void>;
139
+ }
140
+ /**
141
+ * NDJSON-to-a-local-file observability strategy. See
142
+ * {@link FileObservabilityOptions} for the per-option contract, and this
143
+ * module's docstring for the rotation policy and what is NOT bounded.
144
+ */
145
+ export declare function fileObservability(opts: FileObservabilityOptions): ObservabilityStrategy;
146
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../../../src/adapters/observability/file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAE7F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAMvE,MAAM,WAAW,wBAAwB;IACvC;;;2EAGuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;gFAI4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;2BAEuB;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;2EACuE;IACvE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC;;;oEAGgE;IAChE,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAC;IACzD;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACvE;8EAC0E;IAC1E,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,oDAAoD;IACpD,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACvE;2EACuE;IACvE,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD;kDAC8C;IAC9C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAClD,wCAAwC;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,kEAAkE;IAClE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAID;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,wBAAwB,GAAG,qBAAqB,CA2LvF"}
@@ -35,4 +35,5 @@ export type { AuthorizationRequiredMode, ConsentRequest } from './identity/conse
35
35
  export { CredentialConsentRequiredError, type CredentialConsentRequiredContext, } from './identity/CredentialConsentRequiredError.js';
36
36
  export { withCredentialRetry, type WithCredentialRetryOptions, } from './identity/withCredentialRetry.js';
37
37
  export { agentCoreIdentity, type AgentCoreIdentityOptions, type AgentCoreIdentityClientLike, type AgentCoreOauthResponse, } from './adapters/identity/agentcore.js';
38
+ export { vaultCredentials, type VaultCredentialsOptions } from './adapters/identity/vault.js';
38
39
  //# sourceMappingURL=identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,+BAA+B,EAC/B,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AACzF,OAAO,EACL,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIpF,YAAY,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,8BAA8B,EAC9B,KAAK,gCAAgC,GACtC,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,GAC5B,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,+BAA+B,EAC/B,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AACzF,OAAO,EACL,MAAM,EACN,MAAM,EACN,KAAK,EACL,OAAO,EACP,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIpF,YAAY,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,8BAA8B,EAC9B,KAAK,gCAAgC,GACtC,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACL,mBAAmB,EACnB,KAAK,0BAA0B,GAChC,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,sBAAsB,GAC5B,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -30,7 +30,9 @@
30
30
  * - agentcoreObservability ← v2.8.1
31
31
  * - cloudwatchObservability ← v2.8.2
32
32
  * - xrayObservability ← v2.8.3
33
- * - otelObservability ← v2.9.0 (this release)
33
+ * - otelObservability ← v2.9.0
34
+ * - fileObservability ← 9.8.0 (no vendor at all — NDJSON on disk,
35
+ * for the on-premises shop with no collector)
34
36
  *
35
37
  * Note: `datadogObservability` was on the v2.9 roadmap, but Datadog
36
38
  * APM accepts OTLP — point your OTel SDK at Datadog's OTLP endpoint
@@ -46,6 +48,7 @@ export { agentcoreObservability, type AgentcoreObservabilityOptions, } from './a
46
48
  export { cloudwatchObservability, type CloudwatchObservabilityOptions, } from './adapters/observability/cloudwatch.js';
47
49
  export { xrayObservability, type XrayObservabilityOptions, type XRayLikeClient, } from './adapters/observability/xray.js';
48
50
  export { otelObservability, type OtelObservabilityOptions, type OtelObservabilityStrategy, type OtelDecisionEvidenceRecorder, type OtelTracerLike, type OtelSpanLike, type OtelSpanOptions, type OtelAttributeValue, } from './adapters/observability/otel.js';
51
+ export { fileObservability, type FileObservabilityOptions, type FileSinkFs, } from './adapters/observability/file.js';
49
52
  export { auditExport, verifyAuditBundle, AUDIT_BUNDLE_FORMAT, AUDIT_GENESIS_EVENT_TYPE, AUDIT_ZERO_HASH, type AuditBundle, type AuditBundleHeader, type AuditExportOptions, type AuditExportStrategy, type AuditRecord, type AuditVerifyResult, } from './adapters/observability/audit.js';
50
53
  export { canonicalJson, CANONICAL_JSON_VERSION } from './lib/canonicalJson.js';
51
54
  //# sourceMappingURL=observability-providers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"observability-providers.d.ts","sourceRoot":"","sources":["../../src/observability-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,GACnC,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EACL,uBAAuB,EACvB,KAAK,8BAA8B,GACpC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,4BAA4B,EACjC,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC7B,KAAK,UAAU,GAChB,MAAM,kCAAkC,CAAC;AAI1C,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfootprint",
3
- "version": "9.7.0",
3
+ "version": "9.8.0",
4
4
  "description": "The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.",
5
5
  "license": "MIT",
6
6
  "type": "commonjs",