hermes(agent): retry dashboard ticket acquisition
All checks were successful
Tests / Declarative: Post Actions passed: 231
All checks were successful
Tests / Declarative: Post Actions passed: 231
This commit is contained in:
parent
0bec6edba3
commit
987c6e4cee
@ -27,7 +27,13 @@ const socketBefore = [
|
|||||||
' const ws = new WebSocket(url);',
|
' const ws = new WebSocket(url);',
|
||||||
].join("\n");
|
].join("\n");
|
||||||
const socketAfter = [
|
const socketAfter = [
|
||||||
' const url = await api.buildWsUrl("/api/pty", params);',
|
' let url: string;',
|
||||||
|
' try {',
|
||||||
|
' url = await api.buildWsUrl("/api/pty", params);',
|
||||||
|
' } catch {',
|
||||||
|
' if (!unmounting) scheduleReconnect(1006);',
|
||||||
|
' return;',
|
||||||
|
' }',
|
||||||
' if (unmounting) return;',
|
' if (unmounting) return;',
|
||||||
' const ws = new WebSocket(url);',
|
' const ws = new WebSocket(url);',
|
||||||
].join("\n");
|
].join("\n");
|
||||||
@ -70,6 +76,32 @@ const socketStateAfter = [
|
|||||||
' let ws: WebSocket | null = null;',
|
' let ws: WebSocket | null = null;',
|
||||||
' let reconnectTimer: ReturnType<typeof setTimeout> | null = null;',
|
' let reconnectTimer: ReturnType<typeof setTimeout> | null = null;',
|
||||||
].join("\n");
|
].join("\n");
|
||||||
|
const ticketBefore = [
|
||||||
|
' const url = await buildWsUrl("/api/events", { channel });',
|
||||||
|
' if (unmounting) {',
|
||||||
|
' return;',
|
||||||
|
' }',
|
||||||
|
' ws = new WebSocket(url);',
|
||||||
|
].join("\n");
|
||||||
|
const ticketAfter = [
|
||||||
|
' let url: string;',
|
||||||
|
' try {',
|
||||||
|
' url = await buildWsUrl("/api/events", { channel });',
|
||||||
|
' } catch {',
|
||||||
|
' if (unmounting) return;',
|
||||||
|
' const attempt = Math.min(eventsRetryAttempt.current + 1, 6);',
|
||||||
|
' eventsRetryAttempt.current = attempt;',
|
||||||
|
' const delay = Math.min(500 * 2 ** (attempt - 1), 5000);',
|
||||||
|
' setError("events feed disconnected — tool calls may not appear; reconnecting…");',
|
||||||
|
' reconnectTimer = setTimeout(() => {',
|
||||||
|
' reconnectTimer = null;',
|
||||||
|
' if (!unmounting) setVersion((v) => v + 1);',
|
||||||
|
' }, delay);',
|
||||||
|
' return;',
|
||||||
|
' }',
|
||||||
|
' if (unmounting) return;',
|
||||||
|
' ws = new WebSocket(url);',
|
||||||
|
].join("\n");
|
||||||
const handlersBefore = [
|
const handlersBefore = [
|
||||||
' ws.addEventListener("error", () => surface(DISCONNECTED));',
|
' ws.addEventListener("error", () => surface(DISCONNECTED));',
|
||||||
'',
|
'',
|
||||||
@ -121,6 +153,7 @@ const cleanupAfter = [
|
|||||||
for (const [before, after, label] of [
|
for (const [before, after, label] of [
|
||||||
[retryStateBefore, retryStateAfter, "retry state"],
|
[retryStateBefore, retryStateAfter, "retry state"],
|
||||||
[socketStateBefore, socketStateAfter, "socket state"],
|
[socketStateBefore, socketStateAfter, "socket state"],
|
||||||
|
[ticketBefore, ticketAfter, "ticket retry"],
|
||||||
[handlersBefore, handlersAfter, "socket handlers"],
|
[handlersBefore, handlersAfter, "socket handlers"],
|
||||||
[cleanupBefore, cleanupAfter, "socket cleanup"],
|
[cleanupBefore, cleanupAfter, "socket cleanup"],
|
||||||
]) {
|
]) {
|
||||||
|
|||||||
@ -170,7 +170,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 32Mi}
|
requests: {cpu: 25m, memory: 32Mi}
|
||||||
limits: {cpu: 100m, memory: 64Mi}
|
limits: {cpu: 100m, memory: 64Mi}
|
||||||
- name: install-agent-tools
|
- name: install-agent-tools
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
@ -218,7 +218,7 @@ spec:
|
|||||||
requests: {cpu: 100m, memory: 256Mi}
|
requests: {cpu: 100m, memory: 256Mi}
|
||||||
limits: {cpu: "1", memory: 1Gi}
|
limits: {cpu: "1", memory: 1Gi}
|
||||||
- name: patch-auth
|
- name: patch-auth
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -241,7 +241,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 64Mi}
|
requests: {cpu: 25m, memory: 64Mi}
|
||||||
limits: {cpu: 100m, memory: 128Mi}
|
limits: {cpu: 100m, memory: 128Mi}
|
||||||
- name: patch-tui-gateway
|
- name: patch-tui-gateway
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -264,7 +264,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 64Mi}
|
requests: {cpu: 25m, memory: 64Mi}
|
||||||
limits: {cpu: 100m, memory: 128Mi}
|
limits: {cpu: 100m, memory: 128Mi}
|
||||||
- name: patch-codex-runtime
|
- name: patch-codex-runtime
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -295,7 +295,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 64Mi}
|
requests: {cpu: 25m, memory: 64Mi}
|
||||||
limits: {cpu: 100m, memory: 128Mi}
|
limits: {cpu: 100m, memory: 128Mi}
|
||||||
- name: bootstrap-coordinator
|
- name: bootstrap-coordinator
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -305,7 +305,10 @@ spec:
|
|||||||
- {name: HERMES_HOME, value: /opt/data}
|
- {name: HERMES_HOME, value: /opt/data}
|
||||||
- {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json}
|
- {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json}
|
||||||
- {name: HOME, value: /opt/data/home}
|
- {name: HOME, value: /opt/data/home}
|
||||||
|
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
||||||
|
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||||
- {name: PYTHONPATH, value: /opt/hermes}
|
- {name: PYTHONPATH, value: /opt/hermes}
|
||||||
|
- {name: PATH, value: /opt/coordinator:/opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
runAsUser: 10000
|
runAsUser: 10000
|
||||||
@ -321,7 +324,7 @@ spec:
|
|||||||
requests: {cpu: 50m, memory: 128Mi}
|
requests: {cpu: 50m, memory: 128Mi}
|
||||||
limits: {cpu: 500m, memory: 512Mi}
|
limits: {cpu: 500m, memory: 512Mi}
|
||||||
- name: configure-agent-clients
|
- name: configure-agent-clients
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
@ -359,7 +362,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 32Mi}
|
requests: {cpu: 25m, memory: 32Mi}
|
||||||
limits: {cpu: 250m, memory: 128Mi}
|
limits: {cpu: 250m, memory: 128Mi}
|
||||||
- name: prepare-ttyd-index
|
- name: prepare-ttyd-index
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -381,7 +384,7 @@ spec:
|
|||||||
limits: {cpu: 250m, memory: 128Mi}
|
limits: {cpu: 250m, memory: 128Mi}
|
||||||
containers:
|
containers:
|
||||||
- name: hermes
|
- name: hermes
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/init, /opt/hermes/docker/main-wrapper.sh]
|
command: [/init, /opt/hermes/docker/main-wrapper.sh]
|
||||||
args: [gateway, run]
|
args: [gateway, run]
|
||||||
@ -512,7 +515,7 @@ spec:
|
|||||||
- {name: allowlist, mountPath: /etc/oauth2-proxy, readOnly: true}
|
- {name: allowlist, mountPath: /etc/oauth2-proxy, readOnly: true}
|
||||||
- {name: oauth-tmp, mountPath: /tmp}
|
- {name: oauth-tmp, mountPath: /tmp}
|
||||||
- name: terminal
|
- name: terminal
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/bin/sh, -ec]
|
command: [/bin/sh, -ec]
|
||||||
args:
|
args:
|
||||||
@ -604,7 +607,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 64Mi}
|
requests: {cpu: 25m, memory: 64Mi}
|
||||||
limits: {cpu: 500m, memory: 512Mi}
|
limits: {cpu: 500m, memory: 512Mi}
|
||||||
- name: cli-lane-runner
|
- name: cli-lane-runner
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/bin/sh, -ec]
|
command: [/bin/sh, -ec]
|
||||||
args:
|
args:
|
||||||
@ -645,14 +648,17 @@ spec:
|
|||||||
requests: {cpu: 100m, memory: 256Mi}
|
requests: {cpu: 100m, memory: 256Mi}
|
||||||
limits: {cpu: "3", memory: 6Gi}
|
limits: {cpu: "3", memory: 6Gi}
|
||||||
- name: model-steward
|
- name: model-steward
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:0577eb22d28b1ffc649405d31919b2527d9e591ccaa4a1e168dd6d6392a5a43f
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:cf07be056feea8e4f2d5512899f990732f3d26b4915257de8f90105d96cec67d
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/opt/hermes/.venv/bin/python, /opt/coordinator/hermes_coordinator.py, --loop, --interval, "3600"]
|
command: [/opt/hermes/.venv/bin/python, /opt/coordinator/hermes_coordinator.py, --loop, --interval, "3600"]
|
||||||
env:
|
env:
|
||||||
- {name: HERMES_HOME, value: /opt/data}
|
- {name: HERMES_HOME, value: /opt/data}
|
||||||
- {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json}
|
- {name: HERMES_AUTH_FILE, value: /shared-auth/auth.json}
|
||||||
- {name: HOME, value: /opt/data/home}
|
- {name: HOME, value: /opt/data/home}
|
||||||
|
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
||||||
|
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||||
- {name: PYTHONPATH, value: /opt/hermes}
|
- {name: PYTHONPATH, value: /opt/hermes}
|
||||||
|
- {name: PATH, value: /opt/coordinator:/opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
runAsUser: 10000
|
runAsUser: 10000
|
||||||
|
|||||||
@ -723,6 +723,8 @@ def test_agent_dashboard_reconnects_all_transient_websockets():
|
|||||||
assert "eventsRetryAttempt.current" in dockerfile
|
assert "eventsRetryAttempt.current" in dockerfile
|
||||||
assert "if (!unmounting) setVersion((v) => v + 1);" in dockerfile
|
assert "if (!unmounting) setVersion((v) => v + 1);" in dockerfile
|
||||||
assert "events feed rejected (${ev.code}) — reload the page" in dockerfile
|
assert "events feed rejected (${ev.code}) — reload the page" in dockerfile
|
||||||
|
assert 'url = await api.buildWsUrl("/api/pty", params);' in dockerfile
|
||||||
|
assert 'url = await buildWsUrl("/api/events", { channel });' in dockerfile
|
||||||
|
|
||||||
|
|
||||||
def test_agent_refreshes_routes_after_restoring_cli_logins():
|
def test_agent_refreshes_routes_after_restoring_cli_logins():
|
||||||
@ -740,6 +742,24 @@ def test_agent_refreshes_routes_after_restoring_cli_logins():
|
|||||||
env = {item["name"]: item["value"] for item in configure["env"]}
|
env = {item["name"]: item["value"] for item in configure["env"]}
|
||||||
assert env["HERMES_AUTH_FILE"] == "/shared-auth/auth.json"
|
assert env["HERMES_AUTH_FILE"] == "/shared-auth/auth.json"
|
||||||
assert env["PYTHONPATH"] == "/opt/hermes"
|
assert env["PYTHONPATH"] == "/opt/hermes"
|
||||||
|
for name in ("bootstrap-coordinator", "configure-agent-clients"):
|
||||||
|
route_env = {
|
||||||
|
item["name"]: item["value"]
|
||||||
|
for item in init_containers[name]["env"]
|
||||||
|
}
|
||||||
|
assert route_env["CODEX_HOME"] == "/opt/data/home/.codex"
|
||||||
|
assert "/opt/data/tools/bin" in route_env["PATH"]
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
item["name"]: item
|
||||||
|
for item in deployment["spec"]["template"]["spec"]["containers"]
|
||||||
|
}
|
||||||
|
steward_env = {
|
||||||
|
item["name"]: item["value"]
|
||||||
|
for item in containers["model-steward"]["env"]
|
||||||
|
}
|
||||||
|
assert steward_env["CODEX_HOME"] == "/opt/data/home/.codex"
|
||||||
|
assert "/opt/data/tools/bin" in steward_env["PATH"]
|
||||||
|
|
||||||
|
|
||||||
def test_flux_health_checks_follow_the_owner_oauth_sidecar():
|
def test_flux_health_checks_follow_the_owner_oauth_sidecar():
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user