feat(tui): enhance agent turn handling by grouping parameters and improving message management

This commit is contained in:
asepharyana
2026-07-20 15:21:23 +07:00
parent 9bfb95d795
commit 07b217cf4a
6 changed files with 62 additions and 78 deletions
+6 -33
View File
@@ -13,7 +13,7 @@ const DEFAULT_BASE_URL: &str = "https://opencode.ai/zen/v1";
const DEFAULT_MODEL: &str = "deepseek-v4-flash-free";
pub const DEFAULT_API_KEY: &str = "";
const CONNECT_TIMEOUT: Duration = Duration::from_secs(10);
const REQUEST_TIMEOUT: Duration = Duration::from_secs(60);
const REQUEST_TIMEOUT: Duration = Duration::from_secs(600);
// ---------------------------------------------------------------------------
// Retry helpers
@@ -209,9 +209,8 @@ impl LlmClient {
temperature: Option<f32>,
max_tokens: Option<u32>,
mut on_event: impl FnMut(&StreamEvent) -> bool,
abort_flag: Option<&AtomicBool>,
_abort_flag: Option<&AtomicBool>,
) -> anyhow::Result<(ChatMessage, Option<(u64, u64)>)> {
let tools_for_fallback = tools.clone();
let req = ChatRequest {
model: self.model.clone(),
messages: messages.to_vec(),
@@ -228,21 +227,18 @@ impl LlmClient {
};
let url = format!("{}/chat/completions", self.base_url);
let max_retries_stream = 5;
let max_retries_stream = 3;
let mut attempt = 0u32;
let mut meaningful_content = false;
loop {
attempt += 1;
let mut captured_content = false;
let mut wrapped = |event: &StreamEvent| -> bool {
match event {
StreamEvent::Token(_) | StreamEvent::Reasoning(_) => {
StreamEvent::Token(_) | StreamEvent::Reasoning(_) | StreamEvent::ToolCallDelta { .. } => {
captured_content = true;
}
_ => {
tracing::debug!("unhandled stream event type in wrapped closure");
}
_ => {}
}
on_event(event)
};
@@ -250,13 +246,9 @@ impl LlmClient {
Ok(result) => return Ok(result),
Err(e) => {
let err_str = e.to_string();
if is_auth_error(&err_str) {
if is_auth_error(&err_str) || captured_content {
return Err(e);
}
if captured_content || (attempt >= max_retries_stream) {
meaningful_content = captured_content || meaningful_content;
break;
}
if attempt >= max_retries_stream {
return Err(e);
}
@@ -265,25 +257,6 @@ impl LlmClient {
}
}
}
if meaningful_content {
if let Some(flag) = abort_flag {
if flag.load(std::sync::atomic::Ordering::Relaxed) {
return Err(anyhow::anyhow!("aborted"));
}
}
return self.chat_with_tools_non_streaming(
messages,
tools_for_fallback,
max_tokens,
temperature,
abort_flag,
);
}
Err(anyhow::anyhow!(
"streaming request failed after {max_retries_stream} attempts"
))
}
fn try_stream_once(