agentfootprint-lens 0.51.0 → 0.52.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 CHANGED
@@ -1018,12 +1018,20 @@ composed them); tools as sent (names, expandable schemas, the forced tool
1018
1018
  marked, `withheld` shown as the library states it). **BASIS** — epoch, call id,
1019
1019
  commit index, model, provider, params (only the dials the receipt carries — an
1020
1020
  absent dial is not rendered as a default), cache (transform, breakpoints
1021
- applied). **FOLD** — `iteration`, `currentSkillId`, `stepPointer`, engagement,
1021
+ applied, and since 0.52.0 the **cache strategy** as the receipt names it —
1022
+ `*` is the built-in pass-through, printed as itself; the receipt's `null`
1023
+ reads *no cache strategy*; a receipt from before agentfootprint 9.93.0 reads
1024
+ Not on record). **FOLD** — `iteration`, `currentSkillId`, `stepPointer`, engagement,
1022
1025
  active injections, hidden skill ids, read from the fold at the stop; a row the
1023
1026
  fold could not read is printed there as data (skipped indices, or the fold's
1024
1027
  error), beside a Damaged badge.
1025
- **OMISSIONS** — attention drops from the receipt when present, else the
1026
- library's `UNGAPPED_FIELDS` sentence for the field. **GAPS** — every gap on the
1028
+ **OMISSIONS** — the attention drops from the receipt (0.52.0): the count,
1029
+ then one line per turn the agent's window evicted for budget — its hash and
1030
+ the epoch it was **last served on**, paired by the library's own rule (the
1031
+ hash is that earlier receipt's `messages.entries[].hash`), or Not on record
1032
+ when no earlier receipt in this recording served it; a receipt that says
1033
+ nothing was dropped reads count 0, and a record that cannot say draws the
1034
+ badge. **GAPS** — every gap on the
1027
1035
  view: its kind, the fields it covers, its sentence verbatim, and its `cause`
1028
1036
  when the library established one (`receipt-shape-rejected` styled as damage).
1029
1037
  **SINCE PREVIOUS** — messages entered/left, tools added/removed, schemas whose
@@ -1072,7 +1080,8 @@ crossed into the call, one edge per system piece, message, request-only line and
1072
1080
  tool, each carrying its badge and, against the previous epoch, whether it
1073
1081
  *entered*, *left* or is *unchanged* — then **WITHHELD**: held and not sent. The
1074
1082
  withheld band is the reason to build it. The model never learns what it was
1075
- denied; the operator should — the withheld tool list, the attention drops, the
1083
+ denied; the operator should — the withheld tool list, each evicted turn as an
1084
+ edge into the messages slot with the epoch that last served it (0.52.0), the
1076
1085
  skills a role hid (read from the fold, since a receipt carries no authority
1077
1086
  names), a redacted fold, and every gap the view declares, each with the
1078
1087
  library's own sentence. Same cursor, same row, same badges: a Damaged row draws
@@ -746,8 +746,16 @@ interface LensDetailSlotProps {
746
746
  *
747
747
  * It holds no position of its own — it is rebuilt every render. Read it;
748
748
  * never store it.
749
+ *
750
+ * OPTIONAL, and not because it can be missing: `<Lens>` always supplies it.
751
+ * It is optional because a consumer may CONSTRUCT these props — a test that
752
+ * renders its own pane, a wrapper type that extends this one — and a new
753
+ * REQUIRED field would break that consumer's compile on a minor. Measured on
754
+ * a real app at 0.51.0, whose `BandPaneProps extends LensDetailSlotProps`
755
+ * stopped compiling. A receiver that wants it without a guard can read it
756
+ * from `useLensCursor` instead. (0.51.1)
749
757
  */
750
- readonly cursor: LensCursor;
758
+ readonly cursor?: LensCursor;
751
759
  }
752
760
  declare const Lens: React__default.FC<LensProps>;
753
761
 
