anymo Docs
Core concepts

Model providers

Anymo uses OpenAI-compatible chat endpoints: local model servers like Ollama and LM Studio, routers, proxies, or hosted APIs. The model is a configuration choice, not an architectural one.

Setting a provider key

How you supply the key depends on how you run Anymo.

Headless CLI: environment variables

The CLI reads its provider settings from the environment and never writes a key to disk. Export them for the session that runs anymo:

macOS / Linux
export ANYMO_PROVIDER_BASE_URL=http://localhost:11434/v1   # e.g. Ollama; LM Studio uses :1234
export ANYMO_PROVIDER_MODEL=llama3.1
export ANYMO_PROVIDER_API_KEY=<your-api-key>               # only hosted endpoints need a key
Windows (PowerShell)
$env:ANYMO_PROVIDER_BASE_URL = "http://localhost:11434/v1"
$env:ANYMO_PROVIDER_MODEL = "llama3.1"
$env:ANYMO_PROVIDER_API_KEY = "<your-api-key>"             # hosted endpoints only

Then run with anymo run --provider http. The key lives only in that process environment; local model servers usually need no key at all.

Never put a key in config.toml

The workspace .anymo/config.toml holds a commented endpoint template. Keys belong in ANYMO_PROVIDER_API_KEY, never in that file.

Desktop app: sealed at rest

Open Settings → Model provider, enter the base URL, model, and an API key for hosted endpoints, then save. The desktop app seals saved keys at rest: the key is encrypted on disk with a master secret held in the OS keychain, with an encrypted-file fallback. Saved profiles persist across restarts, and a per-profile health check confirms the endpoint is reachable.

In both cases, keys never appear in events, logs, artifacts, or the UI.

How sealed storage works

Provider profile metadata is safe to serialize, but API keys are never written to profile JSON. Keys are stored through the native secret store:

  • An OS keychain master key when the host keychain is available.
  • An encrypted local fallback store when the caller supplies a passphrase or host-managed secret. The fallback file contains only nonces and ciphertext.

Do not commit local provider files, fallback passphrases, or real API keys.

Presets

The kernel exposes these presets:

PresetBase URLNotes
Generic OpenAI-compatiblehttps://api.openai.com/v1Works for compatible hosted APIs and proxies; custom HTTPS URLs are also valid
OpenRouter-stylehttps://openrouter.ai/api/v1Adds sanitized example HTTP-Referer and X-Title headers; callers may replace them
Ollamahttp://localhost:11434/v1Local endpoint only; non-local hosts are rejected for this preset
LM Studiohttp://localhost:1234/v1Local endpoint only; non-local hosts are rejected for this preset
Custom base URLcaller-suppliedRemote URLs must use HTTPS; localhost, 127.0.0.1, and ::1 may use HTTP

Embedding the provider store

The Rust API that backs the desktop store is available to embedders. A generic hosted provider:

rust
use hive_kernel::{ProviderPreset, ProviderProfile, Secret};

let profile = ProviderProfile::from_preset(
    ProviderPreset::GenericOpenAiCompatible,
    "default",
    "Default provider",
    "gpt-example",
    Secret::new("EXAMPLE_PROVIDER_KEY_DO_NOT_USE"),
    Some("https://provider.example.com/v1".into()),
)?;

Local Ollama:

rust
let profile = ProviderProfile::from_preset(
    ProviderPreset::Ollama,
    "ollama",
    "Ollama",
    "llama3.1",
    Secret::default(),
    None,
)?;

An encrypted fallback store for tests or non-keychain hosts:

rust
use anymo_native::{EncryptedFileSecretStore, SecretStoreKey};
use hive_kernel::ProviderProfileStore;

let key = SecretStoreKey::from_passphrase(
    "example passphrase supplied outside the repo",
    b"anymo-example-salt-0000",
)?;
let secrets = EncryptedFileSecretStore::new("provider-secrets.json", key);
let store = ProviderProfileStore::new("profiles.json", secrets);
store.save_profile(&profile)?;

Compatibility checks

ProviderHealthSuite runs a provider-neutral compatibility report covering:

  • Chat completion
  • Streaming, when the capability registry advertises it
  • JSON-object response behavior
  • Tool and action JSON fallback for providers without native tool calls
  • Context-window and max-output-token metadata
  • Latency per networked check and safe error rendering

HttpProvider normalizes provider failures into authentication, invalid request, rate limit, timeout, network, server, parse, unsupported, or unknown errors. Retry and backoff apply only to transient network, timeout, rate-limit, and server responses. Rendered errors redact bearer keys and custom header values before entering logs or events.

Failover

Give a run an ordered fallback chain with --fallback <base_url>,<model> (repeatable), or via ANYMO_PROVIDER_FALLBACK_BASE_URL, ANYMO_PROVIDER_FALLBACK_MODEL, and ANYMO_PROVIDER_FALLBACK_API_KEY. Each fallback takes over when the previous endpoint exhausts retries on a retryable failure, and every switch is recorded as a durable provider.fallback event. In the desktop app, the fallback chain spans your saved profiles.

Routing defaults

When a run does not explicitly set reasoning effort, Anymo applies stable defaults per agent role:

RoleDefault reasoning
Supervisor / plannerxhigh
Reviewer / verifierhigh
Researcher / coder / tester / synthesizerxhigh
Utility / tool worker*medium

*These are defaults; the orchestrator still chooses the best reasoning level for each request.

If a provider supports native reasoning effort, Anymo maps xhigh to the strongest provider-native setting available and keeps the xhigh evaluator and budget intent locally. Providers without native reasoning effort receive no provider-specific field; Anymo still expands local high and xhigh budgets before making requests.