feat: Enhance OAuth module and OpenRouter client functionality
- Updated OAuth module to include unused imports for better clarity. - Refactored OpenRouterClient to improve chat functionality and added support for tools in chat requests. - Modified internet tools (Download, Fetch, Search) to use a more flexible internet mode check. - Introduced new Bash tools for managing background jobs (BashOutput, BashKill). - Enhanced workflow tool to parse and execute workflow scripts with arguments. - Updated status and workflow views to reflect new agent and findings counts. - Added IPC protocol definitions for client requests and state payloads.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use tokio::sync::mpsc;
|
||||
use crate::dto::chat::message::ChatMessage;
|
||||
use crate::tool::{all_tools, tool_is_risky};
|
||||
use super::context::SubagentContext;
|
||||
use super::event::SubagentEvent;
|
||||
|
||||
@@ -21,6 +22,11 @@ pub fn run_subagent(ctx: SubagentContext, tx: mpsc::Sender<SubagentEvent>) -> an
|
||||
let mut messages: Vec<ChatMessage> = Vec::new();
|
||||
messages.push(ChatMessage::system(ctx.system_prompt.clone()));
|
||||
|
||||
let tool_ctx = crate::tool::ToolCtx::builder()
|
||||
.session_dir(ctx.session_dir.clone())
|
||||
.origin(crate::app::state::types::Origin::SubAgent)
|
||||
.build();
|
||||
|
||||
let max_steps = ctx.max_steps.min(MAX_AGENT_STEPS);
|
||||
for step in 0..max_steps {
|
||||
let api_key = std::env::var("OPENROUTER_API_KEY").unwrap_or_default();
|
||||
@@ -55,16 +61,51 @@ pub fn run_subagent(ctx: SubagentContext, tx: mpsc::Sender<SubagentEvent>) -> an
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
let tools = all_tools();
|
||||
for tool_name in &tool_calls {
|
||||
if !ctx.allowed_tools.is_empty() && !ctx.allowed_tools.contains(tool_name) {
|
||||
let explicitly_allowed = ctx.allowed_tools.contains(tool_name);
|
||||
let generally_allowed = ctx.allowed_tools.is_empty() || explicitly_allowed;
|
||||
|
||||
if !generally_allowed {
|
||||
let msg = format!("tool '{}' not allowed for this subagent", tool_name);
|
||||
messages.push(ChatMessage::tool_result("subagent".to_string(), msg));
|
||||
messages.push(ChatMessage::tool_result(tool_name.clone(), msg.clone()));
|
||||
let _ = tx.blocking_send(SubagentEvent::ToolResult {
|
||||
tool: tool_name.clone(),
|
||||
output: msg,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
let _ = tx.blocking_send(SubagentEvent::ToolResult {
|
||||
tool: tool_name.clone(),
|
||||
output: format!("{} executed", tool_name),
|
||||
});
|
||||
|
||||
if tool_is_risky(tool_name) && !explicitly_allowed {
|
||||
let msg = format!("risky tool '{}' requires explicit permission; not allowed for this subagent", tool_name);
|
||||
messages.push(ChatMessage::tool_result(tool_name.clone(), msg.clone()));
|
||||
let _ = tx.blocking_send(SubagentEvent::ToolResult {
|
||||
tool: tool_name.clone(),
|
||||
output: msg,
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
let result = match tools.iter().find(|t| t.name() == *tool_name) {
|
||||
Some(tool) => tool.run(&tool_ctx, &serde_json::json!({})),
|
||||
None => Err(anyhow::anyhow!("tool '{}' not found", tool_name)),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(output_text) => {
|
||||
let _ = tx.blocking_send(SubagentEvent::ToolResult {
|
||||
tool: tool_name.clone(),
|
||||
output: output_text,
|
||||
});
|
||||
}
|
||||
Err(e) => {
|
||||
let msg = format!("tool '{}' failed: {}", tool_name, e);
|
||||
let _ = tx.blocking_send(SubagentEvent::ToolResult {
|
||||
tool: tool_name.clone(),
|
||||
output: msg,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = tx.blocking_send(SubagentEvent::StepCompleted {
|
||||
step,
|
||||
|
||||
Reference in New Issue
Block a user