smooth-operator

Reference

Configuration

38 environment variables, found by sweeping every read in the Rust workspace rather than by transcribing a list. A variable that stopped being read would leave this page; one added upstream arrives without an annotation instead of going unmentioned.

Derived from sourceHand-written noteCaveat / known gap

Every teal entry on this page is generated from every env read under rust/**/src at 158c9b4c, not from prose about it. Regenerate with pnpm --filter @smooai/web gen:operator-reference.

The shape of it

Nothing is required. An unconfigured server boots on loopback, keeps everything in memory, serves /ws, disables /admin, and answers with a clean error instead of an LLM. Every variable below moves it away from that.

no database, no auth, no cloud
# Everything below is optional except the key: unset, the server binds
# 127.0.0.1:8787 on in-memory storage with the admin API disabled.
export SMOOAI_GATEWAY_KEY=sk-...

cargo run -p smooai-smooth-operator-server
# ws://127.0.0.1:8787/ws

Defaults on this page are the server’s, read from Rust source. The Helm chart and the SST deploy set their own values on top, and the chart’s differ — that is the subject of the last section.

Server and model

What the process binds to and which model a turn runs on.

SMOOTH_AGENT_BINDdefault 127.0.0.1

Bind address. Containers need 0.0.0.0 or nothing outside the pod can reach it.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_PORTdefault 8787

TCP port. The WebSocket endpoint is /ws on it.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_MODELdefault claude-haiku-4-5

Deployment-wide default model. A per-agent value overrides it, and a per-turn send_message.model overrides that.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_MAX_ITERATIONSdefault 20

Agent-loop cap per turn. The shipped Helm chart sets 6 in its default values, so a chart deploy does not get this number — see below.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_MAX_TOKENSdefault 8192

max_tokens sent to the gateway. The Helm chart sets 512, which will truncate most real answers — see below.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_JUDGE_MODELdefault same as SMOOTH_AGENT_MODEL

Model for the cheap post-turn judge, separate so a big turn model does not make every turn expensive.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_PREAMBLE_MODELdefault unset ⇒ off

Names a fast model that runs in parallel with the turn and streams one ephemeral stream_preamble sentence to cover time-to-first-token.

smooth-operator-server/src/runner.rs

SMOOTH_AGENT_SEED_KBdefault off

Exactly 1 seeds a couple of demo documents at startup. Any other value is off.

smooth-operator-server/src/config.rs

Gateway and retrieval

One key drives chat, embeddings, and rerank. Everything degrades rather than failing when it is absent.

SMOOAI_GATEWAY_URLdefault https://llm.smoo.ai/v1

OpenAI-compatible gateway base. Serves chat, /v1/embeddings, and /v1/rerank.

adapters/postgres/src/embedder.rsadapters/postgres/src/reranker.rsexamples/dev-support/src/ingest.rsexamples/dev-support/src/main.rssmooth-operator-server/src/config.rs

SMOOAI_GATEWAY_KEYdefault unset

Gateway key. Unset is a working server with no LLM: turns fail cleanly, and embeddings fall back to the network-free deterministic embedder. Setting it is what makes the semantic embedder eligible.

adapters/postgres/src/embedder.rsadapters/postgres/src/reranker.rsevals/src/lib.rsexamples/dev-support/src/ingest.rsexamples/dev-support/src/main.rssmooth-operator-server/src/config.rs

SMOOTH_AGENT_RERANKdefault unset ⇒ off

gateway (or on/1/true) · lexical · anything else is off.

smooth-operator-server/src/reranker.rs

Storage and fan-out

The two variables that decide whether a restart loses your data and whether a second replica can answer.

SMOOTH_AGENT_STORAGEdefault memory

memory · postgres · dynamodb. Also selects the matching settings, connector-config, and indexing stores.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_DATABASE_URLdefault unset

Postgres connection string. Preferred name.

adapters/postgres/src/lib.rsexamples/dev-support/src/serve.rssmooth-operator-server/src/server.rs

DATABASE_URLdefault unset

Fallback for the above, honored only once SMOOTH_AGENT_STORAGE=postgres has explicitly chosen the backend — so an ambient DATABASE_URL alone can never redirect where data goes.

adapters/postgres/src/lib.rsexamples/dev-support/src/serve.rssmooth-operator-server/src/server.rs

SMOOTH_AGENT_DDB_TABLEdefault smooth-operator

DynamoDB single-table name. Credentials and region come from the standard AWS chain.

adapters/dynamodb/src/lib.rs

SMOOTH_AGENT_BACKPLANEdefault memory

memory · redis / valkey · nats. An unknown value fails the boot, and so does naming a backend the binary was not built with.

smooth-operator-server/src/server.rs

SMOOTH_AGENT_BACKPLANE_URLdefault unset

Connection URL for the selected backplane. Falls back to SMOOTH_AGENT_REDIS_URL or SMOOTH_AGENT_NATS_URL.

smooth-operator-server/src/server.rs

Identity

Unset behaves as jwt with no key, which boots the server with the admin API disabled rather than failing. Choosing jwt explicitly with no key is a startup error.

SMOOTH_AGENT_AUTH_MODEdefault jwt

Canonical name. jwt · smoo · trusted · none.

smooth-operator/src/auth.rs

AUTH_MODEdefault

Older alias for the above. The canonical name wins when both are set.

