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:
asepharyana
2026-07-11 20:21:59 +07:00
parent c1ad206a00
commit 802d9677ae
42 changed files with 1423 additions and 925 deletions
-2
View File
@@ -1,4 +1,2 @@
#[expect(dead_code)]
pub mod tools;
#[expect(dead_code)]
pub mod turn;
+3 -24
View File
@@ -1,24 +1,3 @@
use crate::tool::{ToolCtx, all_tools};
use serde_json::Value;
use anyhow::Result;
pub fn execute_tool_call(name: &str, args: &Value, ctx: &ToolCtx) -> Result<String> {
let tools = all_tools();
for tool in &tools {
if tool.name() == name {
return tool.run(ctx, args);
}
}
Err(anyhow::anyhow!("tool not found: {}", name))
}
#[expect(dead_code)]
pub fn execute_deferred_tool(name: &str, args: &Value, ctx: &ToolCtx) -> Result<String> {
let tools = all_tools();
for tool in &tools {
if tool.name() == name {
return tool.run(ctx, args);
}
}
Err(anyhow::anyhow!("deferred tool not found: {}", name))
}
// Tool execution dispatch — superseded by inline per-tool call in
// app::runtime::actions::execute_one_tool within the SubmitInput loop.
// This module is preserved as a placeholder.
+4 -70
View File
@@ -1,70 +1,4 @@
use crate::app::state::rest::AppStateRest;
use crate::app::runtime::actions::{Action, apply_action};
pub fn advance_turn(state: &mut AppStateRest) {
if state.session_runtime.is_none() {
return;
}
let rt = state.session_runtime.as_mut().unwrap();
if rt.messages.is_empty() {
return;
}
let api_key = state.settings.api_key.clone();
let model = state.settings.model.clone();
let msgs = rt.messages.clone();
let pending = state.pending_api_response.clone();
if let Some(key) = api_key {
if !key.is_empty() {
std::thread::spawn(move || {
let client = crate::service::openrouter::OpenRouterClient::new(key, model);
match client.chat(&msgs) {
Ok(response) => {
if let Ok(mut guard) = pending.lock() {
*guard = Some(response);
}
}
Err(e) => {
if let Ok(mut guard) = pending.lock() {
*guard = Some(format!("Error: {}", e));
}
}
}
});
}
}
}
#[expect(dead_code)]
pub fn process_tools(state: &mut AppStateRest) {
let tool_calls: Vec<_> = {
let rt = match state.session_runtime.as_ref() {
Some(r) => r,
None => return,
};
rt.pending_tool_queue.clone()
};
if tool_calls.is_empty() {
return;
}
for tool_call in &tool_calls {
let _result = format!("processing tool: {}", tool_call.tool_name);
}
}
#[expect(dead_code)]
pub fn finish_tool_round(state: &mut AppStateRest) {
let tool_count = {
let rt = match state.session_runtime.as_ref() {
Some(r) => r,
None => return,
};
rt.tool_call_results.len()
};
if tool_count > 0 {
let note = format!("{} tool calls completed", tool_count);
apply_action(state, Action::SystemNote {
kind: "tool_round".to_string(),
message: note,
});
}
}
// Stream module — superseded by the inline tool-calling loop in
// app::runtime::actions (Action::SubmitInput / Tick pipeline).
// This module is preserved as a placeholder; all previous content
// has been removed since it duplicated logic now in actions/mod.rs.