Keyless Local-First Run
Run PraisonAI against a local Ollama or OpenAI-compatible model with zero API keys and zero config
If Ollama (or any OpenAI-compatible local server) is running, praisonai run "...", praisonai code "...", and praisonai chat "..." all work with no API key and no setup — each routes its keyless local-first branch through the shared ensure_configured_or_onboard() helper.
Start a local model, run a prompt — no OPENAI_API_KEY, no --model, no praisonai setup. When no cloud key is configured but a local endpoint answers, PraisonAI adopts it as the zero-config default.
Quick Start
- Start Ollama
bash ollama serve ollama pull llama3.2 - Run a prompt — no key, no model flag
bash praisonai run "Hello"No
OPENAI_API_KEY. No--model. Nopraisonai setup. - See the one-line notice
PraisonAI prints a transparency notice to
stderr, then answers:No cloud key found; using local model ollama/llama3.2. Run `praisonai setup` to add a hosted provider.
How It Works
PraisonAI checks for a cloud provider key first. When none is present, it probes for a local endpoint before falling back to the terminal default. A cloud key always wins.
Detection precedence
The probe honours your environment in this exact order:
PRAISONAI_LOCAL_ENDPOINTSif set — a comma-separated list of candidate endpoints, tried left to right (see Widened runtime probing).- else
OPENAI_BASE_URLif set. - else
OLLAMA_HOSTif set (a barehost:portis accepted; a scheme is added if missing). - else
http://127.0.0.1:11434.
At each host it tries Ollama’s native /api/tags first — the first tag becomes ollama/<name>. If that fails, it tries the OpenAI-compatible /v1/models — the first id becomes openai/<id>. This second path detects llama.cpp, LM Studio, and vLLM.
Timing and safety
| Property | Value |
|---|---|
| Probe timeout | 1 s per probe, so a slow first Ollama response is still caught; a closed port is refused instantly, so nothing listening never stalls the hot path |
| Negative-cache | 30 s, keyed by endpoint so a mid-session env change is never served a stale result |
| Cloud precedence | A cloud key always wins; the local path only fires when no cloud credential is present |
| CI safety | Non-TTY, --quiet, and --output json still exit 1 with guidance when nothing is reachable |
Environment Variables
Point detection at one or more endpoints with these variables.
| Variable | Example | Meaning |
|---|---|---|
PRAISONAI_LOCAL_ENDPOINTS | http://localhost:11434,http://localhost:1234 | Comma-separated candidate endpoints, probed left to right. The first that answers wins. Takes precedence over the single-host variables below |
OPENAI_BASE_URL | http://localhost:1234 | Probe this OpenAI-compatible endpoint when PRAISONAI_LOCAL_ENDPOINTS is unset (llama.cpp, LM Studio, vLLM) |
OLLAMA_HOST | 127.0.0.1:11434 | Probe this Ollama host when the two variables above are unset. A local host is not treated as a cloud key |
PRAISONAI_LOCAL_EMBED_MODEL | all-minilm | Pin the embedding model the resolver picks for knowledge / memory. Accepts a bare name (all-minilm) or a tagged id (all-minilm:latest). Falls back to PREFERRED_EMBED_MODELS order when unset |
Widened runtime probing
PRAISONAI_LOCAL_ENDPOINTS lists every local server to try, so one setting covers a mixed setup — Ollama alongside llama.cpp, LM Studio, or vLLM on different ports.
export PRAISONAI_LOCAL_ENDPOINTS="http://localhost:11434,http://localhost:1234,http://localhost:8000"
praisonai run "Hello"Endpoints are tried in order and the first reachable one wins. At each host the same two-step probe runs: Ollama’s native /api/tags first (first tag → ollama/<name>), then the OpenAI-compatible /v1/models (first id → openai/<id>). The 1 s timeout applies per probe, and a closed port is refused instantly, so an unreachable host is skipped quickly.
Other local servers
llama.cpp, LM Studio, and vLLM expose an OpenAI-compatible /v1/models endpoint, so they are detected via the fallback probe. Point PraisonAI at the port your server uses:
export OPENAI_BASE_URL=http://localhost:1234
praisonai run "Hello"The first model id the server reports becomes openai/<id>.
Behaviour Matrix
Detection combines with your terminal mode as follows.
| Mode | Local reachable | Not reachable |
|---|---|---|
| TTY (interactive) | Uses local model, prints the stderr notice, continues into the TUI | Suggests praisonai setup, then continues into the TUI |
praisonai run | Adopts the detected model, sets OPENAI_BASE_URL via setdefault | Exits 1 with guidance |
praisonai code | Adopts the detected model (no --model); one-line stderr notice | Headless (-p / piped): exits 1 with guidance; TTY: offers wizard |
praisonai chat | Adopts the detected model (no --model); one-line stderr notice | Headless (--json / piped): exits 1 with guidance; TTY: offers wizard |
--quiet | Uses local model | Exits 1 |
--output json | Uses local model | Exits 1 |
All four entrypoints share the local-first branch inside ensure_configured_or_onboard() — see First-run Onboarding → Shared onboarding helper.
The non-TTY / --quiet / --output json error message is:
No API key configured. Run: praisonai setup
(a running local endpoint such as Ollama would be used automatically)Best Practices
Add a hosted provider when you need one
Local-first is zero-config, but praisonai setup is still the way to add a hosted provider (OpenAI, Anthropic, …). Once a cloud key is configured, it takes precedence over any running local server.
An explicit –model still overrides detection
Passing --model <name> bypasses local detection and routes to that model’s own provider gate. Use it to force a specific model regardless of what is running locally.
Force cloud despite a running local server
To ignore a running local endpoint, either unset the local env vars or name a cloud model directly:
unset OPENAI_BASE_URL OLLAMA_HOST
# or
praisonai run --model gpt-4o "Hello"Point at a non-default port
For llama.cpp / LM Studio / vLLM on a custom port, export OPENAI_BASE_URL before running:
export OPENAI_BASE_URL=http://localhost:8000
praisonai run "Hello"List several servers with PRAISONAI_LOCAL_ENDPOINTS
When more than one local server may be running, list them all and let detection pick the first reachable one:
export PRAISONAI_LOCAL_ENDPOINTS="http://localhost:11434,http://localhost:1234"
praisonai run "Hello"Put your preferred server first — probing stops at the first host that answers.
Related
The keyless companion for channels — chat from your terminal, token-free
First-run OnboardingHow PraisonAI routes a keyless first run
SetupAdd a hosted provider credential
Run CommandRun agents from files or prompts
OllamaUse Ollama models with PraisonAI
Local Model ResolverThe explicit form — llm="local" on an Agent