pub struct AppState {Show 17 fields
pub config: Arc<Config>,
pub sessions: SessionStore,
pub agents: Arc<HashMap<AgentKind, Arc<dyn Agent>>>,
pub bot_token: SlackApiToken,
pub slack_client: Arc<SlackHyperClient>,
pub repo_channels: Arc<RwLock<HashMap<String, String>>>,
pub bot_user_id: Arc<String>,
pub in_progress: Arc<Mutex<HashSet<String>>>,
pub pending_repos: Arc<Mutex<HashMap<String, Instant>>>,
pub pending_session_ids: Arc<Mutex<HashSet<String>>>,
pub agent_handles: Arc<Mutex<HashMap<String, AgentHandle>>>,
pub kill_senders: Arc<Mutex<HashMap<String, Sender<()>>>>,
pub last_plan: Arc<Mutex<HashMap<String, String>>>,
pub pending_answers: Arc<Mutex<HashMap<String, Sender<String>>>>,
pub pending_tool_approvals: Arc<Mutex<HashMap<String, Sender<bool>>>>,
pub rate_limiter: Arc<Mutex<HashMap<String, Instant>>>,
pub thread_models: Arc<Mutex<HashMap<String, String>>>,
}Expand description
Shared application state passed to all handlers.
Fields§
§config: Arc<Config>§sessions: SessionStore§agents: Arc<HashMap<AgentKind, Arc<dyn Agent>>>§bot_token: SlackApiToken§slack_client: Arc<SlackHyperClient>§repo_channels: Arc<RwLock<HashMap<String, String>>>Repo name → channel ID mapping (populated on startup).
bot_user_id: Arc<String>Bot’s own user ID (to filter self-messages).
in_progress: Arc<Mutex<HashSet<String>>>Concurrency guard: set of thread_ts currently being processed.
pending_repos: Arc<Mutex<HashMap<String, Instant>>>Repos with in-flight new message processing (prevents sync from duplicating threads). Tracks repo name → timestamp when marked pending for cleanup.
pending_session_ids: Arc<Mutex<HashSet<String>>>Session IDs currently being claimed (not yet persisted to SessionStore). Prevents race between sync and handle_new_message where both try to claim the same session.
agent_handles: Arc<Mutex<HashMap<String, AgentHandle>>>Running agent processes: thread_ts → AgentHandle.
kill_senders: Arc<Mutex<HashMap<String, Sender<()>>>>Kill senders: thread_ts → oneshot kill signal.
Stored separately so !stop can always reach the kill signal
even when the handle is borrowed by a running task.
last_plan: Arc<Mutex<HashMap<String, String>>>Last detected plan content per thread: thread_ts → plan text.
pending_answers: Arc<Mutex<HashMap<String, Sender<String>>>>Pending question answers: thread_ts → oneshot sender for the user’s reply.
pending_tool_approvals: Arc<Mutex<HashMap<String, Sender<bool>>>>Pending tool approvals: thread_ts → oneshot sender for the user’s allow/deny.
rate_limiter: Arc<Mutex<HashMap<String, Instant>>>Per-channel rate limiter: channel_id → last write time.
thread_models: Arc<Mutex<HashMap<String, String>>>Per-thread model overrides from /model command: thread_ts → model ID.
Implementations§
Source§impl AppState
impl AppState
pub fn is_allowed_user(&self, user_id: &str) -> bool
Sourcepub async fn repo_for_channel(&self, channel_id: &str) -> Option<String>
pub async fn repo_for_channel(&self, channel_id: &str) -> Option<String>
Look up which repo a channel belongs to.
Sourcepub async fn try_claim_session_for_sync(
&self,
repo_name: &str,
session_id: &str,
) -> bool
pub async fn try_claim_session_for_sync( &self, repo_name: &str, session_id: &str, ) -> bool
Atomically claim a new session for sync if:
- The session_id is not already owned by Hermes (in SessionStore or pending)
- The repo doesn’t have an in-flight new message
Returns true if the claim succeeded, false if already claimed. On success, the session_id is added to pending_session_ids (caller must remove it later).
Sourcepub async fn release_claimed_session(&self, session_id: &str)
pub async fn release_claimed_session(&self, session_id: &str)
Release a claimed session ID (called after session is persisted to SessionStore).
Sourcepub async fn cleanup_stale_pending_repos(&self)
pub async fn cleanup_stale_pending_repos(&self)
Clean up repos that have been pending for too long (>5 minutes). This handles cases where PendingRepoGuard drop fails silently.
Sourcepub fn is_live_mode(&self) -> bool
pub fn is_live_mode(&self) -> bool
Whether we’re in “live” streaming mode (edit messages in real-time).