examples/dev-support/src/serve.rssmooth-operator/src/auth.rs

AUTH_JWT_RS256_PUBLIC_KEYdefault unset

RS256 PEM. First in key precedence.

smooth-operator/src/auth.rs

AUTH_JWT_HS256_SECRETdefault unset

HS256 shared secret. Second.

smooth-operator/src/auth.rs

AUTH_JWT_JWKS_URLdefault unset

Explicit JWKS endpoint. Third, and the keyless path — any OIDC issuer works.

smooth-operator/src/auth.rs

AUTH_JWT_ISSUERdefault unset

Required iss. Also derives the JWKS URL as {issuer}/.well-known/jwks.json when none is set, and is mandatory in smoo mode.

smooth-operator/src/auth.rs

AUTH_JWT_AUDIENCEdefault unset

Required aud when set.

smooth-operator/src/auth.rs

AUTH_DEV_ORG_IDdefault dev-org

Org the none-mode admin principal belongs to.

smooth-operator/src/auth.rs

WIDGET_AUTH_URLdefault unset

Endpoint asked whether an origin may embed the widget. Unset leaves the permissive provider in place.

smooth-operator-server/src/server.rs

WIDGET_AUTH_BEARERdefault unset

Bearer token for that call.

smooth-operator-server/src/server.rs

WIDGET_AUTH_TTL_SECSdefault provider default

How long an origin decision is cached.

smooth-operator-server/src/server.rs

WIDGET_AUTH_STRICTdefault false

Accepts 1, true, or yes. Tightens widget origin enforcement.

smooth-operator-server/src/config.rs

Capabilities

Every one of these is off when unset, and each says so in a different vocabulary — an empty list, an unset path, an unparsed flag.

SMOOTH_AGENT_CONFIRM_TOOLSdefault empty ⇒ HITL off

Comma-separated tool-name patterns that must be confirmed by a human before they run. Empty or whitespace-only means no confirmation hook is installed at all.

smooth-operator-server/src/config.rs

SMOOTH_AGENT_AUTH_TOOLSdefault empty ⇒ gate inert

Comma-separated names of tools that honor auth levels. With none listed, the per-agent auth gate is not built.

smooth-operator-server/src/handler.rs

SMOOTH_SKILLS_DIRdefault unset ⇒ off

Colon-separated skill roots, searched in order. Unset installs no resolver, so every send_message.skill is unknown.

smooth-operator-server/src/skills.rs

SMOOTH_EXTENSIONS_ALLOWdefault unset ⇒ deny all

Names the out-of-process extensions allowed to contribute tools. Empty means the extension host is never built and nothing is spawned.

smooth-operator-server/src/extensions.rs

SMOOTH_EXTENSIONS_DIRdefault engine default

Overrides where extensions are discovered.

smooth-operator-server/src/extensions.rs

SMOOTH_AGENT_DURABLE_EXECUTORdefault unset ⇒ in-process

Accepts 1/true/on/yes. Asking for durable execution without also supplying an executor logs a warning and runs the turn in-process — the flag alone does not make a turn survive a disconnect.

smooth-operator-server/src/runner.rs

Operations

Tracing, connector credentials, and the gate on tests that cost money.

OTEL_EXPORTER_OTLP_ENDPOINTdefault unset

Set to ship gen_ai.* spans over OTLP gRPC. Unset means local logging only, no collector needed.

smooth-operator/src/telemetry.rs

GITHUB_TOKENdefault unset

Read-scope PAT for the GitHub connector and the github_search tool.

examples/dev-support/src/config.rs

SMOOTH_AGENT_E2Edefault unset

Opts into the gated live-gateway tests. Without it they skip cleanly.

evals/src/lib.rs

What the sweep cannot see

Included deliberately as the exception that shows what the sweep does and does not cover.

RUST_LOGdefault info,smooth_operator=info

Tracing filter. Independent of OTLP export. Read indirectly by the tracing subscriber rather than by a direct environment read, which is why it is not in the swept list above it.

The sweep matches direct environment reads and reads through a named constant. Two backplane fallbacks — SMOOTH_AGENT_REDIS_URL and SMOOTH_AGENT_NATS_URL — are read through a helper that takes the name as an argument, so they are also absent from the generated list above and are described by hand under SMOOTH_AGENT_BACKPLANE_URL.

Where the chart disagrees with the server

Three things in deploy/k8s worth knowing before a first production install, all of them checkable in values.yaml and templates/deployment.yaml.

The chart caps turns much lower. Its defaults are maxIterations: 6 and maxTokens: 512 against the server’s own 20 and 8192. Both are real values; they just are not the same value, and the chart is what a Helm install actually applies.

The chart templates no storage or backplane variable. There is no SMOOTH_AGENT_STORAGE or SMOOTH_AGENT_BACKPLANE key in values.yaml and nothing renders them in deployment.yaml — they reach the container only via server.extraEnv. A default install therefore runs on in-memory storage with an in-memory backplane, even with a database secret configured.

And it runs two replicas by default. replicaCount: 2plus the point above is two pods that cannot see each other’s sockets or share a conversation. Set storage and backplane in extraEnv, or set replicaCount: 1, before this matters to a user.

Verified against deploy/k8s/values.yaml and deploy/k8s/templates/deployment.yaml at the pinned commit. These are chart facts, not code facts, so they are not part of the generated sweep.