fix: resolve deferred review items from PRs #883, #848, #788 (#915)

Address three deferred implementation items flagged during code review:

1. SIGHUP lock held across .await (#883): Split restart_with_addr into
   merged_router_clone() + install_listener() so the async TcpListener
   bind happens outside the mutex, eliminating lock contention risk.

2. Recursion depth limit for check_strings (#848): Cap JSON traversal
   at 32 levels to prevent stack overflow on pathological tool params.

3. Named error type for add_tokens (#788): Replace Result<(), String>
   with TokenBudgetExceeded { used, limit } for type-safe budget errors.

Co-authored-by: Claude Opus 4.6 <[email protected]>
This commit is contained in:
Illia Polosukhin
2026-03-11 07:12:45 +00:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 369741fc60
commit 8f513428f1
6 changed files with 174 additions and 75 deletions
+1 -1
View File
@@ -12,4 +12,4 @@ mod state;
pub use manager::ContextManager;
pub use memory::{ActionRecord, ConversationMemory, Memory};
pub use state::{JobContext, JobState, StateTransition};
pub use state::{JobContext, JobState, StateTransition, TokenBudgetExceeded};
+17 -7
View File
@@ -11,6 +11,16 @@ use uuid::Uuid;
use crate::llm::recording::HttpInterceptor;
/// Error returned when a job exceeds its token budget.
#[derive(Debug, thiserror::Error)]
#[error("Token budget exceeded: used {used} of {limit} allowed tokens")]
pub struct TokenBudgetExceeded {
/// Total tokens consumed (including the call that exceeded the budget).
pub used: u64,
/// Configured token limit for this job.
pub limit: u64,
}
/// State of a job.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
@@ -265,15 +275,15 @@ impl JobContext {
self.actual_cost += cost;
}
/// Record token usage from an LLM call. Returns an error string if the
/// token budget has been exceeded after this addition.
pub fn add_tokens(&mut self, tokens: u64) -> Result<(), String> {
/// Record token usage from an LLM call. Returns an error if the token
/// budget has been exceeded after this addition.
pub fn add_tokens(&mut self, tokens: u64) -> Result<(), TokenBudgetExceeded> {
self.total_tokens_used += tokens;
if self.max_tokens > 0 && self.total_tokens_used > self.max_tokens {
Err(format!(
"Token budget exceeded: used {} of {} allowed tokens",
self.total_tokens_used, self.max_tokens
))
Err(TokenBudgetExceeded {
used: self.total_tokens_used,
limit: self.max_tokens,
})
} else {
Ok(())
}