Skip to content

core/ — The Universal Primitives

Source: kernel/core/content.py · kernel/core/identity.py · kernel/core/usage.py · kernel/core/errors.py

Every agent message, every tool result, and every event payload in the entire system is built from these four files. Nothing in the kernel imports from outside core/ except within core/ itself.


ContentBlock — The Universal Payload Primitive

Every list of data passed between agents, to the LLM, and back from tools is a list[ContentBlock]. There is no other payload type. The type literal field is the discriminator — Pydantic routes deserialization automatically.

Category Block Type Discriminator (type) Core Fields Description
Text & Data TextBlock 'text' text: str Plain text message contents.
CodeBlock 'code' code: str, language: str \| None Program code snippets with optional syntax highlighter hint.
DataBlock 'data' data: dict, schema_id: str \| None Structured JSON data payload tied to a specific schema.
ErrorBlock 'error' error_type: str, message: str, recoverable: bool Standardized execution/system error blocks.
Media ImageBlock 'image' url: str \| None, data: bytes \| None, file_id: str \| None Image reference, inline bytes, or storage file ID.
AudioBlock 'audio' url: str \| None, data: bytes \| None, transcript: str \| None Audio data and optional speech-to-text transcript.
VideoBlock 'video' url: str \| None, data: bytes \| None Video files or URLs.
DocumentBlock 'document' url: str \| None, data: bytes \| None, filename: str \| None Documents (e.g. PDF/DOCX) attached to context.
Agentic ToolUseBlock 'tool_use' call_id: str, tool_name: str, arguments: dict Model request to execute a specific tool with arguments.
ToolResultBlock 'tool_result' call_id: str, content: list[ContentBlock], is_error: bool Tool output payload (can be nested multimodal blocks).
ThinkingBlock 'thinking' content: str, redacted: bool Internal model chain-of-thought/reasoning trace.
UIResourceBlock 'ui_resource' uri: str, render_mode: str Sandbox visual interface metadata for frontend rendering.

Key points

  • All blocks are frozen Pydantic models. They are immutable once created.
  • ToolResultBlock.content is itself a list[ContentBlock] — a tool can return images, code, data, errors, or any mix.
  • ThinkingBlock stores extended chain-of-thought from Anthropic extended thinking. The redacted flag lets the UI hide raw reasoning from users.
  • UIResourceBlock is the narrow waist for interactive UIs. A tool emits a ui://name URI; ravi-ui renders it as a sandboxed iframe. The LLM only sees text — never the iframe.
  • ErrorBlock over TextBlock — use ErrorBlock when a tool fails so consumers can detect errors programmatically without string-matching.
  • register_block_type(cls) extends the discriminator registry for custom block types. Call once at module load time.
  • content_block_from_dict(data) deserializes raw dicts. Unknown type values become UnknownBlock — no data loss in mixed-version deployments.

AgentId and TopicId — Routing Addresses

Class Fields Purpose & String Format Example
AgentId type: str
key: str
namespace: str = 'default'
Point-to-point routing address.
[namespace/]type/key
AgentId("react", "sess-123")
react/sess-123
TopicId type: str
source: str = 'default'
namespace: str = 'default'
Pub/sub channel address.
[namespace/]type/source
TopicId("agent.progress", run_id)
agent.progress/run-abc

AgentId is the point-to-point routing key — send a message to one specific agent instance.

TopicId is the pub/sub routing key — emit on a topic; every follower gets the message.

Standard topic conventions (enforced at L1, not kernel):

Topic Purpose
agent.progress / {run_id} All progress events for one run tree — one subscription covers the whole tree
agent.stream / {agent_id.key} Token stream from one specific agent

Usage — Token Accounting

Field Type Description
input_tokens int Total input/prompt tokens sent to the LLM.
cached_tokens int Input tokens resolved from cache (subset of input_tokens, billed lower).
output_tokens int Total completion/output tokens generated by the LLM.
reasoning_tokens int Output tokens spent on internal reasoning/thinking (subset of output_tokens).
total_tokens int (Property) Sum of input_tokens + output_tokens.

Usage is additive (a + b works). Every LLMResponse carries one. The L1 ExecutionTracker accumulates them to enforce ExecutionBudget.max_tokens.


KernelErrors — Typed Runtime Failures

The kernel error system uses a structured hierarchy for deterministic error handling:

  • KernelError (Base exception for all framework errors)
    • AgentNotFoundError: Sent when a message is routed to an unregistered AgentId.
    • HandlerError: Raised when an agent message handler (on_message) crashes internally.
    • AgentCrashError: Raised when the worker runner crashes or loses its lease unexpectedly.
    • BudgetExhaustedError: Raised when token counts, monetary cost, or turn budgets are hit.
    • MiddlewareTermination: Raised to abort execution from a middleware guard (e.g. rate limit, content warning).
    • CancellationError: Raised when cooperative cancellation triggers or a deadline passes.
    • ConcurrentAppendError: Raised when sequence mismatch occurs while appending to an agent's EventLog.
    • SpawnDenied: Raised when enqueuing a child run exceeds the tree's configured SpawnBudget.

AgentCrashError — the orchestrator catches this, consults the retry policy, and re-dispatches the crashed agent from the last checkpoint.

MiddlewareTermination vs AgentCrashError — termination is intentional (policy blocked the run); crash is unexpected (agent code threw).

ConcurrentAppendError — two workers tried to write to the same EventLog simultaneously. Callers reload last_seq and retry. This fences concurrent writes without a distributed lock.