@@ -746,8 +746,16 @@ interface LensDetailSlotProps {
746
746
  *
747
747
  * It holds no position of its own — it is rebuilt every render. Read it;
748
748
  * never store it.
749
+ *
750
+ * OPTIONAL, and not because it can be missing: `<Lens>` always supplies it.
751
+ * It is optional because a consumer may CONSTRUCT these props — a test that
752
+ * renders its own pane, a wrapper type that extends this one — and a new
753
+ * REQUIRED field would break that consumer's compile on a minor. Measured on
754
+ * a real app at 0.51.0, whose `BandPaneProps extends LensDetailSlotProps`
755
+ * stopped compiling. A receiver that wants it without a guard can read it
756
+ * from `useLensCursor` instead. (0.51.1)
749
757
  */
750
- readonly cursor: LensCursor;
758
+ readonly cursor?: LensCursor;
751
759
  }
752
760
  declare const Lens: React__default.FC<LensProps>;
753
761
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  formatBytes,
3
3
  structureGraphFromRunner
4
- } from "./chunk-ZZJ2OIQP.js";
4
+ } from "./chunk-VQ2C62UL.js";
5
5
 
6
6
  // src/core/buildStepGraphFromSnapshot.ts
7
7
  function buildStepGraphFromSnapshot(snapshot) {
@@ -1189,4 +1189,4 @@ export {
1189
1189
  decisionSentence,
1190
1190
  isConsentDecision
1191
1191
  };
1192
- //# sourceMappingURL=chunk-H63KQNY3.js.map
1192
+ //# sourceMappingURL=chunk-LLKFATWI.js.map
@@ -29,7 +29,7 @@ import {
29
29
  tagStopsStrategy,
30
30
  toSidecar,
31
31
  verify
32
- } from "./chunk-ZZJ2OIQP.js";
32
+ } from "./chunk-VQ2C62UL.js";
33
33
  import {
34
34
  MODE_PALETTES,
35
35
  T,
@@ -1780,9 +1780,10 @@ var GRAPH_LABELS = Object.freeze({
1780
1780
  redacted: "redacted",
1781
1781
  gap: "gap",
1782
1782
  toolWithheld: "withheld",
1783
- count: "count",
1784
- hashes: "hashes",
1785
- fold: "fold"
1783
+ fold: "fold",
1784
+ cacheStrategy: "cache strategy",
1785
+ noCacheStrategy: "no cache strategy",
1786
+ lastServedOn: "last served on"
1786
1787
  });
1787
1788
  var WITHHELD_LABELS = Object.freeze({
1788
1789
  "tool-withheld": GRAPH_LABELS.toolWithheld,
@@ -1859,9 +1860,20 @@ function CallCard({ call }) {
1859
1860
  ]
1860
1861
  }
1861
1862
  )
1863
+ ] }),
1864
+ /* @__PURE__ */ jsxs7("div", { style: rowStyle, "data-testid": "graph-call-strategy", children: [
1865
+ /* @__PURE__ */ jsx8("span", { style: mutedStyle, children: GRAPH_LABELS.cacheStrategy }),
1866
+ /* @__PURE__ */ jsx8(CacheStrategy, { value: call.cacheStrategy })
1862
1867
  ] })
1863
1868
  ] });
1864
1869
  }
