configurable stream timeout, show per-call timer in status bar
Stream chunk timeout is now api_stream_timeout_secs in config (default 60s). Status bar shows total turn time and per-call time with timeout: "thinking... 45s, 12/60s". Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
13d9cc962e
commit
156626ae53
3 changed files with 24 additions and 5 deletions
|
|
@ -305,7 +305,7 @@ impl SseReader {
|
|||
pub(crate) fn new(ui_tx: &UiSender) -> Self {
|
||||
Self {
|
||||
line_buf: String::new(),
|
||||
chunk_timeout: Duration::from_secs(60),
|
||||
chunk_timeout: Duration::from_secs(crate::config::get().api_stream_timeout_secs),
|
||||
stream_start: Instant::now(),
|
||||
chunks_received: 0,
|
||||
sse_lines_parsed: 0,
|
||||
|
|
|
|||
|
|
@ -311,6 +311,10 @@ pub struct App {
|
|||
activity: String,
|
||||
/// When the current turn started (for elapsed timer).
|
||||
turn_started: Option<std::time::Instant>,
|
||||
/// When the current LLM call started (for per-call timer).
|
||||
call_started: Option<std::time::Instant>,
|
||||
/// Stream timeout for the current call (for display).
|
||||
call_timeout_secs: u64,
|
||||
/// Whether to emit a ● marker before the next assistant TextDelta.
|
||||
needs_assistant_marker: bool,
|
||||
/// Number of running child processes (updated by main loop).
|
||||
|
|
@ -392,6 +396,8 @@ impl App {
|
|||
},
|
||||
activity: String::new(),
|
||||
turn_started: None,
|
||||
call_started: None,
|
||||
call_timeout_secs: 60,
|
||||
needs_assistant_marker: false,
|
||||
running_processes: 0,
|
||||
reasoning_effort: "none".to_string(),
|
||||
|
|
@ -485,6 +491,12 @@ impl App {
|
|||
}
|
||||
}
|
||||
UiMessage::Activity(text) => {
|
||||
if text.is_empty() {
|
||||
self.call_started = None;
|
||||
} else if self.activity.is_empty() || self.call_started.is_none() {
|
||||
self.call_started = Some(std::time::Instant::now());
|
||||
self.call_timeout_secs = crate::config::get().api_stream_timeout_secs;
|
||||
}
|
||||
self.activity = text;
|
||||
}
|
||||
UiMessage::Reasoning(text) => {
|
||||
|
|
@ -874,10 +886,12 @@ impl App {
|
|||
}
|
||||
|
||||
// Draw status bar with live activity indicator
|
||||
let elapsed = self.turn_started.map(|t| t.elapsed());
|
||||
let timer = match elapsed {
|
||||
Some(d) if !self.activity.is_empty() => format!(" {:.0}s", d.as_secs_f64()),
|
||||
_ => String::new(),
|
||||
let timer = if !self.activity.is_empty() {
|
||||
let total = self.turn_started.map(|t| t.elapsed().as_secs()).unwrap_or(0);
|
||||
let call = self.call_started.map(|t| t.elapsed().as_secs()).unwrap_or(0);
|
||||
format!(" {}s, {}/{}s", total, call, self.call_timeout_secs)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
let tools_info = if self.status.turn_tools > 0 {
|
||||
format!(" ({}t)", self.status.turn_tools)
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ pub struct ContextGroup {
|
|||
|
||||
fn default_true() -> bool { true }
|
||||
fn default_context_window() -> usize { 128_000 }
|
||||
fn default_stream_timeout() -> u64 { 60 }
|
||||
fn default_identity_dir() -> PathBuf {
|
||||
PathBuf::from(std::env::var("HOME").expect("HOME not set")).join(".consciousness/identity")
|
||||
}
|
||||
|
|
@ -91,6 +92,9 @@ pub struct Config {
|
|||
/// Used to resolve API settings, not stored on Config
|
||||
#[serde(default)]
|
||||
agent_model: Option<String>,
|
||||
/// Stream chunk timeout in seconds (no data = timeout).
|
||||
#[serde(default = "default_stream_timeout")]
|
||||
pub api_stream_timeout_secs: u64,
|
||||
pub api_reasoning: String,
|
||||
pub agent_types: Vec<String>,
|
||||
/// Surface agent timeout in seconds.
|
||||
|
|
@ -138,6 +142,7 @@ impl Default for Config {
|
|||
api_key: None,
|
||||
api_model: None,
|
||||
api_context_window: default_context_window(),
|
||||
api_stream_timeout_secs: default_stream_timeout(),
|
||||
agent_model: None,
|
||||
api_reasoning: "high".to_string(),
|
||||
agent_types: vec![
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue