fix: slim down token usage

This commit is contained in:
eric
2026-04-04 12:37:50 +02:00
parent 97f329c825
commit 1240ab946b
55 changed files with 6799 additions and 2333 deletions

View File

@@ -1,11 +1,12 @@
use std::sync::mpsc::Sender;
use anyhow::Result;
use serde_json::json;
use serde_json::{json, Value};
use crate::app::AppEvent;
use crate::model::{ExecutionResponse, Plan, PlanStep, SessionSource, TaskConfig};
use crate::process;
use crate::prompt;
use crate::storage::toon;
pub fn implement(
@@ -17,23 +18,27 @@ pub fn implement(
) -> Result<ExecutionResponse> {
let goal_md = toon::read_markdown(&config.goal_file)?;
let standards_md = toon::read_markdown(&config.standards_file)?;
let context = build_execution_context(plan, step);
let prompt = format!(
concat!(
"You are the autonomous execution worker for a Rust TUI-first controller.\n",
"You are in execution mode. Do not ask the user questions.\n",
"Implement the step, verify it, clean up the implementation, and leave the codebase in maintainable condition.\n",
"You may edit files in the repository. You own the implementation decisions.\n",
"If the goal itself is ambiguous, set needs_goal_clarification=true.\n",
"Return verification commands and test commands that the controller should run after your work.\n\n",
"Goal:\n{goal}\n\n",
"Standards:\n{standards}\n\n",
"Current plan:\n{plan}\n\n",
"Active step:\n{step}\n"
"Execution mode only. Do not ask the user questions.\n",
"Complete the active step with the smallest correct change set.\n\n",
"Efficiency rules:\n",
"- Inspect only files likely relevant to this step.\n",
"- Avoid repository-wide searches unless the focused path is exhausted.\n",
"- Prefer targeted verification and targeted tests over broad full-suite runs.\n",
"- Keep output terse. Use short summaries and short notes.\n",
"- If the requested change is already present, return done.\n",
"- If the goal is genuinely ambiguous, set needs_goal_clarification=true.\n\n",
"Return empty arrays for verification_commands, test_commands, or notes when not needed.\n\n",
"Goal summary:\n{goal}\n\n",
"Standards summary:\n{standards}\n\n",
"Execution context:\n{context}\n"
),
goal = goal_md,
standards = standards_md,
plan = serde_json::to_string_pretty(plan)?,
step = serde_json::to_string_pretty(step)?,
goal = prompt::compact_markdown(&goal_md, 8, 1200),
standards = prompt::compact_markdown(&standards_md, 10, 1200),
context = serde_json::to_string_pretty(&context)?,
);
let schema = json!({
@@ -59,3 +64,45 @@ pub fn implement(
)?;
Ok(serde_json::from_str(&raw)?)
}
fn build_execution_context(plan: &Plan, step: &PlanStep) -> Value {
let dependency_steps = step
.dependencies
.iter()
.filter_map(|dependency| {
plan.steps
.iter()
.find(|candidate| &candidate.id == dependency)
.map(|candidate| {
json!({
"id": candidate.id,
"title": prompt::truncate_text(&candidate.title, 100),
"status": candidate.status,
})
})
})
.collect::<Vec<_>>();
let next_steps = plan
.steps
.iter()
.filter(|candidate| candidate.id != step.id)
.filter(|candidate| !candidate.status.is_done())
.take(3)
.map(|candidate| {
json!({
"id": candidate.id,
"title": prompt::truncate_text(&candidate.title, 100),
"dependencies": prompt::compact_string_vec(&candidate.dependencies, 4, 60),
"status": candidate.status,
})
})
.collect::<Vec<_>>();
json!({
"goal_summary": prompt::truncate_text(&plan.goal_summary, 200),
"active_step": prompt::compact_step(step),
"dependency_steps": dependency_steps,
"next_pending_steps": next_steps,
})
}