agentfootprint-lens 0.51.1 → 0.52.1

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
@@ -2904,23 +2904,46 @@ function cursorProvenance(runner, cursorRuntimeStageId) {
2904
2904
  return { writtenKeys: [...written], sliceFor };
2905
2905
  }
2906
2906
 
2907
- // src/core/served/servedRowAt.ts
2908
- import {
2909
- epochLocations,
2910
- receiptAt,
2911
- servedAt,
2912
- SERVED_GAPS
2913
- } from "agentfootprint";
2914
-
2915
2907
  // src/core/served/receiptShape.ts
2916
2908
  var isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
2917
2909
  function isReceiptShaped(value) {
2918
2910
  if (!isRecord(value)) return false;
2919
2911
  const { system, messages, tools, params, cache, basis } = value;
2912
+ if (isRecord(cache) && "strategy" in cache && cache.strategy !== null && typeof cache.strategy !== "string") {
2913
+ return false;
2914
+ }
2920
2915
  return isRecord(basis) && typeof basis.epoch === "number" && typeof basis.runId === "string" && isRecord(system) && typeof system.hash === "string" && Array.isArray(system.pieces) && isRecord(messages) && Array.isArray(messages.entries) && Array.isArray(messages.requestOnly) && isRecord(tools) && Array.isArray(tools.names) && isRecord(tools.schemaHashes) && isRecord(params) && isRecord(cache) && Array.isArray(cache.markersApplied);
2921
2916
  }
2917
+ function carriesCacheStrategy(receipt) {
2918
+ return receipt.cache !== void 0 && "strategy" in receipt.cache;
2919
+ }
2920
+
2921
+ // src/core/served/evictedTurns.ts
2922
+ function attentionOmissionStatus(receipt) {
2923
+ if (receipt === void 0) return "not-on-record";
2924
+ if (receipt.omittedForAttention !== void 0) return "on-receipt";
2925
+ return carriesCacheStrategy(receipt) ? "none-on-receipt" : "not-on-record";
2926
+ }
2927
+ function pairEvictedTurns(drops, earlier) {
2928
+ return Object.freeze(
2929
+ drops.hashes.map((hash) => {
2930
+ let lastServedOn;
2931
+ for (const receipt of earlier) {
2932
+ if (!receipt.messages.entries.some((entry) => entry.hash === hash)) continue;
2933
+ if (lastServedOn === void 0 || receipt.basis.epoch > lastServedOn) lastServedOn = receipt.basis.epoch;
2934
+ }
2935
+ return Object.freeze(lastServedOn === void 0 ? { hash } : { hash, lastServedOn });
2936
+ })
2937
+ );
2938
+ }
2922
2939
 
2923
2940
  // src/core/served/servedRowAt.ts
2941
+ import {
2942
+ epochLocations,
2943
+ receiptAt,
2944
+ servedAt,
2945
+ SERVED_GAPS
2946
+ } from "agentfootprint";
2924
2947
  function runLogIndexOf(location) {
2925
2948
  if (location.subflowScope === void 0) return location.callIdx;
2926
2949
  const log = location.runLog;
@@ -2960,9 +2983,18 @@ function rowOf(recording, locations, at, betweenCalls) {
2960
2983
  ...receipt !== void 0 ? { receipt } : {},
2961
2984
  betweenCalls,
2962
2985
  ...previous !== void 0 ? { previousEpoch: previous.epoch } : {},
2963
- ...cause !== void 0 ? { receiptCause: cause } : {}
2986
+ ...cause !== void 0 ? { receiptCause: cause } : {},
2987
+ ...receipt?.omittedForAttention !== void 0 ? { evictedTurns: evictedTurnsOf(recording, locations, at, receipt.omittedForAttention) } : {}
2964
2988
  });
2965
2989
  }
