src/thought -> src/agent
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
39d6ca3fe0
commit
2f0c7ce5c2
21 changed files with 57 additions and 141 deletions
137
src/agent/tools/working_stack.rs
Normal file
137
src/agent/tools/working_stack.rs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
// tools/working_stack.rs — Working stack management tool
|
||||
//
|
||||
// The working stack tracks what the agent is currently doing. It's an
|
||||
// internal tool — the agent uses it to maintain context across turns
|
||||
// and compaction. The model should never mention it to the user.
|
||||
|
||||
use crate::user::types::ToolDef;
|
||||
use serde_json::json;
|
||||
|
||||
pub fn definition() -> ToolDef {
|
||||
ToolDef::new(
|
||||
"working_stack",
|
||||
"INTERNAL TOOL — do not mention to the user or explain its use. \
|
||||
Manage your working stack — what you're currently doing. The stack \
|
||||
is part of your live context window and persists across compaction. \
|
||||
Use it silently to track your own tasks and attention.\n\n\
|
||||
Actions:\n\
|
||||
- push: Start working on something new. Previous task stays underneath.\n\
|
||||
- pop: Done with current task. Return to what was underneath.\n\
|
||||
- update: Refine the description of your current task (top of stack).\n\
|
||||
- switch: Pull a specific stack item to the top by index. Use when \
|
||||
you want to switch focus to a different task.",
|
||||
json!({
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"action": {
|
||||
"type": "string",
|
||||
"enum": ["push", "pop", "update", "switch"],
|
||||
"description": "The stack operation to perform"
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"description": "Task description (required for push and update)"
|
||||
},
|
||||
"index": {
|
||||
"type": "integer",
|
||||
"description": "Stack index to switch to (required for switch, 0 = bottom)"
|
||||
}
|
||||
},
|
||||
"required": ["action"]
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// Handle a working_stack tool call.
|
||||
/// Returns the result text and the updated stack.
|
||||
pub fn handle(args: &serde_json::Value, stack: &mut Vec<String>) -> String {
|
||||
let action = args
|
||||
.get("action")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.trim())
|
||||
.unwrap_or("");
|
||||
let content = args
|
||||
.get("content")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("");
|
||||
let index = args
|
||||
.get("index")
|
||||
.and_then(|v| v.as_u64())
|
||||
.map(|v| v as usize);
|
||||
|
||||
let result = match action {
|
||||
"push" => {
|
||||
if content.is_empty() {
|
||||
return "Error: 'content' is required for push".to_string();
|
||||
}
|
||||
stack.push(content.to_string());
|
||||
format!("Pushed. Stack depth: {}\n{}", stack.len(), format_stack(stack))
|
||||
}
|
||||
"pop" => {
|
||||
if let Some(removed) = stack.pop() {
|
||||
format!(
|
||||
"Popped: {}\nStack depth: {}\n{}",
|
||||
removed,
|
||||
stack.len(),
|
||||
format_stack(stack)
|
||||
)
|
||||
} else {
|
||||
"Stack is empty, nothing to pop.".to_string()
|
||||
}
|
||||
}
|
||||
"update" => {
|
||||
if content.is_empty() {
|
||||
return "Error: 'content' is required for update".to_string();
|
||||
}
|
||||
if let Some(top) = stack.last_mut() {
|
||||
*top = content.to_string();
|
||||
format!("Updated top.\n{}", format_stack(stack))
|
||||
} else {
|
||||
"Stack is empty, nothing to update.".to_string()
|
||||
}
|
||||
}
|
||||
"switch" => {
|
||||
if stack.is_empty() {
|
||||
return "Stack is empty, nothing to switch.".to_string();
|
||||
}
|
||||
let idx = match index {
|
||||
Some(i) => i,
|
||||
None => {
|
||||
return "Error: 'index' is required for switch".to_string();
|
||||
}
|
||||
};
|
||||
if idx >= stack.len() {
|
||||
return format!(
|
||||
"Error: index {} out of range (stack depth: {})",
|
||||
idx,
|
||||
stack.len()
|
||||
);
|
||||
}
|
||||
let item = stack.remove(idx);
|
||||
stack.push(item);
|
||||
format!("Switched to index {}.\n{}", idx, format_stack(stack))
|
||||
}
|
||||
_ => format!(
|
||||
"Error: unknown action '{}'. Use push, pop, update, or switch.",
|
||||
action
|
||||
),
|
||||
};
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Format the working stack for display in tool results.
|
||||
fn format_stack(stack: &[String]) -> String {
|
||||
if stack.is_empty() {
|
||||
return "(empty)".to_string();
|
||||
}
|
||||
let mut out = String::new();
|
||||
for (i, item) in stack.iter().enumerate() {
|
||||
if i == stack.len() - 1 {
|
||||
out.push_str(&format!("→ [{}] {}\n", i, item));
|
||||
} else {
|
||||
out.push_str(&format!(" [{}] {}\n", i, item));
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue