Quick Start

Install the CLI, start the daemon, send a prompt. Python 3.11+.


1. Install the CLI

pip install -U soothe-cli

2. Start the daemon

Choose your deployment option below. All options run the daemon on port 8765.

Option A: Docker (OpenAI — zero-config)

Default model: gpt-4o-mini. No config file required.

docker run --rm -d --name soothed \
  -p 8765:8765 \
  -e OPENAI_API_KEY=sk-... \
  -v soothe-data:/var/lib/soothe \
  registry.cn-hangzhou.aliyuncs.com/lacogito/soothed:latest

Option B: Docker (OpenAI-Compatible)

OpenAI-compatible endpoint using your provider’s base URL.

export OPENAI_API_KEY=sk-...
export OPENAI_BASE_URL="https://your-provider-endpoint/v1"

docker run --rm -d --name soothed \
  -p 8765:8765 \
  -e OPENAI_API_KEY \
  -e OPENAI_BASE_URL \
  -e SOOTHE_ROUTER_PROFILES='[{"name":"default","router":{"default":"openai:qwen3.7-plus","fast":"openai:qwen3.7-plus","think":"openai:qwen3.7-plus"}}]' \
  -e SOOTHE_EMBEDDING_PROFILE='[{"model_role":"openai:text-embedding-3-small","embedding_dims":1536}]' \
  -v soothe-data:/var/lib/soothe \
  registry.cn-hangzhou.aliyuncs.com/lacogito/soothed:latest

With workspace access (file tools):

export OPENAI_API_KEY=sk-...
export OPENAI_BASE_URL="https://your-provider-endpoint/v1"
export HOST_WS="$HOME"
export CONTAINER_WS="/var/lib/soothe/workspaces"

docker run --rm -d --name soothed \
  -p 8765:8765 \
  -e OPENAI_API_KEY \
  -e OPENAI_BASE_URL \
  -e SOOTHE_ROUTER_PROFILES='[{"name":"default","router":{"default":"openai:qwen3.7-plus","fast":"openai:qwen3.7-plus","think":"openai:qwen3.7-plus"}}]' \
  -e SOOTHE_EMBEDDING_PROFILE='[{"model_role":"openai:text-embedding-3-small","embedding_dims":1536}]' \
  -e SOOTHE_WORKSPACE_MOUNT="{\"host_root\":\"$HOST_WS\",\"container_root\":\"$CONTAINER_WS\"}" \
  -v soothe-data:/var/lib/soothe \
  -v "$HOST_WS:$CONTAINER_WS" \
  registry.cn-hangzhou.aliyuncs.com/lacogito/soothed:latest

Option C: Docker Compose (production full stack)

Production-ready stack with PostgreSQL + pgvector + Soothe daemon:

cd deploy
cp env-example .env
# Edit .env with your API keys
docker compose up -d

Production stack components:

Component Image Port
PostgreSQL + pgvector registry.cn-hangzhou.aliyuncs.com/lacogito/pgvector:pg17 5432 (internal)
Soothe Daemon registry.cn-hangzhou.aliyuncs.com/lacogito/soothed:latest 8765

Required environment variables (in deploy/.env):

OPENAI_API_KEY=sk-...              # Required for production
OPENAI_BASE_URL=...                # Required for OpenAI-compatible providers
TAVILY_API_KEY=...                 # Optional (web search)
SOOTHE_WORKSPACE_HOST_ROOT=...     # Optional (default: $HOME)
SOOTHE_DEBUG=false                 # Optional (default: false)

Persistence configuration (production):

# config/nano.yml (production)
persistence:
  default_backend: postgresql
  postgres_base_dsn: "postgresql://postgres:postgres@soothe-pgvector:5432"
  postgres_databases:
    checkpoints: soothe_checkpoints
    metadata: soothe_metadata
    vectors: soothe_vectors
    memory: soothe_memory
  postgres:
    pool_min_size: 4
    checkpoints_pool_size: 32
    metadata_pool_size: 16
    vectors_pool_size: 16
  archive_enabled: true
  archive_retention_days: 90

agent:
  protocols:
    durability:
      backend: default
      checkpointer: default
      thread_inactivity_timeout_hours: 72

PostgreSQL tuning (production defaults):

max_connections: 200
shared_buffers: 256MB
work_mem: 64MB

Full production deployment guide: see deploy/README.md.


Option D: Local pip (development only)

⚠️ Development use only. For production, use Docker Compose (Option C).

pip install -U soothe soothe-daemon
export OPENAI_API_KEY=sk-...
soothed setup --yes   # scaffold nano.yml / soothe.yml / daemon.yml
soothed start

Or interactively (provider endpoint, key, model picker):

soothed setup
soothed start

Minimal daemon config is written by setup (~/.soothe/config/daemon.yml):

transports:
  websocket:
    enabled: true
    host: 127.0.0.1
    port: 8765

D1: PostgreSQL (localhost — development)

For a local PostgreSQL database (port 5432):

