use crate::telemetry::ToolMetricsRegistry;
use super::AppState;
impl AppState {
pub(crate) fn metrics(&self) -> &ToolMetricsRegistry {
self.metrics.as_ref()
}
pub(crate) fn push_recent_tool(&self, name: &str) {
self.recent_tools.push(name.to_owned());
}
pub(crate) fn doom_loop_count(
&self,
session_id: &str,
name: &str,
args_hash: u64,
) -> (usize, bool) {
let mut counters = self
.doom_loop_counter
.lock()
.unwrap_or_else(|p| p.into_inner());
let now = Self::now_ms();
let entry = counters
.entry(session_id.to_owned())
.or_insert_with(|| (String::new(), 0, 0, now));
if entry.0 == name && entry.1 == args_hash {
entry.2 += 1;
} else {
*entry = (name.to_owned(), args_hash, 1, now);
}
let is_rapid = entry.2 >= 3 && (now.saturating_sub(entry.3) < 10_000);
(entry.2, is_rapid)
}
pub(crate) fn recent_tools(&self) -> Vec<String> {
self.recent_tools.snapshot()
}
pub(crate) fn record_file_access(&self, path: &str) {
self.recent_files.push_dedup(path);
}
pub(crate) fn recent_file_paths(&self) -> Vec<String> {
self.recent_files.snapshot()
}
pub(crate) fn push_recent_analysis_id(&self, id: String) {
self.recent_analysis_ids.push(id);
}
pub(crate) fn recent_analysis_ids(&self) -> Vec<String> {
self.recent_analysis_ids.snapshot()
}
pub(crate) fn token_budget(&self) -> usize {
self.token_budget.load(std::sync::atomic::Ordering::Relaxed)
}
pub(crate) fn set_token_budget(&self, budget: usize) {
self.token_budget
.store(budget, std::sync::atomic::Ordering::Relaxed);
}
}