agentfootprint-lens 0.19.0 → 0.20.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/{chunk-A2ELAEZX.js → chunk-N3YJKWK5.js} +125 -35
- package/dist/chunk-N3YJKWK5.js.map +1 -0
- package/dist/core.cjs +129 -41
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +76 -5
- package/dist/core.d.ts +76 -5
- package/dist/core.js +1 -1
- package/dist/index.cjs +136 -48
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-A2ELAEZX.js.map +0 -1
|
@@ -3,7 +3,11 @@ import {
|
|
|
3
3
|
} from "./chunk-KQOLJKKM.js";
|
|
4
4
|
|
|
5
5
|
// src/core/LensRecorder.ts
|
|
6
|
+
import { isDevMode } from "footprintjs";
|
|
6
7
|
import { SequenceStore } from "footprintjs/trace";
|
|
8
|
+
import {
|
|
9
|
+
ALL_EVENT_TYPES
|
|
10
|
+
} from "agentfootprint";
|
|
7
11
|
import { LiveStateRecorder, BoundaryRecorder } from "agentfootprint/observe";
|
|
8
12
|
import {
|
|
9
13
|
createTraceRuntimeOverlay
|
|
@@ -302,8 +306,9 @@ function relTime(runStartMs) {
|
|
|
302
306
|
}
|
|
303
307
|
|
|
304
308
|
// src/core/LensRecorder.ts
|
|
309
|
+
var KNOWN_EVENT_TYPES = new Set(ALL_EVENT_TYPES);
|
|
305
310
|
var LensRecorder = class {
|
|
306
|
-
constructor(rootLabel = "Run") {
|
|
311
|
+
constructor(rootLabel = "Run", options = {}) {
|
|
307
312
|
/** Stable id for idempotent attach. */
|
|
308
313
|
this.id = "lens";
|
|
309
314
|
/** Composition: ordered + keyed event-log storage. */
|
|
@@ -374,6 +379,15 @@ var LensRecorder = class {
|
|
|
374
379
|
* notifier. See `ChangeNotifier` JSDoc for adapter examples.
|
|
375
380
|
*/
|
|
376
381
|
this.notifier = new ChangeNotifier();
|
|
382
|
+
/** Per-type count of events outside the agentfootprint registry.
|
|
383
|
+
* Always maintained (debug only gates console output). */
|
|
384
|
+
this.unknownEventTypes = /* @__PURE__ */ new Map();
|
|
385
|
+
/** Count of `popIfKind` bracket mismatches. Always maintained. */
|
|
386
|
+
this.bracketMismatchCount = 0;
|
|
387
|
+
/** Unknown types already warned about — warn ONCE per type, not per
|
|
388
|
+
* event, so a chatty unknown emitter can't flood the console. */
|
|
389
|
+
this.warnedUnknownTypes = /* @__PURE__ */ new Set();
|
|
390
|
+
this.debug = options.debug;
|
|
377
391
|
this.root = {
|
|
378
392
|
id: "run-root",
|
|
379
393
|
kind: "run",
|
|
@@ -400,11 +414,44 @@ var LensRecorder = class {
|
|
|
400
414
|
this.finalStatus = "running";
|
|
401
415
|
this.runError = void 0;
|
|
402
416
|
this.lastRunId = void 0;
|
|
417
|
+
this.unknownEventTypes.clear();
|
|
418
|
+
this.bracketMismatchCount = 0;
|
|
419
|
+
this.warnedUnknownTypes.clear();
|
|
403
420
|
this.liveState.clear();
|
|
404
421
|
this.boundary.clear();
|
|
405
422
|
this.runtime.reset();
|
|
406
423
|
this.bumpVersion();
|
|
407
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Health counters for the observed event stream (backlog item U4).
|
|
427
|
+
* Always maintained — no debug flag needed — so UIs and tests can
|
|
428
|
+
* assert stream health without scraping the console:
|
|
429
|
+
*
|
|
430
|
+
* - `unknownEventTypes` — per-type counts of events whose `type` is
|
|
431
|
+
* not in agentfootprint's event registry (e.g. a newer
|
|
432
|
+
* agentfootprint emitting types this lens doesn't know, or a
|
|
433
|
+
* custom dispatcher leaking foreign events). These events are
|
|
434
|
+
* still attached to the current top node — counted, not dropped.
|
|
435
|
+
* - `bracketMismatches` — close events (`llm_end`, `tool_end`,
|
|
436
|
+
* `composition.exit`, ...) whose kind didn't match the top of the
|
|
437
|
+
* build stack (malformed ordering). The close is skipped; the
|
|
438
|
+
* tree stays partially structured rather than crashing.
|
|
439
|
+
*
|
|
440
|
+
* Both are `{}` / `0` on a well-formed run. Reset by `clear()`.
|
|
441
|
+
* Returns a fresh snapshot object on every call.
|
|
442
|
+
*/
|
|
443
|
+
getDiagnostics() {
|
|
444
|
+
return {
|
|
445
|
+
unknownEventTypes: Object.fromEntries(this.unknownEventTypes),
|
|
446
|
+
bracketMismatches: this.bracketMismatchCount
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
/** Whether diagnostic warnings go to the console: explicit option
|
|
450
|
+
* wins; otherwise follow footprintjs's global dev-mode flag
|
|
451
|
+
* (evaluated per event so `enableDevMode()` mid-run takes effect). */
|
|
452
|
+
debugEnabled() {
|
|
453
|
+
return this.debug ?? isDevMode();
|
|
454
|
+
}
|
|
408
455
|
/**
|
|
409
456
|
* The StepGraph the UI renders — agentfootprint's ReAct projection
|
|
410
457
|
* (actor-arrow steps with `iterationIndex` + `slotUpdated`, plus
|
|
@@ -555,6 +602,7 @@ var LensRecorder = class {
|
|
|
555
602
|
};
|
|
556
603
|
this.store.push(entry);
|
|
557
604
|
this.top().events.push(entry);
|
|
605
|
+
this.noteUnknownType(event.type);
|
|
558
606
|
this.dispatch(event, runOffsetMs, entry);
|
|
559
607
|
this.bumpVersion();
|
|
560
608
|
}
|
|
@@ -562,6 +610,21 @@ var LensRecorder = class {
|
|
|
562
610
|
bumpVersion() {
|
|
563
611
|
this.notifier.notify();
|
|
564
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* U4 diagnostics — count (and, in debug, warn ONCE per type about)
|
|
615
|
+
* event types outside agentfootprint's registry. One Set lookup per
|
|
616
|
+
* event on the happy path.
|
|
617
|
+
*/
|
|
618
|
+
noteUnknownType(type) {
|
|
619
|
+
if (KNOWN_EVENT_TYPES.has(type)) return;
|
|
620
|
+
this.unknownEventTypes.set(type, (this.unknownEventTypes.get(type) ?? 0) + 1);
|
|
621
|
+
if (this.debugEnabled() && !this.warnedUnknownTypes.has(type)) {
|
|
622
|
+
this.warnedUnknownTypes.add(type);
|
|
623
|
+
console.warn(
|
|
624
|
+
`[lens] LensRecorder: unknown event type '${type}' \u2014 not in agentfootprint's event registry. Attached to the current node without structural handling. (Warned once per type; counts in getDiagnostics().unknownEventTypes.)`
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
565
628
|
/**
|
|
566
629
|
* Kind-specific handling. Keeps the switch exhaustive over every v2
|
|
567
630
|
* event type we structurally care about; the default branch is the
|
|
@@ -586,10 +649,14 @@ var LensRecorder = class {
|
|
|
586
649
|
}
|
|
587
650
|
if (type === "agentfootprint.composition.exit") {
|
|
588
651
|
const p = event.payload;
|
|
589
|
-
this.popIfKind(
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
652
|
+
this.popIfKind(
|
|
653
|
+
"composition",
|
|
654
|
+
{
|
|
655
|
+
endOffsetMs: runOffsetMs,
|
|
656
|
+
status: p.status === "ok" ? "ok" : p.status === "budget_exhausted" ? "budget_exhausted" : "err"
|
|
657
|
+
},
|
|
658
|
+
entry.runtimeStageId
|
|
659
|
+
);
|
|
593
660
|
return;
|
|
594
661
|
}
|
|
595
662
|
if (type === "agentfootprint.composition.iteration_start") {
|
|
@@ -608,11 +675,15 @@ var LensRecorder = class {
|
|
|
608
675
|
}
|
|
609
676
|
if (type === "agentfootprint.composition.iteration_exit") {
|
|
610
677
|
const p = event.payload;
|
|
611
|
-
this.popIfKind(
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
678
|
+
this.popIfKind(
|
|
679
|
+
"iteration",
|
|
680
|
+
{
|
|
681
|
+
endOffsetMs: runOffsetMs,
|
|
682
|
+
status: p.reason === "budget" ? "budget_exhausted" : "ok",
|
|
683
|
+
iterationExit: p.reason
|
|
684
|
+
},
|
|
685
|
+
entry.runtimeStageId
|
|
686
|
+
);
|
|
616
687
|
return;
|
|
617
688
|
}
|
|
618
689
|
if (type === "agentfootprint.agent.turn_start") {
|
|
@@ -629,7 +700,7 @@ var LensRecorder = class {
|
|
|
629
700
|
return;
|
|
630
701
|
}
|
|
631
702
|
if (type === "agentfootprint.agent.turn_end") {
|
|
632
|
-
this.popIfKind("iteration", { endOffsetMs: runOffsetMs, status: "ok" });
|
|
703
|
+
this.popIfKind("iteration", { endOffsetMs: runOffsetMs, status: "ok" }, entry.runtimeStageId);
|
|
633
704
|
return;
|
|
634
705
|
}
|
|
635
706
|
if (type === "agentfootprint.agent.iteration_start") {
|
|
@@ -647,7 +718,7 @@ var LensRecorder = class {
|
|
|
647
718
|
return;
|
|
648
719
|
}
|
|
649
720
|
if (type === "agentfootprint.agent.iteration_end") {
|
|
650
|
-
this.popIfKind("iteration", { endOffsetMs: runOffsetMs, status: "ok" });
|
|
721
|
+
this.popIfKind("iteration", { endOffsetMs: runOffsetMs, status: "ok" }, entry.runtimeStageId);
|
|
651
722
|
return;
|
|
652
723
|
}
|
|
653
724
|
if (type === "agentfootprint.stream.llm_start") {
|
|
@@ -674,16 +745,20 @@ var LensRecorder = class {
|
|
|
674
745
|
}
|
|
675
746
|
if (type === "agentfootprint.stream.llm_end") {
|
|
676
747
|
const p = event.payload;
|
|
677
|
-
this.popIfKind(
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
748
|
+
this.popIfKind(
|
|
749
|
+
"llm-call",
|
|
750
|
+
{
|
|
751
|
+
endOffsetMs: runOffsetMs,
|
|
752
|
+
status: "ok",
|
|
753
|
+
llmEnd: {
|
|
754
|
+
content: p.content,
|
|
755
|
+
toolCallCount: p.toolCallCount,
|
|
756
|
+
usage: p.usage,
|
|
757
|
+
stopReason: p.stopReason
|
|
758
|
+
}
|
|
759
|
+
},
|
|
760
|
+
entry.runtimeStageId
|
|
761
|
+
);
|
|
687
762
|
return;
|
|
688
763
|
}
|
|
689
764
|
if (type === "agentfootprint.stream.tool_start") {
|
|
@@ -708,11 +783,15 @@ var LensRecorder = class {
|
|
|
708
783
|
}
|
|
709
784
|
if (type === "agentfootprint.stream.tool_end") {
|
|
710
785
|
const p = event.payload;
|
|
711
|
-
this.popIfKind(
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
786
|
+
this.popIfKind(
|
|
787
|
+
"tool-call",
|
|
788
|
+
{
|
|
789
|
+
endOffsetMs: runOffsetMs,
|
|
790
|
+
status: p.error === true ? "err" : "ok",
|
|
791
|
+
toolEnd: { result: p.result, error: p.error ?? false }
|
|
792
|
+
},
|
|
793
|
+
entry.runtimeStageId
|
|
794
|
+
);
|
|
716
795
|
return;
|
|
717
796
|
}
|
|
718
797
|
if (type === "agentfootprint.pause.request") {
|
|
@@ -748,12 +827,23 @@ var LensRecorder = class {
|
|
|
748
827
|
}
|
|
749
828
|
/**
|
|
750
829
|
* Pop the top node IF its kind matches, applying finalization fields.
|
|
751
|
-
* Mismatched kinds (indicating malformed event ordering) are
|
|
752
|
-
*
|
|
830
|
+
* Mismatched kinds (indicating malformed event ordering) are SKIPPED,
|
|
831
|
+
* never thrown — Lens prefers partial correctness to crashes. Every
|
|
832
|
+
* mismatch increments `getDiagnostics().bracketMismatches` (U4), and
|
|
833
|
+
* when debug is on (`LensRecorderOptions.debug` or footprintjs
|
|
834
|
+
* `isDevMode()`) each mismatch logs a `console.warn` with the
|
|
835
|
+
* expected vs found kind plus the closing event's `runtimeStageId`.
|
|
836
|
+
* Well-formed runs stay console-silent either way.
|
|
753
837
|
*/
|
|
754
|
-
popIfKind(kind, finalize) {
|
|
838
|
+
popIfKind(kind, finalize, runtimeStageId) {
|
|
755
839
|
const top = this.top();
|
|
756
840
|
if (top.kind !== kind) {
|
|
841
|
+
this.bracketMismatchCount += 1;
|
|
842
|
+
if (this.debugEnabled()) {
|
|
843
|
+
console.warn(
|
|
844
|
+
`[lens] LensRecorder: bracket mismatch \u2014 tried to close a '${kind}' node but the top of the stack is '${top.kind}'` + (runtimeStageId !== void 0 ? ` (runtimeStageId: ${runtimeStageId})` : "") + `. Close event skipped; the tree stays partially structured.`
|
|
845
|
+
);
|
|
846
|
+
}
|
|
757
847
|
return;
|
|
758
848
|
}
|
|
759
849
|
top.endOffsetMs = finalize.endOffsetMs;
|
|
@@ -909,8 +999,8 @@ function buildDetails(n) {
|
|
|
909
999
|
}
|
|
910
1000
|
return void 0;
|
|
911
1001
|
}
|
|
912
|
-
function lensRecorder(rootLabel) {
|
|
913
|
-
return new LensRecorder(rootLabel);
|
|
1002
|
+
function lensRecorder(rootLabel, options) {
|
|
1003
|
+
return new LensRecorder(rootLabel, options);
|
|
914
1004
|
}
|
|
915
1005
|
|
|
916
1006
|
// src/core/buildStepGraphFromSnapshot.ts
|
|
@@ -1618,7 +1708,7 @@ function makeEdge(kind, source, target, options = {}) {
|
|
|
1618
1708
|
}
|
|
1619
1709
|
|
|
1620
1710
|
// src/core/translate/helpers/mergeOutputs.ts
|
|
1621
|
-
import { isDevMode } from "footprintjs";
|
|
1711
|
+
import { isDevMode as isDevMode2 } from "footprintjs";
|
|
1622
1712
|
function mergeOutputs(outputs, rootNodeId) {
|
|
1623
1713
|
const nodes = [];
|
|
1624
1714
|
const edges = [];
|
|
@@ -1626,7 +1716,7 @@ function mergeOutputs(outputs, rootNodeId) {
|
|
|
1626
1716
|
for (const n of o.nodes) nodes.push(n);
|
|
1627
1717
|
for (const e of o.edges) edges.push(e);
|
|
1628
1718
|
}
|
|
1629
|
-
if (
|
|
1719
|
+
if (isDevMode2()) assertNoCollisions(nodes, edges);
|
|
1630
1720
|
return { nodes, edges, rootNodeId };
|
|
1631
1721
|
}
|
|
1632
1722
|
function assertNoCollisions(nodes, edges) {
|
|
@@ -2295,4 +2385,4 @@ export {
|
|
|
2295
2385
|
defaultSize,
|
|
2296
2386
|
layoutLensGraph
|
|
2297
2387
|
};
|
|
2298
|
-
//# sourceMappingURL=chunk-
|
|
2388
|
+
//# sourceMappingURL=chunk-N3YJKWK5.js.map
|