agentfootprint-lens 0.53.4 → 0.54.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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-47W3TQT6.js → chunk-37NHCNSS.js} +352 -1
  3. package/dist/chunk-37NHCNSS.js.map +1 -0
  4. package/dist/{chunk-S4KD5E4C.js → chunk-4AKGKXD6.js} +2 -2
  5. package/dist/{chunk-KGDSDNJI.js → chunk-73SE3HB7.js} +63 -31
  6. package/dist/chunk-73SE3HB7.js.map +1 -0
  7. package/dist/{chunk-RARQT7O5.js → chunk-AE7C4TPA.js} +2 -354
  8. package/dist/chunk-AE7C4TPA.js.map +1 -0
  9. package/dist/{chunk-A3SG5MAG.js → chunk-MLWYULJ4.js} +2 -2
  10. package/dist/chunk-MTPFNZ4L.js +1419 -0
  11. package/dist/chunk-MTPFNZ4L.js.map +1 -0
  12. package/dist/{chunk-KGQIRUBC.js → chunk-UYL7DUOI.js} +322 -1650
  13. package/dist/chunk-UYL7DUOI.js.map +1 -0
  14. package/dist/{chunk-UHA4XB4Z.js → chunk-ZPJAJQFD.js} +42 -57
  15. package/dist/chunk-ZPJAJQFD.js.map +1 -0
  16. package/dist/context.cjs +1774 -79
  17. package/dist/context.cjs.map +1 -1
  18. package/dist/context.d.cts +14 -3
  19. package/dist/context.d.ts +14 -3
  20. package/dist/context.js +4 -4
  21. package/dist/core.js +10 -10
  22. package/dist/index.cjs +99 -82
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.js +21 -21
  27. package/dist/skillgraph.cjs +41 -56
  28. package/dist/skillgraph.cjs.map +1 -1
  29. package/dist/skillgraph.js +1 -1
  30. package/dist/why.js +4 -4
  31. package/package.json +1 -1
  32. package/dist/chunk-35DQLVDZ.js +0 -88
  33. package/dist/chunk-35DQLVDZ.js.map +0 -1
  34. package/dist/chunk-47W3TQT6.js.map +0 -1
  35. package/dist/chunk-KGDSDNJI.js.map +0 -1
  36. package/dist/chunk-KGQIRUBC.js.map +0 -1
  37. package/dist/chunk-RARQT7O5.js.map +0 -1
  38. package/dist/chunk-UHA4XB4Z.js.map +0 -1
  39. /package/dist/{chunk-S4KD5E4C.js.map → chunk-4AKGKXD6.js.map} +0 -0
  40. /package/dist/{chunk-A3SG5MAG.js.map → chunk-MLWYULJ4.js.map} +0 -0
package/README.md CHANGED
@@ -78,7 +78,7 @@ changes.
78
78
  |---|---|
79
79
  | `agentfootprint-lens/why` | Replay a recording as the agent's own milestones. `<WhyLens recording={...} />` takes the recording straight (`recordRun()`'s `{ snapshot, events, structure }`, or the `persistRecording` envelope), validates it at mount, and mounts the shipped `<Lens>` shell on the milestone axis — plus the axis helpers (`scrubAxisFor`, `stepForCommitIdx`, `stepForRuntimeStageId`, `resolveNavigation`) for hosts holding one cursor across views. |
80
80
  | `agentfootprint-lens/skillgraph` | Debug how a run routed through its skills. `<SkillGraphDebugger recorder={...} />` plus its headless selectors (`selectSkillRoute`, `selectSkillBeats`, `selectSkillTopology`, `selectSkillFrameContext`, `stepForRuntimeStageId`, `resolveNavigation`). |
