Skip to main content

Crate rig_ecs

Crate rig_ecs 

Source
Expand description

rig-ecs, the kernel of the rig coding agent: agents, their turns and their calls are Bevy entities, and the calls run on Bevy’s task pools. Every call goes through one effect dispatch path, recorded as it settles (effects); plugins register the tools. The kernel saves every change of an agent’s Conversation to the session_log::SessionStore the app inserts. Time is Bevy’s: a retried model call waits on a delayed command, and plugins that animate or poll run on on_real_timer, not on threads of their own.

The kernel depends on no view and no file system: the app fills in what it needs, such as the store (any rig_memory::Store) and the model::Models.

use rig_ecs::session_log::SessionStore;
use rig_ecs::prelude::*;
use rig_memory::MemoryStore;

let mut app = App::new();
app.insert_resource(SessionStore::new(MemoryStore::default()))
    .add_plugins((AgentPlugin, SessionLogPlugin));

Modules§

agent
The agent entity: its components, the calls it owns, and the requests a view sends it.
effects
The one dispatch path. Every effect entity (stage), a model call, a tool call or a plugin’s effect, runs through Effects under its effect id, recorded in the kernel’s own RecordBuffer, and its record is written as a EffectRecorded when it settles. A plugin that keeps an effect log reads those, and continues the ids of the log it appends to with Effects::continue_after.
fork
Forking an agent: ForkAgent makes a new agent in the same session whose log is a copy of another’s up to a turn boundary, so it goes on from there by itself, a compaction made before the cut can be undone in it, and its requests share the source’s prompt cache.
inbox
Messages to agents. A message, whoever sends it (the user typing, an agent reporting, a plugin), is an effect entity: an Incoming ForAgent the agent, spawned by Deliver or by hand, which plugins edit in Prepare and take over in Gate by answering it. Each carries its Author, kept with the conversation and its log; text that is not the user’s own goes to the model headed by a line naming its sender. Each message is its own entry: nothing merges into the message before.
model
An agent’s model: the catalog model it chose, the reasoning setting it sends, and how the choice is connected. The catalog and how its models are reached are rig-core’s Connector.
prelude
What a plugin needs: Bevy’s app, ECS, reflection and time preludes (with the time run conditions and Disabled), the kernel’s components, requests and stages, the tool registry, rig-core’s conversation types and rig-memory’s store. Message is Bevy’s message trait, a conversation’s message is message::Message, and Conversation is the agent’s component.
prompt
The system prompt, put together for each model call from two parts: the agent’s own SystemPrompt and the PromptSections, the app’s and the agent’s own (SectionOf). Nothing in it depends on the turn, so it stays the same from call to call and the provider’s prompt cache keeps it. A section whose text changes costs the whole conversation’s cache once per change, so what changes goes in a message instead (DeliveryMode::Inform); a section that changes rarely sorts before one that changes more often. A request carries it in parts, rig-core’s SystemPrompt (ModelRequest::prompt), until Start sends it as one system message.
restore
Restoring a session from its agent logs at startup, then one reconcile pass that settles what a crash or a restart left half done, with ordinary records, so the next restore finds nothing left to fix. The session is read as open_session reads it: strictly, refused whole before anything is written when it cannot be read, a torn last line set aside; a retired agent and the agents it spawned are not restored.
retry
What to do about a failed model call: wait and send it again after a transient failure, honouring the wait the provider asked for; recover from a request that outgrew the model’s context window; or give up.
session_log
The session log in the app. Each agent’s log, in the session’s SessionStore, gets every change of the agent’s Conversation and of its ReflectSaved components, such as its model, reasoning setting, system prompt, tool access and last usage. The format, its writer and its readers are rig-memory’s.
stage
The stages every effect moves through within a frame. An effect is an entity whose components are its request and its outcome, such as an EffectRequest and, once answered, an Outcome; generic components say how far it got. Each run of the AgentPass schedule goes through the Stage sets in order, and the loop in Update (AgentLoop) runs it again until nothing moved, so an effect spawned, answered or released goes as far as it can in that frame.
tasks
Work that runs off the main thread: a Running task on an entity becomes a Done component when it finishes, through one poll_tasks system, so observers of that component carry on; on an effect, such as an open tool call, it becomes the effect’s Outcome in Stage::Arrive. A long-lived source, such as a socket or a thread’s channel, is a Running::stream whose every item becomes a Done on the entity, in order. Each finished task and each item also calls Wake, so a loop that sleeps while nothing happens runs a frame for it.
tools
The tool registry and tool calls. A tool is an entity holding its definition and its default Footprint, and, for an ordinary tool, its effect handler; plugins add tools with AppToolsExt::add_tool. A tool call is an effect entity with a ToolRequest. An ordinary tool’s handler answers it; an open tool’s call triggers ToolCalled and stays open until any system decides it (Decision).
turn
The turn loop. A user message spawns a turn entity, TurnOf its agent; its model and tool calls are effect entities CallOf the turn.

Structs§

AgentPlugin
The kernel: agents, their turn loop, effects and the tool registry, and the saving of every conversation change (announced as session_log::ConversationChanged).
SaveSystems
The systems in Last that queue what the frame changed for the session log: every conversation changed and every ReflectSaved value, after StopTurnsOnExit and before WriteLogs. A plugin’s Last system that changes saved state goes .before(SaveSystems): one after it is saved a frame late, and on the exit frame never.
StopTurnsOnExit
The system in Last, on exit, that stops the running turns and leaves them for the restart, unended; before WriteLogs, both in Bevy’s OnAppExitSystems.
WriteLogs
The systems in Last that write the frame’s log records to the session_log::SessionStore, and those a plugin adds to write its own logs, such as the effect log: such a system says .in_set(WriteLogs) and nothing else. It runs after SaveSystems and the turns stopped on exit, so it writes what they left too. A failed write stops the logging and sends a Notice here, at the end of the frame, which a system that runs before it reads the next frame and, on the exit frame, never: on exit, read SessionLog::failure or go .after(WriteLogs).