feat: add output buffer limit, report preset and enriched context diff
This commit is contained in:
11
src/agent.rs
11
src/agent.rs
@@ -3,6 +3,8 @@ use std::collections::HashSet;
|
|||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use crate::claude::{self, StreamEvent, StatusKind};
|
use crate::claude::{self, StreamEvent, StatusKind};
|
||||||
|
|
||||||
|
const MAX_OUTPUT: usize = 50_000;
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum AgentStatus {
|
pub enum AgentStatus {
|
||||||
Thinking,
|
Thinking,
|
||||||
@@ -124,7 +126,14 @@ impl Agent {
|
|||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
match event {
|
match event {
|
||||||
StreamEvent::StreamStart => {}
|
StreamEvent::StreamStart => {}
|
||||||
StreamEvent::Chunk(text) => self.output.push_str(&text),
|
StreamEvent::Chunk(text) => {
|
||||||
|
self.output.push_str(&text);
|
||||||
|
if self.output.len() > MAX_OUTPUT {
|
||||||
|
let trim = self.output.len() - MAX_OUTPUT;
|
||||||
|
let boundary = self.output[trim..].find('\n').map(|i| trim + i + 1).unwrap_or(trim);
|
||||||
|
self.output.drain(..boundary);
|
||||||
|
}
|
||||||
|
}
|
||||||
StreamEvent::StreamEnd => {
|
StreamEvent::StreamEnd => {
|
||||||
self.log("response", &format!("{}chars", self.output.len()));
|
self.log("response", &format!("{}chars", self.output.len()));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ pub fn preset(name: &str) -> Option<Vec<AgentConfig>> {
|
|||||||
AgentConfig { name: "bug-hunt".into(), task: "Find one concrete bug in the codebase. Give file:line and a fix.".into(), cwd: cwd.clone() },
|
AgentConfig { name: "bug-hunt".into(), task: "Find one concrete bug in the codebase. Give file:line and a fix.".into(), cwd: cwd.clone() },
|
||||||
AgentConfig { name: "simplify".into(), task: "Find one function that can be removed or simplified. Be specific.".into(), cwd },
|
AgentConfig { name: "simplify".into(), task: "Find one function that can be removed or simplified. Be specific.".into(), cwd },
|
||||||
]),
|
]),
|
||||||
|
"report" => Some(vec![
|
||||||
|
AgentConfig { name: "agent-view".into(), task: "You are an agent inside aishell. Reflect: What context did you receive? What was missing? What would make your job easier? 3 concrete points from your perspective.".into(), cwd: cwd.clone() },
|
||||||
|
AgentConfig { name: "user-view".into(), task: "You are a developer using aishell daily. Run aishell help and aishell context. What are the 3 biggest friction points in the daily workflow?".into(), cwd: cwd.clone() },
|
||||||
|
AgentConfig { name: "system-view".into(), task: "Read src/headless.rs and src/tui.rs. From the system's perspective: what is the most fragile part? What would break first under heavy use? One concrete issue.".into(), cwd },
|
||||||
|
]),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -917,7 +917,17 @@ pub fn context() {
|
|||||||
println!("status:\n{git_status}");
|
println!("status:\n{git_status}");
|
||||||
}
|
}
|
||||||
if !git_diff.is_empty() {
|
if !git_diff.is_empty() {
|
||||||
println!("diff:\n{git_diff}");
|
println!("diff stat:\n{git_diff}");
|
||||||
|
let git_diff_content = run("git", &["diff", "HEAD"]);
|
||||||
|
if !git_diff_content.is_empty() {
|
||||||
|
let truncated: String = git_diff_content.lines().take(30)
|
||||||
|
.collect::<Vec<_>>().join("\n");
|
||||||
|
let total = git_diff_content.lines().count();
|
||||||
|
println!("diff content:\n{truncated}");
|
||||||
|
if total > 30 {
|
||||||
|
println!("... ({} more lines)", total - 30);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
println!("recent:\n{git_log}");
|
println!("recent:\n{git_log}");
|
||||||
|
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ fn print_help() {
|
|||||||
println!("USAGE:");
|
println!("USAGE:");
|
||||||
println!(" aishell TUI (AI + Agents + Shell)");
|
println!(" aishell TUI (AI + Agents + Shell)");
|
||||||
println!(" aishell run <task> Run single agent");
|
println!(" aishell run <task> Run single agent");
|
||||||
println!(" aishell run -p <preset> Preset: daily, review, improve");
|
println!(" aishell run -p <preset> Preset: daily, review, improve, report");
|
||||||
println!(" aishell run -f <config> Custom config file");
|
println!(" aishell run -f <config> Custom config file");
|
||||||
println!(" aishell commit Git commit with AI-suggested message");
|
println!(" aishell commit Git commit with AI-suggested message");
|
||||||
println!(" aishell status [-v] Show agent status");
|
println!(" aishell status [-v] Show agent status");
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use crate::config::AgentConfig;
|
|||||||
use crate::judge::{self, CommandCache};
|
use crate::judge::{self, CommandCache};
|
||||||
|
|
||||||
const STATE_DIR: &str = "/tmp/aishell";
|
const STATE_DIR: &str = "/tmp/aishell";
|
||||||
|
const MAX_OUTPUT: usize = 50_000;
|
||||||
|
|
||||||
// ── App state ──────────────────────────────────────────────
|
// ── App state ──────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -131,6 +132,11 @@ impl App {
|
|||||||
}
|
}
|
||||||
OutputEvent::StreamChunk(text) => {
|
OutputEvent::StreamChunk(text) => {
|
||||||
self.ai_output.push_str(&text);
|
self.ai_output.push_str(&text);
|
||||||
|
if self.ai_output.len() > MAX_OUTPUT {
|
||||||
|
let trim = self.ai_output.len() - MAX_OUTPUT;
|
||||||
|
let boundary = self.ai_output[trim..].find('\n').map(|i| trim + i + 1).unwrap_or(trim);
|
||||||
|
self.ai_output.drain(..boundary);
|
||||||
|
}
|
||||||
self.ai_scroll = u16::MAX;
|
self.ai_scroll = u16::MAX;
|
||||||
}
|
}
|
||||||
OutputEvent::StreamEnd => {
|
OutputEvent::StreamEnd => {
|
||||||
|
|||||||
Reference in New Issue
Block a user