feat: add phase1 task planner flow

This commit is contained in:
zyl
2026-03-25 03:29:55 +00:00
parent b9773d4719
commit 1ab0012275
5 changed files with 293 additions and 2 deletions

63
src/agent/mod.rs Normal file
View File

@@ -0,0 +1,63 @@
pub mod planner;
use crate::pipe::{AgentMessage, BrowserMessage, BrowserPipeTool, PipeError, Transport};
pub fn execute_task<T: Transport>(
transport: &T,
browser_tool: &BrowserPipeTool<T>,
instruction: &str,
) -> Result<String, PipeError> {
let plan = planner::plan_instruction(instruction)
.map_err(|err| PipeError::Protocol(err.to_string()))?;
for step in &plan.steps {
transport.send(&AgentMessage::LogEntry {
level: "info".to_string(),
message: step.log_message.clone(),
})?;
let result = browser_tool.invoke(
step.action.clone(),
step.params.clone(),
&step.expected_domain,
)?;
if !result.success {
return Err(PipeError::Protocol(format!(
"browser action failed: {}",
result.data
)));
}
}
Ok(plan.summary)
}
pub fn handle_browser_message<T: Transport>(
transport: &T,
browser_tool: &BrowserPipeTool<T>,
message: BrowserMessage,
) -> Result<(), PipeError> {
match message {
BrowserMessage::SubmitTask { instruction } => {
let completion = match execute_task(transport, browser_tool, &instruction) {
Ok(summary) => AgentMessage::TaskComplete {
success: true,
summary,
},
Err(err) => AgentMessage::TaskComplete {
success: false,
summary: err.to_string(),
},
};
transport.send(&completion)
}
BrowserMessage::Init { .. } => {
eprintln!("ignoring duplicate init after handshake");
Ok(())
}
BrowserMessage::Response { seq, .. } => {
eprintln!("ignoring unsolicited response: seq={seq}");
Ok(())
}
}
}