fix: align self-hosting config and docs
This commit is contained in:
parent
7928c39bf4
commit
fd239611a3
|
|
@ -32,7 +32,9 @@ LOG_LEVEL=INFO
|
|||
# =============================================================================
|
||||
# Connection URI for PostgreSQL database with pgvector support
|
||||
# Must use postgresql+psycopg prefix for SQLAlchemy compatibility
|
||||
DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@localhost:5432/postgres
|
||||
# Keep localhost for host-based runs; docker-compose.yml.example overrides the
|
||||
# hostname to the "database" service inside containers.
|
||||
DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
|
||||
# Optional database settings
|
||||
# DB_SCHEMA=public
|
||||
|
|
@ -57,16 +59,19 @@ AUTH_USE_AUTH=false
|
|||
# AUTH_JWT_SECRET=your-secret-key-here
|
||||
|
||||
# =============================================================================
|
||||
# LLM API Keys (REQUIRED for full functionality)
|
||||
# LLM API Keys
|
||||
# =============================================================================
|
||||
# The shipped defaults need Anthropic and Gemini for startup. OpenAI is also
|
||||
# needed if you keep the default embedding behavior
|
||||
# (EMBED_MESSAGES=true and LLM_EMBEDDING_PROVIDER=openai).
|
||||
# OpenAI API key for embeddings
|
||||
LLM_OPENAI_API_KEY=your-openai-api-key-here
|
||||
|
||||
# Anthropic API key for dialectic and deriver functionality
|
||||
# Anthropic API key for dialectic functionality
|
||||
LLM_ANTHROPIC_API_KEY=your-anthropic-api-key-here
|
||||
|
||||
# Google API key for summarization (if using Gemini)
|
||||
# LLM_GEMINI_API_KEY=your-google-api-key-here
|
||||
# Google API key for summary/deriver and Gemini-backed reasoning
|
||||
LLM_GEMINI_API_KEY=your-google-api-key-here
|
||||
|
||||
# Groq API key for query generation (if using Groq)
|
||||
# LLM_GROQ_API_KEY=your-groq-api-key-here
|
||||
|
|
|
|||
59
README.md
59
README.md
|
|
@ -216,20 +216,30 @@ Honcho uses a `.env` file for managing runtime environment variables. A
|
|||
are not required and are only necessary for additional logging, monitoring, and
|
||||
security.
|
||||
|
||||
Below are the required configurations:
|
||||
Below are the required configurations for the shipped defaults:
|
||||
|
||||
```env
|
||||
DB_CONNECTION_URI= # Connection uri for a postgres database (with postgresql+psycopg prefix)
|
||||
|
||||
# LLM Provider API Keys (at least one required depending on your configuration)
|
||||
LLM_ANTHROPIC_API_KEY= # API Key for Anthropic (used for dialectic by default)
|
||||
LLM_OPENAI_API_KEY= # API Key for OpenAI (optional, for embeddings if EMBED_MESSAGES=true)
|
||||
LLM_GEMINI_API_KEY= # API Key for Google Gemini (used for summary/deriver by default)
|
||||
# LLM Provider API Keys
|
||||
LLM_ANTHROPIC_API_KEY= # Required to boot with default dialectic settings
|
||||
LLM_GEMINI_API_KEY= # Required to boot with default summary/deriver and dialectic minimal/low settings
|
||||
LLM_OPENAI_API_KEY= # Required if you keep the default embedding behavior (EMBED_MESSAGES=true and LLM_EMBEDDING_PROVIDER=openai)
|
||||
LLM_GROQ_API_KEY= # API Key for Groq (used for query generation by default)
|
||||
```
|
||||
|
||||
> Note that the `DB_CONNECTION_URI` must have the prefix `postgresql+psycopg` to
|
||||
> function properly. This is a requirement brought by `sqlalchemy`
|
||||
>
|
||||
> If you change the default providers in `config.toml` or via environment
|
||||
> variables, the required LLM keys change with them.
|
||||
>
|
||||
> Current limitation: embeddings have their own provider selector
|
||||
> (`LLM_EMBEDDING_PROVIDER`), but other LLM features use per-feature
|
||||
> `PROVIDER`/`MODEL` fields backed by a shared global client pool. In
|
||||
> particular, `custom` and `vllm` are global OpenAI-compatible connection slots,
|
||||
> so you cannot point two different features at two different custom endpoints at
|
||||
> the same time.
|
||||
|
||||
The template has the additional functionality disabled by default. To ensure
|
||||
that they are disabled you can verify the following environment variables are
|
||||
|
|
@ -266,6 +276,10 @@ uv run alembic upgrade head
|
|||
This will create all tables for Honcho including workspaces, peers, sessions,
|
||||
messages, and the queue system.
|
||||
|
||||
> `uv run alembic ...` reads `DB_CONNECTION_URI` (or `[db].CONNECTION_URI` in
|
||||
> `config.toml`) through Honcho's settings loader. The placeholder URL in
|
||||
> `alembic.ini` is not the effective source of truth.
|
||||
|
||||
6. **Launch Honcho**
|
||||
|
||||
With everything set up, you can now launch a local instance of Honcho. In addition to the database, two
|
||||
|
|
@ -347,8 +361,10 @@ As mentioned earlier a `docker-compose` template is included for running Honcho.
|
|||
As an alternative to running Honcho locally it can also be run with the compose
|
||||
template.
|
||||
|
||||
The docker-compose template is set to use an environment file called `.env`.
|
||||
You can also copy the `.env.template` and fill with the appropriate values.
|
||||
The self-hosting setup treats `.env.template` as the canonical source of truth
|
||||
for local/manual defaults. `config.toml.example` mirrors the same settings in
|
||||
TOML form. The compose example keeps those defaults and only overrides
|
||||
container-local details such as service hostnames.
|
||||
|
||||
Copy the template and update the appropriate environment variables before
|
||||
launching the service:
|
||||
|
|
@ -356,11 +372,19 @@ launching the service:
|
|||
```bash
|
||||
cd honcho
|
||||
cp .env.template .env
|
||||
# update the file with openai key and other wanted environment variables
|
||||
# keep DB_CONNECTION_URI pointed at localhost; docker-compose overrides the host
|
||||
# to the internal "database" service automatically
|
||||
# update the file with LLM keys and any other wanted environment variables
|
||||
cp docker-compose.yml.example docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
|
||||
Once the stack is up, you can verify the API with:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/openapi.json
|
||||
```
|
||||
|
||||
### Deploy on Fly
|
||||
|
||||
The API can also be deployed on fly.io. Follow the [Fly.io
|
||||
|
|
@ -390,6 +414,9 @@ Honcho uses a flexible configuration system that supports both TOML files and en
|
|||
3. `config.toml` file
|
||||
4. Default values
|
||||
|
||||
`.env.template` is the canonical setup template. `config.toml.example` is the
|
||||
equivalent TOML transcription of that template, not a separate set of defaults.
|
||||
|
||||
### Using config.toml
|
||||
|
||||
Copy the example configuration file to get started:
|
||||
|
|
@ -398,7 +425,9 @@ Copy the example configuration file to get started:
|
|||
cp config.toml.example config.toml
|
||||
```
|
||||
|
||||
Then modify the values as needed. The TOML file is organized into sections:
|
||||
Then modify the values as needed. Use `.env.template` as the source of truth
|
||||
for placeholder values and required-vs-optional settings; `config.toml.example`
|
||||
mirrors those same values in TOML form. The TOML file is organized into sections:
|
||||
|
||||
- `[app]` - Application-level settings (log level, session limits, embedding settings, namespace)
|
||||
- `[db]` - Database connection and pool settings
|
||||
|
|
@ -434,6 +463,14 @@ Examples:
|
|||
- `METRICS_ENABLED` - Enable Prometheus metrics
|
||||
- `TELEMETRY_ENABLED` - Enable CloudEvents telemetry
|
||||
|
||||
Canonical mappings used throughout the self-hosting docs:
|
||||
|
||||
- `DB_CONNECTION_URI` ↔ `[db].CONNECTION_URI`
|
||||
- `CACHE_ENABLED` ↔ `[cache].ENABLED`
|
||||
- `CACHE_URL` ↔ `[cache].URL`
|
||||
- `METRICS_ENABLED` ↔ `[metrics].ENABLED`
|
||||
- `LLM_*` env vars ↔ `[llm]` keys
|
||||
|
||||
### Configuration Priority
|
||||
|
||||
When a configuration value is set in multiple places, Honcho uses this priority:
|
||||
|
|
@ -455,14 +492,14 @@ If you have this in `config.toml`:
|
|||
|
||||
```toml
|
||||
[db]
|
||||
CONNECTION_URI = "postgresql://localhost/honcho_dev"
|
||||
CONNECTION_URI = "postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
POOL_SIZE = 10
|
||||
```
|
||||
|
||||
You can override just the connection URI in production:
|
||||
|
||||
```bash
|
||||
export DB_CONNECTION_URI="postgresql://prod-server/honcho_prod"
|
||||
export DB_CONNECTION_URI="postgresql+psycopg://prod-server/honcho_prod"
|
||||
```
|
||||
|
||||
The application will use the production connection URI while keeping the pool size from config.toml.
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ NAMESPACE = "honcho"
|
|||
|
||||
# Database settings
|
||||
[db]
|
||||
CONNECTION_URI = "postgresql+psycopg://postgres:postgres@localhost:5432/postgres"
|
||||
# Keep localhost for host-based runs; docker-compose.yml.example overrides the
|
||||
# hostname to the "database" service inside containers.
|
||||
CONNECTION_URI = "postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
SCHEMA = "public"
|
||||
POOL_CLASS = "default"
|
||||
POOL_PRE_PING = true
|
||||
|
|
@ -37,13 +39,13 @@ TRACING = false
|
|||
# Authentication settings
|
||||
[auth]
|
||||
USE_AUTH = false
|
||||
JWT_SECRET = "your-secret-key-here" # Must be set if USE_AUTH is true
|
||||
# JWT_SECRET = "your-secret-key-here" # Must be set if USE_AUTH is true
|
||||
|
||||
# Sentry settings
|
||||
[sentry]
|
||||
ENABLED = false
|
||||
DSN = ""
|
||||
RELEASE = ""
|
||||
# DSN = "your-sentry-dsn-here"
|
||||
# RELEASE = "your-release-semver"
|
||||
ENVIRONMENT = "development"
|
||||
TRACES_SAMPLE_RATE = 0.1
|
||||
PROFILES_SAMPLE_RATE = 0.1
|
||||
|
|
@ -56,6 +58,11 @@ MAX_TOOL_OUTPUT_CHARS = 10000 # Max chars for tool output (~2500 tokens)
|
|||
MAX_MESSAGE_CONTENT_CHARS = 2000 # Max chars per message in tool results
|
||||
|
||||
# API Keys for LLM providers
|
||||
# Required to boot with the shipped defaults:
|
||||
# - ANTHROPIC_API_KEY for anthropic-backed dialectic levels
|
||||
# - GEMINI_API_KEY for summary/deriver and Gemini-backed reasoning levels
|
||||
# OPENAI_API_KEY is additionally required if you keep the default embedding
|
||||
# behavior (EMBED_MESSAGES=true and EMBEDDING_PROVIDER="openai").
|
||||
# ANTHROPIC_API_KEY = "your-api-key"
|
||||
# OPENAI_API_KEY = "your-api-key"
|
||||
# OPENAI_COMPATIBLE_API_KEY = "your-api-key"
|
||||
|
|
@ -67,6 +74,11 @@ MAX_MESSAGE_CONTENT_CHARS = 2000 # Max chars per message in tool results
|
|||
# VLLM_API_KEY = "your-api-key"
|
||||
# VLLM_BASE_URL = "your-base-url"
|
||||
|
||||
# Current limitation: non-embedding LLM features choose PROVIDER/MODEL in their
|
||||
# own sections, but "custom" and "vllm" connection settings come from these
|
||||
# shared [llm] keys. You cannot configure two different custom OpenAI-compatible
|
||||
# endpoints for two different features at the same time.
|
||||
|
||||
# Deriver settings
|
||||
[deriver]
|
||||
ENABLED = true
|
||||
|
|
@ -121,6 +133,7 @@ MODEL = "claude-haiku-4-5"
|
|||
THINKING_BUDGET_TOKENS = 1024
|
||||
MAX_TOOL_ITERATIONS = 2
|
||||
# MAX_OUTPUT_TOKENS = 8192 # Optional: override global default
|
||||
# TOOL_CHOICE = "any" # Optional: null/auto, "any", or "required"
|
||||
|
||||
[dialectic.levels.high]
|
||||
PROVIDER = "anthropic"
|
||||
|
|
@ -185,7 +198,7 @@ INCLUDE_LEVELS = ["explicit", "deductive"]
|
|||
|
||||
# Webhook settings
|
||||
[webhook]
|
||||
SECRET = ""
|
||||
# SECRET = "your-webhook-signing-secret"
|
||||
MAX_WORKSPACE_LIMIT = 10
|
||||
|
||||
# Prometheus metrics settings (pull-based metrics)
|
||||
|
|
@ -219,7 +232,7 @@ DEFAULT_LOCK_TTL_SECONDS = 5
|
|||
TYPE = "pgvector"
|
||||
# Migration flag: set to true when migration from pgvector is complete
|
||||
MIGRATED = false
|
||||
NAMESPACE = "honcho"
|
||||
# NAMESPACE = "honcho" # Inherits from app.NAMESPACE if not set
|
||||
DIMENSIONS = 1536
|
||||
# TURBOPUFFER_API_KEY = "your-turbopuffer-api-key"
|
||||
# TURBOPUFFER_REGION = "us-east-1"
|
||||
|
|
|
|||
|
|
@ -15,9 +15,15 @@ services:
|
|||
volumes:
|
||||
- .:/app
|
||||
- venv:/app/.venv
|
||||
# .env.template remains the canonical host/manual configuration.
|
||||
# Compose overrides service-local addresses and enables stack-local features.
|
||||
environment:
|
||||
- DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@database:5432/postgres
|
||||
- DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@database:5432/honcho
|
||||
- CACHE_ENABLED=true
|
||||
- CACHE_URL=redis://redis:6379/0?suppress=true
|
||||
- METRICS_ENABLED=true
|
||||
# Provide required LLM_* keys through .env or the shell environment when
|
||||
# using the default provider configuration.
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false
|
||||
|
|
@ -35,9 +41,12 @@ services:
|
|||
- .:/app
|
||||
- venv:/app/.venv
|
||||
environment:
|
||||
- DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@database:5432/postgres
|
||||
- DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@database:5432/honcho
|
||||
- CACHE_ENABLED=true
|
||||
- CACHE_URL=redis://redis:6379/0?suppress=true
|
||||
- METRICS_ENABLED=true
|
||||
# Provide required LLM_* keys through .env or the shell environment when
|
||||
# using the default provider configuration.
|
||||
env_file:
|
||||
- path: .env
|
||||
required: false
|
||||
|
|
@ -48,16 +57,16 @@ services:
|
|||
- 5432:5432
|
||||
command: ["postgres", "-c", "max_connections=800"]
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
- POSTGRES_DB=honcho
|
||||
- POSTGRES_USER=testuser
|
||||
- POSTGRES_PASSWORD=testpwd
|
||||
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||
- PGDATA=/var/lib/postgresql/data/pgdata
|
||||
volumes:
|
||||
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- pgdata:/var/lib/postgresql/data/
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
|
||||
test: ["CMD-SHELL", "pg_isready -U testuser -d honcho"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
|
|
|||
|
|
@ -11,6 +11,14 @@ Honcho uses a flexible configuration system that supports both TOML files and en
|
|||
3. `config.toml` file (base configuration)
|
||||
4. Default values
|
||||
|
||||
`.env.template` is the canonical source of truth for local/self-hosted defaults.
|
||||
`config.toml.example` mirrors the same values in TOML form.
|
||||
The shipped defaults currently require `LLM_ANTHROPIC_API_KEY` and
|
||||
`LLM_GEMINI_API_KEY` to boot. `LLM_OPENAI_API_KEY` is also required if you keep
|
||||
the default embedding behavior (`EMBED_MESSAGES=true` and
|
||||
`LLM_EMBEDDING_PROVIDER=openai`). If you change provider settings, those key
|
||||
requirements change with them.
|
||||
|
||||
## Recommended Configuration Approaches
|
||||
|
||||
### Option 1: Environment Variables Only (Production)
|
||||
|
|
@ -44,7 +52,9 @@ Copy the example configuration file to get started:
|
|||
cp config.toml.example config.toml
|
||||
```
|
||||
|
||||
Then modify the values as needed. The TOML file is organized into sections:
|
||||
Then modify the values as needed. Use `.env.template` for the canonical default
|
||||
values and placeholders; `config.toml.example` mirrors those same settings in
|
||||
TOML form. The TOML file is organized into sections:
|
||||
|
||||
- `[app]` - Application-level settings (log level, session limits, embedding settings, Langfuse integration, local metrics collection, namespace)
|
||||
- `[db]` - Database connection and pool settings (connection URI, pool size, timeouts, connection recycling)
|
||||
|
|
@ -80,6 +90,14 @@ Examples:
|
|||
- `DIALECTIC_LEVELS__minimal__PROVIDER` → `[dialectic.levels.minimal].PROVIDER`
|
||||
- `DREAM_SURPRISAL__ENABLED` → `[dream.surprisal].ENABLED`
|
||||
|
||||
Canonical mappings used throughout the self-hosting docs:
|
||||
|
||||
- `DB_CONNECTION_URI` ↔ `[db].CONNECTION_URI`
|
||||
- `CACHE_ENABLED` ↔ `[cache].ENABLED`
|
||||
- `CACHE_URL` ↔ `[cache].URL`
|
||||
- `METRICS_ENABLED` ↔ `[metrics].ENABLED`
|
||||
- `LLM_*` env vars ↔ `[llm]` keys
|
||||
|
||||
### Configuration Priority
|
||||
|
||||
When a configuration value is set in multiple places, Honcho uses this priority:
|
||||
|
|
@ -101,14 +119,14 @@ If you have this in `config.toml`:
|
|||
|
||||
```toml
|
||||
[db]
|
||||
CONNECTION_URI = "postgresql://localhost/honcho_dev"
|
||||
CONNECTION_URI = "postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
POOL_SIZE = 10
|
||||
```
|
||||
|
||||
You can override just the connection URI in production:
|
||||
|
||||
```bash
|
||||
export DB_CONNECTION_URI="postgresql://prod-server/honcho_prod"
|
||||
export DB_CONNECTION_URI="postgresql+psycopg://prod-server/honcho_prod"
|
||||
```
|
||||
|
||||
The application will use the production connection URI while keeping the pool size from config.toml.
|
||||
|
|
@ -161,7 +179,7 @@ REASONING_TRACES_FILE=traces.jsonl
|
|||
DB_CONNECTION_URI=postgresql+psycopg://username:password@host:port/database
|
||||
|
||||
# Example for local development
|
||||
DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@localhost:5432/honcho
|
||||
DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
|
||||
# Example for production
|
||||
DB_CONNECTION_URI=postgresql+psycopg://honcho_user:secure_password@db.example.com:5432/honcho_prod
|
||||
|
|
@ -190,19 +208,23 @@ services:
|
|||
database:
|
||||
image: pgvector/pgvector:pg15
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: testuser
|
||||
POSTGRES_PASSWORD: testpwd
|
||||
POSTGRES_DB: honcho
|
||||
ports:
|
||||
- "5432:5432"
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
When you use `docker-compose.yml.example`, keep `.env`/`config.toml` on the
|
||||
host-style `localhost` URI. Compose overrides only the hostname to `database`
|
||||
inside containers and enables stack-local caching/metrics there.
|
||||
|
||||
### Authentication Configuration
|
||||
|
||||
**JWT Authentication:**
|
||||
|
|
@ -290,6 +312,41 @@ LLM_MAX_TOOL_OUTPUT_CHARS=10000 # ~2500 tokens at 4 chars/token
|
|||
LLM_MAX_MESSAGE_CONTENT_CHARS=2000 # Max chars per message in tool results
|
||||
```
|
||||
|
||||
### Current Provider Resolution Model
|
||||
|
||||
Honcho currently has two different configuration paths for LLM usage:
|
||||
|
||||
- Embeddings are configured through `[llm]` with `LLM_EMBEDDING_PROVIDER`.
|
||||
- Other LLM-backed features such as `summary`, `deriver`, `dream`, and
|
||||
`dialectic` choose `PROVIDER` and `MODEL` in their own sections.
|
||||
|
||||
This means the current behavior is:
|
||||
|
||||
- `LLM_EMBEDDING_PROVIDER=openai` uses `LLM_OPENAI_API_KEY`
|
||||
- `LLM_EMBEDDING_PROVIDER=gemini` uses `LLM_GEMINI_API_KEY`
|
||||
- `LLM_EMBEDDING_PROVIDER=openrouter` uses
|
||||
`LLM_OPENAI_COMPATIBLE_API_KEY` and `LLM_OPENAI_COMPATIBLE_BASE_URL`
|
||||
(defaulting to OpenRouter's API URL if the base URL is omitted)
|
||||
- `SUMMARY.PROVIDER`, `DERIVER.PROVIDER`, `DREAM.PROVIDER`, and each
|
||||
`DIALECTIC.LEVELS.*.PROVIDER` select from the shared provider pool built from
|
||||
`[llm]`
|
||||
|
||||
There is an important current limitation:
|
||||
|
||||
- `custom` and `vllm` in feature-specific `PROVIDER` fields are not separate
|
||||
per-feature providers. They are global OpenAI-compatible client slots backed
|
||||
by one shared `[llm]` configuration each.
|
||||
- As a result, you cannot configure two different custom OpenAI-compatible
|
||||
endpoints for two different features at the same time.
|
||||
- Similarly, if embeddings use `openrouter`, they consume the same
|
||||
`LLM_OPENAI_COMPATIBLE_*` settings that a feature using `PROVIDER="custom"`
|
||||
would use.
|
||||
|
||||
`SupportedProviders` therefore represents a mix of provider identities
|
||||
(`anthropic`, `google`, `openai`, `groq`) and transport/client styles
|
||||
(`custom`, `vllm`). That is the current implementation contract, even though it
|
||||
is more constrained than a fully per-feature provider configuration model.
|
||||
|
||||
### Feature-Specific Model Configuration
|
||||
|
||||
Different features can use different providers and models:
|
||||
|
|
@ -615,7 +672,7 @@ EMBED_MESSAGES = false
|
|||
NAMESPACE = "honcho-dev"
|
||||
|
||||
[db]
|
||||
CONNECTION_URI = "postgresql+psycopg://postgres:postgres@localhost:5432/honcho_dev"
|
||||
CONNECTION_URI = "postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
POOL_SIZE = 5
|
||||
|
||||
[auth]
|
||||
|
|
@ -698,7 +755,7 @@ ENABLED = false
|
|||
```bash
|
||||
# .env.development
|
||||
LOG_LEVEL=DEBUG
|
||||
DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@localhost:5432/honcho_dev
|
||||
DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
AUTH_USE_AUTH=false
|
||||
CACHE_ENABLED=false
|
||||
|
||||
|
|
@ -851,6 +908,10 @@ uv run alembic downgrade revision_id
|
|||
uv run alembic revision --autogenerate -m "Description of changes"
|
||||
```
|
||||
|
||||
Alembic uses Honcho's application settings for the database URL. Set
|
||||
`DB_CONNECTION_URI` or `[db].CONNECTION_URI`; do not rely on the placeholder
|
||||
value in `alembic.ini`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Common Configuration Issues:**
|
||||
|
|
|
|||
|
|
@ -51,15 +51,24 @@ Copy the example environment file and configure it:
|
|||
cp .env.template .env
|
||||
```
|
||||
|
||||
Edit `.env` and set your API keys (if using LLM features):
|
||||
`.env.template` is the canonical self-hosting template. If you prefer TOML, you
|
||||
can also copy `config.toml.example` to `config.toml`; it mirrors the same
|
||||
settings in TOML form.
|
||||
|
||||
Edit `.env` and set the API keys required by the shipped defaults:
|
||||
|
||||
```bash
|
||||
# Optional API keys (required for LLM features)
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
ANTHROPIC_API_KEY=your-anthropic-api-key
|
||||
# Required to boot with the shipped defaults
|
||||
LLM_ANTHROPIC_API_KEY=your-anthropic-api-key
|
||||
LLM_GEMINI_API_KEY=your-google-api-key
|
||||
|
||||
# Database will be created automatically by Docker
|
||||
DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@database:5432/honcho
|
||||
# Also required if you keep default embeddings enabled
|
||||
LLM_OPENAI_API_KEY=your-openai-api-key
|
||||
|
||||
# Keep localhost here for host/manual runs.
|
||||
# docker-compose.yml.example overrides the hostname to the internal "database"
|
||||
# service automatically, so you do not need to edit this value for Docker.
|
||||
DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
|
||||
# Disable auth for local development
|
||||
AUTH_USE_AUTH=false
|
||||
|
|
@ -86,10 +95,19 @@ docker compose ps
|
|||
Test the Honcho API:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
curl http://localhost:8000/openapi.json
|
||||
```
|
||||
|
||||
You should see a response indicating the service is healthy.
|
||||
You should see the OpenAPI document for the running server.
|
||||
|
||||
If you change the default providers in `config.toml` or via environment
|
||||
variables, the required LLM keys change with them.
|
||||
|
||||
Current limitation: embeddings use `LLM_EMBEDDING_PROVIDER`, but other LLM
|
||||
features use per-feature `PROVIDER`/`MODEL` values backed by shared global
|
||||
client settings in `[llm]`. That means `custom` and `vllm` each represent one
|
||||
global OpenAI-compatible endpoint at a time, not a separate endpoint per
|
||||
feature.
|
||||
|
||||
## Manual Setup
|
||||
|
||||
|
|
@ -135,23 +153,21 @@ Download from [postgresql.org](https://www.postgresql.org/download/windows/)
|
|||
```bash
|
||||
docker run --name honcho-db \
|
||||
-e POSTGRES_DB=honcho \
|
||||
-e POSTGRES_USER=postgres \
|
||||
-e POSTGRES_PASSWORD=postgres \
|
||||
-e POSTGRES_USER=testuser \
|
||||
-e POSTGRES_PASSWORD=testpwd \
|
||||
-p 5432:5432 \
|
||||
-d pgvector/pgvector:pg15
|
||||
```
|
||||
|
||||
### 3. Create Database and Enable Extensions
|
||||
|
||||
Connect to PostgreSQL and set up the database:
|
||||
If you used the Docker command above, the `honcho` database and `testuser`
|
||||
role are created automatically. For a local PostgreSQL installation, create a
|
||||
matching role/database first or update `.env.template` and `config.toml`
|
||||
consistently. Then connect and enable extensions:
|
||||
|
||||
```bash
|
||||
# Connect to PostgreSQL
|
||||
psql -U postgres
|
||||
|
||||
# Create database and enable extensions
|
||||
CREATE DATABASE honcho;
|
||||
\c honcho
|
||||
PGPASSWORD=testpwd psql -h localhost -p 5432 -U testuser -d honcho
|
||||
CREATE EXTENSION IF NOT EXISTS vector;
|
||||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
\q
|
||||
|
|
@ -165,15 +181,21 @@ Create a `.env` file with your settings:
|
|||
cp .env.template .env
|
||||
```
|
||||
|
||||
You can alternatively copy `config.toml.example` to `config.toml`; it mirrors
|
||||
the same settings as `.env.template`.
|
||||
|
||||
Edit `.env` with your configuration:
|
||||
|
||||
```bash
|
||||
# Database connection
|
||||
DB_CONNECTION_URI=postgresql+psycopg://postgres:postgres@localhost:5432/honcho
|
||||
DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho
|
||||
|
||||
# Optional API keys (required for LLM features)
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
ANTHROPIC_API_KEY=your-anthropic-api-key
|
||||
# Required to boot with the shipped defaults
|
||||
LLM_ANTHROPIC_API_KEY=your-anthropic-api-key
|
||||
LLM_GEMINI_API_KEY=your-google-api-key
|
||||
|
||||
# Also required if you keep default embeddings enabled
|
||||
LLM_OPENAI_API_KEY=your-openai-api-key
|
||||
|
||||
# Development settings
|
||||
AUTH_USE_AUTH=false
|
||||
|
|
@ -187,6 +209,10 @@ LOG_LEVEL=DEBUG
|
|||
uv run alembic upgrade head
|
||||
```
|
||||
|
||||
> Honcho's Alembic environment reads `DB_CONNECTION_URI` or
|
||||
> `[db].CONNECTION_URI` from the application config. `alembic.ini` is not the
|
||||
> effective source of truth for the database URL.
|
||||
|
||||
### 6. Start the Server
|
||||
|
||||
```bash
|
||||
|
|
@ -209,7 +235,8 @@ If you prefer to use a managed PostgreSQL service:
|
|||
CREATE EXTENSION IF NOT EXISTS pg_trgm;
|
||||
```
|
||||
3. **Get your connection string** from Settings > Database
|
||||
4. **Update your `.env` file** with the connection string
|
||||
4. **Update your `.env` file** with the connection string or set the equivalent
|
||||
`[db].CONNECTION_URI` value in `config.toml`
|
||||
|
||||
### Railway
|
||||
|
||||
|
|
@ -226,7 +253,7 @@ Once your Honcho server is running, verify everything is working:
|
|||
### 1. Health Check
|
||||
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
curl http://localhost:8000/openapi.json
|
||||
```
|
||||
|
||||
### 2. API Documentation
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ from pydantic_settings import (
|
|||
|
||||
from src.utils.types import SupportedProviders
|
||||
|
||||
# Load .env file for local development.
|
||||
# Make sure this is called before AppSettings is instantiated if you rely on .env for AppSettings construction.
|
||||
load_dotenv(override=True)
|
||||
# Load .env file for local development without overriding explicit environment
|
||||
# variables from the process (for example Docker Compose container overrides).
|
||||
load_dotenv(override=False)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ class DBSettings(HonchoSettings):
|
|||
model_config = SettingsConfigDict(env_prefix="DB_", extra="ignore") # pyright: ignore
|
||||
|
||||
CONNECTION_URI: str = (
|
||||
"postgresql+psycopg://postgres:postgres@localhost:5432/postgres"
|
||||
"postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
)
|
||||
SCHEMA: str = "public"
|
||||
POOL_CLASS: str = "default"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_tracked_db():
|
||||
"""Disable the DB-heavy tracked_db autouse fixture for setup example tests."""
|
||||
yield
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def _load_db_connection_uri(tmp_path: Path, env_overrides: dict[str, str]) -> str:
|
||||
env = os.environ.copy()
|
||||
env["PYTHONPATH"] = str(REPO_ROOT)
|
||||
env.pop("DB_CONNECTION_URI", None)
|
||||
env.update(env_overrides)
|
||||
|
||||
result = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-c",
|
||||
(
|
||||
"from src.config import settings; "
|
||||
"import json; "
|
||||
"print(json.dumps({'db_uri': settings.DB.CONNECTION_URI}))"
|
||||
),
|
||||
],
|
||||
cwd=tmp_path,
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
)
|
||||
return json.loads(result.stdout)["db_uri"]
|
||||
|
||||
|
||||
def test_env_var_overrides_dotenv_and_toml(tmp_path: Path) -> None:
|
||||
(tmp_path / ".env").write_text(
|
||||
"DB_CONNECTION_URI=postgresql+psycopg://dotenv:dotenv@localhost:5432/dotenv\n"
|
||||
)
|
||||
(tmp_path / "config.toml").write_text(
|
||||
'[db]\nCONNECTION_URI = "postgresql+psycopg://toml:toml@localhost:5432/toml"\n'
|
||||
)
|
||||
|
||||
db_uri = _load_db_connection_uri(
|
||||
tmp_path,
|
||||
{
|
||||
"DB_CONNECTION_URI": "postgresql+psycopg://env:env@localhost:5432/env",
|
||||
},
|
||||
)
|
||||
|
||||
assert db_uri == "postgresql+psycopg://env:env@localhost:5432/env"
|
||||
|
||||
|
||||
def test_dotenv_overrides_toml(tmp_path: Path) -> None:
|
||||
(tmp_path / ".env").write_text(
|
||||
"DB_CONNECTION_URI=postgresql+psycopg://dotenv:dotenv@localhost:5432/dotenv\n"
|
||||
)
|
||||
(tmp_path / "config.toml").write_text(
|
||||
'[db]\nCONNECTION_URI = "postgresql+psycopg://toml:toml@localhost:5432/toml"\n'
|
||||
)
|
||||
|
||||
db_uri = _load_db_connection_uri(tmp_path, {})
|
||||
|
||||
assert db_uri == "postgresql+psycopg://dotenv:dotenv@localhost:5432/dotenv"
|
||||
|
||||
|
||||
def test_toml_overrides_builtin_defaults(tmp_path: Path) -> None:
|
||||
(tmp_path / "config.toml").write_text(
|
||||
'[db]\nCONNECTION_URI = "postgresql+psycopg://toml:toml@localhost:5432/toml"\n'
|
||||
)
|
||||
|
||||
db_uri = _load_db_connection_uri(tmp_path, {})
|
||||
|
||||
assert db_uri == "postgresql+psycopg://toml:toml@localhost:5432/toml"
|
||||
|
||||
|
||||
def test_examples_share_the_canonical_local_database_contract() -> None:
|
||||
env_template = (REPO_ROOT / ".env.template").read_text()
|
||||
config_example = (REPO_ROOT / "config.toml.example").read_text()
|
||||
|
||||
assert (
|
||||
"DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"
|
||||
in env_template
|
||||
)
|
||||
assert (
|
||||
'CONNECTION_URI = "postgresql+psycopg://testuser:testpwd@localhost:5432/honcho"'
|
||||
in config_example
|
||||
)
|
||||
|
||||
|
||||
def test_compose_example_matches_the_canonical_contract() -> None:
|
||||
compose_example = (REPO_ROOT / "docker-compose.yml.example").read_text()
|
||||
|
||||
assert (
|
||||
"DB_CONNECTION_URI=postgresql+psycopg://testuser:testpwd@database:5432/honcho"
|
||||
in compose_example
|
||||
)
|
||||
assert "CACHE_ENABLED=true" in compose_example
|
||||
assert compose_example.count("METRICS_ENABLED=true") == 2
|
||||
assert (
|
||||
"./database/init.sql:/docker-entrypoint-initdb.d/init.sql" in compose_example
|
||||
)
|
||||
assert (REPO_ROOT / "database" / "init.sql").exists()
|
||||
|
||||
|
||||
def test_examples_surface_default_llm_requirements() -> None:
|
||||
env_template = (REPO_ROOT / ".env.template").read_text()
|
||||
config_example = (REPO_ROOT / "config.toml.example").read_text()
|
||||
compose_example = (REPO_ROOT / "docker-compose.yml.example").read_text()
|
||||
|
||||
assert "LLM_OPENAI_API_KEY=your-openai-api-key-here" in env_template
|
||||
assert "LLM_ANTHROPIC_API_KEY=your-anthropic-api-key-here" in env_template
|
||||
assert "LLM_GEMINI_API_KEY=your-google-api-key-here" in env_template
|
||||
assert "Required to boot with the shipped defaults:" in config_example
|
||||
assert "two different custom OpenAI-compatible" in config_example
|
||||
assert "Provide required LLM_* keys" in compose_example
|
||||
Loading…
Reference in New Issue