Instructions to use jpanasuk/basecamp with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- HERMES
How to use jpanasuk/basecamp with HERMES:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
| #!/usr/bin/env python3 | |
| """Basecamp wiring recipes β per-service knowledge for fixing and wiring | |
| the AI services Basecamp discovers. Single source of truth for both the | |
| stack skill (inline recipes for discovered services) and the full | |
| references/wiring-recipes.md written into the container's HERMES_HOME. | |
| Each recipe has: | |
| where β where the service's configuration lives (env / file / UI / API) | |
| keys β the exact config keys / env vars / API endpoints involved | |
| fix β the one-line (or one-step) fix to wire it correctly | |
| verify β how to confirm the wiring actually works | |
| """ | |
| WIRING_RECIPES = { | |
| # ββ Inference engines ββ | |
| "ollama": { | |
| "where": "Container env vars + CLI. Clients connect to :11434 (OpenAI-compatible /v1).", | |
| "keys": "OLLAMA_HOST, OLLAMA_MODELS, OLLAMA_FLASH_ATTENTION, OLLAMA_KV_CACHE_TYPE; API: GET /api/tags, POST /api/copy, /v1/chat/completions", | |
| "fix": "Set OLLAMA_HOST=http://0.0.0.0:11434 to accept remote clients. PERF (verified 2026-08-10): do NOT set OLLAMA_CONTEXT_LENGTH globally β a forced 64K pre-allocates a ~6GB KV cache on EVERY load, starving weights of VRAM and dropping speed ~9x (8B: 9 tok/s vs 80). Use OLLAMA_FLASH_ATTENTION=1 + OLLAMA_KV_CACHE_TYPE=q8_0; ollama sizes KV per-request. Hermes's context_length config is an advertised ceiling, not a per-request demand.", | |
| "verify": "curl http://<host>:11434/api/tags returns {\"models\": [...]}; benchmark: ollama run <model> --verbose shows eval rate (expect 60-100 tok/s for an 8B on a 12GB GPU with FA).", | |
| "pitfalls": "VERIFIED 2026-08-10: forced 64K = 6GB KV cache = 8B mostly on CPU (9 tok/s). Removing it + FA + q8 KV = 80 tok/s, 33/33 layers on GPU, KV 272MB. Check offload: docker logs <ollama> | grep offloaded. Keep models resident with keep_alive to avoid reload penalties.", | |
| }, | |
| "tabbyapi": { | |
| "where": "config.yml (model_dir, model_name, max_seq_len) + api_tokens.yml (api_key, admin_key), both mounted from the host.", | |
| "keys": "config.yml: model.model_name, model.max_seq_len, model.cache_8bit; api_tokens.yml: api_key, admin_key; API: /v1/models, /v1/chat/completions (Bearer)", | |
| "fix": "Edit config.yml to point model.model_name at a model present in model_dir, restart the container. Clients use Bearer <api_key> against http://<host>:5000/v1. max_seq_len is VRAM-bound (64K KV cache needs ~16GB for 8B).", | |
| "verify": "curl -H 'Authorization: Bearer <api_key>' http://<host>:5000/v1/models returns the loaded model list.", | |
| }, | |
| "vllm": { | |
| "where": "CLI launch flags (no config file).", | |
| "keys": "--model, --served-model-name, --host, --port, --max-model-len; API: /v1/models, /v1/chat/completions", | |
| "fix": "Relaunch with --host 0.0.0.0 --port 8000 --served-model-name <name> so the served name matches what clients request. Hermes needs --max-model-len >= 65536.", | |
| "verify": "curl http://<host>:8000/v1/models lists the served model id.", | |
| }, | |
| "litellm": { | |
| "where": "config.yaml (model_list) + master key env var.", | |
| "keys": "model_list: [{model_name, litellm_params: {model, api_base, api_key}}]; env: LITELLM_MASTER_KEY; API: /v1/models, /v1/chat/completions (Bearer)", | |
| "fix": "Add the upstream model to model_list with correct api_base, restart. Clients use Bearer <master_key> against http://<host>:4000/v1.", | |
| "verify": "curl -H 'Authorization: Bearer <key>' http://<host>:4000/v1/models lists configured model_names.", | |
| }, | |
| "localai": { | |
| "where": "Env vars + model files in the models directory.", | |
| "keys": "MODELS_PATH, THREADS, DEBUG; API: /v1/models, /v1/chat/completions (OpenAI-compatible)", | |
| "fix": "Drop GGUF models into the models dir (or set MODELS_PATH), restart. Clients use http://<host>:8080/v1 (or the mapped port).", | |
| "verify": "curl http://<host>:8080/v1/models lists models.", | |
| }, | |
| "llamacpp": { | |
| "where": "CLI flags (llama-server).", | |
| "keys": "-m <model>, --host, --port, -c <context>, --api-key; API: /health, /v1/models, /v1/chat/completions", | |
| "fix": "Relaunch with --host 0.0.0.0 so other containers can reach it; -c 65536 for Hermes. If --api-key is set, clients must send it.", | |
| "verify": "curl http://<host>:<port>/health returns 'ok'.", | |
| }, | |
| "text-generation-webui": { | |
| "where": "Settings files + runtime API (model loaded per-session).", | |
| "keys": "API: GET/POST /api/v1/model (load model), /v1/chat/completions; settings in settings.yaml", | |
| "fix": "POST /api/v1/model with {\"model_name\": \"<model>\"} to load a model; clients use http://<host>:5000/v1.", | |
| "verify": "curl http://<host>:5000/api/v1/model returns the loaded model_name.", | |
| }, | |
| "koboldcpp": { | |
| "where": "CLI flags.", | |
| "keys": "--model, --host, --port, --contextsize; API: /api/v1/model, /v1/models, /v1/chat/completions", | |
| "fix": "Relaunch with --host 0.0.0.0 and --contextsize 65536 for Hermes. Clients use http://<host>:5001/v1.", | |
| "verify": "curl http://<host>:5001/api/v1/model returns a result with the model name.", | |
| }, | |
| "lmstudio": { | |
| "where": "In-app GUI only (no server-side config file for the API).", | |
| "keys": "Settings β Developer β Local Server (port 1234); API: /v1/models, /v1/chat/completions", | |
| "fix": "The user must enable the local server in the app GUI (Settings β Developer β Start Server). No remote fix exists β explain the 3 clicks.", | |
| "verify": "curl http://<host>:1234/v1/models lists loaded models.", | |
| }, | |
| "sglang": { | |
| "where": "CLI flags.", | |
| "keys": "--model-path, --host, --port, --served-model-name; API: /v1/models, /v1/chat/completions", | |
| "fix": "Relaunch with --host 0.0.0.0 --served-model-name <name> matching what clients request; --context-length >= 65536 for Hermes.", | |
| "verify": "curl http://<host>:8002/v1/models (response contains 'sglang').", | |
| }, | |
| "llamafile": { | |
| "where": "CLI/env of the single-file binary.", | |
| "keys": "-ngl <layers> (GPU offload), --host, --port; API: /v1/models, /v1/chat/completions", | |
| "fix": "Launch with --host 0.0.0.0 (default is localhost only). Clients use http://<host>:8080/v1.", | |
| "verify": "curl http://<host>:8080/v1/models lists the model.", | |
| }, | |
| "exo": { | |
| "where": "config.yaml + peer discovery.", | |
| "keys": "config.yaml: api_port, peers; API: /v1/models, /v1/chat/completions", | |
| "fix": "Ensure api_port is reachable on the docker network; add peer IPs to config.yaml. Clients use http://<host>:8000/v1.", | |
| "verify": "curl http://<host>:8000/v1/models lists the cluster's models.", | |
| }, | |
| "text-generation-inference": { | |
| "where": "CLI flags (launcher).", | |
| "keys": "--model-id, --port, --hostname, --max-total-tokens; API: /v1/models, /info", | |
| "fix": "Relaunch with --hostname 0.0.0.0 --model-id <hf-repo>. Clients use http://<host>:8080/v1.", | |
| "verify": "curl http://<host>:8080/info returns model_id.", | |
| }, | |
| "aphrodite": { | |
| "where": "CLI flags (vLLM-style).", | |
| "keys": "--model, --served-model-name, --host, --port; API: /v1/models, /v1/chat/completions", | |
| "fix": "Relaunch with --host 0.0.0.0 and --served-model-name matching client requests.", | |
| "verify": "curl http://<host>:8000/v1/models (response contains 'aphrodite').", | |
| }, | |
| "llamapool": { | |
| "where": "config.toml.", | |
| "keys": "[routes] entries mapping route names to upstream endpoints", | |
| "fix": "Add/edit a [routes] entry pointing at the upstream inference server, restart. Clients use the route name as the model id.", | |
| "verify": "curl http://<host>:<port>/v1/models lists route names.", | |
| }, | |
| # ββ UIs / chat frontends ββ | |
| "open-webui": { | |
| "where": "Container env vars (primary) + admin Settings β Connections (runtime override).", | |
| "keys": "OLLAMA_BASE_URL, OPENAI_API_BASE_URL, OPENAI_API_KEY; admin UI: Settings β Connections; API: GET /api/config (public), /api/models (auth), /api/v1/auths/signin", | |
| "fix": "Set OLLAMA_BASE_URL=http://ollama:11434 (and/or OPENAI_API_BASE_URL + key) in the container env, OR have the admin set it in Settings β Connections. This is THE buried needle-in-a-haystack setting β name it explicitly.", | |
| "verify": "curl http://<host>:8080/api/config returns status:true; authenticated GET /api/models lists engine models.", | |
| }, | |
| "sillytavern": { | |
| "where": "config.yaml (config dir mounted) for server auth; per-user API config in the UI.", | |
| "keys": "config.yaml: listen, whitelist, basicAuthUser, basicAuthPassword; UI: extensions β connection settings β API URL + model; API: /api/status (401 = alive behind auth)", | |
| "fix": "Server auth lives in config.yaml (default admin:<password>). The API URL is per-user: UI β extensions β connection settings β set to http://<engine>:<port>/v1 and pick the model.", | |
| "verify": "curl -u admin:<pw> http://<host>:8000/api/status returns JSON.", | |
| }, | |
| "librechat": { | |
| "where": "librechat.yaml (endpoints/agents) + .env.", | |
| "keys": "librechat.yaml: endpoints.agents.<name> {provider, baseURL, apiKey}; .env: END_USER_* vars; API: /api/health", | |
| "fix": "Add an endpoints.agents block with provider=openai (or custom), baseURL=http://<engine>:<port>/v1, apiKey. Restart. Set in the UI's Admin β Providers as an alternative.", | |
| "verify": "curl http://<host>:3080/api/health returns ok; the model appears in the UI model list.", | |
| }, | |
| "lobechat": { | |
| "where": "In-app settings (model providers) + env vars.", | |
| "keys": "UI: Settings β Language Model β providers; env: OPENAI_API_KEY etc; API: /api/status", | |
| "fix": "In the UI: Settings β Language Model β add provider with base URL http://<engine>:<port>/v1 + key (if any). No server-side config file.", | |
| "verify": "curl http://<host>:3001/api/status returns 200; model selectable in chat.", | |
| }, | |
| "anythingllm": { | |
| "where": "In-app Settings (LLM provider + vector DB) + .env.", | |
| "keys": "UI: Settings β LLM Preference β provider + base URL + key; Settings β Vector Database; API: /api/system/endpoints", | |
| "fix": "In the UI: Settings β LLM Preference β pick Ollama/OpenAI, set base URL to the engine, set the key. Vector DB similar (defaults to LanceDB β fine for noobs).", | |
| "verify": "curl http://<host>:3001/api/system/endpoints lists configured endpoints.", | |
| }, | |
| "dify": { | |
| "where": ".env file (backend) + per-app model config in UI.", | |
| "keys": ".env: OPENAI_API_KEY, OPENAI_API_BASE; UI: Settings β Model Provider; API: /health", | |
| "fix": "Set OPENAI_API_BASE + OPENAI_API_KEY in .env (or use the UI Model Provider page) to point at the engine, restart. Model per-app: Settings β Model Provider β add.", | |
| "verify": "curl http://<host>/health returns healthy.", | |
| }, | |
| "flowise": { | |
| "where": "UI credentials store + env.", | |
| "keys": "UI: Settings β Credentials; API: /api/v1/ping, /api/v1/credentials", | |
| "fix": "UI: Settings β Credentials β add the provider credential with base URL + key. Nodes then reference it. No server-side wiring file.", | |
| "verify": "curl http://<host>:3000/api/v1/ping returns pong.", | |
| }, | |
| "n8n": { | |
| "where": "UI credentials store + env (auth).", | |
| "keys": "env: N8N_BASIC_AUTH_USER, N8N_BASIC_AUTH_PASSWORD; UI: Credentials β OpenAI/Ollama; API: /healthz", | |
| "fix": "UI: Credentials β add the AI provider credential (base URL + key) and reference it in nodes. Set basic auth envs if exposed publicly.", | |
| "verify": "curl http://<host>:5678/healthz returns ok.", | |
| }, | |
| "langflow": { | |
| "where": ".env + UI components.", | |
| "keys": "UI: Settings β Global Variables; env: OPENAI_API_KEY etc; API: /api/v1/configs", | |
| "fix": "UI: Settings β Global Variables β add the provider base URL + key; use them in component nodes.", | |
| "verify": "curl http://<host>:7860/api/v1/configs returns 200 (or auth wall).", | |
| }, | |
| "ragflow": { | |
| "where": "service_conf.yaml + .env; models configured in UI.", | |
| "keys": ".env: MODEL providers; service_conf.yaml: es/storage; UI: Settings β Model providers; API: /api/v1/version", | |
| "fix": "UI: Settings β Model providers β add the engine (base URL + key). Backend needs the configured embedding+chat models.", | |
| "verify": "curl http://<host>/api/v1/version returns a version.", | |
| }, | |
| "koboldai": { | |
| "where": "Settings files in the data dir.", | |
| "keys": "API: /api/v1/config/status, /api/v1/model", | |
| "fix": "Legacy app; connect by setting the API URL in the client to http://<host>:5000/v1 and loading a model via its UI.", | |
| "verify": "curl http://<host>:5000/api/v1/config/status returns config.", | |
| }, | |
| # ββ Vector DBs ββ | |
| "qdrant": { | |
| "where": "config.yaml or QDRANT__* env vars.", | |
| "keys": "QDRANT__SERVICE__API_KEY, QDRANT__SERVICE__GRPC_PORT; API: /readyz, /collections", | |
| "fix": "Set API key via env if auth needed; ensure clients use http://<host>:6333. Point your RAG app's vector DB URL here.", | |
| "verify": "curl http://<host>:6333/readyz returns ok.", | |
| }, | |
| "milvus": { | |
| "where": "milvus.yaml + etcd dependency.", | |
| "keys": "milvus.yaml: etcd.endpoints, proxy port 19530; API: /healthz (http :9091)", | |
| "fix": "Milvus needs etcd running and reachable; point your RAG app at grpc://<host>:19530.", | |
| "verify": "curl http://<host>:9091/healthz returns {\"status\":\"OK\"}.", | |
| }, | |
| "chroma": { | |
| "where": "Env vars.", | |
| "keys": "CHROMA_SERVER_HOST, CHROMA_SERVER_PORT, CHROMA_AUTH_*; API: /api/v2/health", | |
| "fix": "Set CHROMA_SERVER_HOST=0.0.0.0 to accept remote clients; point your RAG app at http://<host>:8000.", | |
| "verify": "curl http://<host>:8000/api/v2/health returns 200.", | |
| }, | |
| "weaviate": { | |
| "where": "Env vars.", | |
| "keys": "PERSISTENCE_DATA_PATH, AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED, AUTHENTICATION_APIKEY_ENABLED + APIKEY_ALLOWED_KEYS; API: /v1/meta", | |
| "fix": "Enable anonymous access or set an API key via env; point your RAG app at http://<host>:8081.", | |
| "verify": "curl http://<host>:8081/v1/meta returns version + model info.", | |
| }, | |
| # ββ Image / media ββ | |
| "comfyui": { | |
| "where": "extra_model_paths.yaml (model folder locations).", | |
| "keys": "extra_model_paths.yaml: checkpoints, loras, vae paths; API: /system_stats, /prompt (POST)", | |
| "fix": "Edit extra_model_paths.yaml to point at the real model dirs (or use the default structure), restart. Clients POST workflows to /prompt.", | |
| "verify": "curl http://<host>:8188/system_stats returns GPU/RAM stats.", | |
| }, | |
| "stable-diffusion-webui": { | |
| "where": "webui-user.sh (COMMANDLINE_ARGS) + models dir.", | |
| "keys": "webui-user.sh: COMMANDLINE_ARGS=--api; API: /sdapi/v1/options, /sdapi/v1/txt2img", | |
| "fix": "Add --api to COMMANDLINE_ARGS and restart, or the API endpoints 404. Model picker via /sdapi/v1/options (sd_model_checkpoint).", | |
| "verify": "curl http://<host>:7860/sdapi/v1/options returns options JSON.", | |
| }, | |
| "invokeai": { | |
| "where": "invokeai.yaml + UI model manager.", | |
| "keys": "invokeai.yaml: host, port; API: /api/v1/app/version", | |
| "fix": "Ensure host is 0.0.0.0 in invokeai.yaml; models added via the UI Model Manager (Auto-scan a folder).", | |
| "verify": "curl http://<host>:9090/api/v1/app/version returns a version.", | |
| }, | |
| # ββ Speech ββ | |
| "whisper": { | |
| "where": "CLI flags of the whisper server (faster-whisper-server / whisper.cpp).", | |
| "keys": "--host, --port, --model (size); API: /v1/audio/transcriptions (OpenAI-compatible)", | |
| "fix": "Launch with --host 0.0.0.0; point clients at http://<host>:<port>/v1. Pick model size for the GPU.", | |
| "verify": "curl http://<host>:<port>/health returns ok.", | |
| }, | |
| "piper": { | |
| "where": "CLI flags of the TTS server.", | |
| "keys": "--host, --port; API: / (synthesize GET/POST)", | |
| "fix": "Launch with --host 0.0.0.0; point clients at http://<host>:<port> with the voice model.", | |
| "verify": "curl http://<host>:<port>/health returns ok.", | |
| }, | |
| # ββ Gateways / proxies / hubs ββ | |
| "openrouter": { | |
| "where": "Cloud API β key only.", | |
| "keys": "API key; base https://openrouter.ai/api/v1", | |
| "fix": "Clients send Bearer <key> to https://openrouter.ai/api/v1. No local config.", | |
| "verify": "curl -H 'Authorization: Bearer <key>' https://openrouter.ai/api/v1/models works.", | |
| }, | |
| "kobold-horde": { | |
| "where": "Cloud crowd API β key optional.", | |
| "keys": "API key (optional); API: /api/v1/status, /api/v1/generate", | |
| "fix": "Clients set the horde URL to http://<host>:2323 (or the public horde) and optionally their kudos key.", | |
| "verify": "curl http://<host>:2323/api/v1/status returns queue stats.", | |
| }, | |
| # ββ Basecamp's own companions ββ | |
| "mcpo": { | |
| "where": "config.json (mounted) β the MCP server list.", | |
| "keys": "config.json: servers [{name, transport, route, api_key}]; API: /openapi.json, /mcp (SSE)", | |
| "fix": "Edit mcpo/config.json to add/point MCP servers (name + route + key), restart the container. Basecamp connects to it via SSE at /mcp.", | |
| "verify": "curl http://<host>:8000/openapi.json lists the proxied MCP server routes.", | |
| }, | |
| "searxng": { | |
| "where": "settings.yml (mounted) β search engines + formats.", | |
| "keys": "settings.yml: search.formats (json), engines list; API: /search?q=...&format=json", | |
| "fix": "Ensure 'json' is in search.formats in settings.yml or the JSON API returns 400. Engines added/removed in the engines section.", | |
| "verify": "curl http://<host>:8080/ returns the SearXNG page.", | |
| }, | |
| # ββ Coding starter pack ββ | |
| "code-server": { | |
| "where": "Container env + entrypoint extension installs. The IDE itself is VS Code in the browser.", | |
| "keys": "env: PASSWORD (login); entrypoint: code-server --install-extension Continue.continue / TabbyML.vscode-tabby; API: /healthz, / (web UI)", | |
| "fix": "Login with the PASSWORD env at http://<host>:8443. Continue.dev and the Tabby extension are pre-installed in the Basecamp pack β configure Continue's model to http://ollama:11434/v1 (or tabbyapi:5000/v1) in its config.json, and point the Tabby extension at http://<host>:8082.", | |
| "verify": "curl http://<host>:8443/healthz returns 200; the browser UI loads at :8443.", | |
| "pitfalls": "Extension installs run on first container start β give it ~60s before the IDE is fully ready. Login password comes from the PASSWORD env (default basecamp) β change it.", | |
| }, | |
| "tabby": { | |
| "where": "CLI flags at container start + /data volume for models.", | |
| "keys": "command: serve --device cpu|--device cuda --model <name> --chat-model <name>; env: TABBY_MODEL_CACHE_DIR; API: /v1/health, /v1/completions (code completion)", | |
| "fix": "DO NOT USE in CPU-only containers β BROKEN as of 2026-08-09 (verified on 20260330 pin): tabby's bundled llama-server dlopens libcuda.so.1 at startup EVEN with --device cpu (binary is CUDA-compiled), and crashes with exit 127 'cannot open shared object file' when the container lacks NVIDIA libs. Needs --gpus all + CUDA libs. Removed from the starter pack; re-add only with GPU access or a true CPU-only tabby build.", | |
| "verify": "curl http://<host>:8082/v1/health β expected to FAIL in CPU-only containers until tabby ships a CPU-only build.", | |
| "pitfalls": "VERIFIED 2026-08-09: (1) 'latest' images spawn Nomic-Embed with -ngl 9999 β exit 127 on constrained GPUs; (2) even the 20260330 pin crash-loops in CPU-only containers: llama-server dlopens libcuda.so.1 β 'cannot open shared object file' β exit 127. (3) StarCoder2-3B is completion-only (no chat template) β a separate instruct model is required for --chat-model. Ripped out of the pack.", | |
| }, | |
| "meilisearch": { | |
| "where": "Env vars.", | |
| "keys": "MEILI_MASTER_KEY, MEILI_ENV; API: /health, /indexes, /search", | |
| "fix": "Set MEILI_MASTER_KEY so clients can authenticate; index your code/docs via the API and search at /search with the key.", | |
| "verify": "curl http://<host>:7700/health returns {\"status\":\"available\"}.", | |
| }, | |
| "librechat": { | |
| "where": "Env vars + REQUIRES MongoDB (not self-contained).", | |
| "keys": "MONGO_URI (required), OPENAI_API_KEY, OPENAI_API_BASE; API: /api/health", | |
| "fix": "LibreChat CRASHES on boot without MONGO_URI (verified 2026-08): 'Please define the MONGO_URI environment variable'. It needs a mongo container β the Basecamp pack ships one (starter-mongo, mongo:7) and sets MONGO_URI=mongodb://mongo:27017/LibreChat. Image lives on GHCR (ghcr.io/danny-avila/librechat), NOT Docker Hub.", | |
| "verify": "curl http://<host>:3080/api/health returns ok AFTER mongo is up.", | |
| "pitfalls": "Image is ghcr.io/danny-avila/librechat:latest β the Docker Hub 'danny-avila/librechat' repo 404s. First boot takes ~60s. Depends on mongo; start mongo first (depends_on in compose).", | |
| }, | |
| "flowise": { | |
| "where": "Env vars (PORT, FLOWISE_USERNAME, FLOWISE_PASSWORD) + /root/.flowise volume.", | |
| "keys": "PORT=3000, FLOWISE_USERNAME, FLOWISE_PASSWORD; API: /api/v1/ping", | |
| "fix": "DO NOT USE β BROKEN UPSTREAM as of 2026-08-09 (verified on latest AND 3.1.4): crashes at boot with ERR_PACKAGE_PATH_NOT_EXPORTED β @langchain/langgraph-checkpoint requires './utils/uuid' which @langchain/core doesn't export. Removed from the starter pack. Re-add only when upstream fixes their dependency tree.", | |
| "verify": "curl http://<host>:7860/api/v1/ping β expected to FAIL until upstream fixes the langchain dep.", | |
| "pitfalls": "KNOWN BUG (verified 2026-08-09, both latest and 3.1.4): ERR_PACKAGE_PATH_NOT_EXPORTED './utils/uuid' in @langchain/core crashes node at boot (ReActAgentChat/ReActAgentLLM nodes). Not a compose problem β the image's dependency tree is broken. Ripped out of the pack.", | |
| }, | |
| "postgres": { | |
| "where": "Container env (db/user/password) + data volume.", | |
| "keys": "POSTGRES_DB, POSTGRES_USER, POSTGRES_PASSWORD; port 5432; pgvector extension for embeddings", | |
| "fix": "This is Hermes's long-term memory backend (Postgres + pgvector). Point hermes at it: hermes memory configure --backend postgres --dsn 'postgresql://<user>:<pass>@starter-postgres:5432/<db>'. The pgvector image ships the extension β create it with: docker exec starter-postgres psql -U hermes -d hermes -c 'CREATE EXTENSION IF NOT EXISTS vector;'", | |
| "verify": "docker exec starter-postgres pg_isready -U hermes -d hermes returns 'accepting connections'.", | |
| }, | |
| "mongo": { | |
| "where": "Container env + /data/db volume. Database for LibreChat (and other apps).", | |
| "keys": "MONGO_URI=mongodb://mongo:27017/<db>; port 27017; image mongo:7", | |
| "fix": "Point dependent apps at mongodb://<host>:27017/<dbname>. LibreChat requires MONGO_URI or it crashes on boot (verified 2026-08). No auth by default on the pack's instance β add a root user for anything public.", | |
| "verify": "docker exec starter-mongo mongosh --quiet --eval 'db.runCommand({ping:1}).ok' returns 1.", | |
| }, | |
| } | |
| def wiring_recipe_markdown(service_types=None): | |
| """Render WIRING_RECIPES as markdown, optionally filtered to a type list. | |
| Returns a list of markdown lines (no trailing newline joining) ready to | |
| be embedded in a SKILL.md or written as a standalone reference file. | |
| """ | |
| types = service_types or list(WIRING_RECIPES.keys()) | |
| lines = [] | |
| for t in sorted(types): | |
| r = WIRING_RECIPES.get(t) | |
| if not r: | |
| continue | |
| lines.append(f"### {t}") | |
| lines.append(f"- **Config lives in:** {r['where']}") | |
| lines.append(f"- **Keys/endpoints:** {r['keys']}") | |
| lines.append(f"- **Fix:** {r['fix']}") | |
| lines.append(f"- **Verify:** {r['verify']}") | |
| if r.get("pitfalls"): | |
| lines.append(f"- **Pitfalls (verified):** {r['pitfalls']}") | |
| lines.append("") | |
| return lines | |