revert: remove Rust implementation, keep TypeScript-only idle tool

- Remove idle.rs file completely
- Revert all agent mode files to remove Idle tool integration
- Revert mod.rs to remove idle module
- Keep TypeScript implementation in packages/ai:
  - idle-tool.ts
  - index.ts export
  - analyst-agent.ts integration

Addresses user feedback to implement idle tool only in TypeScript packages/ai

Co-Authored-By: Dallin Bentley <dallinbentley98@gmail.com>
This commit is contained in:
Devin AI 2025-07-21 18:09:19 +00:00
parent 6f6e3ffbc9
commit 5ca93b6de5
6 changed files with 8 additions and 178 deletions

View File

@ -18,7 +18,7 @@ use crate::tools::{
CreateDashboardFilesTool, CreateMetricFilesTool, ModifyDashboardFilesTool,
ModifyMetricFilesTool, SearchDataCatalogTool,
},
response_tools::{Done, Idle},
response_tools::Done,
},
IntoToolCallExecutor,
};
@ -67,7 +67,6 @@ pub fn get_configuration(agent_data: &ModeAgentData, data_source_syntax: Option<
let create_dashboard_files_tool = CreateDashboardFilesTool::new(agent_clone.clone());
let modify_dashboard_files_tool = ModifyDashboardFilesTool::new(agent_clone.clone());
let done_tool = Done::new(agent_clone.clone());
let idle_tool = Idle::new(agent_clone.clone());
let search_data_catalog_tool = SearchDataCatalogTool::new(agent_clone.clone());
// --- Define Conditions based on Agent State (as per original load_tools) ---
@ -145,13 +144,6 @@ pub fn get_configuration(agent_data: &ModeAgentData, data_source_syntax: Option<
.add_tool(
done_tool.get_name(),
done_tool.into_tool_call_executor(),
done_condition.clone(),
)
.await;
agent_clone
.add_tool(
idle_tool.get_name(),
idle_tool.into_tool_call_executor(),
done_condition,
)
.await;
@ -168,7 +160,7 @@ pub fn get_configuration(agent_data: &ModeAgentData, data_source_syntax: Option<
});
// 4. Define terminating tools for this mode
let terminating_tools = vec![Done::get_name(), Idle::get_name()];
let terminating_tools = vec![Done::get_name()];
// 5. Construct and return the ModeConfiguration
ModeConfiguration {

View File

@ -18,7 +18,7 @@ use crate::tools::{
ModifyMetricFilesTool, SearchDataCatalogTool,
},
planning_tools::{CreatePlanInvestigative, CreatePlanStraightforward},
response_tools::{Done, Idle, MessageUserClarifyingQuestion},
response_tools::{Done, MessageUserClarifyingQuestion},
utility_tools::no_search_needed::NoSearchNeededTool,
},
planning_tools::ReviewPlan,
@ -65,7 +65,6 @@ pub fn get_configuration(agent_data: &ModeAgentData) -> ModeConfiguration {
let modify_dashboard_files_tool = ModifyDashboardFilesTool::new(agent_clone.clone());
let message_user_clarifying_question_tool = MessageUserClarifyingQuestion::new();
let done_tool = Done::new(agent_clone.clone());
let idle_tool = Idle::new(agent_clone.clone());
let review_tool = ReviewPlan::new(agent_clone.clone());
// --- Define Conditions based on Agent State (as per original load_tools) ---
@ -173,13 +172,6 @@ pub fn get_configuration(agent_data: &ModeAgentData) -> ModeConfiguration {
.add_tool(
done_tool.get_name(),
done_tool.into_tool_call_executor(),
always_available.clone(),
)
.await;
agent_clone
.add_tool(
idle_tool.get_name(),
idle_tool.into_tool_call_executor(),
always_available,
)
.await;
@ -194,7 +186,6 @@ pub fn get_configuration(agent_data: &ModeAgentData) -> ModeConfiguration {
// Use hardcoded names if static access isn't available
"message_user_clarifying_question".to_string(), // Assuming this is the name
"finish_and_respond".to_string(), // Assuming this is the name for Done tool
Idle::get_name(), // Add idle tool
];
// 5. Construct and return the ModeConfiguration

View File

@ -15,7 +15,7 @@ use super::{ModeAgentData, ModeConfiguration};
use crate::tools::{
categories::{
planning_tools::{CreatePlanInvestigative, CreatePlanStraightforward},
response_tools::{Done, Idle, MessageUserClarifyingQuestion},
response_tools::{Done, MessageUserClarifyingQuestion},
},
IntoToolCallExecutor,
};
@ -56,7 +56,6 @@ pub fn get_configuration(
CreatePlanStraightforward::new(agent_clone.clone());
let create_plan_investigative_tool = CreatePlanInvestigative::new(agent_clone.clone());
let done_tool = Done::new(agent_clone.clone());
let idle_tool = Idle::new(agent_clone.clone());
let clarify_tool = MessageUserClarifyingQuestion::new();
// Condition (always true for this mode's tools)
@ -87,14 +86,6 @@ pub fn get_configuration(
)
.await;
agent_clone
.add_tool(
idle_tool.get_name(),
idle_tool.into_tool_call_executor(),
condition.clone(),
)
.await;
agent_clone
.add_tool(
clarify_tool.get_name(),
@ -111,7 +102,7 @@ pub fn get_configuration(
prompt,
model,
tool_loader,
terminating_tools: vec![Done::get_name(), Idle::get_name(), MessageUserClarifyingQuestion::get_name()],
terminating_tools: vec![Done::get_name(), MessageUserClarifyingQuestion::get_name()],
}
}

View File

@ -13,7 +13,7 @@ use super::{ModeAgentData, ModeConfiguration};
// Import necessary tools for this mode
use crate::tools::{
categories::response_tools::{Done, Idle, MessageUserClarifyingQuestion},
categories::response_tools::{Done, MessageUserClarifyingQuestion},
planning_tools::ReviewPlan,
IntoToolCallExecutor,
};
@ -46,7 +46,6 @@ pub fn get_configuration(
// Instantiate tools for this mode
let review_tool = ReviewPlan::new(agent_clone.clone());
let done_tool = Done::new(agent_clone.clone());
let idle_tool = Idle::new(agent_clone.clone());
// Condition (always true for this mode's tools)
let condition = Some(|_state: &HashMap<String, Value>| -> bool { true });
@ -68,20 +67,12 @@ pub fn get_configuration(
)
.await;
agent_clone
.add_tool(
idle_tool.get_name(),
idle_tool.into_tool_call_executor(),
condition.clone(),
)
.await;
Ok(())
})
});
// 4. Define terminating tools for this mode (From original load_tools)
let terminating_tools = vec![Done::get_name(), Idle::get_name()];
let terminating_tools = vec![Done::get_name()];
// 5. Construct and return the ModeConfiguration
ModeConfiguration {

View File

@ -1,133 +0,0 @@
use anyhow::Result;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::sync::Arc;
use crate::{agent::Agent, tools::ToolExecutor};
#[derive(Debug, Deserialize, Serialize)]
pub struct IdleInput {
final_response: String,
}
// Define the new standard output struct
#[derive(Debug, Serialize, Deserialize)]
pub struct IdleOutput {
pub success: bool,
pub todos: String,
}
pub struct Idle {
agent: Arc<Agent>,
}
impl Idle {
pub fn new(agent: Arc<Agent>) -> Self {
Self { agent }
}
pub fn get_name() -> String {
"idle".to_string()
}
}
#[async_trait]
impl ToolExecutor for Idle {
type Output = IdleOutput;
type Params = IdleInput;
fn get_name(&self) -> String {
"idle".to_string()
}
async fn execute(&self, params: Self::Params, _tool_call_id: String) -> Result<Self::Output> {
// Get the current todos from state
let mut todos = match self.agent.get_state_value("todos").await {
Some(Value::Array(arr)) => arr,
_ => {
// If no todos exist, just return success without a list
return Ok(IdleOutput {
success: true,
todos: "No to-do list found.".to_string(),
});
}
};
let mut marked_by_idle = vec![]; // Track items marked by this tool
// Mark all remaining unfinished todos as complete
for (idx, todo_val) in todos.iter_mut().enumerate() {
if let Value::Object(map) = todo_val {
let is_completed = map
.get("completed")
.and_then(Value::as_bool)
.unwrap_or(false);
if !is_completed {
map.insert("completed".to_string(), Value::Bool(true));
marked_by_idle.push(idx); // Track 0-based index
}
} else {
// Handle invalid item format if necessary, maybe log a warning?
eprintln!("Warning: Invalid todo item format at index {}", idx);
}
}
// Save the updated todos back to state
self.agent
.set_state_value("todos".to_string(), Value::Array(todos.clone()))
.await; // Clone needed for iteration below
// Format the output string, potentially noting items marked by 'idle'
let todos_string = todos
.iter()
.enumerate()
.map(|(idx, todo_val)| {
if let Value::Object(map) = todo_val {
let completed = map
.get("completed")
.and_then(Value::as_bool)
.unwrap_or(false); // Should always be true now
let todo_text = map
.get("todo")
.and_then(Value::as_str)
.unwrap_or("Invalid todo text");
let annotation = if marked_by_idle.contains(&idx) {
" *Marked complete by calling the idle tool"
} else {
""
};
format!("[x] {}{}", todo_text, annotation)
} else {
"Invalid todo item format".to_string()
}
})
.collect::<Vec<_>>()
.join("\n");
Ok(IdleOutput {
success: true,
todos: todos_string,
}) // Include todos in output
}
async fn get_schema(&self) -> Value {
serde_json::json!({
"name": self.get_name(),
"description": "Marks all remaining unfinished tasks as complete, sends a final response to the user, and enters an idle state. Use this when current work is finished but the agent should remain available for future tasks. This must be in markdown format and not use the '•' bullet character.",
"parameters": {
"type": "object",
"required": [
"final_response"
],
"properties": {
"final_response": {
"type": "string",
"description": "The final response message to the user. **MUST** be formatted in Markdown. Use bullet points or other appropriate Markdown formatting. Do not include headers. Do not use the '•' bullet character. Do not include markdown tables."
}
},
"additionalProperties": false
}
})
}
}

View File

@ -1,7 +1,5 @@
pub mod message_user_clarifying_question;
pub mod done;
pub mod idle;
pub use message_user_clarifying_question::*;
pub use done::*;
pub use idle::*;
pub use done::*;