feat(hermes): expose persistent agent TUI
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 153
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 153
This commit is contained in:
parent
5159c98d64
commit
b21843e35a
@ -186,8 +186,9 @@ data:
|
||||
START-HERE.md: |
|
||||
# Agent Hermes
|
||||
|
||||
Select the Cassandra project and state the outcome you want. Hermes will
|
||||
classify its difficulty, choose Codex or Claude Code, preserve the task on
|
||||
The authenticated root of agent.hermes.bstein.dev opens the persistent
|
||||
Herdr terminal interface. Give Hermes the outcome you want and it will
|
||||
classify the difficulty, choose Codex or Claude Code, preserve the task on
|
||||
the Cassandra board, supervise the worker through Herdr, and synthesize the
|
||||
evidence. The first native Codex worker requires one device-code login;
|
||||
subsequent sessions persist on the agent volume.
|
||||
|
||||
@ -24,7 +24,7 @@ spec:
|
||||
ai.bstein.dev/execution: Herdr-supervised Codex and Claude Code
|
||||
ai.bstein.dev/model-policy: difficulty-aware low through xhigh, cross-provider fallback
|
||||
ai.bstein.dev/placement: rpi5 preferred; Jetson deferred until state storage is available
|
||||
ai.bstein.dev/config-rev: "20260808-herdr-coordinator"
|
||||
ai.bstein.dev/config-rev: "20260808-herdr-browser-tui"
|
||||
vault.hashicorp.com/agent-inject: "true"
|
||||
vault.hashicorp.com/role: hermes-agent
|
||||
vault.hashicorp.com/agent-inject-secret-anthropic-token: kv/data/atlas/hermes/agent-tokens
|
||||
@ -155,6 +155,14 @@ spec:
|
||||
chmod 0755 "${tools}/bin/herdr.tmp"
|
||||
mv "${tools}/bin/herdr.tmp" "${tools}/bin/herdr"
|
||||
fi
|
||||
ttyd_version="$("${tools}/bin/ttyd" --version 2>/dev/null || true)"
|
||||
case "${ttyd_version}" in *1.7.7*) ttyd_ready=1 ;; *) ttyd_ready=0 ;; esac
|
||||
if [ "${ttyd_ready}" != "1" ]; then
|
||||
curl -fsSL -o "${tools}/bin/ttyd.tmp" https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.aarch64
|
||||
printf '%s %s\n' b38acadd89d1d396a0f5649aa52c539edbad07f4bc7348b27b4f4b7219dd4165 "${tools}/bin/ttyd.tmp" | sha256sum -c -
|
||||
chmod 0755 "${tools}/bin/ttyd.tmp"
|
||||
mv "${tools}/bin/ttyd.tmp" "${tools}/bin/ttyd"
|
||||
fi
|
||||
if [ ! -f "${tools}/.cli-versions-0.147.0-2.1.226" ]; then
|
||||
npm install --global --omit=dev --no-audit --no-fund --prefix "${tools}" \
|
||||
@openai/codex@0.147.0 \
|
||||
@ -332,6 +340,65 @@ spec:
|
||||
resources:
|
||||
requests: {cpu: 50m, memory: 128Mi}
|
||||
limits: {cpu: 750m, memory: 1Gi}
|
||||
- name: herdr-tui
|
||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [/bin/sh, -ec]
|
||||
args:
|
||||
- |
|
||||
set -a
|
||||
. /opt/data/.env
|
||||
set +a
|
||||
exec /opt/data/tools/bin/ttyd \
|
||||
--writable \
|
||||
--check-origin \
|
||||
--auth-header X-Forwarded-User \
|
||||
--interface 0.0.0.0 \
|
||||
--port 7681 \
|
||||
--cwd /opt/data/workspace \
|
||||
--terminal-type xterm-256color \
|
||||
--client-option "titleFixed=Hermes Agent - HERDR" \
|
||||
--client-option fontSize=15 \
|
||||
/opt/data/tools/bin/herdr
|
||||
ports:
|
||||
- {name: herdr-tui, containerPort: 7681, protocol: TCP}
|
||||
env:
|
||||
- {name: HOME, value: /opt/data/home}
|
||||
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
||||
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
||||
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
||||
- {name: PATH, value: /opt/data/tools/bin:/usr/local/bin:/usr/bin:/bin}
|
||||
volumeMounts:
|
||||
- {name: home, mountPath: /opt/data}
|
||||
- {name: tmp, mountPath: /tmp}
|
||||
startupProbe:
|
||||
tcpSocket: {port: herdr-tui}
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 60
|
||||
readinessProbe:
|
||||
tcpSocket: {port: herdr-tui}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
livenessProbe:
|
||||
tcpSocket: {port: herdr-tui}
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop: [ALL]
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
runAsUser: 10000
|
||||
runAsGroup: 10000
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
resources:
|
||||
requests: {cpu: 25m, memory: 64Mi}
|
||||
limits: {cpu: 500m, memory: 512Mi}
|
||||
- name: herdr-server
|
||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:15c5c538c0b58686af2e54e10bc870b23284789d485a609349df24ed3053622f
|
||||
imagePullPolicy: IfNotPresent
|
||||
@ -352,13 +419,37 @@ spec:
|
||||
done
|
||||
herdr integration install codex || true
|
||||
herdr integration install claude || true
|
||||
pane_file=/opt/data/herdr/coordinator-pane-id
|
||||
pane="$(cat "${pane_file}" 2>/dev/null || true)"
|
||||
if [ -z "${pane}" ] || ! herdr pane get "${pane}" >/dev/null 2>&1; then
|
||||
created="$(herdr workspace create \
|
||||
--cwd /opt/data/workspace \
|
||||
--label coordinator \
|
||||
--env HERMES_HOME=/opt/data \
|
||||
--env HERMES_AUTH_FILE=/shared-auth/auth.json \
|
||||
--env HOME=/opt/data/home \
|
||||
--env PYTHONPATH=/opt/hermes \
|
||||
--focus)"
|
||||
pane="$(printf '%s' "${created}" | /opt/hermes/.venv/bin/python -c \
|
||||
'import json,sys; print(json.load(sys.stdin)["result"]["root_pane"]["pane_id"])')"
|
||||
printf '%s\n' "${pane}" > "${pane_file}"
|
||||
fi
|
||||
process_info="$(herdr pane process-info --pane "${pane}" 2>/dev/null || printf '%s\n' '{"result":{"process_info":{"foreground_processes":[]}}}')"
|
||||
coordinator_running="$(printf '%s' "${process_info}" | /opt/hermes/.venv/bin/python -c \
|
||||
'import json,sys; processes=json.load(sys.stdin)["result"]["process_info"].get("foreground_processes", []); print("yes" if any("hermes" in " ".join(str(p.get(k) or "") for k in ("name", "argv0", "cmdline")) for p in processes) else "no")')"
|
||||
if [ "${coordinator_running}" != "yes" ]; then
|
||||
herdr pane run "${pane}" /opt/hermes/.venv/bin/hermes
|
||||
fi
|
||||
wait "${server_pid}"
|
||||
env:
|
||||
- {name: HERMES_HOME, value: /opt/data}
|
||||
- {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json}
|
||||
- {name: HOME, value: /opt/data/home}
|
||||
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
||||
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
||||
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
||||
- {name: PYTHONPATH, value: /opt/hermes}
|
||||
- {name: PATH, value: /opt/data/tools/bin:/usr/local/bin:/usr/bin:/bin}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
@ -368,6 +459,10 @@ spec:
|
||||
type: RuntimeDefault
|
||||
volumeMounts:
|
||||
- {name: home, mountPath: /opt/data}
|
||||
- {name: provider-auth, mountPath: /shared-auth, readOnly: true}
|
||||
- {name: coordinator, mountPath: /opt/coordinator, readOnly: true}
|
||||
- {name: auth-patch, mountPath: /opt/hermes/hermes_cli/auth.py, subPath: auth.py}
|
||||
- {name: coordinator, mountPath: /opt/data/home/.local/bin/herdr-dispatch, subPath: herdr_dispatch.py, readOnly: true}
|
||||
resources:
|
||||
requests: {cpu: 50m, memory: 128Mi}
|
||||
limits: {cpu: "1", memory: 2Gi}
|
||||
|
||||
@ -72,7 +72,7 @@ spec:
|
||||
matchLabels:
|
||||
app: oauth2-proxy-hermes-agent
|
||||
ports:
|
||||
- {protocol: TCP, port: 8787}
|
||||
- {protocol: TCP, port: 7681}
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
|
||||
@ -96,7 +96,7 @@ spec:
|
||||
- --cookie-samesite=lax
|
||||
- --cookie-refresh=1h
|
||||
- --cookie-expire=8h
|
||||
- --upstream=http://hermes-agent.hermes.svc.cluster.local:8787
|
||||
- --upstream=http://hermes-agent.hermes.svc.cluster.local:7681
|
||||
- --http-address=0.0.0.0:4180
|
||||
- --skip-provider-button=true
|
||||
- --reverse-proxy=true
|
||||
|
||||
@ -54,6 +54,9 @@ spec:
|
||||
- name: dashboard
|
||||
port: 8787
|
||||
targetPort: dashboard
|
||||
- name: herdr-tui
|
||||
port: 7681
|
||||
targetPort: herdr-tui
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user