@faithfulalabi/agent-lens 0.9.0 → 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/src/db/schema.js
CHANGED
|
@@ -197,11 +197,6 @@ CREATE TABLE events (
|
|
|
197
197
|
seq INTEGER NOT NULL, -- thread order; deterministic from the file bytes
|
|
198
198
|
kind TEXT NOT NULL, -- prompt | text | thinking | tool_call
|
|
199
199
|
-- | error | compaction | unknown
|
|
200
|
-
-- MEASURED 2026-09-11 (30,286 events): 'error'
|
|
201
|
-
-- has 0 rows, REACHABLE BUT UNOBSERVED — writer
|
|
202
|
-
-- pipeline.ts:306, gated on the harness line
|
|
203
|
-
-- subtype 'api_error'. Keep the arm; see
|
|
204
|
-
-- task 0.12.
|
|
205
200
|
ts TEXT NOT NULL,
|
|
206
201
|
request_id TEXT, -- groups the N lines of ONE assistant response
|
|
207
202
|
-- (1:1 with message.id; 13,629/13,630 lines = 1 block)
|
|
@@ -2,7 +2,7 @@ import { asyncAgentLaunch, taskNotification } from '../transcript/agents.js';
|
|
|
2
2
|
import { attachmentRecord } from '../transcript/attachments.js';
|
|
3
3
|
import { contentBlocks, imageCount, resultText } from '../transcript/blocks.js';
|
|
4
4
|
import { isHumanPrompt, MACHINERY_TAGS } from '../transcript/human.js';
|
|
5
|
-
import { foldControlLines, foldSessionEnvelope, promptGroupId, toolDenialKind, turnDurationMs, } from '../transcript/line.js';
|
|
5
|
+
import { apiErrorText, foldControlLines, foldSessionEnvelope, permissionDecision, promptGroupId, toolDenialKind, turnDurationMs, } from '../transcript/line.js';
|
|
6
6
|
import { foldRequestGroup, groupByRequestId, modelOfRequestGroup, requestIdOf, } from '../transcript/usage.js';
|
|
7
7
|
import { joinToolCalls, NO_INPUT, NO_WIRE_INPUT, toolInput, wireInput, } from './tools.js';
|
|
8
8
|
import { wireInputOf } from '../transcript/wire.js';
|
|
@@ -137,6 +137,7 @@ export function runPipeline(lines, ctx) {
|
|
|
137
137
|
text: output,
|
|
138
138
|
is_error: block.is_error,
|
|
139
139
|
denial: toolDenialKind(line),
|
|
140
|
+
decision: permissionDecision(line),
|
|
140
141
|
launch: asyncAgentLaunch(line, output),
|
|
141
142
|
ts: line.timestamp ?? '',
|
|
142
143
|
result_offset: line.byte_offset,
|
|
@@ -177,7 +178,7 @@ export function runPipeline(lines, ctx) {
|
|
|
177
178
|
const blocks = blocksAt[index];
|
|
178
179
|
const human = humanAt[index];
|
|
179
180
|
const usage = usageAt.get(index);
|
|
180
|
-
const lineText = blocks.length === 0 ? attachmentRecord(line)?.text : undefined;
|
|
181
|
+
const lineText = blocks.length === 0 ? (attachmentRecord(line)?.text ?? apiErrorText(line)) : undefined;
|
|
181
182
|
let stamped = false;
|
|
182
183
|
const emit = (block, blockIndex) => {
|
|
183
184
|
if (block?.kind === 'unknown_block')
|
|
@@ -49,8 +49,15 @@ function elapsedMs(call, result) {
|
|
|
49
49
|
const ms = epochMs(result) - epochMs(call);
|
|
50
50
|
return ms < 0 ? 0 : ms;
|
|
51
51
|
}
|
|
52
|
+
function statedDenial(decision) {
|
|
53
|
+
if (decision === 'reject')
|
|
54
|
+
return true;
|
|
55
|
+
if (decision === 'accept')
|
|
56
|
+
return false;
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
52
59
|
function statusOf(result) {
|
|
53
|
-
if (result.denial !== undefined)
|
|
60
|
+
if (statedDenial(result.decision) ?? result.denial !== undefined)
|
|
54
61
|
return 'denied';
|
|
55
62
|
return result.is_error ? 'error' : 'ok';
|
|
56
63
|
}
|
|
@@ -102,6 +109,10 @@ export function joinToolCalls(events, results, notifications, drift) {
|
|
|
102
109
|
event.duration_ms = elapsedMs(event.ts, result.ts);
|
|
103
110
|
event.duration_source = 'elapsed';
|
|
104
111
|
event.status = statusOf(result);
|
|
112
|
+
if (result.decision !== undefined &&
|
|
113
|
+
statedDenial(result.decision) !== (result.denial !== undefined)) {
|
|
114
|
+
drift.notePermissionDecisionMismatch();
|
|
115
|
+
}
|
|
105
116
|
if (event.name === 'Agent' && result.launch !== undefined) {
|
|
106
117
|
backPatch(event, answers.get(event.id));
|
|
107
118
|
continue;
|
|
@@ -12,6 +12,7 @@ export class DriftCounter {
|
|
|
12
12
|
blockTypes = new Map();
|
|
13
13
|
unjoinedToolUses = 0;
|
|
14
14
|
sidecarAgentIdMismatches = 0;
|
|
15
|
+
permissionDecisionMismatches = 0;
|
|
15
16
|
noteLine(line, knownFields) {
|
|
16
17
|
for (const name of Object.keys(line)) {
|
|
17
18
|
if (!knownFields.has(name))
|
|
@@ -30,8 +31,12 @@ export class DriftCounter {
|
|
|
30
31
|
noteSidecarMismatch() {
|
|
31
32
|
this.sidecarAgentIdMismatches += 1;
|
|
32
33
|
}
|
|
34
|
+
notePermissionDecisionMismatch() {
|
|
35
|
+
this.permissionDecisionMismatches += 1;
|
|
36
|
+
}
|
|
33
37
|
serialize() {
|
|
34
38
|
return JSON.stringify({
|
|
39
|
+
permission_decision_mismatch: this.permissionDecisionMismatches === 0 ? undefined : this.permissionDecisionMismatches,
|
|
35
40
|
sidecar_agent_id_mismatch: this.sidecarAgentIdMismatches === 0 ? undefined : this.sidecarAgentIdMismatches,
|
|
36
41
|
unjoined_tool_uses: this.unjoinedToolUses === 0 ? undefined : this.unjoinedToolUses,
|
|
37
42
|
unknown_block_types: bucket(this.blockTypes),
|
|
@@ -75,6 +75,7 @@ const LINE_TYPES = new Map([
|
|
|
75
75
|
'classifierMetaLines',
|
|
76
76
|
'toolEndsTurn',
|
|
77
77
|
'toolDenialKind',
|
|
78
|
+
'permissionDecision',
|
|
78
79
|
'imagePasteIds',
|
|
79
80
|
'serverClassifierContext',
|
|
80
81
|
'turnOrigin',
|
|
@@ -106,6 +107,11 @@ const LINE_TYPES = new Map([
|
|
|
106
107
|
'hookAdditionalContext',
|
|
107
108
|
'pendingBackgroundAgentCount',
|
|
108
109
|
'pendingWorkflowCount',
|
|
110
|
+
'error',
|
|
111
|
+
'maxRetries',
|
|
112
|
+
'retryAttempt',
|
|
113
|
+
'retryInMs',
|
|
114
|
+
'source',
|
|
109
115
|
]),
|
|
110
116
|
},
|
|
111
117
|
],
|
|
@@ -264,11 +270,43 @@ export function promptGroupId(line) {
|
|
|
264
270
|
export function toolDenialKind(line) {
|
|
265
271
|
return str(line.raw.toolDenialKind, undefined);
|
|
266
272
|
}
|
|
273
|
+
export function permissionDecision(line) {
|
|
274
|
+
if (line.raw.permissionDecision === undefined)
|
|
275
|
+
return undefined;
|
|
276
|
+
return str(obj(line.raw.permissionDecision, undefined)?.decision, '');
|
|
277
|
+
}
|
|
267
278
|
export function turnDurationMs(line) {
|
|
268
279
|
return line.kind === 'system' && line.subtype === 'turn_duration'
|
|
269
280
|
? num(line.raw.durationMs, undefined)
|
|
270
281
|
: undefined;
|
|
271
282
|
}
|
|
283
|
+
function phrase(value) {
|
|
284
|
+
let text = str(value, '').trim();
|
|
285
|
+
while (/[.!?:;,]/.test(text.slice(-1)))
|
|
286
|
+
text = text.slice(0, -1).trimEnd();
|
|
287
|
+
return text === '' ? undefined : text;
|
|
288
|
+
}
|
|
289
|
+
export function apiErrorText(line) {
|
|
290
|
+
if (line.kind !== 'system' || line.subtype !== 'api_error')
|
|
291
|
+
return undefined;
|
|
292
|
+
const error = obj(line.raw.error, undefined);
|
|
293
|
+
const cause = phrase(error?.formatted) ?? phrase(error?.message);
|
|
294
|
+
const code = phrase(obj(error?.connection, undefined)?.code);
|
|
295
|
+
const ceiling = num(line.raw.maxRetries, undefined);
|
|
296
|
+
const delayMs = num(line.raw.retryInMs, undefined);
|
|
297
|
+
const retry = [
|
|
298
|
+
num(line.raw.retryAttempt, undefined),
|
|
299
|
+
ceiling === undefined ? undefined : `of ${ceiling}`,
|
|
300
|
+
delayMs === undefined ? undefined : `in ${delayMs} ms`,
|
|
301
|
+
].filter((part) => part !== undefined);
|
|
302
|
+
const clauses = [];
|
|
303
|
+
const what = cause !== undefined && code !== undefined ? `${cause} (${code})` : (cause ?? code);
|
|
304
|
+
if (what !== undefined)
|
|
305
|
+
clauses.push(`${what}.`);
|
|
306
|
+
if (retry.length > 0)
|
|
307
|
+
clauses.push(`Retry ${retry.join(' ')}.`);
|
|
308
|
+
return clauses.length === 0 ? undefined : clauses.join(' ');
|
|
309
|
+
}
|
|
272
310
|
const SYNTHETIC_MODEL = '<synthetic>';
|
|
273
311
|
export function foldSessionEnvelope(lines) {
|
|
274
312
|
const envelope = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const PROJECTOR_VERSION =
|
|
1
|
+
export const PROJECTOR_VERSION = 17;
|