############################################################################### # Environment variables used within the AI Engine. # Values can be overridden in the uncommitted sibling `.env.local` file. # Note: This file is committed to Git, so should not contain any private keys. ############################################################################### # Configure the model strings passed to pydantic-ai. Provider credentials are handled by # pydantic-ai and should be set using the provider's native environment variables, for example # ANTHROPIC_API_KEY or OPENAI_API_KEY. STIRLING_SMART_MODEL=anthropic:claude-haiku-4-5 STIRLING_FAST_MODEL=anthropic:claude-haiku-4-5 # Default output token limits applied by the engine for each model tier. STIRLING_SMART_MODEL_MAX_TOKENS=8192 STIRLING_FAST_MODEL_MAX_TOKENS=2048 # Process-wide cap on concurrent model API calls, shared by both model tiers. # Per-request fan-outs (chunked reasoner workers, contradiction detection) are # bounded per request; this bounds their product across concurrent requests. STIRLING_MODEL_MAX_CONCURRENCY=32 # Document store: the one database holding vector chunks, ordered page text, # and ACL rows. Backend is "sqlite" (embedded sqlite-vec) or "pgvector" # (external Postgres). STIRLING_DOCUMENTS_BACKEND=sqlite # Path to the sqlite-vec database file (used when backend=sqlite). STIRLING_DOCUMENTS_SQLITE_PATH=data/rag.db # Postgres DSN for pgvector (used when backend=pgvector). Leave empty when backend=sqlite. # Example: postgresql://user:password@host:5432/dbname STIRLING_DOCUMENTS_PGVECTOR_DSN= # Connection pool bounds for the pgvector backend. STIRLING_DOCUMENTS_PGVECTOR_POOL_MIN_SIZE=1 STIRLING_DOCUMENTS_PGVECTOR_POOL_MAX_SIZE=10 # RAG Configuration - retrieval-augmented generation is always on. # Embedding provider credentials are handled natively (e.g. VOYAGE_API_KEY for VoyageAI). STIRLING_RAG_EMBEDDING_MODEL=voyageai:voyage-4 STIRLING_RAG_CHUNK_SIZE=512 STIRLING_RAG_CHUNK_OVERLAP=64 STIRLING_RAG_TOP_K=20 # Per-run cap on ``search_knowledge`` calls. After this many calls the tool is # removed from the agent's toolset so it must answer from what it already retrieved # rather than chain more searches. STIRLING_RAG_MAX_SEARCHES=5 # Chunked reasoner settings: how big each per-worker slice is (in characters), # how many workers may run in parallel against the fast model, and how long # any single worker is allowed to wait for a response before being abandoned. # Worker timeouts protect gather_notes from upstream model stalls (which # otherwise hang at the provider's ~10 minute HTTP default); the affected # slice is dropped and the rest of the document still answers. STIRLING_CHUNKED_REASONER_CHARS_PER_SLICE=16000 STIRLING_CHUNKED_REASONER_CONCURRENCY=10 STIRLING_CHUNKED_REASONER_WORKER_TIMEOUT_SECONDS=60 # When the rendered slice notes would exceed this many characters, the # reasoner folds them hierarchically with fast-model calls until they fit. # This keeps the synthesis prompt under the model's context limit on long # documents (a 3000-page novel produces ~900k chars of raw notes). STIRLING_CHUNKED_REASONER_NOTES_CHAR_BUDGET=250000 # Upper bounds on PDF page text the engine will request per extraction round. STIRLING_MAX_PAGES=200 STIRLING_MAX_CHARACTERS=200000 # Reject API requests that lack an X-User-Id header. Self-hosted deployments # with security disabled have no user identity, so this is off by default. # Multi-tenant (SaaS) deployments must set it to true. STIRLING_REQUIRE_USER_ID=false # PostHog analytics. Set STIRLING_POSTHOG_ENABLED=true and provide an API key to enable. STIRLING_POSTHOG_ENABLED=false STIRLING_POSTHOG_API_KEY=phc_VOdeYnlevc2T63m3myFGjeBlRcIusRgmhfx6XL5a1iz STIRLING_POSTHOG_HOST=https://eu.i.posthog.com # Log level for the stirling logger hierarchy (DEBUG, INFO, WARNING, ERROR) STIRLING_LOG_LEVEL=INFO # Path to log file. Rolls daily, keeps 1 backup. Leave empty for console only. STIRLING_LOG_FILE= # Set true to log every outgoing httpx / Anthropic SDK request with timing. # Use when diagnosing worker stalls: a hung call shows a "Request" line with # no matching "Response" line. Noisy; leave off in normal use. STIRLING_HTTP_DEBUG=false