feat: add phase1 task planner flow
This commit is contained in:
72
src/agent/planner.rs
Normal file
72
src/agent/planner.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use serde_json::{json, Value};
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::pipe::Action;
|
||||
|
||||
const BAIDU_URL: &str = "https://www.baidu.com";
|
||||
const BAIDU_DOMAIN: &str = "www.baidu.com";
|
||||
const BAIDU_INPUT_SELECTOR: &str = "#kw";
|
||||
const BAIDU_SEARCH_BUTTON_SELECTOR: &str = "#su";
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct PlannedStep {
|
||||
pub action: Action,
|
||||
pub params: Value,
|
||||
pub expected_domain: String,
|
||||
pub log_message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct TaskPlan {
|
||||
pub summary: String,
|
||||
pub steps: Vec<PlannedStep>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error, Clone, PartialEq, Eq)]
|
||||
pub enum PlannerError {
|
||||
#[error("unsupported instruction: {0}")]
|
||||
UnsupportedInstruction(String),
|
||||
#[error("missing search query in instruction")]
|
||||
MissingQuery,
|
||||
}
|
||||
|
||||
pub fn plan_instruction(instruction: &str) -> Result<TaskPlan, PlannerError> {
|
||||
let trimmed = instruction.trim();
|
||||
let query = trimmed
|
||||
.strip_prefix("打开百度搜索")
|
||||
.or_else(|| trimmed.strip_prefix("打开百度并搜索"))
|
||||
.ok_or_else(|| PlannerError::UnsupportedInstruction(trimmed.to_string()))?
|
||||
.trim();
|
||||
|
||||
if query.is_empty() {
|
||||
return Err(PlannerError::MissingQuery);
|
||||
}
|
||||
|
||||
Ok(TaskPlan {
|
||||
summary: format!("已在百度搜索{query}"),
|
||||
steps: vec![
|
||||
PlannedStep {
|
||||
action: Action::Navigate,
|
||||
params: json!({ "url": BAIDU_URL }),
|
||||
expected_domain: BAIDU_DOMAIN.to_string(),
|
||||
log_message: "navigate https://www.baidu.com".to_string(),
|
||||
},
|
||||
PlannedStep {
|
||||
action: Action::Type,
|
||||
params: json!({
|
||||
"selector": BAIDU_INPUT_SELECTOR,
|
||||
"text": query,
|
||||
"clear_first": true
|
||||
}),
|
||||
expected_domain: BAIDU_DOMAIN.to_string(),
|
||||
log_message: format!("type {query} into {BAIDU_INPUT_SELECTOR}"),
|
||||
},
|
||||
PlannedStep {
|
||||
action: Action::Click,
|
||||
params: json!({ "selector": BAIDU_SEARCH_BUTTON_SELECTOR }),
|
||||
expected_domain: BAIDU_DOMAIN.to_string(),
|
||||
log_message: format!("click {BAIDU_SEARCH_BUTTON_SELECTOR}"),
|
||||
},
|
||||
],
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user