1870
+ function CacheStrategy({ value }) {
1871
+ if (value === void 0) return /* @__PURE__ */ jsx8(Badge, { check: { status: "not-on-record" } });
1872
+ if (value === null) {
1873
+ return /* @__PURE__ */ jsx8("span", { style: mutedStyle, "data-testid": "served-cache-strategy", "data-strategy": "null", children: GRAPH_LABELS.noCacheStrategy });
1874
+ }
1875
+ return /* @__PURE__ */ jsx8("span", { style: monoStyle, "data-testid": "served-cache-strategy", "data-strategy": value, children: value });
1876
+ }
1865
1877
  function Band({
1866
1878
  title,
1867
1879
  testId,
@@ -1934,10 +1946,13 @@ function SlotCard({
1934
1946
  "data-kind": node.kind,
1935
1947
  "data-name": node.name,
1936
1948
  "data-slot": slot.slot,
1949
+ "data-hash": node.hash,
1950
+ "data-last-served-on": node.lastServedOn,
1937
1951
  children: [
1938
1952
  /* @__PURE__ */ jsx8(Elbow, {}),
1939
1953
  /* @__PURE__ */ jsx8("span", { style: keyStyle, children: WITHHELD_LABELS[node.kind] }),
1940
- /* @__PURE__ */ jsx8("span", { style: monoMutedStyle, children: node.name })
1954
+ /* @__PURE__ */ jsx8("span", { style: monoMutedStyle, children: node.name }),
1955
+ node.hash !== void 0 && /* @__PURE__ */ jsx8(EvictedTurnFacts, { node })
1941
1956
  ]
1942
1957
  },
1943
1958
  `${node.kind}:${node.name}:${i}`
@@ -1991,6 +2006,8 @@ function WithheldCard({ node }) {
1991
2006
  "data-name": node.name,
1992
2007
  "data-from": node.from,
1993
2008
  "data-slot": node.slot,
2009
+ "data-hash": node.hash,
2010
+ "data-last-served-on": node.lastServedOn,
1994
2011
  children: [
1995
2012
  /* @__PURE__ */ jsxs7("div", { style: rowStyle, children: [
1996
2013
  /* @__PURE__ */ jsx8("span", { style: keyStyle, children: WITHHELD_LABELS[node.kind] }),
@@ -2002,11 +2019,7 @@ function WithheldCard({ node }) {
2002
2019
  ] }),
2003
2020
  node.status !== void 0 && /* @__PURE__ */ jsx8(Badge, { check: { status: node.status } })
2004
2021
  ] }),
2005
- node.count !== void 0 && /* @__PURE__ */ jsxs7("div", { style: rowStyle, "data-testid": "graph-withheld-count", children: [
2006
- /* @__PURE__ */ jsx8("span", { style: keyStyle, children: GRAPH_LABELS.count }),
2007
- /* @__PURE__ */ jsx8("span", { style: monoStyle, children: node.count }),
2008
- node.hashes !== void 0 && /* @__PURE__ */ jsx8("span", { style: monoMutedStyle, children: node.hashes.join(" ") })
2009
- ] }),
2022
+ node.hash !== void 0 && /* @__PURE__ */ jsx8("div", { style: rowStyle, "data-testid": "graph-withheld-turn", children: /* @__PURE__ */ jsx8(EvictedTurnFacts, { node }) }),
2010
2023
  node.cause !== void 0 && /* @__PURE__ */ jsxs7(
2011
2024
  "span",
2012
2025
  {
@@ -2028,6 +2041,17 @@ function WithheldCard({ node }) {
2028
2041
  }
2029
2042
  );
2030
2043
  }
2044
+ function EvictedTurnFacts({ node }) {
2045
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
2046
+ /* @__PURE__ */ jsx8("span", { style: monoMutedStyle, "data-testid": "graph-evicted-hash", children: node.hash }),
2047
+ /* @__PURE__ */ jsx8("span", { style: mutedStyle, children: GRAPH_LABELS.lastServedOn }),
2048
+ node.lastServedOn !== void 0 ? /* @__PURE__ */ jsxs7("span", { style: chipStyle(T.primary), "data-testid": "graph-evicted-epoch", children: [
2049
+ GRAPH_LABELS.epoch,
2050
+ " ",
2051
+ node.lastServedOn
2052
+ ] }) : /* @__PURE__ */ jsx8(Badge, { check: { status: "not-on-record" } })
2053
+ ] });
2054
+ }
2031
2055
  function Elbow() {
2032
2056
  return /* @__PURE__ */ jsx8("span", { "aria-hidden": "true", style: elbowStyle });
2033
2057
  }
