latent.events¶
Agent event types matching agent-studio AgentProtocol.
Classes¶
AgentEvent¶
Base class for all agent events.
Error¶
Agent encountered an error (terminal event).
FunctionCall¶
Inner function block of a :class:ToolCall.
arguments is a JSON-encoded string, not a Python dict — this is the
wire format LiteLLM / OpenAI / Anthropic-via-LiteLLM all use. Parse
with json.loads when inspecting in Python; emit via
json.dumps at the call site (or use
:meth:ToolCall.with_arguments for the common case).
GuidelineMatched¶
A guideline was matched and injected for this turn.
JourneyCompleted¶
The active journey completed all steps.
JourneyStepAdvanced¶
The active journey advanced to a new step.
LLMCallEnd¶
LLMCallEnd(run_id: str, output_preview: str | None = None, input_tokens: int = 0, output_tokens: int = 0, model_id: str | None = None, timestamp: float = 0.0)
LLM call completed.
LLMCallStart¶
LLM call started.
Message¶
Message(role: str, content: str | list[dict[str, Any]], id: str | None = None, tool_calls: list[ToolCall] | None = None, tool_call_id: str | None = None)
A single message in the conversation history.
tool_calls and tool_call_id lock to OpenAI / LiteLLM:
- On an assistant message that invoked tools, set
tool_callsto a list of :class:ToolCallinstances — the same dataclass the agent stream yields. Persisting a step's calls into history is a pure list copy, zero translation. - On a tool message that carries the result of one call, set
role="tool",tool_call_id="<matching id>", andcontentto the stringified output. Onerole="tool"row per result; do not embed results inside the assistant'stool_callsentries.
Field layout matches LiteLLM ChatCompletionMessage verbatim — no
internal-shape translation. See :mod:latent.protocol.
Metadata¶
Metadata(attributes: MetadataAttributes | dict[str, MetadataValue], target: Literal['turn', 'step'] = 'turn')
Primitive trace attributes emitted by an agent stream.
Values are intentionally limited to OpenTelemetry-safe primitives. Omit
absent values rather than passing None. target is advisory: stream
consumers decide whether and how to attach the attributes to a trace span.
MetadataAttributes¶
Immutable dict copy used to preserve Metadata validation invariants.
PhaseCompleted¶
A pipeline phase has completed execution.
PhaseRouted¶
Pipeline routed from one phase to another.
PhaseStarted¶
A pipeline phase has started execution.
ReasoningDelta¶
Incremental reasoning/thinking chunk.
RetrieverEnd¶
RetrieverEnd(run_id: str, documents: list[str], name: str | None = None, timestamp: float = 0.0, parent_run_id: str | None = None)
A retriever query completed.
Emitted after :class:RetrieverStart by the same decorator.
documents carries content previews; consumers that need the
full retrieved chunks consult the underlying retriever directly —
this event is observability, not the canonical retrieval result.
RetrieverStart¶
RetrieverStart(run_id: str, query: str, name: str | None = None, timestamp: float = 0.0, parent_run_id: str | None = None)
A retriever (vector store, BM25 index, etc.) began a query.
Emitted by a function decorated with :func:latent.retriever.retriever
at the start of each retrieval call. The trace pipeline opens a
per-retriever span keyed off run_id. RetrieverEnd carries the
matching run_id so a single retrieval round forms a (start, end)
pair regardless of nesting or parallel retrievals.
StepBoundary¶
Marks the start of an agent loop iteration.
Contract (load-bearing for BaseAgent.invoke()):
- Emitted exactly once at the start of each iteration, before any other events for that iteration.
- All subsequent events (
LLMCallStart/LLMCallEnd/TextDelta/ReasoningDelta/ToolCall/ToolResult/Usage) belong to the iteration that preceded the nextStepBoundaryor end-of-stream. - Subclassed agents that override
stream()must preserve this invariant. If they cannot, they must overrideBaseAgent.invoke()with their own segmentation logic.
invoke() uses StepBoundary as the segmentation primitive between
Step records. Violating the contract silently regresses every
buffered consumer of the agent — the terminal-step text derivation
relies on this being well-formed.
label is an optional, free-form marker describing the kind of step,
surfaced to trace/observability consumers — e.g. a short-circuit /
canned fast-response step sets label="fast_response" so it's
distinguishable from a normal LLM iteration. Purely advisory; invoke()
segmentation ignores it.
TextDelta¶
Incremental text chunk from the agent.
ToolCall¶
Agent is invoking a tool.
Fields mirror LiteLLM's ChatCompletionAssistantToolCall verbatim —
no parallel TypedDict, no translation when persisting into
:attr:Message.tool_calls. The same dataclass plays two roles: the
streaming event the agent yields, and the value type stored on
historical assistant messages. Consumers correlate results by id
against the matching Message(role="tool", tool_call_id=…) row.
ToolResult¶
Result from a tool invocation.
Persists as Message(role="tool", content=str(output_or_error),
tool_call_id=tool_call_id). Kept Python-native (output: Any,
error: str | None) because streaming consumers — tracing,
supervisor UIs — want the structured output; the string
conversion happens once when the result lands in conversation
history.
Usage¶
Usage(input_tokens: int = 0, output_tokens: int = 0, model_id: str | None = None, cache_creation_input_tokens: int = 0, cache_read_input_tokens: int = 0)
Token usage information for a single LLM call.
input_tokens is the TOTAL input, cache included — the cache fields
are informational subsets of it and must never be added on top. Callers
needing disjoint accounting use :attr:uncached_input_tokens.
VerificationResult¶
VerificationResult(accepted: bool, feedback: str | None = None, tools_triggered: list[str] | None = None)
Result of the self-verification step after a response is generated.
Methods¶
ToolCall.from_arguments¶
Build a :class:ToolCall from Python-native arguments.
Most call sites have a dict they need to ship as the
LiteLLM-spec JSON string. This helper handles the encoding once
so emission sites stay terse: ToolCall.from_arguments(id=…,
name=…, arguments={"x": 1}).
Usage.uncached_input_tokens¶
Input tokens that were neither written to nor read from cache.