mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-26 15:40:18 +00:00
fix(engine): eagerly initialize engine v2 at startup
The gateway API endpoints (/api/engine/missions, etc.) call bridge query functions that return empty results when the engine state hasn't been initialized yet. Previously, initialization only happened lazily on the first chat message via handle_with_engine(). Now when ENGINE_V2=true, the engine is initialized in Agent::run() before channels start, so the self-improvement mission and other engine state is available to gateway API endpoints immediately. Also rename get_or_init_engine → init_engine and make it public so it can be called from agent_loop.rs at startup. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
@@ -450,6 +450,14 @@ impl Agent {
|
||||
None
|
||||
};
|
||||
|
||||
// Eagerly initialize engine v2 so gateway API endpoints can serve
|
||||
// data (projects, missions, threads) before the first chat message.
|
||||
if crate::bridge::is_engine_v2_enabled()
|
||||
&& let Err(e) = crate::bridge::init_engine(&self).await
|
||||
{
|
||||
tracing::debug!("engine v2: eager init failed: {e}");
|
||||
}
|
||||
|
||||
// Start channels
|
||||
let mut message_stream = self.channels.start_all().await?;
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ pub use router::{
|
||||
get_engine_mission,
|
||||
get_engine_project,
|
||||
get_engine_thread,
|
||||
// Initialization
|
||||
init_engine,
|
||||
// Action handlers
|
||||
handle_approval,
|
||||
handle_clear,
|
||||
|
||||
@@ -84,7 +84,10 @@ enum PendingApprovalResolution {
|
||||
}
|
||||
|
||||
/// Get or initialize the engine state using the agent's dependencies.
|
||||
async fn get_or_init_engine(agent: &Agent) -> Result<(), Error> {
|
||||
///
|
||||
/// Called eagerly at startup (from `Agent::run()`) when `ENGINE_V2=true`,
|
||||
/// and defensively from each handler as a lazy fallback.
|
||||
pub async fn init_engine(agent: &Agent) -> Result<(), Error> {
|
||||
let lock = ENGINE_STATE.get_or_init(|| RwLock::new(None));
|
||||
let guard = lock.read().await;
|
||||
if guard.is_some() {
|
||||
@@ -456,7 +459,7 @@ pub async fn handle_approval(
|
||||
approved: bool,
|
||||
always: bool,
|
||||
) -> Result<Option<String>, Error> {
|
||||
get_or_init_engine(agent).await?;
|
||||
init_engine(agent).await?;
|
||||
|
||||
let lock = ENGINE_STATE
|
||||
.get()
|
||||
@@ -497,7 +500,7 @@ pub async fn handle_exec_approval(
|
||||
approved: bool,
|
||||
always: bool,
|
||||
) -> Result<Option<String>, Error> {
|
||||
get_or_init_engine(agent).await?;
|
||||
init_engine(agent).await?;
|
||||
|
||||
let lock = ENGINE_STATE
|
||||
.get()
|
||||
@@ -642,7 +645,7 @@ pub async fn handle_interrupt(
|
||||
agent: &Agent,
|
||||
message: &IncomingMessage,
|
||||
) -> Result<Option<String>, Error> {
|
||||
get_or_init_engine(agent).await?;
|
||||
init_engine(agent).await?;
|
||||
|
||||
let lock = ENGINE_STATE
|
||||
.get()
|
||||
@@ -703,7 +706,7 @@ pub async fn handle_clear(
|
||||
|
||||
/// Stop all active threads and clear conversation entries.
|
||||
async fn clear_engine_conversation(agent: &Agent, message: &IncomingMessage) -> Result<(), Error> {
|
||||
get_or_init_engine(agent).await?;
|
||||
init_engine(agent).await?;
|
||||
|
||||
let lock = ENGINE_STATE
|
||||
.get()
|
||||
@@ -758,7 +761,7 @@ pub async fn handle_with_engine(
|
||||
content: &str,
|
||||
) -> Result<Option<String>, Error> {
|
||||
// Ensure engine is initialized
|
||||
get_or_init_engine(agent).await?;
|
||||
init_engine(agent).await?;
|
||||
|
||||
let lock = ENGINE_STATE
|
||||
.get()
|
||||
|
||||
Reference in New Issue
Block a user