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
File size: 8,433 Bytes
fd1a3f5 e725fbe fd1a3f5 e725fbe fd1a3f5 fe9a48a fd1a3f5 fe9a48a fd1a3f5 94e4c89 6093073 2b69294 94e4c89 a8fb550 6093073 a8fb550 fd1a3f5 6093073 fd1a3f5 2b69294 fd1a3f5 2b69294 fd1a3f5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | #!/bin/bash
set -e
echo "================================================"
echo " BASECAMP β AI Agent + Local Inference"
echo " Portable. Auto-discovering. Stack-agnostic."
echo " (Isolated: config lives only in basecamp state)"
echo "================================================"
echo ""
# Start Ollama via supervisor in background
supervisord -c /etc/supervisor/conf.d/supervisord.conf &
# Wait for Ollama to be ready
echo "Starting local Ollama..."
for i in $(seq 1 60); do
if curl -s http://127.0.0.1:11434/api/tags > /dev/null 2>&1; then
echo "Local Ollama is up."
break
fi
sleep 1
done
# First run: show connect screen. Everything written lives inside basecamp's
# own state (the mounted volume) β never touches a host hermes install.
CONFIG_FILE="/root/.hermes/basecamp_config.json"
ENV_FILE="/opt/basecamp/basecamp.env"
# FIX 2026-08-10: ALWAYS re-scan, even when a config exists. The old logic
# skipped discovery when config was found ("Config found. Regenerating
# tavern toolkit..."), so newly-added stack services stayed invisible until
# the user manually ran `tavern rediscover`. The box must discover fresh
# on every boot β that's the whole point of auto-discovery.
echo ""
echo "=== Scanning for AI services ==="
echo ""
if python3 /opt/basecamp/discover.py serve; then
:
else
echo ""
echo "Discovery failed. Falling back to basecamp's own Ollama."
python3 /opt/basecamp/discover.py env || true
# Install the secret-free static tavern so stack commands still work
cp /opt/basecamp/tavern.sh /usr/local/bin/tavern 2>/dev/null || true
chmod +x /usr/local/bin/tavern 2>/dev/null || true
fi
# Apply Hermes runtime config β process-scoped env vars, no config.yaml/.env writes
if [ -f "$ENV_FILE" ]; then
# shellcheck disable=SC1090
. "$ENV_FILE"
fi
# Best-effort: if Hermes has no model configured yet, set it via Hermes' own
# Best-effort: if Hermes has no model configured yet, set it via Hermes' own
# config CLI (schema-safe). This only ever writes inside basecamp's own HERMES_HOME.
if [ -n "${HERMES_MODEL:-}" ] && ! hermes config get model > /dev/null 2>&1; then
hermes config set model "$HERMES_MODEL" > /dev/null 2>&1 || true
fi
# CRITICAL (v0.20+): the stock config.yaml ships a default model+base_url
# (openrouter), so the guard above never fires and env-only wiring
# (OPENAI_BASE_URL / OPENAI_API_KEY) is IGNORED for non-authoritative hosts β
# hermes's #28660 security gate blocks env keys for LAN/custom endpoints and
# sends the "no-key-required" sentinel instead (auth 401). The sanctioned path
# is a NAMED custom provider with an inline api_key. Configure it in
# basecamp's OWN HERMES_HOME (never a host install).
if [ -n "${OPENAI_BASE_URL:-}" ]; then
hermes config set providers.basecamp.api "$OPENAI_BASE_URL" > /dev/null 2>&1 || true
hermes config set providers.basecamp.default_model "$HERMES_MODEL" > /dev/null 2>&1 || true
if [ -n "${OPENAI_API_KEY:-}" ]; then
hermes config set providers.basecamp.api_key "$OPENAI_API_KEY" > /dev/null 2>&1 || true
fi
hermes config set providers.basecamp.context_length 131072 > /dev/null 2>&1 || true
hermes config set model.provider basecamp > /dev/null 2>&1 || true
hermes config set model.default "$HERMES_MODEL" > /dev/null 2>&1 || true
# Drop the stock openrouter base_url so model.base_url doesn't lie about
# where traffic actually goes (the named provider's api is authoritative).
hermes config set model.base_url "" > /dev/null 2>&1 || true
# Local engines (ollama/tabbyapi/vllm) generally don't support hermes's
# reasoning-effort params β sending them yields "does not support thinking"
# HTTP 400. Turn reasoning off for the basecamp provider.
hermes config set agent.reasoning_effort off > /dev/null 2>&1 || true
# Clear stale context probes so the live endpoint is re-queried.
rm -f "${HERMES_HOME:-/root/.hermes}/context_length_cache.yaml" 2>/dev/null || true
fi
# Basecamp's own skin β install into basecamp's HERMES_HOME and activate it.
# (Writes only inside the container's own state, never a host install.)
if [ -d /opt/basecamp/skins ] && [ -f /opt/basecamp/skins/indigo.yaml ]; then
mkdir -p "${HERMES_HOME:-/root/.hermes}/skins"
cp /opt/basecamp/skins/indigo.yaml "${HERMES_HOME:-/root/.hermes}/skins/indigo.yaml"
hermes config set display.skin indigo > /dev/null 2>&1 || true
fi
# ββ The tavern MCP server β exposes the connectivity toolkit as REAL
# Hermes tools (mcp_tavern_status, mcp_tavern_self_check, mcp_tavern_wire,
# mcp_tavern_rediscover, mcp_tavern_models, mcp_tavern_chat). The agent
# sees them in its tool list and CALLS them β it can't invent commands
# that don't exist. Writes only inside basecamp's own HERMES_HOME.
# Injected DIRECTLY into config.yaml with yq (idempotent) β the
# `hermes config set`/`hermes mcp add` paths get clobbered by hermes's
# first-run config regeneration, but a yq write to the file survives.
# Runs again just before exec hermes (below) so the injection happens
# AFTER hermes's first-run config write, on every boot.
inject_tavern_mcp() {
if [ -f /opt/basecamp/tavern_mcp.py ]; then
CFG="${HERMES_HOME:-/root/.hermes}/config.yaml"
if [ -f "$CFG" ]; then
yq -i '.mcp_servers.tavern.command = "python3" |
.mcp_servers.tavern.args = ["/opt/basecamp/tavern_mcp.py"] |
.mcp_servers.tavern.timeout = 120' "$CFG" 2>/dev/null || true
fi
fi
}
inject_tavern_mcp
# Basecamp's own identity β install the SOUL.md that makes this Hermes
# KNOW it must load the basecamp-stack skill for any stack question.
# (Writes only inside the container's own state, never a host install.)
if [ -f /opt/basecamp/SOUL.md ]; then
cp /opt/basecamp/SOUL.md "${HERMES_HOME:-/root/.hermes}/SOUL.md"
fi
# Pull default model in background β AFTER discovery so the network scan
# isn't competing with a multi-GB download (missed-service boot race).
if [ -n "$BASECAMP_MODEL" ]; then
if ! ollama list 2>/dev/null | grep -q "$BASECAMP_MODEL"; then
echo "Pulling $BASECAMP_MODEL in background..."
ollama pull "$BASECAMP_MODEL" > /dev/null 2>&1 &
fi
fi
# Stack wiring audit β show every boot what's connected and what needs a fix.
# (Read-only: audits and prints fixes; never edits other containers' configs.)
if [ -x /opt/basecamp/discover.py ]; then
echo ""
echo "ββββββββββββββββββββββββββββββββββββββββββββ"
echo " β Connected & wired β auditing your stack"
echo "ββββββββββββββββββββββββββββββββββββββββββββ"
python3 /opt/basecamp/discover.py wire 2>/dev/null || true
fi
echo ""
echo "ββββββββββββββββββββββββββββββββββββββββββββ"
echo " π Starting Basecamp Hermes..."
echo " (this is the agent you'll talk to β loading"
echo " its tools, skills, and memory. ~10-30s)"
echo "ββββββββββββββββββββββββββββββββββββββββββββ"
echo ""
# Re-inject the tavern MCP server β config.yaml definitely exists now
# (hermes's first-run write happened above), so the connectivity toolkit
# is registered on EVERY boot, first boot included.
inject_tavern_mcp
# Handle arguments
if [ $# -gt 0 ]; then
case "$1" in
tavern)
shift
exec tavern "$@"
;;
ollama)
shift
exec ollama "$@"
;;
bash|shell)
shift
exec bash "$@"
;;
rediscover)
rm -f "$CONFIG_FILE"
exec python3 /opt/basecamp/discover.py serve
;;
*)
# Force-load the stack skill so hermes always has the discovered
# services + fix recipes in context (description matching alone
# isn't reliable with 67 skills competing).
exec hermes -s basecamp-stack "$@"
;;
esac
else
echo "Type 'tavern help' for stack commands."
echo "Type 'tavern rediscover' to re-scan for services."
echo ""
exec hermes -s basecamp-stack
fi
|