Accounts & models
GET /v1/providers checks only the provider instances authorized by the caller's
driver token. Each instance keeps its own ID, credential resolver, cache and model
allowlist. Two OpenAI accounts, for example, remain separate instances such as
openai-personal and openai-work. The response never includes credentials,
CLI paths, raw provider errors or CLI output. Authorized callers can receive
reported account email/name in the optional connection details;
the provider panel masks that identity by default.
The embedded driver exposes await driver.discoverProviders(). Its optional
providers filter is for trusted hosts to apply their authorization policy;
embedded access itself is trusted. The existing synchronous
driver.listProviders() returns static configuration without running probes.
Refresh and caching
Clients can request a refresh:
| Client | Call |
|---|---|
| TypeScript / JavaScript | await client.providers({ refresh: true }) |
| Python | client.providers(refresh=True) |
| Go | client.RefreshProviders(ctx) |
| Rust | client.refresh_providers() / .await for Rust async |
| HTTP | GET /v1/providers?refresh=true |
The host advertises provider-discovery in /v1/protocol. Older hosts may omit
health/catalog fields or reject the refresh query; clients do not silently retry
against another host or account.
Each instance caches its latest result for 30 seconds, including failures. Explicit refresh bypasses that lifetime but respects a one-second minimum interval. Overlapping checks share the same probe. Timestamps show when the cached check completed; there is no background polling. Replacing a credential returned by an API key resolver takes effect on the next probe or model call.
Host options can change these defaults:
const driver = new AgenticDriver({
providers,
discovery: { cacheTtlMs: 30_000, minRefreshMs: 1000, timeoutMs: 5000 },
});The five-second bound applies only to discovery. It does not add a model-run deadline or enable the optional inactivity timeout. Cancelling an embedded discovery reader stops that reader's wait; a shared probe continues within its own bound for other readers. Custom adapters must honor the probe's abort signal. Discovery uses a separate signal/process from active model runs. Refreshing or cancelling a metadata check never interrupts a generation. Native CLIs may also maintain their own catalog caches; a host refresh does not bypass those caches.
Interpreting results
health contains status, code, a fixed public message, and checkedAt.
| Status | Meaning |
|---|---|
ready | An authenticated API catalog request succeeded; execution, billing and quota remain untested. |
unauthenticated | An API key is missing/rejected, or an official CLI status command reports no login. |
unavailable | A connection, timeout, rate limit, executable or response-format problem prevented the check. |
unsupported | The catalog route, credential permissions, adapter probe or required CLI execution features are unavailable. |
unknown | CLI features are present, but a saved login or an inconclusive status check cannot establish current remote access. |
Health is advisory. A failure never selects another provider, account, billing mode or model. It does not prevent trying an explicitly selected, allowed model after credentials change. Required run capabilities still fail before execution when the adapter does not advertise support.
models retains its original meaning: the host's exact model allowlist. An
omitted allowlist permits any explicit model ID, subject to the provider accepting
it. An empty allowlist denies every model. A discovered catalog never broadens
this permission or changes an application's saved provider/model enablement.
modelCatalog contains source, models and complete. On successful discovery,
its source is provider and it includes every reported ID within the probe
bounds, including IDs outside the host's execution allowlist. On a
failed or unsupported probe, its source is configured when an allowlist exists,
otherwise unavailable. Those inventories are unverified and complete is false.
The old successful inventory is not presented as current after a failed refresh.
Aliases missing from the vendor catalog remain usable when explicitly allowed.
Catalogs are bounded to 1000 unique model IDs, 20 pages and 2 MB of response
data in total. A page/model limit produces complete: false; malformed responses
and repeated pagination cursors produce an unavailable status. OpenAI and xAI
catalogs can include models for other API operations; a catalog entry alone does
not certify compatibility with text generation or every adapter capability.
Gemini's inventory likewise includes reported embedding and other model IDs;
discovery does not add their operations to the generation adapter.
Applications should show these separate facts without automatically enabling a newly discovered model:
| Fact | Contract |
|---|---|
| Reported inventory | modelCatalog.models, source and complete, scoped to the authorized provider instance/account |
| Host permission | models; an empty array permits no execution |
| App enablement/selection | Application-owned preferences and the explicit provider/model in each run request |
| Live qualification | Separate evidence for the exact account, model, adapter and operation; catalog membership is not that evidence |
The existing 0.1.0 client protocol can consume these fields. The expanded host
catalog behavior and init --catalog-only are development-source changes; the
published 0.1.0 host retains its original discovery behavior.
Probe sources and limitations
API probes issue only GET requests against the host-configured endpoint and
disable redirects. Pagination follows the documented model-list cursors. Routes:
OpenAI models,
Anthropic models,
Gemini models, and
xAI models.
Compatible endpoints use the same GET models route; an unsupported route is
reported without trying generation as a substitute.
CLI probes run feature help and supported status commands in an empty temporary
working directory using the configured account directory and restricted
environment. Codex login status
and Claude Code auth status
report local login state. A zero exit status alone becomes CLI_SESSION_PRESENT
with unknown health; it does not prove that a saved credential is unexpired. A login
failure is actionable through the CLI's official sign-in flow. Gemini's documented
/auth command opens an
interactive dialog. Its ACP startup also enters authorization when OAuth
credentials are missing, before accepting protocol input, so this adapter retains
CLI_STATUS_UNKNOWN after checking features. It does not scrape credentials or
start that interactive flow during discovery.
For qualified Codex CLI 0.157.0, a saved login also enables the official
model/list app-server request.
The probe starts a separate native process, initializes the protocol, follows
pagination with includeHidden: true, and exits without starting a thread or
turn. Success is CLI_CATALOG_AVAILABLE with unknown health: native catalogs
may contain cached or bundled entries, so neither account entitlement nor live
model access is established. complete describes pagination completeness, not
fresh account verification. A failed catalog probe retains the honest local
login/configured-inventory result. Credentials stay inside the official CLI.
Claude Code 2.1.282 uses the official SDK initialization response in another
restricted process after its saved-login check. No user message is sent. Both
reported aliases and their optional resolvedModel IDs are retained, including
context-window suffixes such as [1m]. The response is bounded to 1,000 unique
IDs; truncation sets complete: false. As with Codex, health remains unknown:
the native list can be bundled/cached and is not proof of entitlement. Other
Claude versions retain the configured, incomplete inventory until qualified.
Malformed replies and native authority requests cannot turn into model runs.
See the native Claude metadata evidence.
Gemini CLI's configured IDs remain explicitly incomplete. Its official ACP
session/new reply contains a catalog, but an isolated 0.58.0 fixture confirms
that missing OAuth credentials start interactive authorization even with browser
launch disabled. See the reproduction and remaining qualification,
tracked in #23.
Antigravity (#47) and
Grok Build (#32) native
adapters remain pending; their metadata routes must qualify together with effective
native controls. API modes already have
independent catalog probes. No static guessed model list, consumer-subscription
to API switch, or credential/account fallback fills these gaps.
All probes avoid model generation. Live account/model certification is tracked separately for each provider; fixture tests do not establish vendor account access.
Connection details
Provider listings optionally include connection with source, checkedAt,
runtime: {name, version} and account: {status, method?, email?, name?, subscription?}.
Account status is signed-in, signed-out or unknown. These are display
observations from the selected runtime, not execution grants or live model
qualification. TypeScript, Python, Go and Rust expose and validate the same
optional fields; older hosts can omit them.
Codex uses its qualified app-server account/read with refreshToken: false
in the isolated catalogue process. Claude uses auth status --json, retaining
only the supported display fields. CLI version output is parsed into a bounded
version string. No SDK code reads native token files, starts sign-in, changes
accounts, or sends a prompt while collecting these details. Unknown fields,
credential material, local paths and provider organization/account IDs are not
returned by these probes. Gemini CLI currently reports its version without a
supported account identity/subscription probe. Standard API model listings do
not report a person's identity, subscription or server version, so those values
remain absent. An unsupported CLI version remains unsupported even if its
version or saved sign-in can be displayed.
Connection details follow the existing provider authorization filter and per-adapter discovery cache. Revoked/ungranted accounts are not inspected. Failed refreshes drop older identity metadata; successful refreshes replace it. Refresh does not interrupt running model work or expand permissions. The connection metadata is private account information available to authorized readers; the panel's reveal control is a display preference, not another access control or identity system.