1pub mod agent;
25pub mod effects;
26pub mod fork;
27pub mod inbox;
28pub mod model;
29pub mod prompt;
30pub mod restore;
31pub mod retry;
32pub mod session_log;
33pub mod stage;
34pub mod tasks;
35pub mod tools;
36pub mod turn;
37
38pub mod prelude {
45 pub use bevy_app::prelude::*;
46 pub use bevy_ecs::entity_disabling::Disabled;
47 pub use bevy_ecs::prelude::*;
48 pub use bevy_reflect::prelude::*;
49 pub use bevy_time::common_conditions::{on_real_timer, on_timer};
50 pub use bevy_time::prelude::*;
51
52 pub use crate::AgentPlugin;
53 pub use crate::agent::{
54 ActiveTurn, Agent, AgentId, CacheKey, CallOf, Calls, Conversation, EffectParent, LastUsage,
55 Notice, NoticeLevel, Partial, Retry, Spawned, SpawnedBy, StopTurn, SystemPrompt,
56 ToolAccess, Turn, TurnOf, TurnOutcome,
57 };
58 pub use crate::fork::{AgentForked, ForkAgent};
59 pub use crate::inbox::{
60 Attachment, Deliver, DeliveredIn, DeliveryMode, Incoming, MessagePart, MessageRecord,
61 Recalled, Unsent,
62 };
63 pub use crate::model::{
64 Connection, ModelChoice, Models, ReasoningSetting, SetModel, SetReasoning,
65 };
66 pub use crate::prompt::{AgentSections, PromptSection, SectionOf};
67 pub use crate::restore::{Interrupted, Restored, SavedKeys};
68 pub use crate::retry::Verdict;
69 pub use crate::session_log::{
70 ConversationChanged, ReflectSaved, Retire, SessionLogPlugin, SessionRestored,
71 };
72 pub use crate::stage::{
73 Admitted, AgentLoop, AgentPass, AgentWork, Decision, Effect, EffectRecorded, EffectRequest,
74 ForAgent, GateSystems, HoldOf, Holds, IfStopped, IncomingMessages, ModelCalls, Outcome,
75 PluginEffects, PrepareSystems, Published, ReadyToSettle, ReadyToStart, ReviewSystems,
76 Settled, Stage, Started, SupersededBy, Supersedes, ToolCalls, Waiting,
77 despawn_open_children, follow_successor,
78 };
79 pub use crate::tasks::{Done, PollTasks, Running, Wake};
80 pub use crate::tools::{
81 AppToolsExt, CallHandler, DeclaredFootprint, Footprint, ToolCalled, ToolDef, ToolOptions,
82 ToolRequest, WorldToolsExt,
83 };
84 pub use crate::turn::{
85 Adapter, Adapters, Backoff, DroppedOptions, ModelRequest, ModelStarts, Recovery,
86 RetryVerdict, SentTo, SideCall, StreamDelta, StreamTiming, TurnCall,
87 };
88 pub use rig_core::conversation::{
89 Aside, AsideId, Author, AuthorKind, Change, ChangeRecord, Entry, EntryRef, Halt, MessageId,
90 RequestId, STOPPED, Spliced, TurnEnd, TurnRecord,
91 };
92 pub use rig_core::effect::Decider;
93 pub use rig_core::message::{self, AssistantContent, AssistantMessage, ToolCall, UserContent};
94 pub use rig_core::now_ms;
95 pub use rig_core::streaming::{Part, PartKind, StreamEvent};
96 pub use rig_core::tool::{
97 Scope, Tool, ToolContext, ToolExecutionError, ToolResult, Touches, args_schema,
98 };
99 pub use rig_memory::{
100 Files, LogWriteError, Repair, Rewrite, Rewritten, SavedAgent, Session, Stamp, Store,
101 Strings, as_of, history,
102 };
103}
104
105use bevy_app::MainScheduleOrder;
106use bevy_app::prelude::*;
107use bevy_ecs::prelude::*;
108use bevy_ecs::schedule::ScheduleLabel;
109use bevy_ecs::schedule::SingleThreadedExecutor;
110use bevy_time::TimePlugin;
111
112use agent::{Agent, Notice};
113use session_log::{SaveConversations, SavedOne, SessionLog, save_conversations, save_now};
114use tasks::{PollTasks, Wake, poll_tasks, run_settle_frames};
115
116#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]
120pub struct StopTurnsOnExit;
121
122#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]
129pub struct SaveSystems;
130
131#[derive(SystemSet, Debug, Clone, Copy, PartialEq, Eq, Hash)]
140pub struct WriteLogs;
141
142pub struct AgentPlugin;
153
154impl Plugin for AgentPlugin {
155 fn build(&self, app: &mut App) {
156 if !app.is_plugin_added::<TimePlugin>() {
157 let single = |schedule: &mut Schedule| {
164 schedule.set_executor(SingleThreadedExecutor::new());
165 };
166 app.add_plugins(TimePlugin)
167 .edit_schedule(First, single)
168 .edit_schedule(PreUpdate, single)
169 .edit_schedule(Last, single);
170 }
171 if let Some(mut order) = app.world_mut().get_resource_mut::<MainScheduleOrder>()
173 && let Some(at) = order
174 .labels
175 .iter()
176 .position(|label| *label == Update.intern())
177 {
178 order.labels.insert(at, SaveConversations.intern());
179 }
180 app.init_resource::<effects::Effects>()
181 .init_resource::<SessionLog>()
182 .init_resource::<SavedOne>()
183 .edit_schedule(SaveConversations, |schedule| {
184 schedule.set_executor(SingleThreadedExecutor::new());
185 })
186 .add_systems(SaveConversations, save_conversations)
187 .init_resource::<Wake>()
188 .init_resource::<model::Models>()
189 .add_message::<Notice>()
190 .add_message::<session_log::ConversationChanged>()
191 .add_message::<inbox::Recalled>()
192 .allow_ambiguous_resource::<Messages<Notice>>()
195 .allow_ambiguous_resource::<Messages<session_log::ConversationChanged>>()
196 .configure_sets(
197 Last,
198 (StopTurnsOnExit, WriteLogs)
199 .chain()
200 .in_set(bevy_app::OnAppExitSystems),
201 )
202 .configure_sets(Last, SaveSystems.after(StopTurnsOnExit).before(WriteLogs))
203 .add_systems(Startup, spawn_first_agent)
204 .configure_sets(Update, PollTasks.before(stage::AgentLoop))
206 .add_systems(Update, poll_tasks.in_set(PollTasks))
207 .add_systems(
208 PreUpdate,
209 model::reconnect.run_if(resource_changed::<model::Models>),
210 )
211 .add_systems(
212 Last,
213 (
214 run_settle_frames,
215 turn::stop_turns_on_exit
216 .in_set(StopTurnsOnExit)
217 .run_if(on_message::<AppExit>),
218 save_now.map(drop).in_set(SaveSystems),
219 ),
220 )
221 .add_observer(session_log::retire)
222 .add_observer(fork::fork_agent)
223 .add_observer(inbox::on_deliver)
224 .add_observer(turn::on_retry)
225 .add_observer(turn::on_stop_turn)
226 .add_observer(inbox::unsent_on_turn_end)
227 .add_observer(inbox::unmark)
228 .add_observer(model::on_set_model)
229 .add_observer(model::connect)
230 .add_observer(model::check_effort)
231 .add_observer(model::on_set_reasoning);
232 stage::build(app);
233 }
234}
235
236fn spawn_first_agent(agents: Query<(), With<Agent>>, mut commands: Commands) {
237 if agents.is_empty() {
238 commands.spawn((Name::new("agent"), Agent));
239 }
240}