From 62644ed9950ed57852f3de18768cba5631125b77 Mon Sep 17 00:00:00 2001 From: svector-anu Date: Fri, 28 Aug 2026 17:19:18 +0100 Subject: [PATCH] fail hermes runs on api errors --- .github/workflows/ci-tests.yml | 2 ++ harness-adapter/adapters/hermes.sh | 4 +++ scripts/tests/test_hermes_adapter.sh | 48 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 scripts/tests/test_hermes_adapter.sh diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index 1fa376b9644..5bc4d4338ef 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -66,6 +66,8 @@ jobs: run: bash scripts/tests/test_run_grok.sh - name: harness-adapter grok tests run: bash scripts/tests/test_harness_adapter_grok.sh + - name: hermes adapter tests + run: bash scripts/tests/test_hermes_adapter.sh - name: harness capability manifest tests run: bash scripts/tests/test_generate_harnesses_json.sh - name: harness resolution tests diff --git a/harness-adapter/adapters/hermes.sh b/harness-adapter/adapters/hermes.sh index 0db58421576..90d103bbc30 100755 --- a/harness-adapter/adapters/hermes.sh +++ b/harness-adapter/adapters/hermes.sh @@ -19,6 +19,10 @@ PROMPT="$(cat "$RH_PROMPT_FILE")"; PREFIX="${RH_COMPAT_RULES:-}" ARGS=(--usage-file "$RH_TMPDIR/hermes-usage.json" -z "$PROMPT"); [ -n "${RH_MODEL:-}" ] && [ "$RH_MODEL" != "default" ] && ARGS+=(--model "$RH_MODEL"); [ "${RH_MODE:-write}" = "read-only" ] && ARGS+=(--safe-mode); [ -z "${HERMES_AUTH:-}" ] && [ -n "${OPENROUTER_API_KEY:-}" ] && ARGS+=(--provider openrouter) OUT="$RH_TMPDIR/hermes-out.txt"; hermes "${ARGS[@]}" > "$OUT"; rc=$? [ $rc -ne 0 ] && { echo "hermes exited $rc: $(tail -c 4000 "$OUT" | tr '\n' ' ')" >&2; exit $rc; }; RESULT="$(cat "$OUT")" +if grep -Eq '(^|[[:space:]])HTTP [45][0-9][0-9]:' "$OUT"; then + echo "hermes API error: $(tail -c 4000 "$OUT" | tr '\n' ' ')" >&2 + exit 1 +fi TIN=0; TOUT=0; TCR=0; COST=""; SID=""; U="$RH_TMPDIR/hermes-usage.json" if [ -f "$U" ] && jq -e . "$U" >/dev/null 2>&1; then TIN=$(jq -r '.input_tokens // 0' "$U"); TOUT=$(jq -r '.output_tokens // 0' "$U"); TCR=$(jq -r '.cache_read_tokens // 0' "$U"); COST=$(jq -r '.estimated_cost_usd // empty' "$U"); SID=$(jq -r '.session_id // ""' "$U"); fi if [ -n "${RH_JSON_SCHEMA:-}" ]; then RESULT="$(schema_extract_json "$RESULT")"; schema_validate "$RH_JSON_SCHEMA" "$RESULT" || { echo "structured output failed validation" >&2; exit 3; }; fi diff --git a/scripts/tests/test_hermes_adapter.sh b/scripts/tests/test_hermes_adapter.sh new file mode 100644 index 00000000000..216b5e8d5eb --- /dev/null +++ b/scripts/tests/test_hermes_adapter.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT=$(cd "$(dirname "$0")/../.." && pwd) +TMP=$(mktemp -d) +trap 'rm -rf "$TMP"' EXIT +mkdir -p "$TMP/bin" +printf 'score this output' > "$TMP/prompt" + +cat > "$TMP/bin/hermes" <<'SH' +#!/usr/bin/env bash +if [ "${HERMES_STUB_MODE:-ok}" = api-error ]; then + printf '%s\n' 'HTTP 400: modelCode: does not exist' + exit 0 +fi +printf '%s\n' 'usable hermes result' +SH +chmod +x "$TMP/bin/hermes" + +run_adapter() { + local mode=$1 + mkdir -p "$TMP/$mode" + HERMES_STUB_MODE="$mode" \ + PATH="$TMP/bin:$PATH" \ + RH_LIB="$ROOT/harness-adapter/lib" \ + RH_TMPDIR="$TMP/$mode" \ + RH_PROMPT_FILE="$TMP/prompt" \ + RH_MODE=read-only \ + bash "$ROOT/harness-adapter/adapters/hermes.sh" +} + +normal=$(run_adapter ok) +[ "$(jq -r '.result' <<<"$normal")" = 'usable hermes result' ] || { + echo 'normal hermes output was not preserved' >&2 + exit 1 +} + +set +e +error=$(run_adapter api-error 2>&1) +rc=$? +set -e +[ "$rc" -eq 1 ] || { echo "hermes HTTP error returned rc=$rc, want 1" >&2; exit 1; } +grep -Fq 'hermes API error: HTTP 400: modelCode: does not exist' <<<"$error" || { + echo "hermes HTTP error diagnostic missing: $error" >&2 + exit 1 +} + +echo 'hermes adapter error tests passed'