Skip to content

Configuration

The agent reads config in this order, each layer overriding the previous:

  1. Built-in defaults (e.g. LLM_PROVIDER=anthropic, AGENT_HTTP_PORT=5060).
  2. File config at the path in DAVEPI_AGENT_CONFIG, if set.
  3. Environment variables (the documented DAVEPI_* / AGENT_* / LLM_* / SLACK_* names).
  4. Programmatic overrides passed to createAgent({ ... }) or startAgent({ ... }).

Tables below mark required vs. optional and call out the default.

VariablePurpose
DAVEPI_URLBase URL of the davepi backend. Default http://localhost:5050.
LLM_PROVIDERanthropic (default), openai, or ollama.
ANTHROPIC_API_KEY / OPENAI_API_KEYProvider key. Not needed for ollama.
One of DAVEPI_BEARER / DAVEPI_CLIENT_IDService-auth identity. Omit only when AGENT_AUTH_MODE=per-user.
VariableDefaultPurpose
DAVEPI_URLhttp://localhost:5050Base URL of the davepi backend.
DAVEPI_MCP_PATH/mcpPath the MCP server is mounted at on the davepi backend.
VariableDefaultPurpose
LLM_PROVIDERanthropicanthropic, openai, or ollama.
LLM_MODELprovider defaultModel id. Required for ollama — see below.
LLM_SYSTEM_PROMPTbuilt-in defaultOverride the operating-contract block (slot #2 in the prompt assembly).
LLM_MAX_STEPS8Max tool-call loops per turn.
LLM_TEMPERATUREprovider defaultFloat passed straight through.
LLM_PROMPT_CACHINGtrue (Anthropic only)Cache the frozen snapshot prefix. No-op for OpenAI / Ollama.

Provider defaults:

ProviderDefault LLM_MODEL
anthropicclaude-sonnet-4-5
openaigpt-4o
ollamanone — operators ollama pull their own model, so an explicit LLM_MODEL is required.

LLM_PROVIDER=ollama reuses the bundled @ai-sdk/openai provider pointed at Ollama’s OpenAI-compatible /v1 endpoint, so there’s no extra dependency.

VariableDefaultPurpose
LLM_MODEL(required)The exact name you ran ollama pull with (e.g. llama3.1, qwen2.5).
OLLAMA_BASE_URLhttp://localhost:11434/v1Override for a remote Ollama or a reverse proxy.
OLLAMA_API_KEY"ollama"Set only when fronting Ollama with an auth proxy. Ollama itself ignores it.

Tool-calling fidelity depends on the model — llama3.1 and qwen2.5 work well; smaller models may struggle when the backend has many schemas. The tool router keeps the exposed surface under AGENT_TOOL_LIMIT regardless.

VariableDefaultPurpose
AGENT_AUTH_MODEserviceservice or per-user.
DAVEPI_BEARERLong-lived JWT for service mode. Wins when both this and DAVEPI_CLIENT_ID are set.
DAVEPI_CLIENT_IDPublic client id (anonymous reads) for service mode.
AGENT_LINK_BASE_URLPublic base URL of the agent itself (where /link/:nonce is served). Per-user only.
AGENT_SESSION_SECRETHMAC key for the signed davepi_agent_session cookie. Required for HTTP per-user.
AGENT_COOKIE_SECUREtrueEmits Secure on the session cookie. false for HTTP-only dev.
AGENT_ACCESS_TTL_SECONDS900 (15 m)How long an access token is cached before re-minting. Per-user mode only.
AGENT_REFRESH_SKEW_SECONDS60Refresh access tokens this far before expiry to absorb clock skew. Per-user only.
STORE_URLfile:./davepi-agent-store.jsonWhere to persist refresh tokens. memory: for ephemeral / tests.

→ Auth modes

VariableDefaultPurpose
AGENT_HTTP_ENABLEDtrueSet false to disable the HTTP channel entirely.
AGENT_HTTP_PORT / PORT5060HTTP listen port. PORT is read for hosted-platform conventions.
AGENT_CORS_ORIGINSComma-separated allowlist. Empty disables CORS headers.
VariableDefaultPurpose
SLACK_ENABLEDtrue when SLACK_BOT_TOKEN is setForce-enable / disable.
SLACK_BOT_TOKENBot User OAuth Token (xoxb-...). Enables the Slack channel when set.
SLACK_SIGNING_SECRETRequired when Slack is enabled in HTTP mode.
SLACK_APP_TOKENApp-level token for socket mode (xapp-...).
SLACK_SOCKET_MODEfalsetrue to use socket mode (no public URL needed).
SLACK_PORT5061Slack HTTP port when not in socket mode.

→ Channels → Slack

VariableDefaultPurpose
AGENT_TOOL_LIMIT40Above this many MCP tools, switch to routed mode.
AGENT_INCLUDE_RENDERtrueInject render_table + render_chart tools into the tool list.

→ Tools and rendering

VariableDefaultPurpose
AGENT_KEYWhich agent this process is (e.g. support). Selects the persona / memory / skill rows.
AGENT_PERSONA_CACHE_TTL_SECONDS60Per-process cache TTL for the persona lookup. 0 to fetch every turn (strict immediacy).
AGENT_PERSIST_CONVERSATIONStruePersist history + the frozen prompt snapshot to davepi’s conversation schema.
AGENT_SESSION_IDLE_SECONDS1800Idle gap after which a returning user is a NEW session and the snapshot is re-frozen.

AGENT_KEY is the on switch for the whole learning layer. Unset → no persona lookup, default prompt, zero-config.

Set DAVEPI_AGENT_CONFIG=/path/to/agent.config.js to load a JS or JSON config from disk before env vars are applied. The file exports an object shaped like the runtime config tree:

agent.config.js
module.exports = {
davepiUrl: 'http://localhost:5050',
agent: { key: 'support', personaCacheTtlSeconds: 30 },
llm: { provider: 'anthropic', maxSteps: 12, temperature: 0.2 },
auth: { mode: 'per-user', linkBaseUrl: 'https://agent.example.com' },
http: { port: 5060, corsOrigins: ['https://app.example.com'] },
slack: { socketMode: true },
tools: { limit: 60, includeRender: true },
};

Env vars override matching keys; programmatic overrides win overall. Use the file form when you want one place to edit config in development and the env-var form in production.

const { createAgent, startAgent } = require('@davepi/agent');
const agent = await createAgent({
llm: { provider: 'openai', model: 'gpt-4o-mini', maxSteps: 4 },
auth: { mode: 'service', bearer: process.env.MY_TOKEN },
tools: { limit: 100 },
});

The overrides object is shallow-merged on top of the env-resolved config — nested keys (e.g. llm.maxSteps) replace just the field, not the whole sub-object. Use this seam to scope a sub-agent inside a larger process (a multi-tenant dispatcher minting per-tenant agents from one shared codepath).

→ Programmatic API

Terminal window
DAVEPI_URL=https://api.example.com
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
DAVEPI_CLIENT_ID=pk_storefront_live_abc123
AGENT_CORS_ORIGINS=https://shop.example.com
AGENT_TOOL_LIMIT=20

The widget bundles pk_storefront_live_abc123 in the SPA build; the apiClient row on the davepi side carries role: 'storefront' with schema.acl.scope.storefront = { status: 'published' } so only published products / appointments are readable. The agent has no JWT and cannot write.

Terminal window
DAVEPI_URL=https://acme.davepi.dev
LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=sk-ant-...
AGENT_AUTH_MODE=per-user
AGENT_LINK_BASE_URL=https://support.acme.com
AGENT_SESSION_SECRET=$(openssl rand -hex 32)
STORE_URL=file:/var/lib/davepi-agent/acme-store.json
AGENT_KEY=support
SLACK_BOT_TOKEN=xoxb-...
SLACK_SIGNING_SECRET=...

AGENT_KEY=support selects the agentPersona, agentMemory, and skill rows for the support agent within the (Acme-owned) tenant. A sibling process with AGENT_KEY=sales runs the sales agent off its own rows; both share Acme’s customerProfile rows.

Terminal window
ollama pull qwen2.5
LLM_PROVIDER=ollama
LLM_MODEL=qwen2.5
DAVEPI_URL=http://localhost:5050
DAVEPI_BEARER=eyJ...
AGENT_TOOL_LIMIT=20 # smaller surface helps local models

No outbound network. The Anthropic-specific prompt caching is a no-op.