agent-market/deploy.sh
leora d785091d64 Typed chat: hosted free models, then the local model, nothing else; busy reply + Retry; llama-server watchdog
- Remove the keyword-rules agent from typed chat: fallback_agent, parse_look_command (+ tables), the copy-edit parser
  and _rules_check are gone. If every model fails: 'The assistant is busy, please try again in a moment.' with a Retry
  button (agent 'unavailable', no actions). Clicks, forms and payments stay deterministic (fallback_event); the landing
  view is a deterministic featured-listings panel; the Sell button opens the empty form.
- Local model via llama.cpp llama-server directly (ops/local-llm-watchdog.sh, loopback only, restart on exit/hang,
  crash backoff, log rotation; deploy.sh ensures it runs). Lean: no vision projector, no weight repack (mmapped), ctx
  6144, 1 slot, q8 KV, 6 threads at nice 10, poll 0, 1 GiB prompt cache. Idle 0% CPU, 2.9 GB RSS (0.6 GB private).
- Local requests use a JSON GBNF grammar, worked examples in the cached system prompt, and a labelled visitor message.
  10/10 correct on the real prompt, warm 4-13 s.
- Primer re-primes after a model-server restart (llama-server /metrics counter) and otherwise stays idle.
- Fix: hosted calls kept the Authorization header off when a local model was configured (cfg['local'] is a dict on
  hosted configs); now only the local server itself skips the key. Test added.
- Badge/chat header: 'AI: busy', 'AI: quota used up', 'AI: unavailable'; no 'built-in'/'checked by rules' texts.
- Tests: proxy checks expect the busy reply (never rules), clicks still work while busy, no-model server, local grammar/
  prompt/no key; browser checks for busy + Retry; e2e_http accepts busy for typed turns unless REQUIRE_LLM=1;
  test_copyedit.py replaced by test_copy_defaults.py; README updated.
2026-10-08 21:58:41 +08:00

45 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Deploy Agent Market on this box from a git ref.
# ./deploy.sh staging [ref] -> port 8795, data in ~/agent-market/staging-data (test data only)
# ./deploy.sh demo -> port 8796, always origin/main (merged code only)
set -euo pipefail
ENVN=${1:?staging|demo}
REPO=/gitea/leora/agent-market.git
case "$ENVN" in
staging) PORT=8795; REF=${2:-main} ;;
demo) PORT=8796; REF=main ;;
*) echo "unknown env"; exit 1 ;;
esac
ROOT=$HOME/agent-market/$ENVN
mkdir -p "$ROOT"
if [ ! -d "$ROOT/app/.git" ]; then git clone -q "$REPO" "$ROOT/app"; fi
cd "$ROOT/app" && git fetch -q origin && git checkout -q --detach "origin/$REF" 2>/dev/null || git checkout -q --detach "$REF"
echo "deploying $ENVN @ $(git rev-parse --short HEAD) on :$PORT"
# Optional config outside the repo (never committed): shared LLM settings, then per-env overrides.
# llm.env holds e.g. AGENT_MARKET_LLM_API_KEY_FILE / _BASE_URL / _MODELS (a path to the key, never the key itself).
CONF=$HOME/.config/agent-market
set -a
[ -f "$CONF/llm.env" ] && . "$CONF/llm.env"
# optional local model, the last link of the chain (llama-server on this box, see README "Local model")
[ -f "$CONF/local-llm.env" ] && . "$CONF/local-llm.env"
[ -f "$CONF/$ENVN.env" ] && . "$CONF/$ENVN.env"
# Optional extra env file for offline test runs, e.g. point the LLM at tests/mock_llm.py so no real model calls are made:
# AM_EXTRA_ENV=/path/offline.env ./deploy.sh staging my-branch
[ -n "${AM_EXTRA_ENV:-}" ] && . "$AM_EXTRA_ENV"
set +a
# The local model answers when the hosted free models can't, so make sure its watchdog is running (idempotent).
if [ -n "${AGENT_MARKET_LOCAL_LLM_URL:-}" ] && [[ "$AGENT_MARKET_LOCAL_LLM_URL" == http://127.0.0.1:${LLM_PORT:-11434}/* ]]; then
ops/local-llm-watchdog.sh --ensure || echo "warning: local model watchdog not started"
fi
# Build the React frontend (web/ -> static/dist) BEFORE stopping the running server, so a failed build
# leaves the current version up. Reproducible: exact versions from web/package-lock.json via `npm ci`.
command -v npm >/dev/null || { echo "npm not found: Node 20+ is needed to build the frontend"; exit 1; }
( cd web && npm ci --no-audit --no-fund --loglevel=error && npm run build --silent ) || { echo "frontend build failed; still running the previous version"; exit 1; }
[ -f static/dist/index.html ] || { echo "build produced no static/dist/index.html"; exit 1; }
PID=$(ss -ltnp 2>/dev/null | grep ":$PORT " | grep -o 'pid=[0-9]*' | cut -d= -f2 || true)
[ -n "$PID" ] && kill "$PID" && sleep 0.5
AGENT_MARKET_PORT=$PORT AGENT_MARKET_ENV=$ENVN AGENT_MARKET_DATA=$ROOT/data \
nohup python3 server.py >> "$ROOT/server.log" 2>&1 &
sleep 1
curl -sf "http://127.0.0.1:$PORT/healthz" >/dev/null && echo "ok: http://127.0.0.1:$PORT"