@faithfulalabi/agent-lens 0.15.0 → 0.15.2

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.
@@ -192,7 +192,7 @@ const SPILL_SNIPPET = `snippet(spill_fts, 3, '<mark>', '</mark>', '…', 12)`;
192
192
  function ftsPhrase(q) {
193
193
  return `"${q.replaceAll('"', '""')}"`;
194
194
  }
195
- const SEARCHABLE = `e.kind <> 'unknown'`;
195
+ const SEARCHABLE = `(e.kind <> 'unknown' OR json_extract(e.attrs, '$.filename') IS NOT NULL)`;
196
196
  function searchSql(scoped) {
197
197
  const scope = scoped ? ' AND e.session_id = :session' : '';
198
198
  const events = `SELECT e.session_id AS session_id, s.title AS session_title, s.project_path AS project_path,` +
@@ -273,7 +273,7 @@ CREATE TABLE events (
273
273
  -- attributionAgent, effort, permissionMode,
274
274
  -- compactMetadata, toolDenialKind, renderedRole,
275
275
  -- permissionSource, permissionReasonType,
276
- -- unknown_fields[]
276
+ -- filename, unknown_fields[]
277
277
  );
278
278
  CREATE UNIQUE INDEX idx_events_session_seq ON events(session_id, seq);
279
279
  CREATE INDEX idx_events_turn ON events(turn_id, seq);
@@ -178,6 +178,7 @@ function insertEvents(db, events, spills) {
178
178
  tokens_out: event.tokens_out,
179
179
  cache_read: event.tokens_cache_read,
180
180
  cache_write: event.tokens_cache_write,
181
+ cache_write_1h: event.tokens_cache_write_1h,
181
182
  });
182
183
  insert.run(event.id, event.session_id, event.turn_id, event.seq, event.kind, event.ts, event.request_id ?? null, event.block_index, event.name ?? null, event.status ?? null, event.duration_ms ?? null, event.duration_source ?? null, event.input ?? null, event.input_bytes ?? null, event.input_storage ?? null, event.wire_input ?? null, event.wire_input_bytes ?? null, event.wire_input_storage ?? null, event.text ?? null, event.text_bytes ?? null, output.output_storage, output.spill_path, output.spill_bytes, event.src_offset, event.src_len, event.result_offset ?? null, event.result_len ?? null, event.result_block ?? null, event.image_count, event.model ?? null, event.tokens_in ?? null, event.tokens_out ?? null, event.tokens_cache_read ?? null, event.tokens_cache_write ?? null, est_cost, event.child_session_id ?? null, event.agent_type ?? null, event.agent_status ?? null, event.raw_type, event.raw_subtype ?? null, event.attrs);
183
184
  }
