agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
92 lines (91 loc) • 3.88 kB
TypeScript
/**
* LoggingRecorder — firehose-style structured logging of every event.
*
* Pattern: Facade over EventDispatcher's wildcard subscription.
* Role: Tier 3 observability — the low-level helper behind
* `attachLogging(dispatcher, {...})` (exported from
* `agentfootprint/observe`). For the high-level, uniform path use
* `agent.enable.observability({ strategy: consoleObservability() })`.
* Developer debugging tool; production typically uses an OTEL
* recorder instead.
* Emits: Does NOT emit; READS the dispatcher and writes to the logger.
*
* Filtering: consumer picks DOMAINS by name — the same domain segment that
* appears in event types (`agentfootprint.<domain>.<action>`). No internal
* tier jargon leaks into the public API.
*/
import type { EventDispatcher, Unsubscribe } from '../../events/dispatcher.js';
import type { AgentfootprintEvent } from '../../events/registry.js';
/**
* Minimal logger shape — structurally compatible with console, winston,
* pino, etc. Consumers pass their existing logger.
*/
export interface LoggingLogger {
log(message: string, data?: unknown): void;
}
/**
* Domain constants — one per event-registry domain. Use these instead of
* raw strings for autocomplete, typo protection, and rename safety.
*
* Raw strings still work (backed by the same literal union type below).
*
* @example
* attachLogging(dispatcher, { domains: [LoggingDomains.CONTEXT, LoggingDomains.STREAM] });
* attachLogging(dispatcher, { domains: ['context', 'stream'] }); // equivalent
*/
export declare const LoggingDomains: {
/** Context-engineering events (the 3-slot model). THE DEBUG CORE. */
readonly CONTEXT: "context";
/** LLM + tool request/response stream. */
readonly STREAM: "stream";
/** Composition control flow (Sequence / Parallel / Conditional / Loop). */
readonly COMPOSITION: "composition";
/** Agent lifecycle (turn · iteration · route_decided · handoff). */
readonly AGENT: "agent";
/** Memory strategy + store operations. */
readonly MEMORY: "memory";
/** Tool offered / activated / deactivated. */
readonly TOOLS: "tools";
/** Skill activation + deactivation. */
readonly SKILL: "skill";
/** Permission checks + gates. */
readonly PERMISSION: "permission";
/** Risk / guardrail detections. */
readonly RISK: "risk";
/** Provider / tool / skill fallback triggers. */
readonly FALLBACK: "fallback";
/** Cost + budget tracking. */
readonly COST: "cost";
/** Eval scores + threshold crossings. */
readonly EVAL: "eval";
/** Error retries + recoveries. */
readonly ERROR: "error";
/** Pause / resume requests. */
readonly PAUSE: "pause";
/** Embedding generation. */
readonly EMBEDDING: "embedding";
};
/**
* Domain name — the middle segment of event types
* (`agentfootprint.<domain>.<action>`). Consumers already see these in
* the events they subscribe to; reusing them here avoids teaching a
* new taxonomy.
*/
export type LoggingDomain = (typeof LoggingDomains)[keyof typeof LoggingDomains];
export interface LoggingOptions {
/** Logger sink. Defaults to console. */
readonly logger?: LoggingLogger;
/**
* Domains to log. Pass `'all'` for firehose (including consumer custom
* events). Default: `['context', 'stream']` — the core debugging lens
* (what went into the LLM, what came out).
*/
readonly domains?: readonly LoggingDomain[] | 'all';
/** Custom formatter. Default: `[domain.action]`. */
readonly format?: (event: AgentfootprintEvent) => string;
}
/**
* Attach a logging subscription to the event dispatcher.
* Returns an Unsubscribe — call to detach.
*/
export declare function attachLogging(dispatcher: EventDispatcher, options?: LoggingOptions): Unsubscribe;