api: singleton ApiClient, fix log closure threading
Make ApiClient a process-wide singleton via OnceLock so the connection pool is reused across agent calls. Fix the sync wrapper to properly pass the caller's log closure through thread::scope instead of dropping it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
643f9890df
commit
b04a98c6e5
1 changed files with 17 additions and 13 deletions
|
|
@ -12,6 +12,20 @@ use poc_agent::types::*;
|
|||
use poc_agent::tools::{self, ProcessTracker};
|
||||
use poc_agent::ui_channel::StreamTarget;
|
||||
|
||||
use std::sync::OnceLock;
|
||||
|
||||
static API_CLIENT: OnceLock<ApiClient> = OnceLock::new();
|
||||
|
||||
fn get_client() -> Result<&'static ApiClient, String> {
|
||||
Ok(API_CLIENT.get_or_init(|| {
|
||||
let config = crate::config::get();
|
||||
let base_url = config.api_base_url.as_deref().unwrap_or("");
|
||||
let api_key = config.api_key.as_deref().unwrap_or("");
|
||||
let model = config.api_model.as_deref().unwrap_or("qwen-2.5-27b");
|
||||
ApiClient::new(base_url, api_key, model)
|
||||
}))
|
||||
}
|
||||
|
||||
/// Run an agent prompt through the direct API with tool support.
|
||||
/// Returns the final text response after all tool calls are resolved.
|
||||
pub async fn call_api_with_tools(
|
||||
|
|
@ -19,14 +33,7 @@ pub async fn call_api_with_tools(
|
|||
prompt: &str,
|
||||
log: &dyn Fn(&str),
|
||||
) -> Result<String, String> {
|
||||
let config = crate::config::get();
|
||||
|
||||
let base_url = config.api_base_url.as_deref()
|
||||
.ok_or("api_base_url not configured")?;
|
||||
let api_key = config.api_key.as_deref().unwrap_or("");
|
||||
let model = config.api_model.as_deref().unwrap_or("qwen-2.5-27b");
|
||||
|
||||
let client = ApiClient::new(base_url, api_key, model);
|
||||
let client = get_client()?;
|
||||
|
||||
// Set up a minimal UI channel (we just collect messages, no TUI)
|
||||
let (ui_tx, _ui_rx) = poc_agent::ui_channel::channel();
|
||||
|
|
@ -104,18 +111,15 @@ pub async fn call_api_with_tools(
|
|||
pub fn call_api_with_tools_sync(
|
||||
agent: &str,
|
||||
prompt: &str,
|
||||
log: &dyn Fn(&str),
|
||||
log: &(dyn Fn(&str) + Sync),
|
||||
) -> Result<String, String> {
|
||||
// Run on a new thread to avoid conflicts with any existing runtime
|
||||
let agent = agent.to_string();
|
||||
let prompt = prompt.to_string();
|
||||
std::thread::scope(|s| {
|
||||
s.spawn(|| {
|
||||
let rt = tokio::runtime::Builder::new_current_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.map_err(|e| format!("tokio runtime: {}", e))?;
|
||||
rt.block_on(call_api_with_tools(&agent, &prompt, &|msg| eprintln!("[api] {}", msg)))
|
||||
rt.block_on(call_api_with_tools(agent, prompt, log))
|
||||
}).join().unwrap()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue