Documentation

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 / envPurpose
--configPath to main YAML (default: config.yaml)
--secretsOptional overlay YAML merged before load
RG_CONFIG_FILEConfig 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

FormUse
Plain stringURLs, names, model IDs
file:/path/to/secretProduction secrets (recommended)
env:VAR_NAMELocal 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

KeyDescription
listen_addressHTTP bind address (PocketBase serve --http)
encryption_keyPocketBase encryption key (file: recommended)

app

KeyPersonal kit default
nameA1KnowHow Personal
urlhttp://localhost:8383
sender_nameA1KnowHow
sender_address[email protected]

database

KeyDefault
auto_migratetrue

logging

KeyDefault
levelinfo (trace, debug, warn, error, fatal, panic, disabled)
colortrue in Personal kit
pocketbase_forwardfalse
log_auth_idfalse
log_ipfalse
max_days3

vector

KeyNotes
typesqlite-vec
dimensionsRequired; must match embedding model (768 for EmbeddingGemma)
host, port, api_keyNot used

llm

KeyPersonal kit default
providerollama
urlhttp://localhost:11434
modellfm2.5:latest
chat_title_generator_modellfm2.5:latest
embedding_modelembeddinggemma-2:270m
timeout300 (seconds; HTTP client timeout per LLM API call)
api_keyNot 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:

KeyDefaultNotes
importer.providernoneMarkdown/plain text without Docling
importer.url—Set with provider: docling
chunking.providerlocalBuilt-in Go chunker
chunking.max_tokens512Keep 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.

KeyWhen using Docling
importer.urlhttp://localhost:5001 (Compose sample may use 8000)
fallback_urlsoptional
timeout_seconds300

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

KeyDefault
auto_send_verification_emailfalse
email_send_any_recipientEnterprise 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).

SectionPurposeValue forms
variablesNon-sensitive stringsPlain YAML strings
secretsSensitive stringsfile: (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

  1. Do not commit config.yaml with inline secrets or unencrypted secret files
  2. Restrict permissions: chmod 600 on secret files
  3. Prefer file: over env: for any credential in production
  4. Save the credentials printed by ./setup.sh

Troubleshooting

  • Missing encryption key file: run ./setup.sh or create secrets/encryption_key as above
  • Invalid vector.dimensions: must be set and positive before indexing
  • Docling unreachable at startup: set importer.provider: none, or start Docling and fix importer.url
  • Service connection errors: check llm.url and that Ollama is running
  • Config not applied: restart after editing YAML; confirm --config path
  • Seed fails on secret: ensure overlay/secrets: keys exist and file: paths are present

Next steps