@@ -181,7 +181,7 @@ export function runPipeline(lines, ctx) {
181
181
  const usage = usageAt.get(index);
182
182
  const record = blocks.length === 0 ? attachmentRecord(line) : undefined;
183
183
  const lineText = blocks.length === 0 ? (record?.text ?? apiErrorText(line)) : undefined;
184
- const attrs = record?.role === undefined ? '{}' : JSON.stringify({ renderedRole: record.role });
184
+ const attrs = JSON.stringify({ renderedRole: record?.role, filename: record?.filename });
185
185
  let stamped = false;
186
186
  const emit = (block, blockIndex) => {
187
187
  if (block?.kind === 'unknown_block')
@@ -226,6 +226,7 @@ export function runPipeline(lines, ctx) {
226
226
  tokens_out: tokens?.output_tokens,
227
227
  tokens_cache_read: tokens?.cache_read_input_tokens,
228
228
  tokens_cache_write: tokens?.cache_creation_input_tokens,
229
+ tokens_cache_write_1h: tokens?.ephemeral_1h_input_tokens,
229
230
  raw_type: rawTypeOf(line),
230
231
  raw_subtype: rawSubtypeOf(line),
231
232
  attrs,
@@ -35,7 +35,7 @@ export const PRICING_TABLE = Object.freeze({
35
35
  'claude-haiku-4-5': { input: 1, output: 5, cache_read: 0.1, cache_write: 1.25 },
36
36
  'claude-3-5-haiku': { input: 0.8, output: 4, cache_read: 0.08, cache_write: 1 },
37
37
  });
38
- export const PRICING_TABLE_DATE = '2026-09-22';
38
+ export const PRICING_TABLE_DATE = '2026-10-28';
39
39
  export const PRICING_VERSION = `${PRICING_TABLE_DATE}+${createHash('sha256')
40
40
  .update(canonicalJson(PRICING_TABLE), 'utf8')
41
41
  .digest('hex')
@@ -58,9 +58,11 @@ export function estimateCost(model, usage) {
58
58
  if (key === undefined)
59
59
  return null;
60
60
  const price = PRICING_TABLE[key];
61
+ const oneHour = usage.cache_write_1h ?? 0;
61
62
  const millionths = (usage.tokens_in ?? 0) * price.input +
62
63
  (usage.tokens_out ?? 0) * price.output +
63
64
  (usage.cache_read ?? 0) * price.cache_read +
64
- (usage.cache_write ?? 0) * price.cache_write;
65
+ ((usage.cache_write ?? 0) - oneHour) * price.cache_write +
66
+ oneHour * 2 * price.input;
65
67
  return millionths / 1_000_000;
66
68
  }
@@ -6,12 +6,14 @@ function placeholder(subtype) {
6
6
  export function attachmentRecord(line) {
7
7
  if (line.kind !== 'attachment')
8
8
  return undefined;
9
- const subtype = str(obj(line.raw.attachment, undefined)?.type, '');
9
+ const payload = obj(line.raw.attachment, undefined);
10
+ const subtype = str(payload?.type, '');
10
11
  const first = arr(line.raw.rendered, NO_ELEMENTS)[0];
11
12
  const rendered = str(obj(first, undefined)?.content, undefined);
12
13
  return {
13
14
  subtype,
14
15
  text: rendered ?? placeholder(subtype),
15
16
  role: str(line.raw.renderedRole, undefined),
17
+ filename: str(payload?.filename, undefined),
16
18
  };
17
19
  }
@@ -73,7 +73,8 @@ export function classifyContent(content) {
73
73
  export function resultText(children) {
74
74
  const texts = children.flatMap((child) => (child.kind === 'text' ? [child.text] : []));
75
75
  const images = children.flatMap((child) => (child.kind === 'image' ? [child.placeholder] : []));
76
- return [...texts, ...images].join('\n');
76
+ const refs = children.flatMap((child) => child.kind === 'tool_reference' ? [`[tool_reference ${child.name}]`] : []);
77
+ return [...texts, ...images, ...refs].join('\n');
77
78
  }
78
79
  export function contentBlocks(line) {
79
80
  return classifyContent(rawContent(line));
@@ -9,6 +9,7 @@ const ZERO = {
9
9
  output_tokens: 0,
10
10
  cache_creation_input_tokens: 0,
11
11
  cache_read_input_tokens: 0,
12
+ ephemeral_1h_input_tokens: 0,
12
13
  };
13
14
  function usageOf(line) {
14
15
  return obj(obj(obj(line, undefined)?.message, undefined)?.usage, undefined);
@@ -32,6 +33,13 @@ export function foldRequestGroup(lines) {
32
33
  folded[field] = value;
33
34
  taken.add(field);
34
35
  }
36
+ if (!taken.has('ephemeral_1h_input_tokens')) {
37
+ const oneHour = num(obj(usage['cache_creation'], undefined)?.['ephemeral_1h_input_tokens'], undefined);
38
+ if (oneHour !== undefined) {
39
+ folded.ephemeral_1h_input_tokens = oneHour;
40
+ taken.add('ephemeral_1h_input_tokens');
41
+ }
42
+ }
35
43
  const output = num(usage['output_tokens'], undefined);
36
44
  if (output !== undefined)
37
45
  folded.output_tokens = output;
@@ -1 +1 @@
1
- export const PROJECTOR_VERSION = 20;
1
+ export const PROJECTOR_VERSION = 22;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faithfulalabi/agent-lens",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "description": "Local-first agentic tracing platform: inspect everything your agent did in a session.",
5
5
  "type": "module",
6
6
  "license": "MIT",