agentfootprint 2.14.0 → 2.14.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.
Files changed (40) hide show
  1. package/dist/conventions.js +13 -2
  2. package/dist/conventions.js.map +1 -1
  3. package/dist/core/agent/buildAgentChart.js +3 -3
  4. package/dist/core/agent/buildAgentChart.js.map +1 -1
  5. package/dist/esm/conventions.js +13 -2
  6. package/dist/esm/conventions.js.map +1 -1
  7. package/dist/esm/core/agent/buildAgentChart.js +3 -3
  8. package/dist/esm/core/agent/buildAgentChart.js.map +1 -1
  9. package/dist/esm/index.js +1 -0
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/observe.js +1 -0
  12. package/dist/esm/observe.js.map +1 -1
  13. package/dist/esm/recorders/observability/BoundaryRecorder.js +27 -2
  14. package/dist/esm/recorders/observability/BoundaryRecorder.js.map +1 -1
  15. package/dist/esm/recorders/observability/FlowchartRecorder.js +29 -0
  16. package/dist/esm/recorders/observability/FlowchartRecorder.js.map +1 -1
  17. package/dist/esm/recorders/observability/LiveStateRecorder.js +302 -0
  18. package/dist/esm/recorders/observability/LiveStateRecorder.js.map +1 -0
  19. package/dist/index.js +9 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/observe.js +7 -1
  22. package/dist/observe.js.map +1 -1
  23. package/dist/recorders/observability/BoundaryRecorder.js +27 -2
  24. package/dist/recorders/observability/BoundaryRecorder.js.map +1 -1
  25. package/dist/recorders/observability/FlowchartRecorder.js +29 -0
  26. package/dist/recorders/observability/FlowchartRecorder.js.map +1 -1
  27. package/dist/recorders/observability/LiveStateRecorder.js +310 -0
  28. package/dist/recorders/observability/LiveStateRecorder.js.map +1 -0
  29. package/dist/types/conventions.d.ts +13 -2
  30. package/dist/types/conventions.d.ts.map +1 -1
  31. package/dist/types/index.d.ts +1 -0
  32. package/dist/types/index.d.ts.map +1 -1
  33. package/dist/types/observe.d.ts +1 -0
  34. package/dist/types/observe.d.ts.map +1 -1
  35. package/dist/types/recorders/observability/BoundaryRecorder.d.ts.map +1 -1
  36. package/dist/types/recorders/observability/FlowchartRecorder.d.ts +9 -0
  37. package/dist/types/recorders/observability/FlowchartRecorder.d.ts.map +1 -1
  38. package/dist/types/recorders/observability/LiveStateRecorder.d.ts +215 -0
  39. package/dist/types/recorders/observability/LiveStateRecorder.d.ts.map +1 -0
  40. package/package.json +3 -3
