Expand description
Generic subprocess-based LLM provider.
Covers Claude Desktop / Claude CLI, Gemini CLI, Cursor Agent, and OpenCode — the four “subscription CLIs” a developer commonly has logged in on a workstation. Each has its own argv shape but they all share the same execution contract:
- spawn the binary with a fixed flag set + the prompt as argv;
- stdin is closed (these tools read their prompt from
-p); - exit 0 + non-empty stdout = success;
- anything else =
LlmError::Providerwith stderr text.
§Why a single generic provider
caloron-noether already implements this multi-provider fallback in
Python (stages/phases/_llm.py) and learned the hard edge cases —
the 25-second timeout cap to stay under Nix’s default 30-second
kill, the SKIP_CLI escape hatch for sandboxed environments where
CLI auth isn’t mounted, the exact argv incantation per tool. This
module ports those lessons into the Rust engine so noether-grid
workers get the same behaviour, for free, with the same failure
modes. See docs/research/llm-here.md for the long-term plan to
unify all three implementations behind one shared tool.
§Sandbox handling
When NOETHER_LLM_SKIP_CLI=1 is set, every CLI provider refuses to
advertise itself as available (available() == false). Intended
for stages that run inside the Nix executor, which mounts a
restricted $HOME that doesn’t carry the operator’s CLI auth
state — without this gate, a subscription CLI stalls waiting for
interactive login and gets SIGKILL’d by the runner.
§Timeout
Default timeout_secs = 25. Deliberately under Nix’s 30-second
default stage kill so a stalled CLI reports Provider(timeout)
instead of the stage runner’s less useful “process killed” error.
Callers outside the Nix executor can bump it up via
CliConfig::timeout_secs.
Modules§
- specs
- Concrete per-CLI specs. Argv shapes are identical to what
caloron’s
_llm.pyuses — keep in sync when either side changes.
Structs§
- CliConfig
- Tunables for one
CliProviderinstance. - CliProvider
- LLM provider that delegates each completion to a subscription CLI. Stateless — each call spawns a fresh subprocess.
- CliSpec
- A static description of one CLI tool: the binary name, the argv
template, and how system prompts are passed (if at all). Used by
CliProvider::newto pick a concrete tool.
Enums§
Functions§
- cli_
providers_ suppressed - Check whether CLI providers are globally suppressed. Set
NOETHER_LLM_SKIP_CLI=1inside a sandboxed environment (the Nix executor being the obvious one) where subscription CLIs would stall waiting for auth state that isn’t mounted. - new_
claude_ cli - Convenience constructor preserved for the call-site in providers.rs.
Type Aliases§
- Claude
CliProvider Deprecated - Old name kept so existing call-sites still compile.