pub enum Agent {
Claude,
Codex,
Copilot,
}Expand description
A coding agent this crate can drive headlessly.
Variants§
Claude
Anthropic’s Claude Code (claude).
Codex
The OpenAI Codex CLI (codex).
Copilot
GitHub Copilot CLI (copilot).
Implementations§
Source§impl Agent
impl Agent
Sourcepub fn reports_account_usage(self) -> bool
pub fn reports_account_usage(self) -> bool
Whether this agent can report account-wide usage without a terminal.
Worth asking before building a quota panel, since two of the three cannot and no amount of retrying changes that.
Sourcepub async fn account_usage(self) -> Result<AccountUsage>
pub async fn account_usage(self) -> Result<AccountUsage>
Ask the agent what the account has spent and what remains.
§Errors
Error::Unsupported where the agent has no headless way to answer,
which today is Claude and Copilot; check
Agent::reports_account_usage first to avoid the round trip.
Error::NotInstalled if the binary is missing, Error::Spawn if it
cannot be run, Error::Timeout if it does not reply,
Error::AgentError if it replies with a refusal, and
Error::Parse if the reply is not the expected shape.
Source§impl Agent
impl Agent
Sourcepub fn auth_status_argv(self) -> Option<&'static [&'static str]>
pub fn auth_status_argv(self) -> Option<&'static [&'static str]>
The command that asks this agent whether it is logged in, or None
when it offers no way to ask.
Verified against each CLI: Claude has auth status, which answers JSON
by default, and Codex has login status, which answers prose. Copilot
has neither, so its credentials cannot be confirmed without spending a
request.
Sourcepub fn auth_env_vars(self) -> &'static [&'static str]
pub fn auth_env_vars(self) -> &'static [&'static str]
The environment variables this agent accepts a credential in, most preferred first.
Copilot documents its precedence explicitly: COPILOT_GITHUB_TOKEN,
then GH_TOKEN, then GITHUB_TOKEN.
Sourcepub fn login_hint(self) -> &'static str
pub fn login_hint(self) -> &'static str
The command that resolves a missing login for this agent.
Verified against each CLI’s own help: Codex and Copilot expose a login
subcommand, while Claude authenticates interactively or through a
long-lived token.
Sourcepub fn verified_version(self) -> Version
pub fn verified_version(self) -> Version
The release this crate’s flag mappings were verified against.
Every mapping in this module was checked by running these exact
versions, not by reading their documentation. crate::Probe compares
an installed CLI against this so drift is a question a host can ask up
front rather than something a failing run reveals.
Sourcepub fn install_hint(self) -> &'static str
pub fn install_hint(self) -> &'static str
The documented install command, surfaced by Error::NotInstalled.
Sourcepub fn essential_env(self) -> Vec<&'static str>
pub fn essential_env(self) -> Vec<&'static str>
The environment variables this agent needs to function, used by
EnvPolicy::Minimal.
Two groups: what any process needs to start, and this agent’s own
credential and config variables. Permission-controlling variables are
excluded on principle: COPILOT_ALLOW_ALL is Copilot’s env equivalent
of --allow-all-tools, so inheriting it would let the host’s ambient
environment widen a run’s permissions behind Permission’s back. A name absent from the parent
environment is skipped, so nothing here is fabricated.
Proxy and custom-CA variables are deliberately not here. They are
environment-specific rather than required, and HTTP_PROXY /
HTTPS_PROXY routinely embed credentials (http://user:pass@proxy), so
passing them automatically would leak one through the very policy meant
to withhold secrets. A host that needs them should offer them as a
setting and pass them with crate::Request::env; NETWORK_ENV names
them so a settings screen does not have to hardcode the list.
PATH, HOME and USER are the verified floor on macOS: all three CLIs
answer correctly with exactly those set, and Claude reports “Not logged
in” without USER, since its keychain lookup is keyed on it. The Windows
names are included on the same reasoning but are not verified, as
this crate has not been run there.
Sourcepub fn thinking_env(
self,
thinking: Option<bool>,
) -> Option<(&'static str, &'static str)>
pub fn thinking_env( self, thinking: Option<bool>, ) -> Option<(&'static str, &'static str)>
The environment variable that turns reasoning off for this agent, if it
has one, given the request’s thinking setting.
Returns Some only when a caller asked to disable thinking and this
agent exposes a lever for it. Claude reads MAX_THINKING_TOKENS: the
claude CLI sends a thinking block to the API only while that value is
above zero (verified against claude 2.1.212, where the gate is
MAX_THINKING_TOKENS > 0), so 0 disables it. Codex and Copilot have no
equivalent, so they return None and steer reasoning through
crate::Request::effort instead.
None for thinking (the default) and Some(true) both leave the
agent’s own default untouched, so nothing is set.
Sourcepub fn session_format(self) -> Option<Format>
pub fn session_format(self) -> Option<Format>
The format that can carry this agent’s session id, if any. A named session upgrades to this when the caller did not pin a format.
Sourcepub fn format_carries_session(self, format: Format) -> bool
pub fn format_carries_session(self, format: Format) -> bool
Whether format can carry this agent’s session id.
Distinct from Agent::session_format, which names the preferred one:
Claude reports its id under both Json and Stream, and only plain text
loses it. A named session needs this, not equality with the preferred
format, or streaming a named Claude session would be refused for no
reason.
Sourcepub fn argv(self, plan: &Plan) -> Result<Vec<String>>
pub fn argv(self, plan: &Plan) -> Result<Vec<String>>
Build the command line for plan.
The first element is the binary; the rest are its arguments. Returns
Error::Unsupported when the plan asks for a capability this agent
lacks, never a quiet downgrade.
§Errors
Error::Unsupported if the plan needs a capability this agent lacks.
Sourcepub fn effective_prompt(self, plan: &Plan) -> String
pub fn effective_prompt(self, plan: &Plan) -> String
The prompt text actually delivered, with the system prompt folded in for agents that have no flag for it. Never dropped silently.
Source§impl Agent
impl Agent
Sourcepub fn models(&self) -> Vec<Model>
pub fn models(&self) -> Vec<Model>
The models this agent offers, best first.
Advisory: this is not enforced, and it does not tell you what an account
may actually use. See Model and Agent::models_verified.
Sourcepub fn models_verified(&self) -> Verified
pub fn models_verified(&self) -> Verified
How this agent’s compiled-in catalogue was established, and when.
Sourcepub async fn discover_models(&self) -> Result<Vec<Model>>
pub async fn discover_models(&self) -> Result<Vec<Model>>
Ask the installed CLI what models it has, rather than trusting the compiled-in list.
Worth preferring wherever it works: it reflects the binary actually present instead of the one this crate was written against.
§Errors
Error::Unsupported on an agent with no headless way to answer, which
today is Claude and Copilot. That is deliberately an error rather than a
silent fall back to Agent::models: a caller asking for discovery is
asking for freshness, and handing back a compiled list without saying so
answers a question they did not ask. Error::NotInstalled if the
binary is missing, Error::Spawn if it cannot be run, and
Error::Parse if its output is not the expected shape.