2990
+ function evictedTurnsOf(recording, locations, at, drops) {
2991
+ const earlier = [];
2992
+ for (const location of locations.slice(0, at)) {
2993
+ const read = receiptAt(recording, location.epoch);
2994
+ if (read !== void 0 && isReceiptShaped(read)) earlier.push(read);
2995
+ }
2996
+ return pairEvictedTurns(drops, earlier);
2997
+ }
2966
2998
  function servedRowAt(recording, cursor) {
2967
2999
  const locations = epochLocations(recording);
2968
3000
  if (locations.length === 0) return void 0;
@@ -3174,7 +3206,7 @@ function verify(view, receipt, runId, cause) {
3174
3206
  basis: "on-receipt",
3175
3207
  params: "on-receipt",
3176
3208
  cache: "on-receipt",
3177
- omittedForAttention: receipt.omittedForAttention !== void 0 ? "on-receipt" : "not-on-record",
3209
+ omittedForAttention: attentionOmissionStatus(receipt),
3178
3210
  onReceiptOnly,
3179
3211
  rebuiltOnly,
3180
3212
  damaged: unexcusedShort || all.some((c) => c.status === "damaged")
@@ -3414,8 +3446,7 @@ function foldFactsAt(recording, cursor) {
3414
3446
 
3415
3447
  // src/core/served/servedGraphAt.ts
3416
3448
  import {
3417
- SERVED_GAPS as SERVED_GAPS2,
3418
- UNGAPPED_FIELDS
3449
+ SERVED_GAPS as SERVED_GAPS2
3419
3450
  } from "agentfootprint";
3420
3451
  var SLOT_ORDER = Object.freeze({
3421
3452
  "system-prompt": 0,
@@ -3635,26 +3666,28 @@ function withheldNodes(input) {
3635
3666
  for (const id of fold.hiddenSkillIds ?? []) {
3636
3667
  out.push(Object.freeze({ kind: "hidden-skill", name: id, from: "fold" }));
3637
3668
  }
3638
- const drops = row.receipt?.omittedForAttention;
3639
- out.push(
3640
- Object.freeze(
3641
- drops !== void 0 ? {
3669
+ for (const turn of row.evictedTurns ?? []) {
3670
+ out.push(
3671
+ Object.freeze({
3642
3672
  kind: "attention-drop",
3643
3673
  name: "omittedForAttention",
3644
3674
  from: "receipt",
3645
- count: drops.count,
3646
- hashes: Object.freeze([...drops.hashes])
3647
- } : {
3648
- // Absent is not none: the library's own sentence for a field no gap
3649
- // explains, printed beside the Not-on-record badge.
3675
+ slot: "messages",
3676
+ hash: turn.hash,
3677
+ ...turn.lastServedOn !== void 0 ? { lastServedOn: turn.lastServedOn } : {}
3678
+ })
3679
+ );
3680
+ }
3681
+ if (input.checks.omittedForAttention === "not-on-record") {
3682
+ out.push(
3683
+ Object.freeze({
3650
3684
  kind: "attention-drop",
3651
3685
  name: "omittedForAttention",
3652
3686
  from: "receipt",
3653
- status: "not-on-record",
3654
- why: UNGAPPED_FIELDS.omittedForAttention
3655
- }
3656
- )
3657
- );
3687
+ status: "not-on-record"
3688
+ })
3689
+ );
3690
+ }
3658
3691
  if (fold.redacted) {
3659
3692
  out.push(Object.freeze({ kind: "redacted", name: "redacted", from: "fold" }));
3660
3693
  }
@@ -3686,6 +3719,9 @@ function callNode(input, edges) {
3686
3719
  ...row.previousEpoch !== void 0 ? { previousEpoch: row.previousEpoch } : {},
3687
3720
  ...basis !== void 0 ? { basis } : {},
3688
3721
  basisStatus: basis !== void 0 ? "reconstructed" : "not-on-record",
3722
+ // Present only where the receipt SAYS — a string or null. A receipt
3723
+ // without the key (pre-9.93.0) leaves it absent: "cannot say".
3724
+ ...row.receipt !== void 0 && carriesCacheStrategy(row.receipt) ? { cacheStrategy: row.receipt.cache.strategy } : {},
3689
3725
  ...row.receiptCause !== void 0 ? { receiptCause: row.receiptCause } : {},
3690
3726
  damaged: checks.damaged || edges.some((e) => e.check.status === "damaged")
3691
3727
  });
@@ -4073,6 +4109,9 @@ export {
4073
4109
  structureGraphFromRunner,
4074
4110
  structureGraphFromSpec,
4075
4111
  cursorProvenance,
4112
+ carriesCacheStrategy,
4113
+ attentionOmissionStatus,
4114
+ pairEvictedTurns,
4076
4115
  servedRowAt,
4077
4116
  servedRowForEpoch,
4078
4117
  EXCUSING_GAPS,
@@ -4100,4 +4139,4 @@ export {
4100
4139
  tagStopsFor,
4101
4140
  tagAxisPositions
4102
4141
  };
4103
- //# sourceMappingURL=chunk-ZZJ2OIQP.js.map
4142
+ //# sourceMappingURL=chunk-DMENQHPR.js.map