fix(hermes): run coding workers unattended
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 193
Some checks failed
Tests / Declarative: Post Actions failed: 2, passed: 193
This commit is contained in:
parent
17e2ecfcf6
commit
2c51b46b7f
@ -4,6 +4,13 @@ FROM nousresearch/hermes-agent@sha256:9c841866021c54c4596849f6135717e8a4d52ba510
|
|||||||
|
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
|
# Codex uses the distribution bubblewrap package when a bounded sandbox is
|
||||||
|
# requested. Full-access workers rely on the pod as their isolation boundary,
|
||||||
|
# but keep bwrap installed for diagnostics and any future restricted profile.
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends bubblewrap \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# Keep a credential-free search provider available for private chat tenants.
|
# Keep a credential-free search provider available for private chat tenants.
|
||||||
# Paid/provider-backed search remains selectable through normal Hermes config.
|
# Paid/provider-backed search remains selectable through normal Hermes config.
|
||||||
RUN uv pip install --python /opt/hermes/.venv/bin/python ddgs==9.14.4
|
RUN uv pip install --python /opt/hermes/.venv/bin/python ddgs==9.14.4
|
||||||
|
|||||||
@ -142,7 +142,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:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
@ -194,7 +194,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:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -217,7 +217,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:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -243,12 +243,13 @@ spec:
|
|||||||
requests: {cpu: 50m, memory: 128Mi}
|
requests: {cpu: 50m, memory: 128Mi}
|
||||||
limits: {cpu: 500m, memory: 512Mi}
|
limits: {cpu: 500m, memory: 512Mi}
|
||||||
- name: install-herdr-integrations
|
- name: install-herdr-integrations
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
- -ec
|
- -ec
|
||||||
- |
|
- |
|
||||||
|
/opt/hermes/.venv/bin/python /opt/coordinator/configure_agent_clients.py
|
||||||
herdr integration install codex
|
herdr integration install codex
|
||||||
herdr integration install claude
|
herdr integration install claude
|
||||||
herdr integration install hermes
|
herdr integration install hermes
|
||||||
@ -257,7 +258,7 @@ spec:
|
|||||||
- {name: HOME, value: /opt/data/home}
|
- {name: HOME, value: /opt/data/home}
|
||||||
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
- {name: CODEX_HOME, value: /opt/data/home/.codex}
|
||||||
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||||
- {name: PATH, value: /opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
- {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
|
||||||
@ -266,11 +267,12 @@ spec:
|
|||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- {name: home, mountPath: /opt/data}
|
- {name: home, mountPath: /opt/data}
|
||||||
|
- {name: coordinator, mountPath: /opt/coordinator, readOnly: true}
|
||||||
resources:
|
resources:
|
||||||
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:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- /opt/hermes/.venv/bin/python
|
- /opt/hermes/.venv/bin/python
|
||||||
@ -292,7 +294,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:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/opt/hermes/.venv/bin/hermes]
|
command: [/opt/hermes/.venv/bin/hermes]
|
||||||
args: [gateway, run, --no-supervise]
|
args: [gateway, run, --no-supervise]
|
||||||
@ -307,7 +309,7 @@ spec:
|
|||||||
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
||||||
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
||||||
- {name: KUBECONFIG, value: /opt/data/home/.kube/config}
|
- {name: KUBECONFIG, value: /opt/data/home/.kube/config}
|
||||||
- {name: PATH, value: /opt/data/tools/bin:/opt/data/home/.local/bin:/opt/hermes/.venv/bin:/opt/hermes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
|
- {name: PATH, value: /opt/coordinator:/opt/data/tools/bin:/opt/data/home/.local/bin:/opt/hermes/.venv/bin:/opt/hermes/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin}
|
||||||
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
|
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
|
||||||
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
|
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
|
||||||
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
|
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
|
||||||
@ -407,7 +409,7 @@ spec:
|
|||||||
requests: {cpu: 50m, memory: 128Mi}
|
requests: {cpu: 50m, memory: 128Mi}
|
||||||
limits: {cpu: 750m, memory: 1Gi}
|
limits: {cpu: 750m, memory: 1Gi}
|
||||||
- name: herdr-tui
|
- name: herdr-tui
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command: [/bin/sh, -ec]
|
command: [/bin/sh, -ec]
|
||||||
args:
|
args:
|
||||||
@ -442,9 +444,10 @@ spec:
|
|||||||
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
- {name: CLAUDE_CONFIG_DIR, value: /opt/data/home/.claude}
|
||||||
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
- {name: HERDR_CONFIG_PATH, value: /opt/data/home/.config/herdr/config.toml}
|
||||||
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
||||||
- {name: PATH, value: /opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
- {name: PATH, value: /opt/coordinator:/opt/data/tools/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- {name: home, mountPath: /opt/data}
|
- {name: home, mountPath: /opt/data}
|
||||||
|
- {name: coordinator, mountPath: /opt/coordinator, readOnly: true}
|
||||||
- {name: tmp, mountPath: /tmp}
|
- {name: tmp, mountPath: /tmp}
|
||||||
- {name: ttyd-index, mountPath: /ttyd-index, readOnly: true}
|
- {name: ttyd-index, mountPath: /ttyd-index, readOnly: true}
|
||||||
startupProbe:
|
startupProbe:
|
||||||
@ -475,7 +478,7 @@ spec:
|
|||||||
requests: {cpu: 25m, memory: 64Mi}
|
requests: {cpu: 25m, memory: 64Mi}
|
||||||
limits: {cpu: 500m, memory: 512Mi}
|
limits: {cpu: 500m, memory: 512Mi}
|
||||||
- name: herdr-server
|
- name: herdr-server
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
command:
|
command:
|
||||||
- sh
|
- sh
|
||||||
@ -557,7 +560,7 @@ spec:
|
|||||||
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
- {name: HERDR_SOCKET_PATH, value: /opt/data/herdr/herdr.sock}
|
||||||
- {name: KUBECONFIG, value: /opt/data/home/.kube/config}
|
- {name: KUBECONFIG, value: /opt/data/home/.kube/config}
|
||||||
- {name: PYTHONPATH, value: /opt/hermes}
|
- {name: PYTHONPATH, value: /opt/hermes}
|
||||||
- {name: PATH, value: /opt/data/tools/bin:/opt/data/home/.local/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
- {name: PATH, value: /opt/coordinator:/opt/data/tools/bin:/opt/data/home/.local/bin:/opt/hermes/.venv/bin:/usr/local/bin:/usr/bin:/bin}
|
||||||
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
|
- {name: PLAYWRIGHT_BROWSERS_PATH, value: /opt/hermes/.playwright}
|
||||||
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
|
- {name: AGENT_BROWSER_EXECUTABLE_PATH, value: /opt/hermes/.playwright/chromium_headless_shell-1228/chrome-linux/headless_shell}
|
||||||
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
|
- {name: AGENT_BROWSER_ARGS, value: "--no-sandbox,--disable-dev-shm-usage"}
|
||||||
@ -579,7 +582,7 @@ spec:
|
|||||||
requests: {cpu: 50m, memory: 128Mi}
|
requests: {cpu: 50m, memory: 128Mi}
|
||||||
limits: {cpu: "1", memory: 2Gi}
|
limits: {cpu: "1", memory: 2Gi}
|
||||||
- name: model-steward
|
- name: model-steward
|
||||||
image: registry.bstein.dev/bstein/hermes-agent@sha256:7a1daefae2f068dcf14e7eb1f2f9aab2e1ce79c1b55b4bb0aa1092fbf4019bbc
|
image: registry.bstein.dev/bstein/hermes-agent@sha256:22d36d47a65877e0e45c3b004641e038ae10eb522e7463e791d4a00adf42b928
|
||||||
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:
|
||||||
|
|||||||
@ -45,6 +45,9 @@ configMapGenerator:
|
|||||||
- name: hermes-coordinator
|
- name: hermes-coordinator
|
||||||
namespace: hermes
|
namespace: hermes
|
||||||
files:
|
files:
|
||||||
|
- claude=scripts/claude
|
||||||
|
- codex=scripts/codex
|
||||||
|
- configure_agent_clients.py=scripts/configure_agent_clients.py
|
||||||
- gitea_askpass.sh=scripts/gitea_askpass.sh
|
- gitea_askpass.sh=scripts/gitea_askpass.sh
|
||||||
- herdr_dispatch.py=scripts/herdr_dispatch.py
|
- herdr_dispatch.py=scripts/herdr_dispatch.py
|
||||||
- herdr_tab_router.py=scripts/herdr_tab_router.py
|
- herdr_tab_router.py=scripts/herdr_tab_router.py
|
||||||
|
|||||||
9
services/hermes/scripts/claude
Executable file
9
services/hermes/scripts/claude
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Run Claude Code unattended inside the externally isolated Hermes agent pod.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
exec /opt/data/tools/bin/claude \
|
||||||
|
--dangerously-skip-permissions \
|
||||||
|
--permission-mode bypassPermissions \
|
||||||
|
--autocompact auto \
|
||||||
|
"$@"
|
||||||
8
services/hermes/scripts/codex
Executable file
8
services/hermes/scripts/codex
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Run Codex unattended inside the externally isolated Hermes agent pod.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
exec /opt/data/tools/bin/codex \
|
||||||
|
--dangerously-bypass-approvals-and-sandbox \
|
||||||
|
--dangerously-bypass-hook-trust \
|
||||||
|
"$@"
|
||||||
35
services/hermes/scripts/configure_agent_clients.py
Executable file
35
services/hermes/scripts/configure_agent_clients.py
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Apply persistent non-interactive settings for managed coding clients."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
|
||||||
|
def configure_claude_state(path: Path) -> None:
|
||||||
|
"""Disable Claude's long-session resume chooser without losing state."""
|
||||||
|
value: dict[str, Any] = {}
|
||||||
|
if path.is_file():
|
||||||
|
try:
|
||||||
|
loaded = json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, json.JSONDecodeError):
|
||||||
|
loaded = {}
|
||||||
|
if isinstance(loaded, dict):
|
||||||
|
value = loaded
|
||||||
|
value["resumeReturnDismissed"] = True
|
||||||
|
path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
path.write_text(json.dumps(value, indent=2) + "\n", encoding="utf-8")
|
||||||
|
os.chmod(path, 0o600)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Configure provider clients under the persistent Hermes home."""
|
||||||
|
home = Path(os.environ.get("CLAUDE_CONFIG_DIR", "/opt/data/home/.claude"))
|
||||||
|
configure_claude_state(home / ".claude.json")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@ -164,9 +164,6 @@ def launch_worker(
|
|||||||
plan["model"],
|
plan["model"],
|
||||||
"-c",
|
"-c",
|
||||||
f'model_reasoning_effort="{plan["effort"]}"',
|
f'model_reasoning_effort="{plan["effort"]}"',
|
||||||
"--approve-for-me",
|
|
||||||
"--sandbox",
|
|
||||||
"workspace-write",
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
@ -176,8 +173,6 @@ def launch_worker(
|
|||||||
plan["model"],
|
plan["model"],
|
||||||
"--effort",
|
"--effort",
|
||||||
plan["effort"],
|
plan["effort"],
|
||||||
"--permission-mode",
|
|
||||||
"auto",
|
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
started = _run(command, env)
|
started = _run(command, env)
|
||||||
|
|||||||
@ -27,6 +27,7 @@ dispatch = _load("herdr_dispatch")
|
|||||||
tab_router = _load("herdr_tab_router")
|
tab_router = _load("herdr_tab_router")
|
||||||
auth_patch = _load("patch_hermes_auth")
|
auth_patch = _load("patch_hermes_auth")
|
||||||
ttyd_patch = _load("patch_ttyd_index")
|
ttyd_patch = _load("patch_ttyd_index")
|
||||||
|
client_config = _load("configure_agent_clients")
|
||||||
|
|
||||||
|
|
||||||
def test_herdr_plan_chooses_task_shape_and_caps_effort():
|
def test_herdr_plan_chooses_task_shape_and_caps_effort():
|
||||||
@ -113,10 +114,16 @@ def test_claude_worker_waits_for_prompt_readiness(tmp_path: Path, monkeypatch):
|
|||||||
assert workspace_create[-3:] == ["--label", "project-claude-review", "--no-focus"]
|
assert workspace_create[-3:] == ["--label", "project-claude-review", "--no-focus"]
|
||||||
start = calls[1]
|
start = calls[1]
|
||||||
assert start[1:4] == ["agent", "start", "project-claude-review"]
|
assert start[1:4] == ["agent", "start", "project-claude-review"]
|
||||||
assert start[-2:] == ["--permission-mode", "auto"]
|
assert start[-4:] == [
|
||||||
|
"--model",
|
||||||
|
"claude-haiku-4-5-20251001",
|
||||||
|
"--effort",
|
||||||
|
"low",
|
||||||
|
]
|
||||||
|
assert "--permission-mode" not in start
|
||||||
|
|
||||||
|
|
||||||
def test_codex_worker_uses_automatic_review_without_prompts(tmp_path: Path, monkeypatch):
|
def test_codex_worker_leaves_inner_policy_to_unattended_wrapper(tmp_path: Path, monkeypatch):
|
||||||
herdr = tmp_path / "herdr"
|
herdr = tmp_path / "herdr"
|
||||||
herdr.touch()
|
herdr.touch()
|
||||||
project = tmp_path / "cassandra"
|
project = tmp_path / "cassandra"
|
||||||
@ -141,11 +148,38 @@ def test_codex_worker_uses_automatic_review_without_prompts(tmp_path: Path, monk
|
|||||||
assert calls[0][-3:] == ["--label", "cassandra-codex-api-fix", "--no-focus"]
|
assert calls[0][-3:] == ["--label", "cassandra-codex-api-fix", "--no-focus"]
|
||||||
start = calls[1]
|
start = calls[1]
|
||||||
assert start[1:4] == ["agent", "start", "cassandra-codex-api-fix"]
|
assert start[1:4] == ["agent", "start", "cassandra-codex-api-fix"]
|
||||||
assert "--approve-for-me" in start
|
assert "--dangerously-bypass-approvals-and-sandbox" not in start
|
||||||
assert start[-2:] == ["--sandbox", "workspace-write"]
|
assert "--dangerously-bypass-hook-trust" not in start
|
||||||
|
assert "--approve-for-me" not in start
|
||||||
|
assert "--sandbox" not in start
|
||||||
assert not any("on-request" in value for value in start)
|
assert not any("on-request" in value for value in start)
|
||||||
|
|
||||||
|
|
||||||
|
def test_provider_wrappers_force_unattended_modes():
|
||||||
|
codex = (HERMES / "scripts/codex").read_text(encoding="utf-8")
|
||||||
|
claude = (HERMES / "scripts/claude").read_text(encoding="utf-8")
|
||||||
|
|
||||||
|
assert "/opt/data/tools/bin/codex" in codex
|
||||||
|
assert "--dangerously-bypass-approvals-and-sandbox" in codex
|
||||||
|
assert "--dangerously-bypass-hook-trust" in codex
|
||||||
|
assert "/opt/data/tools/bin/claude" in claude
|
||||||
|
assert "--dangerously-skip-permissions" in claude
|
||||||
|
assert "--permission-mode bypassPermissions" in claude
|
||||||
|
assert "--autocompact auto" in claude
|
||||||
|
|
||||||
|
|
||||||
|
def test_claude_resume_prompt_is_persistently_suppressed(tmp_path: Path):
|
||||||
|
state = tmp_path / ".claude.json"
|
||||||
|
state.write_text('{"promptQueueUseCount": 4}\n', encoding="utf-8")
|
||||||
|
|
||||||
|
client_config.configure_claude_state(state)
|
||||||
|
|
||||||
|
value = yaml.safe_load(state.read_text(encoding="utf-8"))
|
||||||
|
assert value["promptQueueUseCount"] == 4
|
||||||
|
assert value["resumeReturnDismissed"] is True
|
||||||
|
assert state.stat().st_mode & 0o777 == 0o600
|
||||||
|
|
||||||
|
|
||||||
def test_agent_config_uses_bounded_noninteractive_approvals():
|
def test_agent_config_uses_bounded_noninteractive_approvals():
|
||||||
configmap = yaml.safe_load((HERMES / "agent-configmap.yaml").read_text())
|
configmap = yaml.safe_load((HERMES / "agent-configmap.yaml").read_text())
|
||||||
config = yaml.safe_load(configmap["data"]["config.yaml"])
|
config = yaml.safe_load(configmap["data"]["config.yaml"])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user