open-swe/deploy/seahaven/seed_store.sh
Adam Moussa cf57ba7aa5 feat(deploy): add Sea Haven self-hosted deployment capture
Captures the stock-LangGraph deployment of this fork at Sea Haven:
- systemd/open-swe.service: langgraph dev (:2024) + store seed ExecStartPost
- seed_store.sh: re-seeds team_settings + user_mappings (in-memory store
  resets on restart); env-parameterized, no secrets
- nginx/openswe.conf: dashboard SPA + scoped /dashboard/api proxy (security
  boundary; agent API not exposed)
- aegra/: deferred self-hosted-runtime alternative (not active on stock)
- DEPLOYMENT.md: full runbook (models, build, ingress, OAuth callback)

Secrets and internal infra identifiers are intentionally excluded (public
fork); real values live in private IT docs.
2026-06-25 17:28:34 -04:00

74 lines
3.4 KiB
Bash
Executable file

#!/usr/bin/env bash
# Seed the LangGraph store after a (re)start.
#
# The stock `langgraph dev` server uses an IN-MEMORY store, so anything written
# to it (team model settings, user mappings) is lost on every restart. This
# script idempotently re-PUTs that state and is wired as a systemd
# ExecStartPost on the open-swe.service unit so it runs after each start.
#
# Replace this with Postgres-backed durability (Aegra / `langgraph up`) to make
# the store survive restarts and drop this script.
#
# Configuration comes from the environment (set these in the service env or a
# sourced file alongside the app .env) — no real values are committed here:
# OPENSWE_BASE_URL default http://127.0.0.1:2024
# OPENSWE_AGENT_MODEL default anthropic:claude-opus-4-8
# OPENSWE_AGENT_EFFORT default high
# OPENSWE_REVIEWER_MODEL default openai:gpt-5.5
# OPENSWE_REVIEWER_EFFORT default high
# OPENSWE_DEFAULT_REPO e.g. your-org/your-pilot-repo (required)
# OPENSWE_OWNER_LOGIN GitHub login of the triggering owner (required)
# OPENSWE_OWNER_EMAIL work email mapped to that login (required)
set -euo pipefail
BASE="${OPENSWE_BASE_URL:-http://127.0.0.1:2024}"
AGENT_MODEL="${OPENSWE_AGENT_MODEL:-anthropic:claude-opus-4-8}"
AGENT_EFFORT="${OPENSWE_AGENT_EFFORT:-high}"
REVIEWER_MODEL="${OPENSWE_REVIEWER_MODEL:-openai:gpt-5.5}"
REVIEWER_EFFORT="${OPENSWE_REVIEWER_EFFORT:-high}"
DEFAULT_REPO="${OPENSWE_DEFAULT_REPO:?set OPENSWE_DEFAULT_REPO=owner/repo}"
OWNER_LOGIN="${OPENSWE_OWNER_LOGIN:?set OPENSWE_OWNER_LOGIN=github-login}"
OWNER_EMAIL="${OPENSWE_OWNER_EMAIL:?set OPENSWE_OWNER_EMAIL=work-email}"
NOW="$(date -u +%Y-%m-%dT%H:%M:%S+00:00)"
# Wait for the server to accept requests (up to ~60s).
for _ in $(seq 1 30); do
[ "$(curl -s -o /dev/null -w '%{http_code}' "$BASE/ok" || true)" = "200" ] && break
sleep 2
done
# 1) team_settings/default — builder + reviewer models (NOT read from env by the
# app; the store value wins over LLM_MODEL_ID). gpt-4.1 is NOT in this fork's
# SUPPORTED_MODELS, so the reviewer uses gpt-5.5 (cross-family vs the builder).
curl -s -X PUT "$BASE/store/items" -H "Content-Type: application/json" -d @- <<JSON
{"namespace":["team_settings"],"key":"default","value":{
"review_draft_prs": false,
"pr_summaries": true,
"review_trace_links": true,
"org_guidelines": null,
"default_agent_model": "$AGENT_MODEL",
"default_agent_reasoning_effort": "$AGENT_EFFORT",
"default_agent_subagent_model": "$AGENT_MODEL",
"default_agent_subagent_reasoning_effort": "$AGENT_EFFORT",
"default_repo": "$DEFAULT_REPO",
"default_reviewer_model": "$REVIEWER_MODEL",
"default_reviewer_reasoning_effort": "$REVIEWER_EFFORT",
"default_reviewer_subagent_model": "$REVIEWER_MODEL",
"default_reviewer_subagent_reasoning_effort": "$REVIEWER_EFFORT",
"default_grouping_model": null,
"default_grouping_reasoning_effort": null,
"default_chat_model": null,
"default_chat_reasoning_effort": null,
"updated_at": "$NOW"
}}
JSON
# 2) user_mappings/<login> — required, or the @openswe trigger ignores the commenter.
curl -s -X PUT "$BASE/store/items" -H "Content-Type: application/json" -d @- <<JSON
{"namespace":["user_mappings"],"key":"$OWNER_LOGIN","value":{
"github_login":"$OWNER_LOGIN","work_email":"$OWNER_EMAIL","slack_user_id":null,
"source":"slack_oauth","status":"active","created_at":"$NOW","updated_at":"$NOW"
}}
JSON
echo "seed_store: done at $NOW"