agy_bridge/runtime/config.rs
1//! Runtime configuration types: [`RuntimeConfig`] and [`BackendLogLevel`].
2
3use std::time::Duration;
4
5use super::{DEFAULT_CHANNEL_CAPACITY, DEFAULT_INTER_AGENT_DELAY, DEFAULT_SHUTDOWN_TIMEOUT};
6
7/// Log verbosity for the agent backend runtime.
8///
9/// Controls the logging level of the underlying agent runtime. This is
10/// intentionally backend-agnostic — consumers should not need to know
11/// the implementation details of the runtime layer.
12#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
13#[serde(rename_all = "lowercase")]
14pub enum BackendLogLevel {
15 /// Errors only.
16 Error,
17 /// Warnings and errors (default — matches upstream SDK behavior).
18 #[default]
19 Warn,
20 /// Informational messages (verbose — includes raw protocol traffic).
21 Info,
22 /// Full debug output.
23 Debug,
24}
25
26impl BackendLogLevel {
27 /// Return the lowercase string representation used by the Python side.
28 #[must_use]
29 pub fn as_str(self) -> &'static str {
30 match self {
31 Self::Error => "error",
32 Self::Warn => "warn",
33 Self::Info => "info",
34 Self::Debug => "debug",
35 }
36 }
37}
38
39impl std::fmt::Display for BackendLogLevel {
40 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41 f.write_str(self.as_str())
42 }
43}
44
45/// Configuration for the bridge runtime.
46#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
47#[serde(default)]
48pub struct RuntimeConfig {
49 /// Channel buffer size for the command channel.
50 pub channel_capacity: usize,
51 /// Timeout for joining the Python thread on shutdown.
52 pub shutdown_timeout: Duration,
53 /// Delay injected between successive chat commands to prevent burst requests.
54 pub inter_agent_delay: Duration,
55 /// Backend runtime log verbosity.
56 ///
57 /// Defaults to `Warn`, matching the upstream SDK's default behavior.
58 /// Set to `Info` or `Debug` for verbose protocol-level diagnostics.
59 pub backend_log_level: BackendLogLevel,
60 /// Maximum number of consecutive model-quality error steps before the
61 /// bridge aborts the stream. `None` uses the built-in default (3).
62 /// Set to `0` to disable the limit entirely (pure SDK pass-through).
63 pub max_consecutive_model_errors: Option<u32>,
64 /// Maximum number of consecutive thinking-only/empty steps before the
65 /// bridge aborts the stream. `None` uses the built-in default (500).
66 /// Set to `0` to disable the limit entirely (pure SDK pass-through).
67 pub max_consecutive_empty_steps: Option<u32>,
68 /// Buffer size for streaming response channels.
69 /// `None` uses the built-in default (256). Each chat call creates
70 /// ~7 channels of this size.
71 pub streaming_channel_buffer: Option<usize>,
72}
73
74impl Default for RuntimeConfig {
75 fn default() -> Self {
76 Self {
77 channel_capacity: DEFAULT_CHANNEL_CAPACITY,
78 shutdown_timeout: DEFAULT_SHUTDOWN_TIMEOUT,
79 inter_agent_delay: DEFAULT_INTER_AGENT_DELAY,
80 backend_log_level: BackendLogLevel::default(),
81 max_consecutive_model_errors: None,
82 max_consecutive_empty_steps: None,
83 streaming_channel_buffer: None,
84 }
85 }
86}