- Mouse text selection with highlight rendering in panes - OSC 52 clipboard copy on selection, middle-click paste via tmux buffer - Bracketed paste support (Event::Paste) - yield_to_user: no tool result appended, ends turn immediately - yield_to_user: no parameters, just a control signal - Drop arboard dependency, use crossterm OSC 52 + tmux for clipboard Co-Authored-By: Proof of Concept <poc@bcachefs.org>
44 lines
2.2 KiB
Rust
44 lines
2.2 KiB
Rust
use std::sync::Arc;
|
|
// tools/control.rs — Agent control tools
|
|
//
|
|
// These set agent state directly via the Arc<Mutex<Agent>> handle,
|
|
// then return a text confirmation.
|
|
|
|
pub(super) fn tools() -> [super::Tool; 3] {
|
|
use super::Tool;
|
|
[
|
|
Tool { name: "switch_model",
|
|
description: "Switch to a different LLM model mid-conversation. Memories and history carry over.",
|
|
parameters_json: r#"{"type":"object","properties":{"model":{"type":"string","description":"Name of the model to switch to"}},"required":["model"]}"#,
|
|
handler: Arc::new(|agent, v| Box::pin(async move {
|
|
let model = v.get("model").and_then(|v| v.as_str())
|
|
.ok_or_else(|| anyhow::anyhow!("'model' parameter is required"))?;
|
|
if model.is_empty() { anyhow::bail!("'model' parameter cannot be empty"); }
|
|
if let Some(agent) = agent {
|
|
let mut a = agent.state.lock().await;
|
|
a.pending_model_switch = Some(model.to_string());
|
|
}
|
|
Ok(format!("Switching to model '{}' after this turn.", model))
|
|
})) },
|
|
Tool { name: "pause",
|
|
description: "Pause all autonomous behavior. Only the user can unpause (Ctrl+P or /wake).",
|
|
parameters_json: r#"{"type":"object","properties":{}}"#,
|
|
handler: Arc::new(|agent, _v| Box::pin(async move {
|
|
if let Some(agent) = agent {
|
|
let mut a = agent.state.lock().await;
|
|
a.pending_yield = true;
|
|
a.pending_dmn_pause = true;
|
|
}
|
|
Ok("Pausing autonomous behavior. Only user input will wake you.".into())
|
|
})) },
|
|
Tool { name: "yield_to_user",
|
|
description: "Wait for user input before continuing. The only way to enter a waiting state.",
|
|
parameters_json: r#"{"type":"object","properties":{}}"#,
|
|
handler: Arc::new(|agent, _| Box::pin(async move {
|
|
if let Some(agent) = agent {
|
|
agent.state.lock().await.pending_yield = true;
|
|
}
|
|
Ok(String::new())
|
|
})) },
|
|
]
|
|
}
|