Configuration
A1KnowHow loads settings from config.yaml. Non-secret values are plain YAML; secrets use file: paths.
The Personal install zip ships a ready config.yaml. Edit it in place; ./setup.sh creates secrets/encryption_key if missing and may write config.overlay.yaml for bootstrap credentials.
Quick start
# After unzipping the Personal kit:
# edit config.yaml (app.url, llm.*, importer.*)
./setup.sh # creates secrets/encryption_key + overlay; migrate + seed
./run.sh # ./a1kh --dir pb_data --config config.yaml serve CLI flags:
| Flag / env | Purpose |
|---|---|
--config | Path to main YAML (default: config.yaml) |
--secrets | Optional overlay YAML merged before load |
RG_CONFIG_FILE | Config file path only (e.g. Docker); not for secrets |
./run.sh passes --config config.yaml and --dir pb_data (override data dir with DB_DIR=...).
Value forms
| Form | Use |
|---|---|
| Plain string | URLs, names, model IDs |
file:/path/to/secret | Production secrets (recommended) |
env:VAR_NAME | Local dev only; warned on secret fields |
Toggles use YAML booleans (true / false), for example smtp.enabled and features.auto_send_verification_email.
Dynamic maps variables and secrets use string keys and string values only; secret values support the same file: and env: indirection as structured fields.
Required settings
version: 1
server:
listen_address: "127.0.0.1:8383" # Personal default; use 0.0.0.0:8383 for LAN
encryption_key: "file:./secrets/encryption_key"
vector:
type: sqlite-vec
dimensions: 768 # must match embedding model ./setup.sh generates the encryption key file when absent. To create one yourself:
mkdir -p secrets
openssl rand -base64 32 | tr -dc 'a-zA-Z0-9' | head -c 32 > secrets/encryption_key
chmod 600 secrets/encryption_key Reference by section
Defaults below match the Personal install kit.
Example configuration
version: 1
server:
listen_address: "127.0.0.1:8383"
encryption_key: "file:./secrets/encryption_key"
app:
name: "A1KnowHow Personal"
url: "http://localhost:8383"
sender_name: "A1KnowHow"
sender_address: "[email protected]"
database:
auto_migrate: true
logging:
stderr_output: true
level: info
color: true
pocketbase_forward: false
log_auth_id: false
log_ip: false
max_days: 3
smtp:
enabled: false
s3:
enabled: false
vector:
type: sqlite-vec
dimensions: 768
llm:
provider: ollama
url: "http://localhost:11434"
model: "lfm2.5:latest"
chat_title_generator_model: "lfm2.5:latest"
embedding_model: "embeddinggemma-2:270m"
search:
rag_context_limit: 3
importer:
provider: none
# provider: docling
# url: "http://localhost:5001"
chunking:
provider: local
max_tokens: 512
workflow:
step_runner_polling_interval_seconds: 5
features:
auto_send_verification_email: false
rate_limits:
enabled: false
backups:
cron: "0 0 * * *"
cron_max_keep: 1 server
| Key | Description |
|---|---|
listen_address | HTTP bind address (PocketBase serve --http) |
encryption_key | PocketBase encryption key (file: recommended) |
app
| Key | Personal kit default |
|---|---|
name | A1KnowHow Personal |
url | http://localhost:8383 |
sender_name | A1KnowHow |
sender_address | [email protected] |
database
| Key | Default |
|---|---|
auto_migrate | true |
logging
| Key | Default |
|---|---|
level | info (trace, debug, warn, error, fatal, panic, disabled) |
color | true in Personal kit |
pocketbase_forward | false |
log_auth_id | false |
log_ip | false |
max_days | 3 |
vector
| Key | Notes |
|---|---|
type | sqlite-vec |
dimensions | Required; must match embedding model (768 for EmbeddingGemma) |
host, port, api_key | Not used |
llm
| Key | Personal kit default |
|---|---|
provider | ollama |
url | http://localhost:11434 |
model | lfm2.5:latest |
chat_title_generator_model | lfm2.5:latest |
embedding_model | embeddinggemma-2:270m |
timeout | 300 (seconds; HTTP client timeout per LLM API call) |
api_key | Not used with Ollama |
Timeouts: llm.timeout limits a single chat/completions HTTP request when no parent context deadline is set (e.g. UI chat). Workflow agent steps set a separate deadline via the step timeout field in workflow YAML (1–3600 seconds), or 1800 seconds by default when unset; that value is passed on context.Context and is not overridden by the cached LLM HTTP client. For slow models or tool-heavy workflows, raise both as needed—for example llm.timeout: 600 and timeout: 1800 on the agent step.
importer and chunking
Personal kit defaults:
| Key | Default | Notes |
|---|---|---|
importer.provider | none | Markdown/plain text without Docling |
importer.url | — | Set with provider: docling |
chunking.provider | local | Built-in Go chunker |
chunking.max_tokens | 512 | Keep at or below embedding input limit |
When importer.provider is docling, install Docling-serve and set importer.url. On startup, A1KnowHow checks that URL; if unreachable, serve fails. See Dependencies.
| Key | When using Docling |
|---|---|
importer.url | http://localhost:5001 (Compose sample may use 8000) |
fallback_urls | optional |
timeout_seconds | 300 |
smtp, s3
Enable with enabled: true. Passwords and API keys should use file: paths.
Personal does not register a1kh_email_send; outbound email workflows need Enterprise (or custom tooling) even if SMTP is enabled.
features
| Key | Default |
|---|---|
auto_send_verification_email | false |
email_send_any_recipient | Enterprise only; ignored on Personal |
Google sign-in (auth.oauth)
SaaS and Enterprise only. See Google OAuth setup.
trusted_proxy, rate_limits, backups
See example YAML above for backup cron and rate-limit toggles.
variables and secrets (dynamic maps)
Top-level maps for arbitrary string values when a fixed config section does not fit (for example seed bootstrap).
| Section | Purpose | Value forms |
|---|---|---|
variables | Non-sensitive strings | Plain YAML strings |
secrets | Sensitive strings | file: (recommended) or env: |
Prefer structured sections (llm, smtp, server, and so on) for well-known settings. Use variables / secrets only as an escape hatch.
./setup.sh writes bootstrap email/password into config.overlay.yaml using these maps.
Example:
variables:
SEED_BOOTSTRAP_USER_EMAIL: "[email protected]"
secrets:
SEED_BOOTSTRAP_PASSWORD: "file:./secrets/seed_bootstrap_password_hash" Database seeding
The install kit runs seed via ./setup.sh. Manual seed with config loaded:
./a1kh --dir pb_data --config config.yaml seed
./a1kh --dir pb_data --config config.yaml seed --seed-config path/to/seed.yaml In seed YAML files, reference config secrets with:
password: "__::secrets::SEED_BOOTSTRAP_PASSWORD::__" The name after secrets:: must match a key in config.yaml / overlay secrets:. See seed README.
Optional secrets overlay
--secrets config.overlay.yaml merges an overlay before file: / env: resolution. Setup writes an overlay beside config.yaml for bootstrap credentials; ./run.sh / serve pick it up when present next to the main config.
For encrypted config at rest, use SOPS and decrypt to a mount path before serve.
Docker dependencies
If Ollama or Docling run in Compose, keep URLs as localhost ports published to the host while the app runs via ./run.sh. See Docker Setup.
Security
- Do not commit
config.yamlwith inline secrets or unencrypted secret files - Restrict permissions:
chmod 600on secret files - Prefer
file:overenv:for any credential in production - Save the credentials printed by
./setup.sh
Troubleshooting
- Missing encryption key file: run
./setup.shor createsecrets/encryption_keyas above - Invalid
vector.dimensions: must be set and positive before indexing - Docling unreachable at startup: set
importer.provider: none, or start Docling and fiximporter.url - Service connection errors: check
llm.urland that Ollama is running - Config not applied: restart after editing YAML; confirm
--configpath - Seed fails on secret: ensure overlay/
secrets:keys exist andfile:paths are present
Next steps
- Dependencies — Ollama and optional Docling
- Docker Setup
- Features — using A1KnowHow after install