feat(honcho): add role + day1 playbook + traefik route for lincoln

Deploys Honcho (plastic-labs/honcho) as a rootful Podman + Quadlet
service on the lincoln VM (10.1.71.132). Three containers on a
user-defined network:

  - honcho-postgres  pgvector/pgvector:pg16
  - honcho-api       FastAPI on :8000
  - honcho-deriver   background worker for theory-of-mind derivations

LLM provider: Anthropic Claude (claude-sonnet-4-5). Switching providers
is two env-var changes — see README.

Traefik route hall-of-presidents.local.mk-labs.cloud -> lincoln:8000
added under boilerplates/traefik/dynamic/. JARVIS itself talks to
Honcho directly at lincoln:8000 (east-west); the Traefik alias exists
only for browser access to the Swagger /docs UI.

Requires three new vault entries before first run:
  - vault_honcho_database_password
  - vault_honcho_jwt_secret
  - vault_honcho_anthropic_api_key
This commit is contained in:
JARVIS
2026-05-30 22:41:33 -05:00
parent 09ae954085
commit 4d7766d1b1
17 changed files with 667 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
# {{ ansible_managed }}
# mk-labs Honcho API service (FastAPI on :8000)
# Managed by Ansible - honcho role
[Unit]
Description=Honcho API
After=network-online.target {{ honcho_postgres_container_name }}.service
Wants=network-online.target
Requires={{ honcho_postgres_container_name }}.service
[Container]
Image={{ honcho_image }}
ContainerName={{ honcho_container_name }}
Network={{ honcho_network_name }}
PublishPort={{ honcho_listen_address }}:{{ honcho_listen_port }}:8000
# Run the entrypoint that performs DB migration before starting FastAPI.
Exec=/app/docker/entrypoint.sh
# -- Database ---------------------------------------------------------------
Environment=DB_CONNECTION_URI=postgresql+psycopg://{{ honcho_db_user }}:{{ honcho_db_password }}@{{ honcho_postgres_container_name }}:5432/{{ honcho_db_name }}
# -- Auth -------------------------------------------------------------------
Environment=AUTH_USE_AUTH={{ honcho_auth_enabled | string | lower }}
Environment=AUTH_JWT_SECRET={{ honcho_jwt_secret }}
# -- LLM provider (deriver / summary / dialectic) ---------------------------
{% if honcho_llm_transport == 'anthropic' %}
Environment=LLM_ANTHROPIC_API_KEY={{ honcho_anthropic_api_key }}
{% endif %}
Environment=DERIVER_MODEL_CONFIG__TRANSPORT={{ honcho_llm_transport }}
Environment=DERIVER_MODEL_CONFIG__MODEL={{ honcho_deriver_model }}
Environment=SUMMARY_MODEL_CONFIG__TRANSPORT={{ honcho_llm_transport }}
Environment=SUMMARY_MODEL_CONFIG__MODEL={{ honcho_summary_model }}
Environment=DIALECTIC_MODEL_CONFIG__TRANSPORT={{ honcho_llm_transport }}
Environment=DIALECTIC_MODEL_CONFIG__MODEL={{ honcho_dialectic_model }}
# -- Vector store -----------------------------------------------------------
Environment=VECTOR_STORE_TYPE=pgvector
# -- Public-facing URL (empty -> relative URLs, host-agnostic) --------------
{% if honcho_web_url | length > 0 %}
Environment=HONCHO_PUBLIC_URL={{ honcho_web_url }}
{% endif %}
# Timezone matches host baseline
Environment=TZ=America/Chicago
Environment=LOG_LEVEL=INFO
[Service]
Restart=always
TimeoutStartSec=180
[Install]
WantedBy=multi-user.target default.target

View File

@@ -0,0 +1,58 @@
# {{ ansible_managed }}
# mk-labs Honcho deriver worker (background queue consumer)
# Managed by Ansible - honcho role
#
# Same image as the API; different command. The deriver pulls jobs off
# the DB-backed queue and calls the LLM provider to perform theory-of-mind
# derivations against user sessions.
[Unit]
Description=Honcho deriver worker
After=network-online.target {{ honcho_postgres_container_name }}.service {{ honcho_container_name }}.service
Wants=network-online.target
Requires={{ honcho_postgres_container_name }}.service
[Container]
Image={{ honcho_image }}
ContainerName={{ honcho_deriver_container_name }}
Network={{ honcho_network_name }}
# Run the deriver script instead of the FastAPI server. The deriver
# polls the queue and processes work in a loop. Number of concurrent
# workers controlled via DERIVER_WORKERS.
Exec=/app/.venv/bin/python /app/src/deriver/deriver.py
# -- Database ---------------------------------------------------------------
Environment=DB_CONNECTION_URI=postgresql+psycopg://{{ honcho_db_user }}:{{ honcho_db_password }}@{{ honcho_postgres_container_name }}:5432/{{ honcho_db_name }}
# -- Auth -------------------------------------------------------------------
# Deriver does not serve HTTP, but it reads the same config object — keep
# secrets aligned with the API container.
Environment=AUTH_USE_AUTH={{ honcho_auth_enabled | string | lower }}
Environment=AUTH_JWT_SECRET={{ honcho_jwt_secret }}
# -- LLM provider -----------------------------------------------------------
{% if honcho_llm_transport == 'anthropic' %}
Environment=LLM_ANTHROPIC_API_KEY={{ honcho_anthropic_api_key }}
{% endif %}
Environment=DERIVER_ENABLED={{ honcho_deriver_enabled | string | lower }}
Environment=DERIVER_WORKERS={{ honcho_deriver_workers }}
Environment=DERIVER_POLLING_SLEEP_INTERVAL_SECONDS={{ honcho_deriver_polling_seconds }}
Environment=DERIVER_MODEL_CONFIG__TRANSPORT={{ honcho_llm_transport }}
Environment=DERIVER_MODEL_CONFIG__MODEL={{ honcho_deriver_model }}
Environment=SUMMARY_MODEL_CONFIG__TRANSPORT={{ honcho_llm_transport }}
Environment=SUMMARY_MODEL_CONFIG__MODEL={{ honcho_summary_model }}
# -- Vector store -----------------------------------------------------------
Environment=VECTOR_STORE_TYPE=pgvector
# Timezone matches host baseline
Environment=TZ=America/Chicago
Environment=LOG_LEVEL=INFO
[Service]
Restart=always
TimeoutStartSec=180
[Install]
WantedBy=multi-user.target default.target

View File

@@ -0,0 +1,35 @@
# {{ ansible_managed }}
# mk-labs pgvector-enabled PostgreSQL backing store for Honcho
# Managed by Ansible - honcho role
[Unit]
Description=PostgreSQL (pgvector) for Honcho
After=network-online.target
Wants=network-online.target
[Container]
Image={{ honcho_postgres_image }}
ContainerName={{ honcho_postgres_container_name }}
Network={{ honcho_network_name }}
# Persistent data on a named volume. :Z relabels for SELinux; harmless on
# Ubuntu's ext4/apparmor stack and portable to any future host.
Volume={{ honcho_postgres_volume }}:/var/lib/postgresql/data:Z
Environment=POSTGRES_USER={{ honcho_db_user }}
Environment=POSTGRES_DB={{ honcho_db_name }}
Environment=POSTGRES_PASSWORD={{ honcho_db_password }}
Environment=POSTGRES_INITDB_ARGS={{ honcho_postgres_initdb_args }}
# Healthcheck — systemd doesn't act on this, but it's useful diagnostically
HealthCmd=pg_isready -U {{ honcho_db_user }} -d {{ honcho_db_name }}
HealthInterval=10s
HealthTimeout=5s
HealthRetries=3
[Service]
Restart=always
TimeoutStartSec=120
[Install]
WantedBy=multi-user.target default.target