81
- | `agentfootprint-lens/context` | The context object at a stop, key by key — who wrote each, what moved, what was served. `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). |
81
+ | `agentfootprint-lens/context` | What the model HAD at a stop — the served document of that epoch on top (the Served tab itself: pieces, messages, tools, verdicts, delta since the previous call) — and what it was BUILT from beneath: the record key by key, who wrote each, what moved; a long value opens in place (0.54.0). `<ContextView runner={...} />` walks the milestone axis on its own; hand it `cursor` and it follows the ONE cursor (0.53.1). |
82
82
 
83
83
  The axis model in three sentences: one run leaves one causal trace, and each
84
84
  lens replays one AXIS of it — the Why reading scrubs the milestones, the Flow
@@ -486,6 +486,351 @@ function verify(view, receipt, runId, cause) {
486
486
  });
487
487
  }
488
488
 
489
+ // src/core/served/foldFactsAt.ts
490
+ import { stateAt } from "footprintjs/trace";
491
+ var FOLD_FACT_KEYS = Object.freeze([
492
+ "iteration",
493
+ "currentSkillId",
494
+ "stepPointer",
495
+ "mapEngagement",
496
+ "activeInjections",
497
+ "hiddenSkillIds"
498
+ ]);
499
+ function skippedIndicesOf(folded) {
500
+ const gaps = folded.skipped;
501
+ return gaps !== void 0 && gaps.length > 0 ? Object.freeze(gaps.map((g) => g.index)) : void 0;
502
+ }
503
+ function foldFactsAt(recording, cursor) {
504
+ const source = typeof recording === "object" && recording !== null ? recording : void 0;
505
+ let folded;
506
+ try {
507
+ folded = stateAt(source, cursor.commitIdx);
508
+ } catch (e) {
509
+ return Object.freeze({
510
+ redacted: false,
511
+ present: Object.freeze([]),
512
+ foldError: e instanceof Error ? e.message : String(e)
513
+ });
514
+ }
515
+ const state = folded.state;
516
+ const present = [];
517
+ const out = {};
518
+ for (const key of FOLD_FACT_KEYS) {
519
+ const value = state[key];
520
+ if (value === void 0) continue;
521
+ present.push(key);
522
+ out[key] = value;
523
+ }
524
+ const hidden = out.hiddenSkillIds;
525
+ const injections = out.activeInjections;
526
+ const skipped = skippedIndicesOf(folded);
527
+ return Object.freeze({
528
+ basis: folded.basis,
529
+ redacted: folded.redacted,
530
+ present: Object.freeze(present),
531
+ ...skipped !== void 0 ? { skipped } : {},
532
+ ...typeof out.iteration === "number" ? { iteration: out.iteration } : {},
533
+ ...typeof out.currentSkillId === "string" ? { currentSkillId: out.currentSkillId } : {},
534
+ ...out.stepPointer !== void 0 ? { stepPointer: out.stepPointer } : {},
535
+ ...out.mapEngagement !== void 0 ? { mapEngagement: out.mapEngagement } : {},
536
+ ...Array.isArray(injections) ? { activeInjections: Object.freeze([...injections]) } : {},
537
+ ...Array.isArray(hidden) && hidden.every((h) => typeof h === "string") ? { hiddenSkillIds: Object.freeze([...hidden]) } : {}
538
+ });
539
+ }
540
+
541
+ // src/core/served/servedGraphAt.ts
542
+ import {
543
+ SERVED_GAPS as SERVED_GAPS2
544
+ } from "agentfootprint";
545
+ var SLOT_ORDER = Object.freeze({
546
+ "system-prompt": 0,
547
+ messages: 1,
548
+ tools: 2
549
+ });
550
+ var SERVED_SLOTS = Object.freeze(
551
+ Object.keys(SLOT_ORDER).sort((a, b) => SLOT_ORDER[a] - SLOT_ORDER[b])
552
+ );
553
+ var HELD_HONESTY_KEYS = Object.freeze([
554
+ "basis",
555
+ "redacted",
556
+ "skipped",
557
+ "foldError"
558
+ ]);
559
+ var HELD_KEYS = Object.freeze([
560
+ ...FOLD_FACT_KEYS,
561
+ ...HELD_HONESTY_KEYS
562
+ ]);
563
+ var RECONSTRUCTED = Object.freeze({ status: "reconstructed" });
564
+ var NOT_ON_RECORD = Object.freeze({ status: "not-on-record" });
565
+ function slotsOfFields(fields) {
566
+ const out = [];
567
+ for (const field of fields) {
568
+ const slot = field.startsWith("system.") ? "system-prompt" : field.startsWith("messages.") ? "messages" : field.startsWith("tools.") ? "tools" : void 0;
569
+ if (slot !== void 0 && !out.includes(slot)) out.push(slot);
570
+ }
571
+ return out;
572
+ }
573
+ function heldNodes(fold) {
574
+ const node = (key, value, status) => Object.freeze(value === void 0 ? { key, status } : { key, value, status });
575
+ const out = [];
576
+ for (const key of FOLD_FACT_KEYS) {
577
+ const value = fold[key];
578
+ out.push(value === void 0 ? node(key, void 0, "not-on-record") : node(key, value, "reconstructed"));
579
+ }
580
+ out.push(
581
+ fold.basis === void 0 ? node("basis", void 0, "not-on-record") : node("basis", fold.basis, "reconstructed")
582
+ );
583
+ out.push(node("redacted", fold.redacted, "reconstructed"));
584
+ if (fold.skipped !== void 0) out.push(node("skipped", fold.skipped, "damaged"));
585
+ if (fold.foldError !== void 0) out.push(node("foldError", fold.foldError, "damaged"));
586
+ return Object.freeze(out);
587
+ }
588
+ function servedEdges(input) {
589
+ const { row, checks, since } = input;
590
+ const view = row.view;
591
+ const edge = (e) => Object.freeze(e);
592
+ const out = [];
593
+ const compared = since !== void 0;
594
+ const enteredPieces = new Set(since?.system.enteredIndexes ?? []);
595
+ const enteredMessages = new Set(since?.messages.enteredIndexes ?? []);
596
+ const stateOf = (entered) => compared ? entered ? "entered" : "unchanged" : void 0;
597
+ const withState = (state) => state !== void 0 ? { state } : {};
598
+ view.system.pieces.forEach((piece, i) => {
599
+ out.push(
600
+ edge({
601
+ id: `piece:${i}`,
602
+ kind: "piece",
603
+ slot: piece.slot,
604
+ source: piece.source,
605
+ origin: piece.source,
606
+ text: piece.text,
607
+ check: checks.pieces[i] ?? RECONSTRUCTED,
608
+ ...withState(stateOf(enteredPieces.has(i)))
609
+ })
610
+ );
611
+ });
612
+ (since?.system.leftPieces ?? []).forEach((piece, i) => {
613
+ out.push(
614
+ edge({
615
+ id: `piece-left:${i}`,
616
+ kind: "piece",
617
+ slot: piece.slot,
618
+ source: piece.source,
619
+ origin: piece.source,
620
+ text: piece.text,
621
+ // Not on this request at all: there is no row here for a hash to check.
622
+ check: NOT_ON_RECORD,
623
+ state: "left"
624
+ })
625
+ );
626
+ });
627
+ view.messages.asSent.forEach((message, i) => {
628
+ const label = message.toolName ?? message.toolCallId;
629
+ out.push(
630
+ edge({
631
+ id: `message:${i}`,
632
+ kind: "message",
633
+ slot: "messages",
634
+ role: message.role,
635
+ origin: message.role,
636
+ ...label !== void 0 ? { label } : {},
637
+ text: message.content,
638
+ check: checks.messages[i] ?? RECONSTRUCTED,
639
+ ...withState(stateOf(enteredMessages.has(i)))
640
+ })
641
+ );
642
+ });
643
+ (since?.messages.leftEntries ?? []).forEach((message, i) => {
644
+ out.push(
645
+ edge({
646
+ id: `message-left:${i}`,
647
+ kind: "message",
648
+ slot: "messages",
649
+ role: message.role,
650
+ origin: message.role,
651
+ text: message.content,
652
+ check: NOT_ON_RECORD,
653
+ state: "left"
654
+ })
655
+ );
656
+ });
657
+ view.messages.requestOnly.forEach((line, i) => {
658
+ out.push(
659
+ edge({
660
+ id: `request-only:${i}`,
661
+ kind: "request-only",
662
+ slot: "messages",
663
+ role: line.role,
664
+ origin: line.role,
665
+ label: line.reason,
666
+ text: line.text,
667
+ check: checks.requestOnly[i] ?? RECONSTRUCTED
668
+ })
669
+ );
670
+ });
671
+ view.tools.names.forEach((name) => {
672
+ const schema = view.tools.schemas.find((s) => s.name === name);
673
+ const state = compared ? since !== void 0 && since.tools.added.includes(name) ? "entered" : "unchanged" : void 0;
674
+ out.push(
675
+ edge({
676
+ id: `tool:${name}`,
677
+ kind: "tool",
678
+ slot: "tools",
679
+ label: name,
680
+ // No rebuilt schema means no hash on this side; a NAME is never
681
+ // verified — the receipt carries names as plain strings.
682
+ check: schema !== void 0 ? checks.toolSchemas[name] ?? RECONSTRUCTED : RECONSTRUCTED,
683
+ ...view.tools.forced === name ? { forced: true } : {},
684
+ ...checks.onReceiptOnly.schemas.includes(name) ? { schemaOnReceiptOnly: true } : {},
685
+ ...since !== void 0 && since.tools.schemaChanged.includes(name) ? { schemaChanged: true } : {},
686
+ ...withState(state)
687
+ })
688
+ );
689
+ });
690
+ (since?.tools.removed ?? []).forEach((name) => {
691
+ out.push(
692
+ edge({
693
+ id: `tool-left:${name}`,
694
+ kind: "tool",
695
+ slot: "tools",
696
+ label: name,
697
+ check: NOT_ON_RECORD,
698
+ state: "left"
699
+ })
700
+ );
701
+ });
702
+ return Object.freeze(out);
703
+ }
704
+ function slotNodes(input, edges) {
705
+ const { row, checks } = input;
706
+ const view = row.view;
707
+ const receipt = row.receipt;
708
+ const gapsFor = (slot) => Object.freeze(view.gaps.filter((g) => slotsOfFields(g.fields).includes(slot)));
709
+ const rebuiltIn = (slot) => edges.filter((e) => e.slot === slot && e.state !== "left").length;
710
+ const onReceipt = {
711
+ "system-prompt": receipt?.system.pieces.length,
712
+ messages: receipt !== void 0 ? receipt.messages.entries.length + receipt.messages.requestOnly.length : void 0,
713
+ tools: checks.namesOnReceipt?.length
714
+ };
715
+ const check2 = {
716
+ "system-prompt": checks.system,
717
+ messages: void 0,
718
+ tools: checks.toolNames
719
+ };
720
+ const onReceiptOnly = {
721
+ "system-prompt": checks.onReceiptOnly.pieces,
722
+ messages: checks.onReceiptOnly.messages + checks.onReceiptOnly.requestOnly,
723
+ tools: checks.onReceiptOnly.toolNames.length
724
+ };
725
+ const rebuiltOnly = {
726
+ "system-prompt": checks.rebuiltOnly.pieces,
727
+ messages: checks.rebuiltOnly.messages + checks.rebuiltOnly.requestOnly,
728
+ tools: checks.rebuiltOnly.toolNames.length
729
+ };
730
+ return Object.freeze(
731
+ SERVED_SLOTS.map((slot) => {
732
+ const aggregate = check2[slot];
733
+ const count = onReceipt[slot];
734
+ return Object.freeze({
735
+ slot,
736
+ ...aggregate !== void 0 ? { check: aggregate } : {},
737
+ rebuilt: rebuiltIn(slot),
738
+ ...count !== void 0 ? { onReceipt: count } : {},
739
+ onReceiptOnly: onReceiptOnly[slot],
740
+ rebuiltOnly: rebuiltOnly[slot],
741
+ gaps: gapsFor(slot)
742
+ });
743
+ })
744
+ );
745
+ }
746
+ function withheldNodes(input) {
747
+ const { row, fold } = input;
748
+ const view = row.view;
749
+ const out = [];
750
+ if (view.tools.withheld !== void 0) {
751
+ out.push(
752
+ Object.freeze({
753
+ kind: "tool-withheld",
754
+ name: view.tools.withheld,
755
+ from: "view",
756
+ slot: "tools"
757
+ })
758
+ );
759
+ }
760
+ for (const id of fold.hiddenSkillIds ?? []) {
761
+ out.push(Object.freeze({ kind: "hidden-skill", name: id, from: "fold" }));
762
+ }
763
+ for (const turn of row.evictedTurns ?? []) {
764
+ out.push(
765
+ Object.freeze({
766
+ kind: "attention-drop",
767
+ name: "omittedForAttention",
768
+ from: "receipt",
769
+ slot: "messages",
770
+ hash: turn.hash,
771
+ ...turn.lastServedOn !== void 0 ? { lastServedOn: turn.lastServedOn } : {}
772
+ })
773
+ );
774
+ }
775
+ if (input.checks.omittedForAttention === "not-on-record") {
776
+ out.push(
777
+ Object.freeze({
778
+ kind: "attention-drop",
779
+ name: "omittedForAttention",
780
+ from: "receipt",
781
+ status: "not-on-record"
782
+ })
783
+ );
784
+ }
785
+ if (fold.redacted) {
786
+ out.push(Object.freeze({ kind: "redacted", name: "redacted", from: "fold" }));
787
+ }
788
+ for (const gap of view.gaps) {
789
+ const slots = slotsOfFields(gap.fields);
790
+ out.push(
791
+ Object.freeze({
792
+ kind: "gap",
793
+ name: gap.gap,
794
+ from: "view",
795
+ // One slot named: draw it there. Several, or none: the band itself.
796
+ ...slots.length === 1 ? { slot: slots[0] } : {},
797
+ why: SERVED_GAPS2[gap.gap].why,
798
+ fields: gap.fields,
799
+ ...gap.cause !== void 0 ? { cause: gap.cause } : {}
800
+ })
801
+ );
802
+ }
803
+ return Object.freeze(out);
804
+ }
805
+ function callNode(input, edges) {
806
+ const { row, checks } = input;
807
+ const basis = row.view.basis;
808
+ return Object.freeze({
809
+ epoch: row.epoch,
810
+ callRuntimeStageId: row.callRuntimeStageId,
811
+ commitIdx: row.commitIdx,
812
+ betweenCalls: row.betweenCalls,
813
+ ...row.previousEpoch !== void 0 ? { previousEpoch: row.previousEpoch } : {},
814
+ ...basis !== void 0 ? { basis } : {},
815
+ basisStatus: basis !== void 0 ? "reconstructed" : "not-on-record",
816
+ // Present only where the receipt SAYS — a string or null. A receipt
817
+ // without the key (pre-9.93.0) leaves it absent: "cannot say".
818
+ ...row.receipt !== void 0 && carriesCacheStrategy(row.receipt) ? { cacheStrategy: row.receipt.cache.strategy } : {},
819
+ ...row.receiptCause !== void 0 ? { receiptCause: row.receiptCause } : {},
820
+ damaged: checks.damaged || edges.some((e) => e.check.status === "damaged")
821
+ });
822
+ }
823
+ function servedGraphAt(input) {
824
+ const edges = servedEdges(input);
825
+ return Object.freeze({
826
+ held: heldNodes(input.fold),
827
+ served: slotNodes(input, edges),
828
+ withheld: withheldNodes(input),
829
+ call: callNode(input, edges),
830
+ edges
831
+ });
832
+ }
833
+
489
834
  // src/core/utils/snapshotOfRunner.ts
490
835
  function snapshotOfRunner(runner) {
491
836
  const fn = runner?.getLastSnapshot;
@@ -590,6 +935,12 @@ export {
590
935
  sincePrevious,
591
936
  EXCUSING_GAPS,
592
937
  verify,
938
+ FOLD_FACT_KEYS,
939
+ foldFactsAt,
940
+ SERVED_SLOTS,
941
+ HELD_HONESTY_KEYS,
942
+ HELD_KEYS,
943
+ servedGraphAt,
593
944
  snapshotOfRunner,
594
945
  mountLogsOf,
595
946
  snapshotLogKey,
@@ -597,4 +948,4 @@ export {
597
948
  tagStopsFor,
598
949
  tagAxisPositions
599
950
  };
600
- //# sourceMappingURL=chunk-47W3TQT6.js.map
951
+ //# sourceMappingURL=chunk-37NHCNSS.js.map