Skip to content

Provider health

Check whether a provider is set up correctly — without committing to using it. caw reports raw signals and forms no "available" verdict, so you write your own predicate. The default check is fast and free; a live probe round-trips a tiny request to confirm the provider responds and isn't rate-limited.

from caw import Agent, check_providers

for h in check_providers():               # fast: no network, no token cost
    print(h.provider, h.installed, h.binary_path,
          h.auth.detail if h.auth else None)

Compose your own "available"

Because caw gives you signals rather than a verdict, you decide what "usable" means:

usable = [h.provider for h in check_providers()
          if h.installed and not (h.auth and h.auth.token_expired)]

Two depths of check

  • Fast (default). Is the CLI installed, where is its binary, and what can caw cheaply tell about its credentials? No network, no token cost — safe at startup.
  • Live (live=True). Additionally round-trips a minimal prompt to confirm the provider actually responds and whether it's currently rate-limited. Costs one probe request per provider.
h = Agent(provider="codex").check_health(live=True)
if h.rate_limited:
    print(f"codex rate-limited, ~{h.wait_minutes}m until reset")

What ProviderHealth exposes

ProviderHealth carries:

Field Meaning
provider Canonical provider name
installed CLI binary found on PATH (or a known fallback)
binary_path Resolved path to the CLI, or None
auth An AuthSignal, or None if not introspectable
probed Whether a live round-trip was attempted
rate_limited From the probe; None if not probed
wait_minutes Estimated minutes until the limit resets
error Exception text if the live probe failed

AuthSignal adds present, detail, credentials_path, token_expires_at, and token_expired. Every field is a signalNone means "couldn't determine", not a negative result — so treat a falsy present as a hint, not a verdict.

From the CLI

caw doctor prints the same signals as a table:

caw doctor            # fast: installed + credential signals (no token cost)
caw doctor --live     # also probe each provider (costs one request each)

Full example

examples/health.py:

"""Checking provider health / availability at runtime.

caw reports *raw signals* about each provider — it forms no verdict on what
counts as "available", so you compose your own predicate from the fields.

Two depths of check:

* **fast** (default): is the CLI installed, and what can we cheaply learn about
  its credentials?  No network, no token cost — safe to call at startup.
* **live** (``live=True``): also round-trips a tiny probe to confirm the
  provider responds and isn't rate-limited.  Costs one request per provider.

See also the ``caw doctor`` CLI command, which prints this as a table.
"""

from caw import Agent, check_providers


def main():
    # --- Fast sweep over every registered provider (no token cost). ---
    print("Provider health (fast check):\n")
    for h in check_providers():
        auth = h.auth.detail if h.auth else "unknown"
        print(f"  {h.provider:12} installed={h.installed!s:5} auth={auth}")

    # Compose your own "available" predicate from the raw signals. Here:
    # installed, and (if we can tell) the credential token isn't expired.
    def is_usable(h) -> bool:
        return h.installed and not (h.auth and h.auth.token_expired)

    usable = [h.provider for h in check_providers() if is_usable(h)]
    print(f"\nUsable right now (installed + non-expired creds): {usable}")

    # --- Health of a specific agent's provider. ---
    health = Agent(provider="claude_code").check_health()
    print(f"\nclaude_code → installed={health.installed} binary={health.binary_path}")

    # --- Live probe (uncomment to actually round-trip; costs a request each). ---
    # for h in check_providers(["claude", "codex"], live=True):
    #     if h.rate_limited:
    #         print(f"  {h.provider}: rate-limited, ~{h.wait_minutes}m until reset")
    #     elif h.error:
    #         print(f"  {h.provider}: probe failed: {h.error}")
    #     else:
    #         print(f"  {h.provider}: responds OK")


if __name__ == "__main__":
    main()