Expand description
AI agent logging facade – the producer side of the
*ai:<provider>:<index>* buffer views (AI-1b).
§Inspiration
A direct port of lattice-lsp’s logging facade
(lattice_lsp::logging), adapted per-process for AI agent sessions. LSP puts
per-server stderr / protocol events in *lsp:<server-id>*
buffers keyed by (server_id, workspace); AI agents are the
same shape one level simpler – a SessionKey { provider, index } distinguishes a second opencode session (its own
ring/buffer) from the first, exactly as two rust-analyzer
instances against different workspaces stay distinct.
§Producer / consumer split
This module is the producer: the ACP connection and
session machinery emit AiLogRecords through
AiLogger::log. Records land in bounded LogRings held
inside the logger.
The consumer – buffer-backed log views in
lattice-ui-tui (AI-1b, later slice) – snapshots a ring on
demand via AiLogger::snapshot_global /
AiLogger::snapshot_session and renders the records.
Auto-scroll-to-tail and live tail-follow are buffer-side
concerns; the producer just appends.
§Tracing crate fan-out
Every AiLogger::log call also emits a tracing::* event
at the matching level (target "ai") so users who prefer
RUST_LOG=ai=debug ./lattice still see everything. The two
paths are independent: the in-memory rings survive even when
no tracing subscriber is installed, and tracing users see
the same events whether or not the buffer views are open.
§Deviation from the LSP template
lattice_lsp::logging::LspLogger also gates a per-instance
JSON-RPC wire trace (instance_trace / enable_trace /
is_tracing / toggle_trace / disable_trace). AI-1b has no
per-message wire trace to toggle – streamed agent text is a
first-class AiLogSource::AgentText, not an opt-in trace –
so that machinery is intentionally omitted here. Everything
else mirrors the LSP logger verbatim.
Structs§
- AiLog
Pushed - The typed event fired on every successful append. Analogue of
lattice_lsp::events::LspLogPushed. - AiLog
Record - One log entry. Cheap to clone (
Arc<str>for the session’s provider name; the message is a plainString). - AiLogger
- Producer-side log facade. One per AI subsystem; each agent
connection gets a clone (cheap – internal state is
Arc<Mutex<...>>). - LogRing
- Bounded ring of log records. Append-only; oldest is evicted when capacity is reached.
- Session
Key - Per-process key for the per-session log ring – the
(provider, index)pair that distinguishes concurrent agent processes of the same provider. A secondopencodesession (index = 2) is a distinct ring/buffer from the first, analogous to LSP’sInstanceKey(server_id, workspace). Cheap to clone (oneArc<str>+ aCopyinteger).
Enums§
- AiLog
Level - Severity levels. Ordered low-to-high so the derived
PartialOrdmatches “Error > Warn > … > Trace”. Per-session min level filters records BELOW it (i.e.level < mindrops;level >= minkeeps). - AiLog
Source - Where a log record originated.
Functions§
- format_
ai_ log_ line - Format one log record line for append to a synthetic AI log
buffer. Shape:
HH:MM:SS.mmm [<provider>:<index>] <level> <source>: <message>. Trailing newline is the caller’s responsibility (the drain batches many records into one buffer-append). - level_
tag - Compact severity tag for
AiLogPushed. MirrorsAiLogSource::tag’s shape for the level discriminator.
Type Aliases§
- AiLog
Event Publisher - Closure invoked on every successful append. Wired by the App
(or test harness) to publish
AiLogPushedonto the runtime event bus, which lets log buffers refresh live as records arrive. Optional:AiLogger::with_defaults()starts with no publisher;set_event_publisherinstalls one.