@sensigo/realm 0.10.1 → 0.11.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/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/observability/failed-attempt-record.d.ts +59 -0
- package/dist/observability/failed-attempt-record.d.ts.map +1 -0
- package/dist/observability/failed-attempt-record.js +154 -0
- package/dist/observability/failed-attempt-record.js.map +1 -0
- package/dist/store/failed-attempt-store.d.ts +36 -0
- package/dist/store/failed-attempt-store.d.ts.map +1 -0
- package/dist/store/failed-attempt-store.js +100 -0
- package/dist/store/failed-attempt-store.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,10 @@ export { decideIdempotencyPolicy } from './store/idempotency-policy.js';
|
|
|
11
11
|
export type { IdempotencyDecision } from './store/idempotency-policy.js';
|
|
12
12
|
export { executeStep } from './engine/execution-loop.js';
|
|
13
13
|
export { abandonRun } from './engine/abandon-run.js';
|
|
14
|
+
export { buildFailedAttemptRecord, serializeFailedAttemptLine, } from './observability/failed-attempt-record.js';
|
|
15
|
+
export type { BuildFailedAttemptInput, FailedAttemptRecord, ValidationErrorSummaryEntry, } from './observability/failed-attempt-record.js';
|
|
16
|
+
export { FailedAttemptStore, FAILED_ATTEMPT_SIDECAR_MAX_BYTES, } from './store/failed-attempt-store.js';
|
|
17
|
+
export type { FailedAttemptReadResult } from './store/failed-attempt-store.js';
|
|
14
18
|
export type { StepDispatcher, ExecuteStepOptions } from './engine/execution-loop.js';
|
|
15
19
|
export { submitHumanResponse, executeChain, buildNextActions, buildPreExecutionErrorEnvelope, } from './engine/execution-loop.js';
|
|
16
20
|
export type { SubmitGateOptions, ExecuteChainOptions } from './engine/execution-loop.js';
|
|
@@ -19,7 +23,7 @@ export { TERMINAL_PHASES, RESUMABLE_PHASES, WAITING_PHASES, isTerminalPhase, TER
|
|
|
19
23
|
export { evaluatePrecondition, checkPreconditions, evaluateAllPreconditions, } from './engine/precondition.js';
|
|
20
24
|
export type { PreconditionResult } from './engine/precondition.js';
|
|
21
25
|
export type { StepDiagnostics } from './types/run-record.js';
|
|
22
|
-
export declare const VERSION = "0.
|
|
26
|
+
export declare const VERSION = "0.11.0";
|
|
23
27
|
export type { ToolCallRecord, McpServerConfig } from './types/mcp-types.js';
|
|
24
28
|
export type { ServiceAdapter, ServiceResponse } from './extensions/service-adapter.js';
|
|
25
29
|
export type { StepHandler, StepHandlerInputs, StepContext, StepHandlerResult, } from './extensions/step-handler.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -10,11 +10,13 @@ export { hashParams, canonicalJson } from './store/params-hash.js';
|
|
|
10
10
|
export { decideIdempotencyPolicy } from './store/idempotency-policy.js';
|
|
11
11
|
export { executeStep } from './engine/execution-loop.js';
|
|
12
12
|
export { abandonRun } from './engine/abandon-run.js';
|
|
13
|
+
export { buildFailedAttemptRecord, serializeFailedAttemptLine, } from './observability/failed-attempt-record.js';
|
|
14
|
+
export { FailedAttemptStore, FAILED_ATTEMPT_SIDECAR_MAX_BYTES, } from './store/failed-attempt-store.js';
|
|
13
15
|
export { submitHumanResponse, executeChain, buildNextActions, buildPreExecutionErrorEnvelope, } from './engine/execution-loop.js';
|
|
14
16
|
export { findEligibleSteps, isWorkflowComplete, deriveRunPhase, buildEvidenceByStep, propagateSkips, } from './engine/eligibility.js';
|
|
15
17
|
export { TERMINAL_PHASES, RESUMABLE_PHASES, WAITING_PHASES, isTerminalPhase, TERMINAL_STATES, RESUMABLE_STATES, WAITING_STATES, isTerminalState, } from './engine/lifecycle.js';
|
|
16
18
|
export { evaluatePrecondition, checkPreconditions, evaluateAllPreconditions, } from './engine/precondition.js';
|
|
17
|
-
export const VERSION = '0.
|
|
19
|
+
export const VERSION = '0.11.0';
|
|
18
20
|
export { ExtensionRegistry } from './extensions/registry.js';
|
|
19
21
|
export { createDefaultRegistry } from './extensions/default-registry.js';
|
|
20
22
|
// Evidence
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/** Input to {@link buildFailedAttemptRecord}. */
|
|
2
|
+
export interface BuildFailedAttemptInput {
|
|
3
|
+
run_id: string;
|
|
4
|
+
workflow_id: string;
|
|
5
|
+
step_id: string;
|
|
6
|
+
/** ISO timestamp; supplied by the caller (e.g. `new Date().toISOString()`). */
|
|
7
|
+
ts: string;
|
|
8
|
+
/** One of the three VALIDATION_* error codes. */
|
|
9
|
+
error_code: string;
|
|
10
|
+
/** The raw `error_details.errors` array (may be anything — coerced defensively). */
|
|
11
|
+
ajv_errors: unknown[];
|
|
12
|
+
/** The agent's submitted output (`args.params`). */
|
|
13
|
+
params: Record<string, unknown>;
|
|
14
|
+
/** `args.trace?.length ?? 0`. */
|
|
15
|
+
trace_entry_count: number;
|
|
16
|
+
}
|
|
17
|
+
/** A single whitelisted Ajv error — value echoes (`params`/`data`) are intentionally excluded. */
|
|
18
|
+
export interface ValidationErrorSummaryEntry {
|
|
19
|
+
instancePath: string;
|
|
20
|
+
schemaPath: string;
|
|
21
|
+
keyword: string;
|
|
22
|
+
message: string;
|
|
23
|
+
}
|
|
24
|
+
/** Metadata-only record describing a failed agent-step validation attempt. */
|
|
25
|
+
export interface FailedAttemptRecord {
|
|
26
|
+
run_id: string;
|
|
27
|
+
workflow_id: string;
|
|
28
|
+
step_id: string;
|
|
29
|
+
ts: string;
|
|
30
|
+
error_code: string;
|
|
31
|
+
validation_error_summary: ValidationErrorSummaryEntry[];
|
|
32
|
+
submitted_key_count: number;
|
|
33
|
+
submitted_keys: string[];
|
|
34
|
+
submitted_bytes: number;
|
|
35
|
+
trace_entry_count: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Build a metadata-only {@link FailedAttemptRecord}. Pure and deterministic — no timestamps or I/O
|
|
39
|
+
* generated here. Never throws on malformed input.
|
|
40
|
+
*/
|
|
41
|
+
export declare function buildFailedAttemptRecord(input: BuildFailedAttemptInput): FailedAttemptRecord;
|
|
42
|
+
/**
|
|
43
|
+
* Serialize a failed-attempt record (optionally wrapped with extra keys like `event`) to a single
|
|
44
|
+
* JSON line guaranteed to be ≤ `maxBytes`. When the serialized form (plus a 1-byte newline budget)
|
|
45
|
+
* exceeds the limit, reduce progressively and set `truncated: true`:
|
|
46
|
+
* 1. drop `validation_error_summary` entries from the end (down to empty);
|
|
47
|
+
* 2. if still over, replace `submitted_keys` with `[]` (keeping `submitted_key_count`);
|
|
48
|
+
* 3. if still over, hard byte-truncate the JSON string to `maxBytes` as a final guarantee.
|
|
49
|
+
* Wrapper keys (e.g. `event`, `dropped_attempts`) are preserved; only the known record fields are
|
|
50
|
+
* reduced. The returned `line` is ALWAYS ≤ `maxBytes` (verified on the serialized string).
|
|
51
|
+
*
|
|
52
|
+
* This is the single source of truth for line size — P3's atomic append reuses it verbatim (where
|
|
53
|
+
* ≤PIPE_BUF matters for lock-free atomicity).
|
|
54
|
+
*/
|
|
55
|
+
export declare function serializeFailedAttemptLine(obj: Record<string, unknown>, maxBytes?: number): {
|
|
56
|
+
line: string;
|
|
57
|
+
truncated: boolean;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=failed-attempt-record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failed-attempt-record.d.ts","sourceRoot":"","sources":["../../src/observability/failed-attempt-record.ts"],"names":[],"mappings":"AAaA,iDAAiD;AACjD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,+EAA+E;IAC/E,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,UAAU,EAAE,OAAO,EAAE,CAAC;IACtB,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,iCAAiC;IACjC,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,kGAAkG;AAClG,MAAM,WAAW,2BAA2B;IAC1C,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB,EAAE,2BAA2B,EAAE,CAAC;IACxD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AA0DD;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,mBAAmB,CAwB5F;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,QAAQ,GAAE,MAA0B,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CA8BtC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Pure, I/O-free builder + serializer for failed agent-step validation telemetry.
|
|
2
|
+
//
|
|
3
|
+
// When an agent's execute_step output fails pre-claim schema validation, the engine returns an
|
|
4
|
+
// error envelope on a WRITE-FREE path (nothing persisted, nothing logged). These helpers turn that
|
|
5
|
+
// ephemeral rejection into a structured, METADATA-ONLY record for stderr emission (P2) and a durable
|
|
6
|
+
// sidecar (P3, which reuses this exact builder/serializer).
|
|
7
|
+
//
|
|
8
|
+
// PII guard: the record never contains raw model output values — only Ajv error metadata (whitelisted
|
|
9
|
+
// fields, with offending-value echoes dropped), submitted key NAMES (capped), counts, and byte size.
|
|
10
|
+
//
|
|
11
|
+
// Determinism: no Date.now()/Math.random()/I/O here — the timestamp is supplied by the caller — so
|
|
12
|
+
// these functions are deterministic and unit-testable.
|
|
13
|
+
const MAX_SUMMARY_ENTRIES = 10;
|
|
14
|
+
const MAX_FIELD_CHARS = 200;
|
|
15
|
+
const MAX_KEYS = 50;
|
|
16
|
+
const MAX_KEY_CHARS = 100;
|
|
17
|
+
const DEFAULT_MAX_BYTES = 3072;
|
|
18
|
+
/** Coerce to a string ONLY when already a string; otherwise '' (never leak objects via String()). */
|
|
19
|
+
function asString(value) {
|
|
20
|
+
return typeof value === 'string' ? value : '';
|
|
21
|
+
}
|
|
22
|
+
function truncate(value, max) {
|
|
23
|
+
return value.length > max ? value.slice(0, max) : value;
|
|
24
|
+
}
|
|
25
|
+
/** Byte length of a string, guarded so it never throws. */
|
|
26
|
+
function byteLength(value) {
|
|
27
|
+
try {
|
|
28
|
+
return Buffer.byteLength(value, 'utf8');
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return value.length;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** JSON.stringify guarded against circular refs / throwers; returns '{}' on failure. */
|
|
35
|
+
function safeStringify(value) {
|
|
36
|
+
try {
|
|
37
|
+
const s = JSON.stringify(value);
|
|
38
|
+
return typeof s === 'string' ? s : '{}';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return '{}';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Map raw Ajv errors to the whitelisted summary. Drops `params`/`data` (Ajv embeds offending VALUES
|
|
46
|
+
* there — a leak vector). Skips non-object entries, caps at the first 10, truncates path/message
|
|
47
|
+
* fields to 200 chars. Never throws.
|
|
48
|
+
*/
|
|
49
|
+
function summarizeAjvErrors(ajvErrors) {
|
|
50
|
+
if (!Array.isArray(ajvErrors))
|
|
51
|
+
return [];
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const entry of ajvErrors) {
|
|
54
|
+
if (out.length >= MAX_SUMMARY_ENTRIES)
|
|
55
|
+
break;
|
|
56
|
+
if (entry === null || typeof entry !== 'object')
|
|
57
|
+
continue;
|
|
58
|
+
const e = entry;
|
|
59
|
+
out.push({
|
|
60
|
+
instancePath: truncate(asString(e['instancePath']), MAX_FIELD_CHARS),
|
|
61
|
+
schemaPath: truncate(asString(e['schemaPath']), MAX_FIELD_CHARS),
|
|
62
|
+
keyword: truncate(asString(e['keyword']), MAX_FIELD_CHARS),
|
|
63
|
+
message: truncate(asString(e['message']), MAX_FIELD_CHARS),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build a metadata-only {@link FailedAttemptRecord}. Pure and deterministic — no timestamps or I/O
|
|
70
|
+
* generated here. Never throws on malformed input.
|
|
71
|
+
*/
|
|
72
|
+
export function buildFailedAttemptRecord(input) {
|
|
73
|
+
const params = input.params !== null && typeof input.params === 'object' ? input.params : {};
|
|
74
|
+
const allKeys = Object.keys(params);
|
|
75
|
+
let submittedBytes = 0;
|
|
76
|
+
try {
|
|
77
|
+
const s = JSON.stringify(params);
|
|
78
|
+
if (typeof s === 'string')
|
|
79
|
+
submittedBytes = byteLength(s);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
submittedBytes = 0;
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
run_id: input.run_id,
|
|
86
|
+
workflow_id: input.workflow_id,
|
|
87
|
+
step_id: input.step_id,
|
|
88
|
+
ts: input.ts,
|
|
89
|
+
error_code: input.error_code,
|
|
90
|
+
validation_error_summary: summarizeAjvErrors(input.ajv_errors),
|
|
91
|
+
submitted_key_count: allKeys.length,
|
|
92
|
+
submitted_keys: allKeys.slice(0, MAX_KEYS).map((k) => truncate(k, MAX_KEY_CHARS)),
|
|
93
|
+
submitted_bytes: submittedBytes,
|
|
94
|
+
trace_entry_count: typeof input.trace_entry_count === 'number' ? input.trace_entry_count : 0,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
/** Byte-safe truncation: returns the longest prefix of `value` whose UTF-8 length is ≤ maxBytes. */
|
|
98
|
+
function byteTruncate(value, maxBytes) {
|
|
99
|
+
if (byteLength(value) <= maxBytes)
|
|
100
|
+
return value;
|
|
101
|
+
let lo = 0;
|
|
102
|
+
let hi = value.length;
|
|
103
|
+
while (lo < hi) {
|
|
104
|
+
const mid = Math.ceil((lo + hi) / 2);
|
|
105
|
+
if (byteLength(value.slice(0, mid)) <= maxBytes)
|
|
106
|
+
lo = mid;
|
|
107
|
+
else
|
|
108
|
+
hi = mid - 1;
|
|
109
|
+
}
|
|
110
|
+
return value.slice(0, lo);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Serialize a failed-attempt record (optionally wrapped with extra keys like `event`) to a single
|
|
114
|
+
* JSON line guaranteed to be ≤ `maxBytes`. When the serialized form (plus a 1-byte newline budget)
|
|
115
|
+
* exceeds the limit, reduce progressively and set `truncated: true`:
|
|
116
|
+
* 1. drop `validation_error_summary` entries from the end (down to empty);
|
|
117
|
+
* 2. if still over, replace `submitted_keys` with `[]` (keeping `submitted_key_count`);
|
|
118
|
+
* 3. if still over, hard byte-truncate the JSON string to `maxBytes` as a final guarantee.
|
|
119
|
+
* Wrapper keys (e.g. `event`, `dropped_attempts`) are preserved; only the known record fields are
|
|
120
|
+
* reduced. The returned `line` is ALWAYS ≤ `maxBytes` (verified on the serialized string).
|
|
121
|
+
*
|
|
122
|
+
* This is the single source of truth for line size — P3's atomic append reuses it verbatim (where
|
|
123
|
+
* ≤PIPE_BUF matters for lock-free atomicity).
|
|
124
|
+
*/
|
|
125
|
+
export function serializeFailedAttemptLine(obj, maxBytes = DEFAULT_MAX_BYTES) {
|
|
126
|
+
// Fits if the serialized bytes plus a 1-byte newline budget stay within the limit.
|
|
127
|
+
const fits = (s) => byteLength(s) + 1 <= maxBytes;
|
|
128
|
+
let line = safeStringify(obj);
|
|
129
|
+
if (fits(line))
|
|
130
|
+
return { line, truncated: false };
|
|
131
|
+
let work = { ...obj };
|
|
132
|
+
// Step 1: drop validation_error_summary entries from the end.
|
|
133
|
+
if (Array.isArray(work['validation_error_summary'])) {
|
|
134
|
+
const arr = [...work['validation_error_summary']];
|
|
135
|
+
while (arr.length > 0 && !fits(safeStringify({ ...work, validation_error_summary: arr }))) {
|
|
136
|
+
arr.pop();
|
|
137
|
+
}
|
|
138
|
+
work = { ...work, validation_error_summary: arr };
|
|
139
|
+
line = safeStringify(work);
|
|
140
|
+
if (fits(line))
|
|
141
|
+
return { line, truncated: true };
|
|
142
|
+
}
|
|
143
|
+
// Step 2: drop submitted_keys (keep submitted_key_count).
|
|
144
|
+
if ('submitted_keys' in work) {
|
|
145
|
+
work = { ...work, submitted_keys: [] };
|
|
146
|
+
line = safeStringify(work);
|
|
147
|
+
if (fits(line))
|
|
148
|
+
return { line, truncated: true };
|
|
149
|
+
}
|
|
150
|
+
// Step 3: hard byte-truncate as a final guarantee.
|
|
151
|
+
line = byteTruncate(line, maxBytes);
|
|
152
|
+
return { line, truncated: true };
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=failed-attempt-record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failed-attempt-record.js","sourceRoot":"","sources":["../../src/observability/failed-attempt-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { FailedAttemptRecord } from '../observability/failed-attempt-record.js';
|
|
2
|
+
/**
|
|
3
|
+
* Append-and-stop byte ceiling per sidecar (~80+ full ≤3072B records — ample forensics). Approximate
|
|
4
|
+
* under concurrency: bounded overshoot ≈ concurrent-writers × max-record. Kept lock-free deliberately.
|
|
5
|
+
*/
|
|
6
|
+
export declare const FAILED_ATTEMPT_SIDECAR_MAX_BYTES: number;
|
|
7
|
+
export interface FailedAttemptReadResult {
|
|
8
|
+
/** Parsed records, in append order; torn/unparseable lines are skipped. */
|
|
9
|
+
records: FailedAttemptRecord[];
|
|
10
|
+
/** True when the sidecar reached the byte ceiling — later attempts were dropped (append-and-stop). */
|
|
11
|
+
capped: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* File-backed store for failed agent-attempt sidecars. Append (MCP server) + read (CLI). Best-effort:
|
|
15
|
+
* append never throws/propagates. Lock-free: each line is ≤PIPE_BUF, so a single O_APPEND write is
|
|
16
|
+
* atomic and interleave-safe across concurrent processes (the size bound is what buys lock-freedom —
|
|
17
|
+
* the deliberate difference from the WAL store).
|
|
18
|
+
*/
|
|
19
|
+
export declare class FailedAttemptStore {
|
|
20
|
+
private readonly runsDir;
|
|
21
|
+
constructor(runsDir: string);
|
|
22
|
+
/** Sidecar path — derived ONLY from the (server-generated UUID) runId. `.jsonl` is mandatory. */
|
|
23
|
+
private sidecarPath;
|
|
24
|
+
/**
|
|
25
|
+
* Append one already-serialized line (from `serializeFailedAttemptLine`, guaranteed ≤3072B ≤ PIPE_BUF).
|
|
26
|
+
* Append-and-stop: if the file is already at the ceiling the record is dropped. Best-effort — a
|
|
27
|
+
* failed append (disk full, perms) never propagates and never alters the caller's response.
|
|
28
|
+
*/
|
|
29
|
+
append(runId: string, line: string): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Read the sidecar for a run. Parses line-by-line, skipping blank/torn/unparseable lines; never
|
|
32
|
+
* throws. Missing file → empty result. `capped` is reported per the (race-free) size≥ceiling rule.
|
|
33
|
+
*/
|
|
34
|
+
read(runId: string): Promise<FailedAttemptReadResult>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=failed-attempt-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failed-attempt-store.d.ts","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAErF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,QAAa,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACtC,2EAA2E;IAC3E,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,sGAAsG;IACtG,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,MAAM;IAI3B,iGAAiG;IACjG,OAAO,CAAC,WAAW;IAInB;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD;;;OAGG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;CA+B5D"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// failed-attempt-store.ts — durable, co-located per-run sidecar for failed agent-attempt telemetry.
|
|
2
|
+
//
|
|
3
|
+
// A pure observability SIDE-CHANNEL: it never touches the run file, never bumps version, never
|
|
4
|
+
// affects eligibility/phase/failed_steps[]. It lives in `runsDir` alongside run files and adopts the
|
|
5
|
+
// same operator-managed retention (Realm has no run-GC by design — see #107).
|
|
6
|
+
//
|
|
7
|
+
// File: <runsDir>/<runId>.attempts.jsonl — one JSON record per line.
|
|
8
|
+
// - The `.jsonl` suffix is MANDATORY: JsonFileStore.list() does readdir → filter(.json) → JSON.parse
|
|
9
|
+
// as a RunRecord with no try/catch, so a `<id>.attempts.json` sibling would corrupt
|
|
10
|
+
// list()/cleanup/reconcile. `.jsonl` is invisible to that filter (like trace-buffer-*.jsonl and
|
|
11
|
+
// the keys/ subdir).
|
|
12
|
+
// - The path is derived ONLY from the server-generated UUIDv4 runId (`[0-9a-f-]`), never from
|
|
13
|
+
// caller-supplied input — a path-safety invariant.
|
|
14
|
+
import { existsSync } from 'node:fs';
|
|
15
|
+
import { appendFile, readFile, stat } from 'node:fs/promises';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
/**
|
|
18
|
+
* Append-and-stop byte ceiling per sidecar (~80+ full ≤3072B records — ample forensics). Approximate
|
|
19
|
+
* under concurrency: bounded overshoot ≈ concurrent-writers × max-record. Kept lock-free deliberately.
|
|
20
|
+
*/
|
|
21
|
+
export const FAILED_ATTEMPT_SIDECAR_MAX_BYTES = 256 * 1024;
|
|
22
|
+
/**
|
|
23
|
+
* File-backed store for failed agent-attempt sidecars. Append (MCP server) + read (CLI). Best-effort:
|
|
24
|
+
* append never throws/propagates. Lock-free: each line is ≤PIPE_BUF, so a single O_APPEND write is
|
|
25
|
+
* atomic and interleave-safe across concurrent processes (the size bound is what buys lock-freedom —
|
|
26
|
+
* the deliberate difference from the WAL store).
|
|
27
|
+
*/
|
|
28
|
+
export class FailedAttemptStore {
|
|
29
|
+
runsDir;
|
|
30
|
+
constructor(runsDir) {
|
|
31
|
+
this.runsDir = runsDir;
|
|
32
|
+
}
|
|
33
|
+
/** Sidecar path — derived ONLY from the (server-generated UUID) runId. `.jsonl` is mandatory. */
|
|
34
|
+
sidecarPath(runId) {
|
|
35
|
+
return join(this.runsDir, `${runId}.attempts.jsonl`);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Append one already-serialized line (from `serializeFailedAttemptLine`, guaranteed ≤3072B ≤ PIPE_BUF).
|
|
39
|
+
* Append-and-stop: if the file is already at the ceiling the record is dropped. Best-effort — a
|
|
40
|
+
* failed append (disk full, perms) never propagates and never alters the caller's response.
|
|
41
|
+
*/
|
|
42
|
+
async append(runId, line) {
|
|
43
|
+
const path = this.sidecarPath(runId);
|
|
44
|
+
try {
|
|
45
|
+
// O(1) ceiling check via stat — never read+count the file (that would be quadratic under a
|
|
46
|
+
// retry storm). Missing file → treat as size 0 and proceed.
|
|
47
|
+
try {
|
|
48
|
+
const info = await stat(path);
|
|
49
|
+
if (info.size >= FAILED_ATTEMPT_SIDECAR_MAX_BYTES)
|
|
50
|
+
return; // append-and-stop (drop)
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// file does not exist yet → proceed with the first append
|
|
54
|
+
}
|
|
55
|
+
// Exactly one O_APPEND write — one record per line, atomic because line + '\n' ≤ PIPE_BUF.
|
|
56
|
+
await appendFile(path, line + '\n', 'utf8');
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Best-effort observability side-channel — never propagate.
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Read the sidecar for a run. Parses line-by-line, skipping blank/torn/unparseable lines; never
|
|
64
|
+
* throws. Missing file → empty result. `capped` is reported per the (race-free) size≥ceiling rule.
|
|
65
|
+
*/
|
|
66
|
+
async read(runId) {
|
|
67
|
+
const path = this.sidecarPath(runId);
|
|
68
|
+
if (!existsSync(path))
|
|
69
|
+
return { records: [], capped: false };
|
|
70
|
+
let capped = false;
|
|
71
|
+
try {
|
|
72
|
+
const info = await stat(path);
|
|
73
|
+
capped = info.size >= FAILED_ATTEMPT_SIDECAR_MAX_BYTES;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// ignore — capped stays false
|
|
77
|
+
}
|
|
78
|
+
let content;
|
|
79
|
+
try {
|
|
80
|
+
content = await readFile(path, 'utf8');
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return { records: [], capped };
|
|
84
|
+
}
|
|
85
|
+
const records = [];
|
|
86
|
+
for (const raw of content.split('\n')) {
|
|
87
|
+
const trimmed = raw.trim();
|
|
88
|
+
if (trimmed.length === 0)
|
|
89
|
+
continue;
|
|
90
|
+
try {
|
|
91
|
+
records.push(JSON.parse(trimmed));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// skip a torn/partial/unparseable line — never throw
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return { records, capped };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=failed-attempt-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failed-attempt-store.js","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"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"}
|