@@ -0,0 +1,215 @@
1
+ /**
2
+ * LiveStateRecorder — domain trackers built on the footprintjs
3
+ * `BoundaryStateTracker<TState>` storage primitive (v4.17.2+).
4
+ *
5
+ * **What this answers:** "Right now, mid-run, what's happening?"
6
+ *
7
+ * - Is an LLM call in flight? What's the partial answer so far?
8
+ * - Is a tool executing? Which tool? What args?
9
+ * - Is the agent in a turn? Which turn index?
10
+ *
11
+ * All reads are O(1) — the trackers maintain incremental state via
12
+ * the framework's bracket-scoped storage primitive. No event-log fold,
13
+ * no walking arrays per render.
14
+ *
15
+ * **Mental model — observers vs. bookkeepers:**
16
+ *
17
+ * `BoundaryStateTracker<TState>` (footprintjs) = STORAGE shelf.
18
+ * `EventDispatcher.on(...)` (agentfootprint) = OBSERVER source.
19
+ *
20
+ * Each domain tracker (`LiveLLMTracker`, `LiveToolTracker`,
21
+ * `LiveAgentTurnTracker`) extends the storage shelf AND subscribes
22
+ * to the dispatcher. The composition `LiveStateRecorder` bundles
23
+ * all three so a consumer only attaches once.
24
+ *
25
+ * **Tier 1 (live) only.** Past states are not stored — when a boundary
26
+ * closes, its transient state clears. For time-travel queries, snapshot
27
+ * to a `SequenceRecorder<TState>` instead. See the BoundaryStateTracker
28
+ * JSDoc for the rationale.
29
+ *
30
+ * @example Use the bundled façade — one attach, three live views:
31
+ *
32
+ * ```typescript
33
+ * import { LiveStateRecorder } from 'agentfootprint';
34
+ *
35
+ * const liveState = new LiveStateRecorder();
36
+ * liveState.subscribe(runner);
37
+ *
38
+ * await runner.run({ input });
39
+ *
40
+ * // Read at any moment during the run (e.g., from another async task):
41
+ * liveState.isLLMInFlight(); // true between llm_start ↔ llm_end
42
+ * liveState.getPartialLLM(); // accumulated tokens so far
43
+ * liveState.isToolExecuting(); // true between tool_start ↔ tool_end
44
+ * liveState.isAgentInTurn(); // true between turn_start ↔ turn_end
45
+ *
46
+ * liveState.unsubscribe();
47
+ * ```
48
+ *
49
+ * @example Use a single tracker directly when you only need one slice:
50
+ *
51
+ * ```typescript
52
+ * import { LiveLLMTracker } from 'agentfootprint';
53
+ *
54
+ * const llm = new LiveLLMTracker();
55
+ * llm.subscribe(runner);
56
+ * await runner.run({ input });
57
+ *
58
+ * llm.isInFlight(); // O(1)
59
+ * llm.getLatestPartial(); // most recent active call's partial
60
+ * llm.getActive(rid)?.tokens; // tokens accumulated for one call
61
+ * ```
62
+ */
63
+ import { BoundaryStateTracker } from 'footprintjs/trace';
64
+ import type { Unsubscribe } from '../../events/dispatcher.js';
65
+ import type { AgentfootprintEvent, AgentfootprintEventType } from '../../events/registry.js';
66
+ /** Minimal Runner shape this recorder needs — only the public `on(...)`
67
+ * subscription method, so the same trackers can attach to a real Runner
68
+ * (Agent, etc.) OR to a test mock without exposing the protected
69
+ * internal dispatcher. */
70
+ export interface LiveStateRunnerLike {
71
+ on<K extends AgentfootprintEventType>(type: K, listener: (event: Extract<AgentfootprintEvent, {
72
+ type: K;
73
+ }>) => void): Unsubscribe;
74
+ }
75
+ /** Live transient state of one in-flight LLM call. */
76
+ export interface LLMLiveState {
77
+ /** Accumulated content from `stream.token` events since `llm_start`. */
78
+ readonly partial: string;
79
+ /** Number of tokens received so far. */
80
+ readonly tokens: number;
81
+ /** Iteration index (from the LLMStartPayload). */
82
+ readonly iteration: number;
83
+ /** Provider name (e.g., 'anthropic', 'openai'). */
84
+ readonly provider: string;
85
+ /** Model id. */
86
+ readonly model: string;
87
+ /** Wall-clock ms when llm_start fired. */
88
+ readonly startedAtMs: number;
89
+ }
90
+ /** Live transient state of one in-flight tool call. */
91
+ export interface ToolLiveState {
92
+ readonly toolName: string;
93
+ readonly args: Readonly<Record<string, unknown>>;
94
+ readonly toolCallId: string;
95
+ readonly startedAtMs: number;
96
+ }
97
+ /** Live transient state of one in-flight agent turn. */
98
+ export interface AgentTurnLiveState {
99
+ readonly turnIndex: number;
100
+ readonly userPrompt: string;
101
+ readonly startedAtMs: number;
102
+ }
103
+ /**
104
+ * Tracks the in-flight state of LLM calls. Subscribes to:
105
+ * - `agentfootprint.stream.llm_start` → opens a boundary
106
+ * - `agentfootprint.stream.token` → appends to partial
107
+ * - `agentfootprint.stream.llm_end` → closes the boundary
108
+ *
109
+ * Boundary key: `runtimeStageId` of the call-llm stage. Parallel LLM
110
+ * calls (Parallel composition with multiple branches) get distinct
111
+ * keys and are tracked independently.
112
+ */
113
+ export declare class LiveLLMTracker extends BoundaryStateTracker<LLMLiveState> {
114
+ readonly id = "live-llm";
115
+ /** Subscribe to a runner's dispatcher. Returns an Unsubscribe. */
116
+ subscribe(runner: LiveStateRunnerLike): Unsubscribe;
117
+ /** True if any LLM call is currently in flight. Same as `hasActive`. */
118
+ isInFlight(): boolean;
119
+ /** Accumulated partial content of the MOST RECENTLY started active
120
+ * LLM call. Empty string when no call is active. Useful for the
121
+ * classic "Chatbot is responding: …" live commentary line. */
122
+ getLatestPartial(): string;
123
+ }
124
+ /**
125
+ * Tracks in-flight tool calls. Subscribes to:
126
+ * - `agentfootprint.stream.tool_start` → opens a boundary
127
+ * - `agentfootprint.stream.tool_end` → closes the boundary
128
+ *
129
+ * Boundary key: `toolCallId` (more granular than `runtimeStageId` —
130
+ * parallel tools share one calling stage but have distinct toolCallIds).
131
+ */
132
+ export declare class LiveToolTracker extends BoundaryStateTracker<ToolLiveState> {
133
+ readonly id = "live-tool";
134
+ subscribe(runner: LiveStateRunnerLike): Unsubscribe;
135
+ /** True if any tool is currently executing. */
136
+ isExecuting(): boolean;
137
+ /** Names of tools currently executing. Empty when none. */
138
+ getExecutingToolNames(): readonly string[];
139
+ }
140
+ /**
141
+ * Tracks in-flight agent turns. Subscribes to:
142
+ * - `agentfootprint.agent.turn_start` → opens a boundary
143
+ * - `agentfootprint.agent.turn_end` → closes the boundary
144
+ *
145
+ * Boundary key: stringified `turnIndex` from the payload — survives
146
+ * across runner instances because turnIndex resets per-session.
147
+ */
148
+ export declare class LiveAgentTurnTracker extends BoundaryStateTracker<AgentTurnLiveState> {
149
+ readonly id = "live-agent-turn";
150
+ subscribe(runner: LiveStateRunnerLike): Unsubscribe;
151
+ /** True if the agent is currently inside a turn. */
152
+ isInTurn(): boolean;
153
+ /** Index of the most-recently started active turn (-1 if none). */
154
+ getCurrentTurnIndex(): number;
155
+ }
156
+ /**
157
+ * One-stop façade bundling `LiveLLMTracker` + `LiveToolTracker` +
158
+ * `LiveAgentTurnTracker`. Consumers attach this once and get O(1)
159
+ * reads across all three live-state slices.
160
+ *
161
+ * Use the bundled façade unless you ONLY need one slice — using a
162
+ * single tracker directly avoids subscribing to events you don't read.
163
+ *
164
+ * **Lifecycle**: call `subscribe(runner)` to wire all three trackers,
165
+ * then `unsubscribe()` to detach. `clear()` resets all transient state
166
+ * across the three (called automatically by consumers like Lens between
167
+ * runs).
168
+ *
169
+ * **What this is NOT for:**
170
+ * - Time-travel queries (Tier 1 only — live state)
171
+ * - Aggregations (use SequenceRecorder.aggregate)
172
+ * - Stage-level observation (use Recorder.onStageStart/End)
173
+ *
174
+ * **Composition over inheritance:** the façade does NOT extend
175
+ * `BoundaryStateTracker` itself — different boundary kinds need
176
+ * separate active maps to avoid key collisions between LLM and tool
177
+ * boundaries. Each sub-tracker keeps its own state.
178
+ */
179
+ export declare class LiveStateRecorder {
180
+ readonly id = "live-state";
181
+ /** LLM call live state. */
182
+ readonly llm: LiveLLMTracker;
183
+ /** Tool execution live state. */
184
+ readonly tool: LiveToolTracker;
185
+ /** Agent turn live state. */
186
+ readonly turn: LiveAgentTurnTracker;
187
+ /** Active subscription disposer, if `subscribe()` is called. */
188
+ private active;
189
+ constructor();
190
+ /** Subscribe all three trackers to one runner. Idempotent — calling
191
+ * twice on the same recorder unsubscribes the prior subscription
192
+ * first to avoid double-counting. */
193
+ subscribe(runner: LiveStateRunnerLike): Unsubscribe;
194
+ /** Detach all three trackers from the current runner. Idempotent. */
195
+ unsubscribe(): void;
196
+ /** Reset transient state across all three trackers. Called by the
197
+ * executor / consumer between runs. */
198
+ clear(): void;
199
+ /** True if any LLM call is currently in flight. */
200
+ isLLMInFlight(): boolean;
201
+ /** Accumulated partial content of the most-recently started LLM call. */
202
+ getPartialLLM(): string;
203
+ /** True if any tool is currently executing. */
204
+ isToolExecuting(): boolean;
205
+ /** Names of tools currently executing. */
206
+ getExecutingToolNames(): readonly string[];
207
+ /** True if the agent is currently inside a turn. */
208
+ isAgentInTurn(): boolean;
209
+ /** Current turn index (-1 if not in a turn). */
210
+ getCurrentTurnIndex(): number;
211
+ }
212
+ /** Convenience factory — same shape as `boundaryRecorder()` /
213
+ * `topologyRecorder()` / `inOutRecorder()` in footprintjs. */
214
+ export declare function liveStateRecorder(): LiveStateRecorder;
215
+ //# sourceMappingURL=LiveStateRecorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LiveStateRecorder.d.ts","sourceRoot":"","sources":["../../../../src/recorders/observability/LiveStateRecorder.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentfootprint",
3
- "version": "2.14.0",
3
+ "version": "2.14.2",
4
4
  "description": "The explainable agent framework — build AI agents you can explain, audit, and trust. Built on footprintjs.",
5
5
  "license": "MIT",
6
6
  "author": "Sanjay Krishna Anbalagan",
@@ -184,7 +184,7 @@
184
184
  "@aws-sdk/client-xray": "*",
185
185
  "@modelcontextprotocol/sdk": "*",
186
186
  "@opentelemetry/api": "*",
187
- "footprintjs": ">=4.17.1",
187
+ "footprintjs": ">=4.17.2",
188
188
  "ioredis": "*",
189
189
  "openai": "*",
190
190
  "zod": "*"
@@ -228,7 +228,7 @@
228
228
  "@vitest/coverage-v8": "^4.1.5",
229
229
  "eslint": "^8.44.0",
230
230
  "eslint-config-prettier": "^6.15.0",
231
- "footprintjs": "^4.17.1",
231
+ "footprintjs": "^4.17.2",
232
232
  "prettier": "^2.8.1",
233
233
  "typedoc": "^0.28.19",
234
234
  "typedoc-plugin-markdown": "^4.11.0",