# Create database
createdb soothe

# Start daemon with PostgreSQL backend
SOOTHE_PERSISTENCE_DEFAULT_BACKEND="postgresql" \
SOOTHE_PERSISTENCE_POSTGRES_BASE_DSN="postgresql://user:password@localhost:5432" \
soothed start

Or with config file (~/.soothe/config/nano.yml):

persistence:
  default_backend: postgresql
  postgres_base_dsn: "postgresql://user:password@localhost:5432"
  postgres_databases:
    checkpoints: soothe_checkpoints
    metadata: soothe_metadata
    vectors: soothe_vectors
    memory: soothe_memory

D2: SQLite (localhost — development)

For a lightweight SQLite database (no external dependency):

# Scaffold config + configure provider, then start
soothed setup          # interactive: endpoint, key, model picker
# or: soothed setup --yes   (CI/scripts; merge provider from env)
soothed start

SQLite is the default backend; no default_backend override is required. The setup wizard writes nano.yml / soothe.yml / daemon.yml under ~/.soothe/config/ (see Installation → Configuration Setup). If you skip soothed setup, soothed start still runs with in-memory defaults but does not write template config files.

# Confirm the daemon is live (client-side RPC table)
soothe status

soothe status queries the running daemon over WebSocket and prints a unified table including PID, Started (the daemon process start time, an ISO-8601 UTC timestamp), active threads, daemon/core versions, and readiness state.

Purpose databases live under ~/.soothe/data/databases/ (checkpoints.db, context.db, display.db, cron.db, identity.db, metadata.db, persist.db, vectors.db). Upgrading from older builds that used flat ~/.soothe/data/*.db files requires deleting those legacy files; there is no automatic import.

Full reference: Environment variables.

Verify

# HTTP health check
curl -sf http://127.0.0.1:8765/healthz

# Client-side status table (PID, Started time, threads, versions, readiness)
soothe status

# Fast local check (no RPC): soothed status
soothed status

Persistence Verification Notes

Key Persistence Parameters

Parameter Production (Docker Compose) Development (SQLite)
default_backend postgresql sqlite (default)
archive_enabled true true
archive_retention_days 90 90
postgres.checkpoints_pool_size 32 N/A
thread_inactivity_timeout_hours 72 72

Checkpoint & Durability

The daemon persists loop state automatically:

agent:
  loop:
    checkpoint:
      progressive: true        # Incremental checkpoint writes
      auto_resume_on_start: false  # true = resume incomplete solo loops on daemon start
      auto_resume_max_loops: 16
      auto_resume_max_age_hours: 24
      auto_resume_clarifications: skip  # skip | reannounce
  protocols:
    durability:
      backend: default          # Uses persistence.default_backend
      checkpointer: default     # Uses persistence backend
      thread_inactivity_timeout_hours: 72  # Cleanup threshold

When auto_resume_on_start is false (default), incomplete running loops are detected and logged; use soothe loop continue <id> to resume manually. When true, the daemon re-enters StrangeLoop on the same loop_id (reusing CE state and CoreAgent thread checkpoints). Completing work before loop_status_reconciliation.stale_running_seconds (default 180s) avoids demotion to idle when auto-resume is off.

Vector Store Configuration

Default SQLite vector store:

vector_stores:
- name: sqlite_vec_default
  provider_type: sqlite_vec
  index_type: hnsw

vector_store_router:
  default: sqlite_vec_default:soothe_default

For production PostgreSQL with pgvector:

vector_stores:
- name: pgvector_default
  provider_type: pgvector
  dsn: "postgresql://postgres:postgres@soothe-pgvector:5432/soothe_vectors"

vector_store_router:
  default: pgvector_default:soothe_vectors

Daemon Lifecycle Management

The daemon automatically manages stale resources:

Setting Default Purpose
loop_gc.interval_seconds 3600 Garbage collect ephemeral/empty loops hourly
loop_gc.ephemeral_idle_hours 24 Threshold for ephemeral loop cleanup
loop_status_reconciliation.stale_running_seconds 180 Demote stale running loops (no heartbeat)
stale_worker_reap.interval_seconds 1800 Cleanup idle workers every 30 min

3. Run a prompt

soothe -p "Research top 5 Python web frameworks"
soothe   # interactive TUI

Optional: Custom configuration

Prefer the setup wizard (scaffolds all three files and configures a provider):

soothed setup

Re-run anytime to modify or add providers without wiping unrelated keys. For a fresh copy of packaged templates over existing files, use soothed setup --force.

The daemon loads agent config from SOOTHE_DAEMON_SOOTHE_CONFIG_PATH or ~/.soothe/config/nano.yml (composed with sibling soothe.yml when present).


Next

Guide What you get
Installation Pip options, packages, verification, troubleshooting
Language Clients Python / TypeScript / Go / Rust WebSocket SDKs
Basic Concepts Goals, loops, subagents, context
Configuration guide YAML, providers, patterns
CLI reference All commands
TUI guide Interactive terminal UI