AutoAgent: multi-step autonomous agent wrapping Agent

Agent::fork() clones context for KV cache sharing with conscious agent.
AutoAgent runs multi-step prompt sequences with tool dispatch — used by
both oneshot CLI agents and (soon) Mind's subconscious agents.

call_api_with_tools() now delegates to AutoAgent internally; existing
callers unchanged.

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
Kent Overstreet 2026-04-07 01:07:04 -04:00
parent cbf7653cdf
commit 0084b71bbf
2 changed files with 318 additions and 165 deletions

View file

@ -185,7 +185,6 @@ pub struct Agent {
pub changed: Arc<tokio::sync::Notify>,
}
impl Agent {
pub fn new(
client: ApiClient,
@ -241,9 +240,46 @@ impl Agent {
agent
}
/// Create a lightweight agent forked from this one's context.
///
/// The forked agent shares the same conversation prefix (system prompt,
/// personality, journal, entries) for KV cache sharing. The caller
/// appends the subconscious prompt as a user message and runs the turn.
pub fn fork(&self, tools: Vec<tools::Tool>) -> Self {
let tokenizer = tiktoken_rs::cl100k_base()
.expect("failed to load cl100k_base tokenizer");
Self {
client: self.client.clone(),
tools,
last_prompt_tokens: 0,
reasoning_effort: "none".to_string(),
temperature: self.temperature,
top_p: self.top_p,
top_k: self.top_k,
activities: Vec::new(),
next_activity_id: 0,
pending_yield: false,
pending_model_switch: None,
pending_dmn_pause: false,
conversation_log: None,
tokenizer,
context: self.context.clone(),
shared_context: context::shared_context_state(),
app_config: self.app_config.clone(),
prompt_file: self.prompt_file.clone(),
session_id: self.session_id.clone(),
generation: 0,
memory_scoring_in_flight: false,
memory_scores: Vec::new(),
active_tools: tools::shared_active_tools(),
changed: Arc::new(tokio::sync::Notify::new()),
}
}
/// Assemble the full message list for the API call from typed sources.
/// System prompt + personality context + journal + conversation messages.
fn assemble_api_messages(&self) -> Vec<Message> {
pub fn assemble_api_messages(&self) -> Vec<Message> {
let mut msgs = Vec::new();
msgs.push(Message::system(&self.context.system_prompt));
let ctx = self.context.render_context_message();