feat(reliability): bound + fail over + surface LLM-optional ops #82
Reference in New Issue
Block a user
Delete Branch "feat/llm-resilience"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Makes mcpctl resilient to a bad/slow/wrong LLM — the gate stays responsive and honest even when the homelab model is thinking-only, drifted, or down.
Root cause (live-debugged)
begin_session's prompt-selection called the LLM with no timeout (a thinking model blocks it for minutes), its fallback only fired on outright error and was silent, and it forced the project's vLLM model onto the anthropic heavy provider → selection failed silently every time.read_promptsis already LLM-free.Changes
withTimeout(run, ms, label)— Promise.race + AbortSignal (fetch-based providers cancel via newCompletionOptions.signal, threaded into anthropic/openai).begin_session: time-bounded selection (MCPCTL_GATE_LLM_TIMEOUT_MS, 8s); on timeout/error → deterministic tag matching, loud[gate]log, a⚠ Smart prompt-selection unavailable (<reason>)note in the response, anddegraded/degradedReasonon the auditgate_decision.Tests
with-timeout unit tests (hang → TimeoutError + signal aborted); gate degradation test (LLM error → visible ⚠ + deterministic prompts, no hang). mcplocal 737 + mcpd 945 green; tsc clean. No new eslint errors.
Deploy: mcpd + mcplocal image rebuild (no schema change) + RPM.
🤖 Generated with Claude Code