agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
153 lines • 11 kB
JavaScript
/**
* agentfootprint/observe — observability recorders.
*
* Pattern: Observer (GoF) — pluggable, fire-and-forget event listeners
* for the agent's typed event stream.
* Role: Outer ring (Hexagonal). Attach via `runner.attachScopeRecorder()`;
* the runner emits events, recorders accumulate state.
*
* Three tiers (progressive disclosure):
*
* Tier 1 — context + stream (the core)
* • ContextRecorder — every slot composition
* • StreamRecorder — token-level LLM streaming
*
* Tier 2 — composition + agent (structural nav)
* • CompositionRecorder — Sequence/Parallel/Conditional/Loop entries
* • AgentRecorder — agent-loop iterations, tool calls
* • BoundaryRecorder — domain-tagged subflow entry/exit
* • FlowchartRecorder — StepGraph projection (Lens-friendly)
*
* Tier 3 — domain dashboards (attach on demand)
* • CostRecorder — token/USD spend
* • EvalRecorder — eval scores from `runner.emit('eval.*', ...)`
* • MemoryRecorder — memory injections + writes
* • EmbeddingRecorder — embedding cost, index-time vs query-time
* • PermissionRecorder — permission decisions + denials
* • SkillRecorder — skill activations
* • LoggingRecorder — structured log lines per event
* • StatusRecorder — chat-bubble first-person status
*
* Domain-flavored consumers (Lens, Grafana, Datadog) compose Tier 1+2
* directly; Tier 3 dashboards are opt-in.
*/
// Tier 1 — context + stream
export { ContextRecorder } from './recorders/core/ContextRecorder.js';
export { streamRecorder } from './recorders/core/StreamRecorder.js';
// Tier 2 — composition + agent
export { compositionRecorder, } from './recorders/core/CompositionRecorder.js';
export { agentRecorder } from './recorders/core/AgentRecorder.js';
export { boundaryRecorder, BoundaryRecorder, } from './recorders/observability/BoundaryRecorder.js';
export { RunStepRecorder, runStepRecorder, } from './recorders/observability/RunStepRecorder.js';
export { attachFlowchart, buildStepGraph, buildStepGraphFromEvents, } from './recorders/observability/FlowchartRecorder.js';
// recordRun — save a run so a viewer can show it later. THE producer for
// `{ snapshot, events, structure }`: the timeline, the state, and the chart,
// which is the shape the UIs consume (lens's `observeRecording`) and the one
// every integration used to assemble by hand, each missing a different piece.
export { recordRun, } from './recorders/observability/recordRun.js';
// A recording with every repeated value written ONCE — what to store or send
// when the run is long: plain JSON repeats the history once per place that
// saw it (K²·R), packed it grows with K·R. `unpackRecording` reads both
// shapes, so a reader that calls it reads every recording ever minted — and
// expands a packed one only when the plain recording it stands for is within
// `maxBytes` (default `DEFAULT_UNPACK_MAX_BYTES`).
export { packRecording, unpackRecording, isPackedRecording, PACKED_RECORDING_FORMAT, DEFAULT_UNPACK_MAX_BYTES, PackedRecordingError, PackedRecordingTooLargeError, } from './recorders/observability/recordingPack.js';
// Runtime selected-policy evidence: typed subscription only, with one bounded
// capture owner. recordRun can own its lifecycle and snapshot bundle.
export { trustBoundaryRecorder, } from './trust-boundaries/index.js';
// accountForAnswer — "Explain this answer": one answer's recording (plus what
// the app declared) in, a typed account out — facts, each with who vouches for
// it and where it lives in the record, and fixed sentences from a closed,
// versioned template table. Pure and read-time: no clock, network or model.
// See src/answer-account/README.md.
// `answerAccountPointerKey(pointer)` is the key of the `shown` map the hosting
// op `{ op: 'answer-account', ref }` returns beside the account.
export { accountForAnswer, answerAccountPointerKey, } from './answer-account/index.js';
// assessAnswer — the answer's STANDING, folded from the run's committed record:
// known · consistent with the record · not sure (with the reasons) · ask · not
// assessed. Never read from how sure the model sounds, never "known" from
// silence, never from events. The account's "How sure" row renders the same
// fold. ONE public type; its family (a reason, a witness, a check that ran) by
// indexed access. See src/core/agent/assessment/README.md.
export { assessAnswer } from './core/agent/assessment/assess.js';
// The recording ENVELOPE — the versioned contract that makes a recording
// archivable. `recordRun` freezes a run; this states which run it is, how much
// of it this is, who produced it and under what privacy policy, so a saved run
// can be filed, attached to a bug report, or read by an analysis tool without
// every consumer inventing its own wrapper. Every field is derived from the
// run's own events or stated by the caller — never guessed.
export { buildRecordingEnvelope, persistRecording, FULL_PRIVACY_POLICY_ID, RECORDING_ENVELOPE_FORMAT, IndeterminateRunFactError, UnsupportedPrivacyModeError, } from './recorders/observability/recordingEnvelope.js';
// The reference sink: one archived run per JSON file, written atomically
// (tmp + rename) so a crash never leaves a half-parsed archive. The file name
// derives from the run id, which makes it a key — hence the asserted safe
// charset and `UnsafeRecordingIdError` rather than a hopeful `${runId}.json`.
export { fileRecordingSink, recordingFileName, UnsafeRecordingIdError, } from './recorders/observability/fileRecordingSink.js';
// exportBugReport — a bug report IS the evidence. `describeBugReport` measures
// the run first (selectable units, sizes, the redacted keys by NAME) so a human
// can consent to exactly what leaves; `exportBugReport` bundles the units they
// kept as named files plus a real (stored) zip. `githubBugReporter` — in this
// same door, from the providers barrel — files that bundle.
//
// The evidence in that zip is a RecordingEnvelope (bundle layout 2), built by
// the same `buildRecordingEnvelope` above rather than a second wrapper — so the
// producer facts are stamped once. `BugReportRunFacts` is the pair the envelope
// cannot derive; without it the bundle still ships, as the bare recording, with
// the manifest naming the fact that was missing.
export { describeBugReport, exportBugReport, } from './bug-report/index.js';
// What a recording keeps of a vector: `{ dims, norm }`, not the bytes (8.20.0).
// Applied by BoundaryRecorder and recordRun unless `recordEmbeddings: true`;
// exported so consumers that render or post-process recordings can apply or
// recognise the same projection.
export { summarizeEmbeddings, summarizeVector, } from './recorders/observability/embeddingSummary.js';
// Offline replay: freeze a live run model into a UI-free, JSON-lossless Trace
// (redaction applied at the serialize boundary). agentfootprint-lens's <Replay>
// rehydrates it. See docs/design/local-observability-and-pii.md.
export { serializeTrace, redactContent, traceToStepGraph, } from './recorders/observability/trace.js';
// localObservability — Tier-3 retain: live onLive(graph) + offline
// getTrace()/onRecorded. NOT a Lens recorder — to render a run in Lens, use
// `recordRun` above and lens's `observeRecording`.
export { attachLocalObservability, } from './recorders/observability/localObservability.js';
export { liveStateRecorder, LiveStateRecorder, LiveLLMTracker, LiveToolTracker, LiveAgentTurnTracker, } from './recorders/observability/LiveStateRecorder.js';
// Tier 3 — domain dashboards
export { costRecorder } from './recorders/core/CostRecorder.js';
export { toolsRecorder } from './recorders/core/ToolsRecorder.js';
export { contextEvaluatedRecorder, } from './recorders/core/ContextEvaluatedRecorder.js';
export { evalRecorder } from './recorders/core/EvalRecorder.js';
export { memoryRecorder } from './recorders/core/MemoryRecorder.js';
export { embeddingRecorder, } from './recorders/core/EmbeddingRecorder.js';
export { permissionRecorder, } from './recorders/core/PermissionRecorder.js';
export { skillRecorder } from './recorders/core/SkillRecorder.js';
// Provider-decorator telemetry (fallback.triggered / error.retried /
// error.recovered / error.circuit_changed). Attached automatically by
// Agent / LLMCall / Parallel;
// exported so consumers running the public message-api charts on a bare
// FlowChartExecutor can wire the bridge themselves.
export { resilienceRecorder, } from './recorders/core/ResilienceRecorder.js';
export { attachLogging, LoggingDomains, } from './recorders/observability/LoggingRecorder.js';
export { attachStatus, } from './recorders/observability/StatusRecorder.js';
// Tool→tool DATA-FLOW graph, derived by value provenance from the tool emit
// stream (see finding 2: causalChain can't see LLM-mediated tool dependencies).
export { toolLineageRecorder, } from './recorders/observability/ToolLineageRecorder.js';
// AgentThinkingUI Trace (run → the "watch it think" beat list, collected during
// traversal). Lets any agentfootprint run drive AgentThinkingUI / domain views.
export { agentThinkingTrace, } from './recorders/observability/AgentThinkingTraceRecorder.js';
// Emit primitive — used by every Tier-3 source-domain.
export { typedEmit } from './recorders/core/typedEmit.js';
// ── Diagnosis tools ────────────────────────────────────────────
// influence-core, trace-toolpack, context-bisect and tool-lint live in
// `src/debug.ts`. 8.0.0 folded their import path INTO this one, and 9.0.0
// removed the separate `agentfootprint/debug` subpath, so this re-export is
// how they reach the door. Watching a healthy run and performing the autopsy
// on a broken one come through the same door on purpose.
export * from './debug.js';
// Tool-choice margin recorder (RFC-002 tier 2, C4–C6) — per LLM call,
// ranks the OFFERED catalog against the choice context (user message +
// latest assistant reasoning) via influence-core scoreMargin; embeds
// LAZILY on first read; flags narrow margins + proxy disagreements.
export { buildChoiceContext, toolChoiceRecorder, } from './recorders/observability/ToolChoiceRecorder.js';
export { routeRecorder, formatRouteHop, } from './recorders/observability/RouteRecorder.js';
// context-ledger — which context pieces EARNED their tokens? Post-run
// bookkeeping (offers/uses/outcomes from the commit log) feeding the gating
// seams. See src/context-ledger/README.md.
export { contextLedger, ledgerToolGate, ledgerEntryScorer, ledgerGated, } from './context-ledger/index.js';
//# sourceMappingURL=observe.js.map