fix(engine): add user message and system prompt to thread before execution

The ExecutionLoop was sending empty messages to the LLM because the
thread was spawned with the user's input as the goal but no messages.

Fixes:
- ThreadManager.spawn_thread() now adds the goal as an initial user
  message before starting the execution loop
- ExecutionLoop.run() injects a default system prompt if none exists

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
This commit is contained in:
2026-03-22 00:35:56 -07:00
co-authored by Claude Opus 4.6
parent ac4ced02ae
commit 9d6d76d9c9
2 changed files with 14 additions and 0 deletions
@@ -61,6 +61,17 @@ impl ExecutionLoop {
// Transition to Running
self.thread.transition_to(ThreadState::Running, None)?;
// Inject system prompt if none exists
if !self.thread.messages.iter().any(|m| m.role == crate::types::message::MessageRole::System) {
self.thread.messages.insert(
0,
ThreadMessage::system(
"You are a helpful assistant. Use the available tools to accomplish the user's request. \
Respond concisely.",
),
);
}
let max_iterations = self.thread.config.max_iterations;
let max_nudges = self.thread.config.max_tool_intent_nudges;
let nudge_enabled = self.thread.config.enable_tool_intent_nudge;
@@ -95,6 +95,9 @@ impl ThreadManager {
thread.capability_leases.push(lease.id);
}
// Add the goal as the initial user message so the LLM has context
thread.add_message(crate::types::message::ThreadMessage::user(&thread.goal));
// Persist
self.store.save_thread(&thread).await?;