opencrabs 0.3.58

The autonomous, self-improving AI agent. Single Rust binary. Every channel. Install with: cargo install opencrabs
//! Project-author-original rolling status quips for the Telegram
//! pre-tool reasoning phase.
//!
//! When the agent has been thinking for a while without yet calling a
//! tool, the status line falls back to one of these. They rotate every
//! ~15s so a 3-minute reasoning phase doesn't show the same message
//! for the entire wait (the bug observed 2026-06-03: "Marathon mode โ€”
//! still on: <preview>" stuck for 3+ minutes because the previous
//! `pre_tool_rolling` only had four elapsed-time buckets and ran out
//! of variation past 60s).
//!
//! The list is the exact set introduced in commit `f5b5de1a`
//! (2026-05, "feat: rolling status quips on Telegram during long tool
//! execution") and consistent across every commit that touched it
//! through `512bf002` where it was removed. Restored verbatim.

/// The rolling-status quip pool, verbatim from `f5b5de1a`. Order
/// matters โ€” `rotating_quip` indexes into this slice with
/// `(elapsed_secs / WINDOW_SECS) % len`, so reordering the entries
/// changes which one users see first.
pub(crate) const TOOL_STATUS_QUIPS: &[&str] = &[
    "โ˜• Grab a coffee โ€” my sub-agents are on fire right now",
    "๐Ÿฆ€ My crabs are working their claws off โ€” hang tight",
    "๐Ÿ”ฅ Still cooking... deep in the code",
    "โšก Sub-agents going brrr โ€” almost there",
    "๐Ÿง  Thinking hard so you don't have to",
    "๐Ÿ—๏ธ Building something beautiful โ€” one sec",
    "๐ŸŽฏ Locked in โ€” the crabs are laser-focused",
    "๐Ÿš€ Full speed ahead โ€” engines at max",
    "๐Ÿ’ช Crunching through the code like a boss",
    "๐ŸŒŠ Riding the wave โ€” results incoming",
    "๐ŸŽช The circus is in town โ€” all crabs performing",
    "๐Ÿ”ง Wrenching away at it โ€” precision work",
    "๐ŸŽ๏ธ Pedal to the metal โ€” no brakes",
    "๐Ÿงช Experimenting... for science!",
    "๐ŸŽต Working to the rhythm โ€” almost done",
];

/// Seconds between quip rotations. Picked to be slow enough that a
/// user reading the line has time to register the words (less than
/// 5s would feel jittery), fast enough that a multi-minute marathon
/// cycles through several entries. With 15 quips ร— 15s = full pool
/// every 3m 45s.
const WINDOW_SECS: u64 = 15;

/// Pick the quip for the current elapsed time. `elapsed_secs` is the
/// total time since the user's message was received. Same input
/// always yields the same output โ€” deterministic so the picker
/// stays stable across the multiple build-status ticks that happen
/// inside one rotation window.
pub(crate) fn rotating_quip(elapsed_secs: u64) -> &'static str {
    let idx = (elapsed_secs / WINDOW_SECS) as usize % TOOL_STATUS_QUIPS.len();
    TOOL_STATUS_QUIPS[idx]
}