fix(channel): clamp configurable timeout to minimum 30s
This commit is contained in:
parent
41a6ed30dd
commit
d548caa5f3
2 changed files with 22 additions and 1 deletions
|
|
@ -65,6 +65,7 @@ Notes:
|
||||||
|
|
||||||
- Default `300s` is optimized for on-device LLMs (Ollama) which are slower than cloud APIs.
|
- Default `300s` is optimized for on-device LLMs (Ollama) which are slower than cloud APIs.
|
||||||
- If using cloud APIs (OpenAI, Anthropic, etc.), you can reduce this to `60` or lower.
|
- If using cloud APIs (OpenAI, Anthropic, etc.), you can reduce this to `60` or lower.
|
||||||
|
- Values below `30` are clamped to `30` to avoid immediate timeout churn.
|
||||||
- When a timeout occurs, users receive: `⚠️ Request timed out while waiting for the model. Please try again.`
|
- When a timeout occurs, users receive: `⚠️ Request timed out while waiting for the model. Please try again.`
|
||||||
|
|
||||||
See detailed channel matrix and allowlist behavior in [channels-reference.md](channels-reference.md).
|
See detailed channel matrix and allowlist behavior in [channels-reference.md](channels-reference.md).
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ const BOOTSTRAP_MAX_CHARS: usize = 20_000;
|
||||||
|
|
||||||
const DEFAULT_CHANNEL_INITIAL_BACKOFF_SECS: u64 = 2;
|
const DEFAULT_CHANNEL_INITIAL_BACKOFF_SECS: u64 = 2;
|
||||||
const DEFAULT_CHANNEL_MAX_BACKOFF_SECS: u64 = 60;
|
const DEFAULT_CHANNEL_MAX_BACKOFF_SECS: u64 = 60;
|
||||||
|
const MIN_CHANNEL_MESSAGE_TIMEOUT_SECS: u64 = 30;
|
||||||
/// Default timeout for processing a single channel message (LLM + tools).
|
/// Default timeout for processing a single channel message (LLM + tools).
|
||||||
/// Used as fallback when not configured in channels_config.message_timeout_secs.
|
/// Used as fallback when not configured in channels_config.message_timeout_secs.
|
||||||
const CHANNEL_MESSAGE_TIMEOUT_SECS: u64 = 300;
|
const CHANNEL_MESSAGE_TIMEOUT_SECS: u64 = 300;
|
||||||
|
|
@ -73,6 +74,10 @@ const MODEL_CACHE_PREVIEW_LIMIT: usize = 10;
|
||||||
type ProviderCacheMap = Arc<Mutex<HashMap<String, Arc<dyn Provider>>>>;
|
type ProviderCacheMap = Arc<Mutex<HashMap<String, Arc<dyn Provider>>>>;
|
||||||
type RouteSelectionMap = Arc<Mutex<HashMap<String, ChannelRouteSelection>>>;
|
type RouteSelectionMap = Arc<Mutex<HashMap<String, ChannelRouteSelection>>>;
|
||||||
|
|
||||||
|
fn effective_channel_message_timeout_secs(configured: u64) -> u64 {
|
||||||
|
configured.max(MIN_CHANNEL_MESSAGE_TIMEOUT_SECS)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
struct ChannelRouteSelection {
|
struct ChannelRouteSelection {
|
||||||
provider: String,
|
provider: String,
|
||||||
|
|
@ -1811,6 +1816,8 @@ pub async fn start_channels(config: Config) -> Result<()> {
|
||||||
|
|
||||||
let mut provider_cache_seed: HashMap<String, Arc<dyn Provider>> = HashMap::new();
|
let mut provider_cache_seed: HashMap<String, Arc<dyn Provider>> = HashMap::new();
|
||||||
provider_cache_seed.insert(provider_name.clone(), Arc::clone(&provider));
|
provider_cache_seed.insert(provider_name.clone(), Arc::clone(&provider));
|
||||||
|
let message_timeout_secs =
|
||||||
|
effective_channel_message_timeout_secs(config.channels_config.message_timeout_secs);
|
||||||
|
|
||||||
let runtime_ctx = Arc::new(ChannelRuntimeContext {
|
let runtime_ctx = Arc::new(ChannelRuntimeContext {
|
||||||
channels_by_name,
|
channels_by_name,
|
||||||
|
|
@ -1833,7 +1840,7 @@ pub async fn start_channels(config: Config) -> Result<()> {
|
||||||
reliability: Arc::new(config.reliability.clone()),
|
reliability: Arc::new(config.reliability.clone()),
|
||||||
provider_runtime_options,
|
provider_runtime_options,
|
||||||
workspace_dir: Arc::new(config.workspace_dir.clone()),
|
workspace_dir: Arc::new(config.workspace_dir.clone()),
|
||||||
message_timeout_secs: config.channels_config.message_timeout_secs,
|
message_timeout_secs,
|
||||||
});
|
});
|
||||||
|
|
||||||
run_message_dispatch_loop(rx, runtime_ctx, max_in_flight_messages).await;
|
run_message_dispatch_loop(rx, runtime_ctx, max_in_flight_messages).await;
|
||||||
|
|
@ -1879,6 +1886,19 @@ mod tests {
|
||||||
tmp
|
tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn effective_channel_message_timeout_secs_clamps_to_minimum() {
|
||||||
|
assert_eq!(
|
||||||
|
effective_channel_message_timeout_secs(0),
|
||||||
|
MIN_CHANNEL_MESSAGE_TIMEOUT_SECS
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
effective_channel_message_timeout_secs(15),
|
||||||
|
MIN_CHANNEL_MESSAGE_TIMEOUT_SECS
|
||||||
|
);
|
||||||
|
assert_eq!(effective_channel_message_timeout_secs(300), 300);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct RecordingChannel {
|
struct RecordingChannel {
|
||||||
sent_messages: tokio::sync::Mutex<Vec<String>>,
|
sent_messages: tokio::sync::Mutex<Vec<String>>,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue