Add self-hosted AI worker bootstrap
This commit is contained in:
@@ -0,0 +1,53 @@
|
|||||||
|
# Local AI Agent Guardrails
|
||||||
|
|
||||||
|
These rules apply to any self-hosted AI coding assistant working on Agrarian.
|
||||||
|
|
||||||
|
## Mandatory Behavior
|
||||||
|
|
||||||
|
- Inspect existing project patterns before proposing changes.
|
||||||
|
- Classify every task as `low`, `medium`, or `high` risk.
|
||||||
|
- State evidence checked: files, docs, commands, logs, and build results.
|
||||||
|
- Make the smallest useful change.
|
||||||
|
- Do not refactor unrelated code.
|
||||||
|
- Do not invent APIs or project conventions.
|
||||||
|
- Do not merge directly to `main`.
|
||||||
|
- Do not store secrets, private keys, wallet keys, passwords, or tokens in the
|
||||||
|
repo.
|
||||||
|
- Passing tests/builds matter more than finishing the task.
|
||||||
|
|
||||||
|
## Stop And Escalate
|
||||||
|
|
||||||
|
Stop local work and prepare a Codex handoff when any of these are true:
|
||||||
|
|
||||||
|
- confidence is below `0.65`,
|
||||||
|
- tests fail twice,
|
||||||
|
- build fails twice,
|
||||||
|
- Unreal compile errors persist after one focused fix,
|
||||||
|
- the task touches security, auth, payments, AGR wallet integration, save/load,
|
||||||
|
multiplayer, marketplace logic, migrations, or core engine architecture,
|
||||||
|
- the diff touches more files than the brief allows,
|
||||||
|
- local model context is overloaded,
|
||||||
|
- the model cannot point to evidence for its recommendation.
|
||||||
|
|
||||||
|
## Required Handoff Format
|
||||||
|
|
||||||
|
```text
|
||||||
|
Project:
|
||||||
|
Branch:
|
||||||
|
Goal:
|
||||||
|
Risk:
|
||||||
|
Confidence:
|
||||||
|
Files inspected:
|
||||||
|
Files changed:
|
||||||
|
Commands run:
|
||||||
|
Errors:
|
||||||
|
What local AI tried:
|
||||||
|
Why local AI stopped:
|
||||||
|
Requested Codex action:
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quality Bar
|
||||||
|
|
||||||
|
Local AI is useful only when it is disciplined. It should be allowed to be
|
||||||
|
uncertain, but it should not be allowed to be vague, overconfident, or
|
||||||
|
unverified.
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
# Agrarian Self-Hosted AI Development Stack
|
||||||
|
|
||||||
|
This stack is meant to reduce pressure on Codex over time, not replace it
|
||||||
|
immediately. The first production target is supervised local assistance:
|
||||||
|
repository awareness, documentation, small safe edits, tests/builds, and clear
|
||||||
|
Codex escalation when local tooling is over its head.
|
||||||
|
|
||||||
|
## Current Services
|
||||||
|
|
||||||
|
- Gitea:
|
||||||
|
`http://192.168.5.21:3000/nathan/agrarian-game.git`
|
||||||
|
- Ollama:
|
||||||
|
`http://192.168.5.23:11434`
|
||||||
|
- Open WebUI:
|
||||||
|
`http://192.168.5.26:8085`
|
||||||
|
- Local AI worker VM:
|
||||||
|
`LinaAI / 192.168.5.27`
|
||||||
|
- Primary Unreal/Linux development VM:
|
||||||
|
`unreal-engine / 192.168.5.20`
|
||||||
|
|
||||||
|
## Current Local Model
|
||||||
|
|
||||||
|
- `qwen2.5-coder:7b`
|
||||||
|
- Role:
|
||||||
|
repo summaries, documentation, small patch suggestions, test generation,
|
||||||
|
straightforward scripts, and structured handoff preparation.
|
||||||
|
- Not the role:
|
||||||
|
broad Unreal architecture changes, risky save/multiplayer/economy rewrites,
|
||||||
|
security-sensitive code, or autonomous merges.
|
||||||
|
|
||||||
|
## Operating Model
|
||||||
|
|
||||||
|
1. Local AI gathers context and proposes small changes.
|
||||||
|
2. Work happens on a branch, not directly on `main`.
|
||||||
|
3. The agent reports risk, files inspected, commands run, and confidence.
|
||||||
|
4. Tests/builds decide whether a change is acceptable.
|
||||||
|
5. After two failed local attempts, stop and escalate.
|
||||||
|
6. Codex escalation uses the npm Codex CLI, not the API.
|
||||||
|
7. Human review controls merges.
|
||||||
|
|
||||||
|
## Codex Escalation
|
||||||
|
|
||||||
|
Use `Scripts/ai_codex_escalate.sh` with a completed task status file. The
|
||||||
|
script prefers a locally installed `codex` command and falls back to
|
||||||
|
`npx -y @openai/codex exec`.
|
||||||
|
|
||||||
|
Codex should be called for:
|
||||||
|
|
||||||
|
- confidence below `0.65`,
|
||||||
|
- two failed build/test attempts,
|
||||||
|
- Unreal compile errors that persist,
|
||||||
|
- tasks touching save systems, multiplayer, auth, payments, AGR wallet
|
||||||
|
integration, marketplace logic, migrations, or core architecture,
|
||||||
|
- patches that grow beyond the intended small scope,
|
||||||
|
- contradictions between local model output and official/project docs.
|
||||||
|
|
||||||
|
## VM Boundaries
|
||||||
|
|
||||||
|
- `LinaAI` owns local AI coding tools, Aider, Codex CLI escalation wrappers,
|
||||||
|
repo indexing, documentation generation, and small supervised branch work.
|
||||||
|
- `unreal-engine` owns Unreal Engine source, editor builds, commandlets, and
|
||||||
|
game compile/package verification.
|
||||||
|
- Keep these roles separated so AI tooling experiments do not destabilize the
|
||||||
|
Unreal build host.
|
||||||
|
|
||||||
|
## Immediate Next Work
|
||||||
|
|
||||||
|
- Verify Open WebUI model selection uses the Ollama backend at
|
||||||
|
`http://192.168.5.23:11434`.
|
||||||
|
- Use Aider from `LinaAI`, not from `unreal-engine`.
|
||||||
|
- Build project memory inside this repo under `Docs/` rather than creating a
|
||||||
|
separate documentation repository.
|
||||||
|
- Add small local-agent tasks first: summarize systems, write docs, generate
|
||||||
|
tests, inspect logs, and prepare Codex handoffs.
|
||||||
@@ -14,6 +14,56 @@
|
|||||||
- The old `/home/nathan/agrarian/dev/ROADMAP.md` is coin/wallet-specific and
|
- The old `/home/nathan/agrarian/dev/ROADMAP.md` is coin/wallet-specific and
|
||||||
should not be treated as the game roadmap.
|
should not be treated as the game roadmap.
|
||||||
|
|
||||||
|
## Self-Hosted AI Development Stack Bootstrap - 2026-05-23
|
||||||
|
|
||||||
|
- Nathan is starting a self-hosted AI build to reduce pressure on Codex while
|
||||||
|
keeping Codex as escalation through the npm Codex CLI rather than API usage.
|
||||||
|
- Current service inventory:
|
||||||
|
- Gitea: `http://192.168.5.21:3000`
|
||||||
|
- Ollama: `http://192.168.5.23:11434`
|
||||||
|
- Open WebUI: `http://192.168.5.26:8085`
|
||||||
|
- local AI worker VM: `LinaAI / 192.168.5.27`
|
||||||
|
- primary Unreal build VM: `unreal-engine / 192.168.5.20`
|
||||||
|
- Hardware observed:
|
||||||
|
- Unraid host: 12 CPU threads, 46 GiB RAM.
|
||||||
|
- `unreal-engine` VM: 8 CPU threads, 31 GiB RAM.
|
||||||
|
- local Codex shell host: 4 CPU threads, 3.7 GiB RAM.
|
||||||
|
- Ollama model currently available:
|
||||||
|
`qwen2.5-coder:7b`.
|
||||||
|
- Verified from `unreal-engine`:
|
||||||
|
Ollama chat API responded successfully with `local ai ready`.
|
||||||
|
- Open WebUI is reachable, but the container template currently shows
|
||||||
|
`OLLAMA_BASE_URL=http://localhost:11434`; corrected the running container and
|
||||||
|
Unraid template to use `http://192.168.5.23:11434` and port `8085`.
|
||||||
|
- Created `LinaAI` on Unraid:
|
||||||
|
- 4 vCPU,
|
||||||
|
- 12 GiB RAM,
|
||||||
|
- 100 GiB disk,
|
||||||
|
- static IP `192.168.5.27`,
|
||||||
|
- user `nathan`,
|
||||||
|
- passwordless sudo for MVP operations,
|
||||||
|
- autostart enabled.
|
||||||
|
- Reduced `unreal-engine` persistent next-boot allocation to 6 vCPU / 24 GiB
|
||||||
|
RAM so LinaAI and the Unreal build VM can coexist. The running Unreal VM was
|
||||||
|
not hot-resized.
|
||||||
|
- Cleaned the interrupted Aider install from `unreal-engine`; local AI tooling
|
||||||
|
belongs on `LinaAI`.
|
||||||
|
- Installed on `LinaAI`:
|
||||||
|
- `aider-chat` via `pipx`,
|
||||||
|
- npm `@openai/codex`,
|
||||||
|
- Gitea clone at `/home/nathan/repos/AgrarianGame`.
|
||||||
|
- Added self-hosted AI project documentation:
|
||||||
|
- `Docs/AI/SelfHostedAiDevelopmentStack.md`
|
||||||
|
- `Docs/AI/LocalAgentGuardrails.md`
|
||||||
|
- Added initial supervised-agent scripts:
|
||||||
|
- `Scripts/ai_check_stack.sh`
|
||||||
|
- `Scripts/ai_task_status_template.json`
|
||||||
|
- `Scripts/ai_codex_escalate.sh`
|
||||||
|
- Guardrail:
|
||||||
|
this is a supervised local-agent lane. No autonomous merges to `main`; local
|
||||||
|
AI prepares small changes, status files, verification results, and Codex
|
||||||
|
handoffs when confidence/build/test gates fail.
|
||||||
|
|
||||||
## AGR Wallet Integration Roadmap Update - 2026-05-21
|
## AGR Wallet Integration Roadmap Update - 2026-05-21
|
||||||
|
|
||||||
- Nathan clarified that AGR coin is a major investor hook for Agrarian:
|
- Nathan clarified that AGR coin is a major investor hook for Agrarian:
|
||||||
|
|||||||
Executable
+33
@@ -0,0 +1,33 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
OLLAMA_URL="${OLLAMA_URL:-http://192.168.5.23:11434}"
|
||||||
|
OPEN_WEBUI_URL="${OPEN_WEBUI_URL:-http://192.168.5.26:8085}"
|
||||||
|
GITEA_URL="${GITEA_URL:-http://192.168.5.21:3000}"
|
||||||
|
MODEL="${MODEL:-qwen2.5-coder:7b}"
|
||||||
|
|
||||||
|
echo "Gitea: ${GITEA_URL}"
|
||||||
|
curl -fsSI "${GITEA_URL}/user/login" >/dev/null
|
||||||
|
echo " ok"
|
||||||
|
|
||||||
|
echo "Ollama: ${OLLAMA_URL}"
|
||||||
|
curl -fsS "${OLLAMA_URL}/api/tags" >/tmp/agrarian_ollama_tags.json
|
||||||
|
if ! grep -q "\"${MODEL}\"" /tmp/agrarian_ollama_tags.json; then
|
||||||
|
echo " model ${MODEL} not found"
|
||||||
|
cat /tmp/agrarian_ollama_tags.json
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo " ok, model ${MODEL} available"
|
||||||
|
|
||||||
|
echo "Ollama chat smoke test"
|
||||||
|
curl -fsS "${OLLAMA_URL}/api/chat" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "{\"model\":\"${MODEL}\",\"messages\":[{\"role\":\"user\",\"content\":\"Reply with exactly: ok\"}],\"stream\":false}" \
|
||||||
|
| grep -Eiq '"content":"[[:space:]]*ok[[:space:]]*"'
|
||||||
|
echo " ok"
|
||||||
|
|
||||||
|
echo "Open WebUI: ${OPEN_WEBUI_URL}"
|
||||||
|
curl -fsSI "${OPEN_WEBUI_URL}" >/dev/null
|
||||||
|
echo " ok"
|
||||||
|
|
||||||
|
echo "Self-hosted AI stack reachable."
|
||||||
Executable
+50
@@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ $# -lt 1 ]]; then
|
||||||
|
echo "Usage: $0 <task-status-json-or-handoff-text> [extra prompt]" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
STATUS_FILE="$1"
|
||||||
|
EXTRA_PROMPT="${2:-}"
|
||||||
|
|
||||||
|
if [[ ! -f "$STATUS_FILE" ]]; then
|
||||||
|
echo "Missing status/handoff file: $STATUS_FILE" >&2
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
||||||
|
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
|
||||||
|
OUT_DIR="${ROOT}/Saved/AiEscalations/${STAMP}"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
PROMPT_FILE="${OUT_DIR}/codex_prompt.txt"
|
||||||
|
LOG_FILE="${OUT_DIR}/codex_exec.log"
|
||||||
|
|
||||||
|
{
|
||||||
|
echo "You are Codex being called as an escalation worker for Agrarian."
|
||||||
|
echo "Use the repository at: ${ROOT}"
|
||||||
|
echo
|
||||||
|
echo "Local AI stopped and requested escalation. Review the status below,"
|
||||||
|
echo "inspect the repo, make only the needed changes, run verification, and"
|
||||||
|
echo "summarize the result. Do not hide uncertainty."
|
||||||
|
echo
|
||||||
|
echo "Status / handoff:"
|
||||||
|
cat "$STATUS_FILE"
|
||||||
|
if [[ -n "$EXTRA_PROMPT" ]]; then
|
||||||
|
echo
|
||||||
|
echo "Extra prompt:"
|
||||||
|
echo "$EXTRA_PROMPT"
|
||||||
|
fi
|
||||||
|
} > "$PROMPT_FILE"
|
||||||
|
|
||||||
|
echo "Prompt written to ${PROMPT_FILE}"
|
||||||
|
|
||||||
|
if command -v codex >/dev/null 2>&1; then
|
||||||
|
codex exec "$(cat "$PROMPT_FILE")" 2>&1 | tee "$LOG_FILE"
|
||||||
|
else
|
||||||
|
npx -y @openai/codex exec "$(cat "$PROMPT_FILE")" 2>&1 | tee "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Codex escalation log written to ${LOG_FILE}"
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"task": "",
|
||||||
|
"project": "AgrarianGame",
|
||||||
|
"branch": "",
|
||||||
|
"risk": "low|medium|high",
|
||||||
|
"confidence": 0.0,
|
||||||
|
"attempts": 0,
|
||||||
|
"files_inspected": [],
|
||||||
|
"files_changed": [],
|
||||||
|
"commands_run": [],
|
||||||
|
"tests_passed": false,
|
||||||
|
"build_passed": false,
|
||||||
|
"blocked_reason": "",
|
||||||
|
"recommended_escalation": "none|codex|human",
|
||||||
|
"requested_codex_action": ""
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user