use serde_json::json;
use super::general_planner::compose_edit_request;
use super::planner::{fetch_arguments, plan_one, tool_for, AgenticPlan, Capability, Progress};
use crate::protocol::ChatMessage;
pub(super) fn plan_web_fetch_step(
task: &str,
messages: &[ChatMessage],
tool_names: &[&str],
) -> Option<AgenticPlan> {
let url = crate::solver_handlers::http_fetch_url_for(task)?;
let tool = tool_for(tool_names, Capability::Fetch)?;
let progress = Progress::scan(messages);
if progress.done(Capability::Fetch) {
return Some(AgenticPlan::Final(web_fetch_final_answer(
&url,
progress.fetched_text(),
)));
}
Some(plan_one(tool, fetch_arguments(&url)))
}
pub(super) fn plan_web_search_step(
task: &str,
messages: &[ChatMessage],
tool_names: &[&str],
) -> Option<AgenticPlan> {
let query = crate::solver_handlers::web_search_query_for(task)?;
let tool = tool_for(tool_names, Capability::Search)?;
let progress = Progress::scan(messages);
if progress.done(Capability::Search) {
return Some(AgenticPlan::Final(web_search_final_answer(
&query,
progress.search_output(),
)));
}
Some(plan_one(tool, json!({ "query": query }).to_string()))
}
pub(super) fn plan_edit_step(
task: &str,
messages: &[ChatMessage],
tool_names: &[&str],
) -> Option<AgenticPlan> {
let (target, old, new) = compose_edit_request(task)?;
let tool = tool_for(tool_names, Capability::Edit)?;
let progress = Progress::scan(messages);
if progress.done(Capability::Edit) {
return Some(AgenticPlan::Final(format!(
"Edited `{target}`: replaced `{old}` with `{new}`."
)));
}
Some(plan_one(tool, edit_arguments(&target, &old, &new)))
}
fn web_fetch_final_answer(url: &str, fetched_text: Option<&str>) -> String {
fetched_text
.map(str::trim)
.filter(|text| !text.is_empty())
.map_or_else(
|| format!("Fetched `{url}`."),
|text| format!("Fetched `{url}`. Response body:\n\n```text\n{text}\n```"),
)
}
fn web_search_final_answer(query: &str, search_output: Option<&str>) -> String {
search_output
.map(str::trim)
.filter(|text| !text.is_empty())
.map_or_else(
|| format!("Searched the web for `{query}`."),
|text| format!("Searched the web for `{query}`. Results:\n\n{text}"),
)
}
fn edit_arguments(path: &str, old: &str, new: &str) -> String {
json!({
"path": path,
"filePath": path,
"file_path": path,
"oldString": old,
"old_string": old,
"old_str": old,
"old": old,
"newString": new,
"new_string": new,
"new_str": new,
"new": new,
})
.to_string()
}