hermes: pin account-listed Claude context variant and bound ingress

This commit is contained in:
jenkins 2026-09-29 08:09:48 -05:00
parent 089fe21384
commit 5af516f9c2
5 changed files with 26 additions and 5 deletions

View File

@ -60,7 +60,11 @@ def api(path, value=None, *, key=None, token=None, method=None):
return response.status, json.load(response)
except HTTPError as exc:
try:
return exc.code, json.load(exc)
try:
value = json.load(exc)
except ValueError:
value = {"error": {"code": "request_too_large" if exc.code == 413 else "http_error"}}
return exc.code, value
finally:
exc.close()

View File

@ -97,7 +97,7 @@ def claude_command(model, max_cost):
"--strict-mcp-config", "--mcp-config", '{"mcpServers":{}}',
"--setting-sources", "", "--disable-slash-commands",
"--permission-mode", "dontAsk", "--no-chrome",
"--model", model, "--effort", "medium", "--max-budget-usd", str(max_cost),
"--model", MODELS["claude"]["cli_model"], "--effort", "medium", "--max-budget-usd", str(max_cost),
"--max-turns", "3", "--system-prompt", SYSTEM,
"--json-schema", encoded(SCHEMA).decode()]
@ -111,6 +111,7 @@ def claude_environment(directory, token):
for key in ("DISABLE_COMPACT", "DISABLE_AUTO_COMPACT", "DISABLE_TELEMETRY",
"DISABLE_ERROR_REPORTING", "DISABLE_AUTOUPDATER", "DISABLE_UPDATES",
"DISABLE_PROMPT_CACHING", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC",
"CLAUDE_CODE_DISABLE_BACKGROUND_TASKS", "CLAUDE_CODE_DISABLE_TERMINAL_TITLE",
"CLAUDE_CODE_DISABLE_AUTO_MEMORY", "CLAUDE_CODE_SKIP_PROMPT_HISTORY"):
env[key] = "1"
return env
@ -161,7 +162,10 @@ def parse_claude(raw, expected_model):
if not models or set(models) - aliases:
observed = [name if re.fullmatch(r"claude-[a-z0-9.-]+(?:\[1m\])?", name)
else "unrecognized" for name in models]
raise Problem("model_changed", 502, observed_models=observed)
limits_seen = [{k: v for k, v in entry.items()
if k in {"contextWindow", "maxOutputTokens"} and type(v) is int}
for entry in models.values() if isinstance(entry, dict)]
raise Problem("model_changed", 502, observed_models=observed, limits=limits_seen)
for limits in models.values():
if (limits.get("contextWindow") != 1000000 or limits.get("maxOutputTokens") != 64000
or limits.get("canonicalModel") != expected_model

View File

@ -20,6 +20,7 @@ MODELS = {
"output": 2048, "overhead": 1024, "backend": "ollama-model-gate",
"enabled": True, "reasoning": "none"},
"claude": {"model": "claude-fable-5", "context": 1000000,
"cli_model": "claude-fable-5[1m]",
"output": 64000, "overhead": 8192, "backend": "claude-code-2.1.226",
"enabled": True, "reasoning": "medium"},
"codex": {"model": "gpt-6-astra", "context": 258400,

View File

@ -36,7 +36,7 @@ spec:
app: hermes-suite-planner
annotations:
fluentbit.io/exclude: "true"
ai.bstein.dev/config-rev: suite-v3-20260929
ai.bstein.dev/config-rev: suite-v4-20260929
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-pre-populate-only: "true"
vault.hashicorp.com/agent-init-first: "true"

View File

@ -9,6 +9,18 @@ spec:
prefixes: [/suite-planning]
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: hermes-suite-body-limit
namespace: hermes
spec:
buffering:
maxRequestBodyBytes: 1048576
memRequestBodyBytes: 1048576
maxResponseBodyBytes: 2097152
memResponseBodyBytes: 2097152
---
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: hermes-suite-planner
@ -26,7 +38,7 @@ metadata:
namespace: hermes
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: hermes-hermes-model-gate-lan-allowlist@kubernetescrd,hermes-hermes-suite-prefix@kubernetescrd
traefik.ingress.kubernetes.io/router.middlewares: hermes-hermes-model-gate-lan-allowlist@kubernetescrd,hermes-hermes-suite-body-limit@kubernetescrd,hermes-hermes-suite-prefix@kubernetescrd
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/service.serverstransport: hermes-hermes-suite-planner@kubernetescrd
spec: