@autter/runtime-node 1.4.0 → 1.5.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/README.md +106 -16
- package/dist/chunk-3TJHUCZ6.js +1680 -0
- package/dist/chunk-GI47WGRR.cjs +779 -0
- package/dist/chunk-L6SRL65J.cjs +202 -0
- package/dist/chunk-L7HWKMCZ.js +779 -0
- package/dist/chunk-P4VRTFAV.cjs +1680 -0
- package/dist/chunk-ZS4WQJQR.js +202 -0
- package/dist/cli.cjs +40 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +40 -0
- package/dist/index.cjs +1272 -1141
- package/dist/index.d.cts +420 -42
- package/dist/index.d.ts +420 -42
- package/dist/index.js +1083 -917
- package/dist/sinks-RFV76lF1.d.cts +313 -0
- package/dist/sinks-RFV76lF1.d.ts +313 -0
- package/dist/testing.cjs +121 -0
- package/dist/testing.d.cts +57 -0
- package/dist/testing.d.ts +57 -0
- package/dist/testing.js +121 -0
- package/package.json +16 -5
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural copy of OpenTelemetry's `Attributes` so runtime-core stays
|
|
3
|
+
* dependency-free (it is bundled into the zero-dependency edge package).
|
|
4
|
+
* Assignable both ways with `@opentelemetry/api`'s type.
|
|
5
|
+
*/
|
|
6
|
+
type AttributeValue = string | number | boolean | Array<null | undefined | string> | Array<null | undefined | number> | Array<null | undefined | boolean>;
|
|
7
|
+
type Attributes = Record<string, AttributeValue | undefined>;
|
|
8
|
+
|
|
9
|
+
interface RedactOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Extra patterns matched against lower-cased attribute KEYS; a match
|
|
12
|
+
* masks the whole value. Strings become case-insensitive substring
|
|
13
|
+
* patterns. Extends the built-in list.
|
|
14
|
+
*/
|
|
15
|
+
additionalKeyPatterns?: (RegExp | string)[];
|
|
16
|
+
/**
|
|
17
|
+
* Extra patterns scrubbed inside string VALUES — attribute values,
|
|
18
|
+
* exception messages, stack traces, span status messages, URLs, log
|
|
19
|
+
* lines. Strings are compiled as case-insensitive regex sources. Every
|
|
20
|
+
* pattern is applied globally. Extends the built-in list.
|
|
21
|
+
*/
|
|
22
|
+
additionalValuePatterns?: (RegExp | string)[];
|
|
23
|
+
/** Replacement token. Default "[redacted]". */
|
|
24
|
+
mask?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Scrub email-shaped substrings from ALL string values, not just
|
|
27
|
+
* sensitive keys. Default true.
|
|
28
|
+
*/
|
|
29
|
+
scrubEmailValues?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Scrub Luhn-valid payment card numbers from all string values.
|
|
32
|
+
* Default true.
|
|
33
|
+
*/
|
|
34
|
+
scrubCardNumbers?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Return a copy of `attributes` with PII/secrets masked. Never mutates the
|
|
38
|
+
* input; non-string primitives pass through untouched; `undefined` values
|
|
39
|
+
* are dropped (OpenTelemetry rejects them).
|
|
40
|
+
*/
|
|
41
|
+
declare function redactAttributes(attributes?: Attributes | null, options?: RedactOptions): Attributes;
|
|
42
|
+
/**
|
|
43
|
+
* Scrub secrets/PII embedded in one string — an error message, a stack
|
|
44
|
+
* trace, a URL, a log line. Same value patterns as redactAttributes().
|
|
45
|
+
*/
|
|
46
|
+
declare function redactText(text: string, options?: RedactOptions): string;
|
|
47
|
+
/** A compiled redactor: callable for attribute bags, plus string and
|
|
48
|
+
* export-time helpers. */
|
|
49
|
+
interface Redactor$1 {
|
|
50
|
+
(attributes?: Attributes | null): Attributes;
|
|
51
|
+
/** Scrub one string (messages, stacks, URLs). Identity when disabled. */
|
|
52
|
+
text(value: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Export-time pass over attributes already on a span (set by any
|
|
55
|
+
* instrumentation, not just Autter's capture calls). Strings are
|
|
56
|
+
* value-scrubbed, string values under sensitive KEYS are masked, and
|
|
57
|
+
* numbers/booleans pass untouched — usage counters such as
|
|
58
|
+
* `ai.usage.promptTokens` must survive for cost tracking.
|
|
59
|
+
*/
|
|
60
|
+
exported(attributes: Attributes): Attributes;
|
|
61
|
+
readonly enabled: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type RuntimeLogContextValue = string | number | boolean | null | undefined | RuntimeLogContextValue[] | {
|
|
65
|
+
[key: string]: RuntimeLogContextValue;
|
|
66
|
+
};
|
|
67
|
+
type RuntimeLogContext = Record<string, RuntimeLogContextValue>;
|
|
68
|
+
type RuntimeLogLevel = "debug" | "info" | "warning" | "error";
|
|
69
|
+
type RuntimeOutcome = "succeeded" | "failed" | "degraded" | "cancelled" | "pending";
|
|
70
|
+
type RuntimeOperationKind = "request" | "operation";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Structured, coded errors shared by every Autter Runtime server SDK.
|
|
74
|
+
*
|
|
75
|
+
* export const billingErrors = defineRuntimeErrors("billing", {
|
|
76
|
+
* declined: { status: 402, message: "Payment declined", expected: true,
|
|
77
|
+
* why: "The card issuer rejected the charge",
|
|
78
|
+
* fix: "Ask the customer for another card" },
|
|
79
|
+
* limit: ({ plan }: { plan: string }) => ({ status: 429, message: `Plan ${plan} limit reached` }),
|
|
80
|
+
* });
|
|
81
|
+
* throw billingErrors.limit({ plan: "free" }); // code "billing.limit"
|
|
82
|
+
*
|
|
83
|
+
* A code groups every occurrence into one issue (scheme "code-v1"), so codes
|
|
84
|
+
* must be stable, namespaced and low-cardinality: never ids, user data or
|
|
85
|
+
* secrets. Anything not matching CODE_PATTERN is dropped and the error
|
|
86
|
+
* groups by message exactly as before.
|
|
87
|
+
*/
|
|
88
|
+
/** `namespace.key` with up to four segments, lower-case, max 80 characters. */
|
|
89
|
+
declare const CODE_PATTERN: RegExp;
|
|
90
|
+
interface RuntimeErrorDefinition {
|
|
91
|
+
/** Human-readable message. Safe to show to clients. */
|
|
92
|
+
message: string;
|
|
93
|
+
/** HTTP-ish status. Default 500 when the error reaches a response. */
|
|
94
|
+
status?: number;
|
|
95
|
+
/** Expected business failure (decline, validation): recorded, never an incident. */
|
|
96
|
+
expected?: boolean;
|
|
97
|
+
/** Declared cause, ≤ 1000 chars. Treated as a hypothesis by Autter's RCA. */
|
|
98
|
+
why?: string;
|
|
99
|
+
/** Declared remedy, ≤ 1000 chars. */
|
|
100
|
+
fix?: string;
|
|
101
|
+
/** Docs link, ≤ 500 chars. */
|
|
102
|
+
link?: string;
|
|
103
|
+
}
|
|
104
|
+
interface RuntimeErrorExtras {
|
|
105
|
+
/** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
|
|
106
|
+
cause?: unknown;
|
|
107
|
+
/** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
|
|
108
|
+
internal?: Record<string, unknown>;
|
|
109
|
+
/** Override the catalog message for this throw. */
|
|
110
|
+
message?: string;
|
|
111
|
+
}
|
|
112
|
+
interface RuntimeErrorOptions extends RuntimeErrorDefinition {
|
|
113
|
+
/** Stable namespaced code, e.g. "inventory.reservation_timeout". */
|
|
114
|
+
code?: string;
|
|
115
|
+
/** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
|
|
116
|
+
cause?: unknown;
|
|
117
|
+
/** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
|
|
118
|
+
internal?: Record<string, unknown>;
|
|
119
|
+
}
|
|
120
|
+
/** The fields Autter reads from any error (duck-typed). */
|
|
121
|
+
interface RuntimeErrorLike {
|
|
122
|
+
message?: string;
|
|
123
|
+
code?: string;
|
|
124
|
+
why?: string;
|
|
125
|
+
fix?: string;
|
|
126
|
+
link?: string;
|
|
127
|
+
status?: number;
|
|
128
|
+
expected?: boolean;
|
|
129
|
+
}
|
|
130
|
+
declare class RuntimeError extends Error implements RuntimeErrorLike {
|
|
131
|
+
readonly code?: string;
|
|
132
|
+
readonly why?: string;
|
|
133
|
+
readonly fix?: string;
|
|
134
|
+
readonly link?: string;
|
|
135
|
+
readonly status?: number;
|
|
136
|
+
readonly expected?: boolean;
|
|
137
|
+
/** Non-enumerable so JSON.stringify / loggers never serialise it. */
|
|
138
|
+
readonly internal?: Record<string, unknown>;
|
|
139
|
+
constructor(options: RuntimeErrorOptions | string);
|
|
140
|
+
/** Client-safe JSON (what `toClientError` returns, minus the wrapper). */
|
|
141
|
+
toJSON(): Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
type CatalogEntry = RuntimeErrorDefinition | ((args: any) => RuntimeErrorDefinition);
|
|
144
|
+
/** A typed factory for one catalog entry; `.code` is the namespaced code. */
|
|
145
|
+
type RuntimeErrorFactory<E> = E extends (args: infer A) => RuntimeErrorDefinition ? ((args: A, extras?: RuntimeErrorExtras) => RuntimeError) & {
|
|
146
|
+
readonly code: string;
|
|
147
|
+
} : ((extras?: RuntimeErrorExtras) => RuntimeError) & {
|
|
148
|
+
readonly code: string;
|
|
149
|
+
};
|
|
150
|
+
type RuntimeErrorCatalog<C extends Record<string, CatalogEntry>> = {
|
|
151
|
+
readonly [K in keyof C]: RuntimeErrorFactory<C[K]>;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Build typed error factories from a catalog. Each key becomes the code
|
|
155
|
+
* `${namespace}.${key}`; an invalid resulting code is dropped with a
|
|
156
|
+
* one-time warning (the factory still produces a normal RuntimeError).
|
|
157
|
+
*/
|
|
158
|
+
declare function defineRuntimeErrors<const C extends Record<string, CatalogEntry>>(namespace: string, catalog: C): RuntimeErrorCatalog<C>;
|
|
159
|
+
/**
|
|
160
|
+
* True for any error carrying Autter's structured fields — a RuntimeError,
|
|
161
|
+
* or ANY object with a string `code`/`why`/`fix`/`link`, a numeric `status`
|
|
162
|
+
* (or `statusCode`) or a boolean `expected`. Existing error classes benefit
|
|
163
|
+
* without being rewritten.
|
|
164
|
+
*/
|
|
165
|
+
declare function isRuntimeErrorLike(err: unknown): err is RuntimeErrorLike;
|
|
166
|
+
interface ErrorAttributeOptions {
|
|
167
|
+
/** Also emit `exception.cause.N.*` for the cause chain (default true). */
|
|
168
|
+
causes?: boolean;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Wire attributes for an error: `autter.error.code|why|fix|link|status|expected`
|
|
172
|
+
* and `exception.cause.N.type|message|code` (N = 1..5). Never includes
|
|
173
|
+
* `internal` — see `errorInternal`.
|
|
174
|
+
*/
|
|
175
|
+
declare function errorAttributes(err: unknown, options?: ErrorAttributeOptions): Record<string, string | number | boolean>;
|
|
176
|
+
interface ClientErrorBody {
|
|
177
|
+
error: {
|
|
178
|
+
message: string;
|
|
179
|
+
code?: string;
|
|
180
|
+
why?: string;
|
|
181
|
+
fix?: string;
|
|
182
|
+
link?: string;
|
|
183
|
+
requestId?: string;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Client-safe JSON body for an error:
|
|
188
|
+
* `{ error: { message, code?, why?, fix?, link?, requestId? } }`.
|
|
189
|
+
* Never includes `internal`, stacks or causes. The message of an
|
|
190
|
+
* unstructured 5xx error (a plain `throw new Error(...)`) is replaced with a
|
|
191
|
+
* generic one, because it was never written for clients.
|
|
192
|
+
*/
|
|
193
|
+
declare function toClientError(err: unknown, requestId?: string): ClientErrorBody;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* One runtime record before it is encoded for any sink: an operation or
|
|
197
|
+
* request summary (`autter.event.type = "operation"`) or a plain log line.
|
|
198
|
+
* `attributes` are already redacted and bounded.
|
|
199
|
+
*/
|
|
200
|
+
interface RuntimeEvent {
|
|
201
|
+
/** Epoch milliseconds. */
|
|
202
|
+
time: number;
|
|
203
|
+
level: RuntimeLogLevel;
|
|
204
|
+
message: string;
|
|
205
|
+
attributes: RuntimeLogContext;
|
|
206
|
+
traceId?: string;
|
|
207
|
+
spanId?: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Serialisable link from a producer operation to work it hands off (a queue
|
|
212
|
+
* job, another process): `{ v: 1, op, req?, traceparent? }`. Put it in the
|
|
213
|
+
* job payload; the consumer passes it as `withRuntimeOperation(..., { from })`.
|
|
214
|
+
*/
|
|
215
|
+
interface RuntimeCarrier {
|
|
216
|
+
v: 1;
|
|
217
|
+
/** Producer operation id (becomes the consumer's `autter.operation.parent_id`). */
|
|
218
|
+
op: string;
|
|
219
|
+
/** Request id the work belongs to. */
|
|
220
|
+
req?: string;
|
|
221
|
+
/** W3C traceparent of the producer span (consumer links to it). */
|
|
222
|
+
traceparent?: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Where runtime records go. The logger pipeline is
|
|
227
|
+
* `enrich → redact/bound → sinks[]`; each sink receives the same immutable
|
|
228
|
+
* RuntimeEvent. Defaults: `[otlpSink(), consoleSink()]` (+ `fileSink()` when
|
|
229
|
+
* NODE_ENV=development). Sinks must never throw into application code.
|
|
230
|
+
*/
|
|
231
|
+
interface RuntimeSink {
|
|
232
|
+
readonly name: string;
|
|
233
|
+
/** Called when the logger is (re)configured; null before init. */
|
|
234
|
+
start?(context: RuntimeSinkContext): void;
|
|
235
|
+
write(event: RuntimeEvent): void;
|
|
236
|
+
flush?(): Promise<void>;
|
|
237
|
+
shutdown?(): Promise<void>;
|
|
238
|
+
/** Records held in memory awaiting delivery. */
|
|
239
|
+
buffered?(): number;
|
|
240
|
+
/** @internal Receives every captureException call (testing sinks). */
|
|
241
|
+
exception?(record: CapturedException): void;
|
|
242
|
+
}
|
|
243
|
+
interface RuntimeSinkContext {
|
|
244
|
+
endpoint: string;
|
|
245
|
+
apiKey: string;
|
|
246
|
+
service: string;
|
|
247
|
+
environment: string;
|
|
248
|
+
release?: string;
|
|
249
|
+
/** SDK identity for the `telemetry.distro.*` resource attributes. */
|
|
250
|
+
distro?: {
|
|
251
|
+
name: string;
|
|
252
|
+
version: string;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
interface CapturedException {
|
|
256
|
+
time: number;
|
|
257
|
+
error: unknown;
|
|
258
|
+
message: string;
|
|
259
|
+
type: string;
|
|
260
|
+
attributes: Record<string, unknown>;
|
|
261
|
+
operationId?: string;
|
|
262
|
+
requestId?: string;
|
|
263
|
+
}
|
|
264
|
+
interface OtlpSinkOptions {
|
|
265
|
+
/** Override the ingester base URL (default: the configured endpoint). */
|
|
266
|
+
endpoint?: string;
|
|
267
|
+
/** Override the ingest key (default: the configured apiKey). */
|
|
268
|
+
apiKey?: string;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* OTLP/HTTP JSON export to `${endpoint}/v1/logs`. Bounded exactly like
|
|
272
|
+
* 1.4.0: 1000 records / 4 MiB buffered, 256 KiB per record, batches of 50
|
|
273
|
+
* (≤ 512 KiB), 3 attempts within a 10 s deadline, exponential back-off
|
|
274
|
+
* on failure, undelivered records reported at shutdown.
|
|
275
|
+
*/
|
|
276
|
+
declare function otlpSink(options?: OtlpSinkOptions): RuntimeSink;
|
|
277
|
+
interface ConsoleSinkOptions {
|
|
278
|
+
/** Default: "pretty" unless NODE_ENV === "production", then "json". */
|
|
279
|
+
format?: "pretty" | "json";
|
|
280
|
+
/** Colourise pretty output. Default: stdout is a TTY and NO_COLOR is unset. */
|
|
281
|
+
color?: boolean;
|
|
282
|
+
/** Line writer. Default console.log. */
|
|
283
|
+
write?: (line: string) => void;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Console output. JSON lines (identical to 1.4.0) in production; a compact
|
|
287
|
+
* human-readable tree elsewhere, coloured only on a TTY.
|
|
288
|
+
*/
|
|
289
|
+
declare function consoleSink(options?: ConsoleSinkOptions): RuntimeSink;
|
|
290
|
+
interface FileSinkOptions {
|
|
291
|
+
/** Directory for `YYYY-MM-DD.jsonl` files. Default ".autter/runtime" (cwd-relative). */
|
|
292
|
+
dir?: string;
|
|
293
|
+
/** Keep at most this many files (oldest deleted). Default 7. */
|
|
294
|
+
maxFiles?: number;
|
|
295
|
+
/** Start a new `YYYY-MM-DD.N.jsonl` file past this size. Default 10 MiB. */
|
|
296
|
+
maxBytes?: number;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* NDJSON on local disk, one record per line, for coding agents and
|
|
300
|
+
* `autter logs --local`. Daily files (UTC), size rotation, bounded file
|
|
301
|
+
* count. Writes are synchronous appends (dev-sized volumes). Disables itself
|
|
302
|
+
* with one warning on read-only or permission-denied filesystems.
|
|
303
|
+
*/
|
|
304
|
+
declare function fileSink(options?: FileSinkOptions): RuntimeSink;
|
|
305
|
+
interface MemorySink extends RuntimeSink {
|
|
306
|
+
readonly events: RuntimeEvent[];
|
|
307
|
+
readonly exceptions: CapturedException[];
|
|
308
|
+
clear(): void;
|
|
309
|
+
}
|
|
310
|
+
/** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
|
|
311
|
+
declare function memorySink(): MemorySink;
|
|
312
|
+
|
|
313
|
+
export { otlpSink as A, redactAttributes as B, type CapturedException as C, redactText as D, toClientError as E, type FileSinkOptions as F, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, CODE_PATTERN as i, type ClientErrorBody as j, type ConsoleSinkOptions as k, RuntimeError as l, memorySink as m, type RuntimeErrorCatalog as n, type RuntimeErrorDefinition as o, type RuntimeErrorExtras as p, type RuntimeErrorFactory as q, type RuntimeErrorLike as r, type RuntimeErrorOptions as s, type RuntimeLogContextValue as t, type RuntimeSinkContext as u, consoleSink as v, defineRuntimeErrors as w, errorAttributes as x, fileSink as y, isRuntimeErrorLike as z };
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural copy of OpenTelemetry's `Attributes` so runtime-core stays
|
|
3
|
+
* dependency-free (it is bundled into the zero-dependency edge package).
|
|
4
|
+
* Assignable both ways with `@opentelemetry/api`'s type.
|
|
5
|
+
*/
|
|
6
|
+
type AttributeValue = string | number | boolean | Array<null | undefined | string> | Array<null | undefined | number> | Array<null | undefined | boolean>;
|
|
7
|
+
type Attributes = Record<string, AttributeValue | undefined>;
|
|
8
|
+
|
|
9
|
+
interface RedactOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Extra patterns matched against lower-cased attribute KEYS; a match
|
|
12
|
+
* masks the whole value. Strings become case-insensitive substring
|
|
13
|
+
* patterns. Extends the built-in list.
|
|
14
|
+
*/
|
|
15
|
+
additionalKeyPatterns?: (RegExp | string)[];
|
|
16
|
+
/**
|
|
17
|
+
* Extra patterns scrubbed inside string VALUES — attribute values,
|
|
18
|
+
* exception messages, stack traces, span status messages, URLs, log
|
|
19
|
+
* lines. Strings are compiled as case-insensitive regex sources. Every
|
|
20
|
+
* pattern is applied globally. Extends the built-in list.
|
|
21
|
+
*/
|
|
22
|
+
additionalValuePatterns?: (RegExp | string)[];
|
|
23
|
+
/** Replacement token. Default "[redacted]". */
|
|
24
|
+
mask?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Scrub email-shaped substrings from ALL string values, not just
|
|
27
|
+
* sensitive keys. Default true.
|
|
28
|
+
*/
|
|
29
|
+
scrubEmailValues?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Scrub Luhn-valid payment card numbers from all string values.
|
|
32
|
+
* Default true.
|
|
33
|
+
*/
|
|
34
|
+
scrubCardNumbers?: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Return a copy of `attributes` with PII/secrets masked. Never mutates the
|
|
38
|
+
* input; non-string primitives pass through untouched; `undefined` values
|
|
39
|
+
* are dropped (OpenTelemetry rejects them).
|
|
40
|
+
*/
|
|
41
|
+
declare function redactAttributes(attributes?: Attributes | null, options?: RedactOptions): Attributes;
|
|
42
|
+
/**
|
|
43
|
+
* Scrub secrets/PII embedded in one string — an error message, a stack
|
|
44
|
+
* trace, a URL, a log line. Same value patterns as redactAttributes().
|
|
45
|
+
*/
|
|
46
|
+
declare function redactText(text: string, options?: RedactOptions): string;
|
|
47
|
+
/** A compiled redactor: callable for attribute bags, plus string and
|
|
48
|
+
* export-time helpers. */
|
|
49
|
+
interface Redactor$1 {
|
|
50
|
+
(attributes?: Attributes | null): Attributes;
|
|
51
|
+
/** Scrub one string (messages, stacks, URLs). Identity when disabled. */
|
|
52
|
+
text(value: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Export-time pass over attributes already on a span (set by any
|
|
55
|
+
* instrumentation, not just Autter's capture calls). Strings are
|
|
56
|
+
* value-scrubbed, string values under sensitive KEYS are masked, and
|
|
57
|
+
* numbers/booleans pass untouched — usage counters such as
|
|
58
|
+
* `ai.usage.promptTokens` must survive for cost tracking.
|
|
59
|
+
*/
|
|
60
|
+
exported(attributes: Attributes): Attributes;
|
|
61
|
+
readonly enabled: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
type RuntimeLogContextValue = string | number | boolean | null | undefined | RuntimeLogContextValue[] | {
|
|
65
|
+
[key: string]: RuntimeLogContextValue;
|
|
66
|
+
};
|
|
67
|
+
type RuntimeLogContext = Record<string, RuntimeLogContextValue>;
|
|
68
|
+
type RuntimeLogLevel = "debug" | "info" | "warning" | "error";
|
|
69
|
+
type RuntimeOutcome = "succeeded" | "failed" | "degraded" | "cancelled" | "pending";
|
|
70
|
+
type RuntimeOperationKind = "request" | "operation";
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Structured, coded errors shared by every Autter Runtime server SDK.
|
|
74
|
+
*
|
|
75
|
+
* export const billingErrors = defineRuntimeErrors("billing", {
|
|
76
|
+
* declined: { status: 402, message: "Payment declined", expected: true,
|
|
77
|
+
* why: "The card issuer rejected the charge",
|
|
78
|
+
* fix: "Ask the customer for another card" },
|
|
79
|
+
* limit: ({ plan }: { plan: string }) => ({ status: 429, message: `Plan ${plan} limit reached` }),
|
|
80
|
+
* });
|
|
81
|
+
* throw billingErrors.limit({ plan: "free" }); // code "billing.limit"
|
|
82
|
+
*
|
|
83
|
+
* A code groups every occurrence into one issue (scheme "code-v1"), so codes
|
|
84
|
+
* must be stable, namespaced and low-cardinality: never ids, user data or
|
|
85
|
+
* secrets. Anything not matching CODE_PATTERN is dropped and the error
|
|
86
|
+
* groups by message exactly as before.
|
|
87
|
+
*/
|
|
88
|
+
/** `namespace.key` with up to four segments, lower-case, max 80 characters. */
|
|
89
|
+
declare const CODE_PATTERN: RegExp;
|
|
90
|
+
interface RuntimeErrorDefinition {
|
|
91
|
+
/** Human-readable message. Safe to show to clients. */
|
|
92
|
+
message: string;
|
|
93
|
+
/** HTTP-ish status. Default 500 when the error reaches a response. */
|
|
94
|
+
status?: number;
|
|
95
|
+
/** Expected business failure (decline, validation): recorded, never an incident. */
|
|
96
|
+
expected?: boolean;
|
|
97
|
+
/** Declared cause, ≤ 1000 chars. Treated as a hypothesis by Autter's RCA. */
|
|
98
|
+
why?: string;
|
|
99
|
+
/** Declared remedy, ≤ 1000 chars. */
|
|
100
|
+
fix?: string;
|
|
101
|
+
/** Docs link, ≤ 500 chars. */
|
|
102
|
+
link?: string;
|
|
103
|
+
}
|
|
104
|
+
interface RuntimeErrorExtras {
|
|
105
|
+
/** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
|
|
106
|
+
cause?: unknown;
|
|
107
|
+
/** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
|
|
108
|
+
internal?: Record<string, unknown>;
|
|
109
|
+
/** Override the catalog message for this throw. */
|
|
110
|
+
message?: string;
|
|
111
|
+
}
|
|
112
|
+
interface RuntimeErrorOptions extends RuntimeErrorDefinition {
|
|
113
|
+
/** Stable namespaced code, e.g. "inventory.reservation_timeout". */
|
|
114
|
+
code?: string;
|
|
115
|
+
/** Underlying error; becomes `exception.cause.N.*` (max 5 levels). */
|
|
116
|
+
cause?: unknown;
|
|
117
|
+
/** Debug-only details: redacted and attached to the span only, never to logs or client responses. */
|
|
118
|
+
internal?: Record<string, unknown>;
|
|
119
|
+
}
|
|
120
|
+
/** The fields Autter reads from any error (duck-typed). */
|
|
121
|
+
interface RuntimeErrorLike {
|
|
122
|
+
message?: string;
|
|
123
|
+
code?: string;
|
|
124
|
+
why?: string;
|
|
125
|
+
fix?: string;
|
|
126
|
+
link?: string;
|
|
127
|
+
status?: number;
|
|
128
|
+
expected?: boolean;
|
|
129
|
+
}
|
|
130
|
+
declare class RuntimeError extends Error implements RuntimeErrorLike {
|
|
131
|
+
readonly code?: string;
|
|
132
|
+
readonly why?: string;
|
|
133
|
+
readonly fix?: string;
|
|
134
|
+
readonly link?: string;
|
|
135
|
+
readonly status?: number;
|
|
136
|
+
readonly expected?: boolean;
|
|
137
|
+
/** Non-enumerable so JSON.stringify / loggers never serialise it. */
|
|
138
|
+
readonly internal?: Record<string, unknown>;
|
|
139
|
+
constructor(options: RuntimeErrorOptions | string);
|
|
140
|
+
/** Client-safe JSON (what `toClientError` returns, minus the wrapper). */
|
|
141
|
+
toJSON(): Record<string, unknown>;
|
|
142
|
+
}
|
|
143
|
+
type CatalogEntry = RuntimeErrorDefinition | ((args: any) => RuntimeErrorDefinition);
|
|
144
|
+
/** A typed factory for one catalog entry; `.code` is the namespaced code. */
|
|
145
|
+
type RuntimeErrorFactory<E> = E extends (args: infer A) => RuntimeErrorDefinition ? ((args: A, extras?: RuntimeErrorExtras) => RuntimeError) & {
|
|
146
|
+
readonly code: string;
|
|
147
|
+
} : ((extras?: RuntimeErrorExtras) => RuntimeError) & {
|
|
148
|
+
readonly code: string;
|
|
149
|
+
};
|
|
150
|
+
type RuntimeErrorCatalog<C extends Record<string, CatalogEntry>> = {
|
|
151
|
+
readonly [K in keyof C]: RuntimeErrorFactory<C[K]>;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Build typed error factories from a catalog. Each key becomes the code
|
|
155
|
+
* `${namespace}.${key}`; an invalid resulting code is dropped with a
|
|
156
|
+
* one-time warning (the factory still produces a normal RuntimeError).
|
|
157
|
+
*/
|
|
158
|
+
declare function defineRuntimeErrors<const C extends Record<string, CatalogEntry>>(namespace: string, catalog: C): RuntimeErrorCatalog<C>;
|
|
159
|
+
/**
|
|
160
|
+
* True for any error carrying Autter's structured fields — a RuntimeError,
|
|
161
|
+
* or ANY object with a string `code`/`why`/`fix`/`link`, a numeric `status`
|
|
162
|
+
* (or `statusCode`) or a boolean `expected`. Existing error classes benefit
|
|
163
|
+
* without being rewritten.
|
|
164
|
+
*/
|
|
165
|
+
declare function isRuntimeErrorLike(err: unknown): err is RuntimeErrorLike;
|
|
166
|
+
interface ErrorAttributeOptions {
|
|
167
|
+
/** Also emit `exception.cause.N.*` for the cause chain (default true). */
|
|
168
|
+
causes?: boolean;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Wire attributes for an error: `autter.error.code|why|fix|link|status|expected`
|
|
172
|
+
* and `exception.cause.N.type|message|code` (N = 1..5). Never includes
|
|
173
|
+
* `internal` — see `errorInternal`.
|
|
174
|
+
*/
|
|
175
|
+
declare function errorAttributes(err: unknown, options?: ErrorAttributeOptions): Record<string, string | number | boolean>;
|
|
176
|
+
interface ClientErrorBody {
|
|
177
|
+
error: {
|
|
178
|
+
message: string;
|
|
179
|
+
code?: string;
|
|
180
|
+
why?: string;
|
|
181
|
+
fix?: string;
|
|
182
|
+
link?: string;
|
|
183
|
+
requestId?: string;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Client-safe JSON body for an error:
|
|
188
|
+
* `{ error: { message, code?, why?, fix?, link?, requestId? } }`.
|
|
189
|
+
* Never includes `internal`, stacks or causes. The message of an
|
|
190
|
+
* unstructured 5xx error (a plain `throw new Error(...)`) is replaced with a
|
|
191
|
+
* generic one, because it was never written for clients.
|
|
192
|
+
*/
|
|
193
|
+
declare function toClientError(err: unknown, requestId?: string): ClientErrorBody;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* One runtime record before it is encoded for any sink: an operation or
|
|
197
|
+
* request summary (`autter.event.type = "operation"`) or a plain log line.
|
|
198
|
+
* `attributes` are already redacted and bounded.
|
|
199
|
+
*/
|
|
200
|
+
interface RuntimeEvent {
|
|
201
|
+
/** Epoch milliseconds. */
|
|
202
|
+
time: number;
|
|
203
|
+
level: RuntimeLogLevel;
|
|
204
|
+
message: string;
|
|
205
|
+
attributes: RuntimeLogContext;
|
|
206
|
+
traceId?: string;
|
|
207
|
+
spanId?: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Serialisable link from a producer operation to work it hands off (a queue
|
|
212
|
+
* job, another process): `{ v: 1, op, req?, traceparent? }`. Put it in the
|
|
213
|
+
* job payload; the consumer passes it as `withRuntimeOperation(..., { from })`.
|
|
214
|
+
*/
|
|
215
|
+
interface RuntimeCarrier {
|
|
216
|
+
v: 1;
|
|
217
|
+
/** Producer operation id (becomes the consumer's `autter.operation.parent_id`). */
|
|
218
|
+
op: string;
|
|
219
|
+
/** Request id the work belongs to. */
|
|
220
|
+
req?: string;
|
|
221
|
+
/** W3C traceparent of the producer span (consumer links to it). */
|
|
222
|
+
traceparent?: string;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Where runtime records go. The logger pipeline is
|
|
227
|
+
* `enrich → redact/bound → sinks[]`; each sink receives the same immutable
|
|
228
|
+
* RuntimeEvent. Defaults: `[otlpSink(), consoleSink()]` (+ `fileSink()` when
|
|
229
|
+
* NODE_ENV=development). Sinks must never throw into application code.
|
|
230
|
+
*/
|
|
231
|
+
interface RuntimeSink {
|
|
232
|
+
readonly name: string;
|
|
233
|
+
/** Called when the logger is (re)configured; null before init. */
|
|
234
|
+
start?(context: RuntimeSinkContext): void;
|
|
235
|
+
write(event: RuntimeEvent): void;
|
|
236
|
+
flush?(): Promise<void>;
|
|
237
|
+
shutdown?(): Promise<void>;
|
|
238
|
+
/** Records held in memory awaiting delivery. */
|
|
239
|
+
buffered?(): number;
|
|
240
|
+
/** @internal Receives every captureException call (testing sinks). */
|
|
241
|
+
exception?(record: CapturedException): void;
|
|
242
|
+
}
|
|
243
|
+
interface RuntimeSinkContext {
|
|
244
|
+
endpoint: string;
|
|
245
|
+
apiKey: string;
|
|
246
|
+
service: string;
|
|
247
|
+
environment: string;
|
|
248
|
+
release?: string;
|
|
249
|
+
/** SDK identity for the `telemetry.distro.*` resource attributes. */
|
|
250
|
+
distro?: {
|
|
251
|
+
name: string;
|
|
252
|
+
version: string;
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
interface CapturedException {
|
|
256
|
+
time: number;
|
|
257
|
+
error: unknown;
|
|
258
|
+
message: string;
|
|
259
|
+
type: string;
|
|
260
|
+
attributes: Record<string, unknown>;
|
|
261
|
+
operationId?: string;
|
|
262
|
+
requestId?: string;
|
|
263
|
+
}
|
|
264
|
+
interface OtlpSinkOptions {
|
|
265
|
+
/** Override the ingester base URL (default: the configured endpoint). */
|
|
266
|
+
endpoint?: string;
|
|
267
|
+
/** Override the ingest key (default: the configured apiKey). */
|
|
268
|
+
apiKey?: string;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* OTLP/HTTP JSON export to `${endpoint}/v1/logs`. Bounded exactly like
|
|
272
|
+
* 1.4.0: 1000 records / 4 MiB buffered, 256 KiB per record, batches of 50
|
|
273
|
+
* (≤ 512 KiB), 3 attempts within a 10 s deadline, exponential back-off
|
|
274
|
+
* on failure, undelivered records reported at shutdown.
|
|
275
|
+
*/
|
|
276
|
+
declare function otlpSink(options?: OtlpSinkOptions): RuntimeSink;
|
|
277
|
+
interface ConsoleSinkOptions {
|
|
278
|
+
/** Default: "pretty" unless NODE_ENV === "production", then "json". */
|
|
279
|
+
format?: "pretty" | "json";
|
|
280
|
+
/** Colourise pretty output. Default: stdout is a TTY and NO_COLOR is unset. */
|
|
281
|
+
color?: boolean;
|
|
282
|
+
/** Line writer. Default console.log. */
|
|
283
|
+
write?: (line: string) => void;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Console output. JSON lines (identical to 1.4.0) in production; a compact
|
|
287
|
+
* human-readable tree elsewhere, coloured only on a TTY.
|
|
288
|
+
*/
|
|
289
|
+
declare function consoleSink(options?: ConsoleSinkOptions): RuntimeSink;
|
|
290
|
+
interface FileSinkOptions {
|
|
291
|
+
/** Directory for `YYYY-MM-DD.jsonl` files. Default ".autter/runtime" (cwd-relative). */
|
|
292
|
+
dir?: string;
|
|
293
|
+
/** Keep at most this many files (oldest deleted). Default 7. */
|
|
294
|
+
maxFiles?: number;
|
|
295
|
+
/** Start a new `YYYY-MM-DD.N.jsonl` file past this size. Default 10 MiB. */
|
|
296
|
+
maxBytes?: number;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* NDJSON on local disk, one record per line, for coding agents and
|
|
300
|
+
* `autter logs --local`. Daily files (UTC), size rotation, bounded file
|
|
301
|
+
* count. Writes are synchronous appends (dev-sized volumes). Disables itself
|
|
302
|
+
* with one warning on read-only or permission-denied filesystems.
|
|
303
|
+
*/
|
|
304
|
+
declare function fileSink(options?: FileSinkOptions): RuntimeSink;
|
|
305
|
+
interface MemorySink extends RuntimeSink {
|
|
306
|
+
readonly events: RuntimeEvent[];
|
|
307
|
+
readonly exceptions: CapturedException[];
|
|
308
|
+
clear(): void;
|
|
309
|
+
}
|
|
310
|
+
/** Keeps every record in memory — for tests (`@autter/runtime-node/testing`). */
|
|
311
|
+
declare function memorySink(): MemorySink;
|
|
312
|
+
|
|
313
|
+
export { otlpSink as A, redactAttributes as B, type CapturedException as C, redactText as D, toClientError as E, type FileSinkOptions as F, type MemorySink as M, type OtlpSinkOptions as O, type RuntimeEvent as R, type RuntimeOutcome as a, type RedactOptions as b, type Redactor$1 as c, type RuntimeLogLevel as d, type RuntimeOperationKind as e, type RuntimeSink as f, type RuntimeLogContext as g, type RuntimeCarrier as h, CODE_PATTERN as i, type ClientErrorBody as j, type ConsoleSinkOptions as k, RuntimeError as l, memorySink as m, type RuntimeErrorCatalog as n, type RuntimeErrorDefinition as o, type RuntimeErrorExtras as p, type RuntimeErrorFactory as q, type RuntimeErrorLike as r, type RuntimeErrorOptions as s, type RuntimeLogContextValue as t, type RuntimeSinkContext as u, consoleSink as v, defineRuntimeErrors as w, errorAttributes as x, fileSink as y, isRuntimeErrorLike as z };
|