@@ -2193,7 +2217,7 @@ function chipStyle(color) {
2193
2217
 
2194
2218
  // src/react/components/ServedTab.tsx
2195
2219
  import React6, { useMemo as useMemo6, useState as useState6 } from "react";
2196
- import { SERVED_GAPS, UNGAPPED_FIELDS } from "agentfootprint";
2220
+ import { SERVED_GAPS } from "agentfootprint";
2197
2221
  import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2198
2222
  var LABELS = Object.freeze({
2199
2223
  tab: "Served",
@@ -2246,6 +2270,9 @@ var LABELS = Object.freeze({
2246
2270
  attentionDrops: "attention drops",
2247
2271
  count: "count",
2248
2272
  hashes: "hashes",
2273
+ lastServedOn: GRAPH_LABELS.lastServedOn,
2274
+ cacheStrategy: GRAPH_LABELS.cacheStrategy,
2275
+ noCacheStrategy: GRAPH_LABELS.noCacheStrategy,
2249
2276
  covers: "covers",
2250
2277
  cause: "cause",
2251
2278
  from: "from",
@@ -2278,7 +2305,8 @@ var SECTION_FIELDS = Object.freeze({
2278
2305
  tools: ["tools.names", "tools.schemaHashes", "tools.forced", "tools.withheld"],
2279
2306
  basis: ["basis.model", "basis.provider", "basis.runId", "basis.epoch", "epoch"],
2280
2307
  params: ["params"],
2281
- cache: ["cache.transform", "cache.transformHash", "cache.markersApplied"]
2308
+ cache: ["cache.transform", "cache.transformHash", "cache.markersApplied", "cache.strategy"],
2309
+ omissions: ["omittedForAttention"]
2282
2310
  });
2283
2311
  function cursorAnchor(props) {
2284
2312
  return {
@@ -2460,7 +2488,9 @@ function ServedTabBody(props) {
2460
2488
  ] }, name);
2461
2489
  }),
2462
2490
  checks.onReceiptOnly.toolNames.length > 0 && /* @__PURE__ */ jsx9(DataLine, { label: `${LABELS.tools} \xB7 ${LABELS.onReceiptOnly}`, children: checks.onReceiptOnly.toolNames.join(", ") }),
2463
- checks.rebuiltOnly.toolNames.length > 0 && /* @__PURE__ */ jsx9(DataLine, { label: `${LABELS.tools} \xB7 ${LABELS.rebuiltOnly}`, children: checks.rebuiltOnly.toolNames.join(", ") })
2491
+ checks.rebuiltOnly.toolNames.length > 0 && /* @__PURE__ */ jsx9(DataLine, { label: `${LABELS.tools} \xB7 ${LABELS.rebuiltOnly}`, children: checks.rebuiltOnly.toolNames.join(", ") }),
2492
+ checks.onReceiptOnly.schemas.length > 0 && /* @__PURE__ */ jsx9(DataLine, { label: `${LABELS.schema} \xB7 ${LABELS.onReceiptOnly}`, testId: "served-schemas-on-receipt-only", children: /* @__PURE__ */ jsx9("span", { style: monoStyle2, children: checks.onReceiptOnly.schemas.join(", ") }) }),
2493
+ checks.rebuiltOnly.schemas.length > 0 && /* @__PURE__ */ jsx9(DataLine, { label: `${LABELS.schema} \xB7 ${LABELS.rebuiltOnly}`, testId: "served-schemas-rebuilt-only", children: /* @__PURE__ */ jsx9("span", { style: monoStyle2, children: checks.rebuiltOnly.schemas.join(", ") }) })
2464
2494
  ]
2465
2495
  }
2466
2496
  ),
@@ -2485,15 +2515,21 @@ function ServedTabBody(props) {
2485
2515
  " ",
2486
2516
  row.receipt.cache.markersApplied.map((m) => `${m.field}[${m.boundaryIndex}] ${m.ttl}`).join(" \xB7 ")
2487
2517
  ] })
2488
- ] })
2518
+ ] }),
2519
+ /* @__PURE__ */ jsx9(DataLine, { label: LABELS.cacheStrategy, testId: "served-strategy", children: /* @__PURE__ */ jsx9(CacheStrategy, { value: graph.call.cacheStrategy }) })
2489
2520
  ] }) : /* @__PURE__ */ jsx9(Presence, { label: LABELS.cache }) }),
2490
2521
  /* @__PURE__ */ jsx9(SectionTitle, { children: LABELS.fold }),
2491
2522
  /* @__PURE__ */ jsx9(FoldSection, { fold }),
2492
2523
  /* @__PURE__ */ jsx9(SectionTitle, { children: LABELS.omissions }),
2493
- /* @__PURE__ */ jsx9(Section, { testId: "served-omissions", title: LABELS.attentionDrops, children: row.receipt?.omittedForAttention !== void 0 ? /* @__PURE__ */ jsxs8(Fragment4, { children: [
2494
- /* @__PURE__ */ jsx9(DataLine, { label: LABELS.count, children: row.receipt.omittedForAttention.count }),
2495
- /* @__PURE__ */ jsx9(DataLine, { label: LABELS.hashes, children: /* @__PURE__ */ jsx9("span", { style: monoMutedStyle2, children: row.receipt.omittedForAttention.hashes.join(" ") }) })
2496
- ] }) : /* @__PURE__ */ jsx9(Library, { "data-testid": "served-omissions-why", children: UNGAPPED_FIELDS.omittedForAttention }) }),
2524
+ /* @__PURE__ */ jsx9(
2525
+ Section,
2526
+ {
2527
+ testId: "served-omissions",
2528
+ title: LABELS.attentionDrops,
2529
+ gaps: gapsCovering(SECTION_FIELDS.omissions),
2530
+ children: /* @__PURE__ */ jsx9(Omissions, { row, status: checks.omittedForAttention })
2531
+ }
2532
+ ),
2497
2533
  /* @__PURE__ */ jsx9(SectionTitle, { children: LABELS.gaps }),
2498
2534
  /* @__PURE__ */ jsx9("div", { "data-testid": "served-gaps", children: view.gaps.map((gap) => /* @__PURE__ */ jsx9(GapCard, { gap }, gap.gap)) }),
2499
2535
  /* @__PURE__ */ jsx9(SectionTitle, { children: LABELS.sincePrevious }),
@@ -2647,6 +2683,35 @@ function GapCard({ gap }) {
2647
2683
  }
2648
2684
  );
2649
2685
  }
2686
+ function Omissions({
2687
+ row,
2688
+ status
2689
+ }) {
2690
+ if (status === "not-on-record") return /* @__PURE__ */ jsx9(Presence, { label: LABELS.attentionDrops });
2691
+ const drops = row.receipt?.omittedForAttention;
2692
+ return /* @__PURE__ */ jsxs8(Fragment4, { children: [
2693
+ /* @__PURE__ */ jsx9(DataLine, { label: LABELS.count, testId: "served-omissions-count", children: drops?.count ?? 0 }),
2694
+ (row.evictedTurns ?? []).map((turn, i) => /* @__PURE__ */ jsxs8(
2695
+ DataLine,
2696
+ {
2697
+ label: LABELS.hashes,
2698
+ testId: "served-evicted-turn",
2699
+ children: [
2700
+ /* @__PURE__ */ jsx9("span", { style: monoMutedStyle2, "data-testid": "served-evicted-hash", children: turn.hash }),
2701
+ " ",
2702
+ /* @__PURE__ */ jsx9("span", { style: dataLabelStyle, children: LABELS.lastServedOn }),
2703
+ " ",
2704
+ turn.lastServedOn !== void 0 ? /* @__PURE__ */ jsxs8("span", { style: chipStyle2(T.primary), "data-testid": "served-evicted-epoch", children: [
2705
+ LABELS.epoch,
2706
+ " ",
2707
+ turn.lastServedOn
2708
+ ] }) : /* @__PURE__ */ jsx9(Badge, { check: { status: "not-on-record" } })
2709
+ ]
2710
+ },
2711
+ `${turn.hash}:${i}`
2712
+ ))
2713
+ ] });
2714
+ }
2650
2715
  function FoldSection({ fold }) {
2651
2716
  return /* @__PURE__ */ jsxs8(Section, { testId: "served-fold", title: LABELS.fold, children: [
2652
2717
  fold.foldError !== void 0 && /* @__PURE__ */ jsxs8(DataLine, { label: LABELS.foldUnavailable, testId: "served-fold-error", children: [
@@ -6108,4 +6173,4 @@ export {
6108
6173
  useBookmarkSidecar,
6109
6174
  Lens
6110
6175
  };
6111
- //# sourceMappingURL=chunk-7QSK7EJW.js.map
6176
+ //# sourceMappingURL=chunk-NPOCJFXS.js.map