molecule-core/tests/e2e/lib/model_slug.sh
Hongming Wang ac6f65ab5e test(e2e): pin pick_model_slug behavior with bash unit tests
PR #2571 fixed synth-E2E by branching MODEL_SLUG per runtime, but only
the langgraph branch was verified at runtime — hermes / claude-code /
override / fallback had zero automated coverage. A future regression
(e.g. dropping the langgraph case) would silently revert and only
surface as "Could not resolve authentication method" mid-E2E.

This PR:
- Extracts the dispatch into tests/e2e/lib/model_slug.sh as a sourceable
  pick_model_slug() function. No behavior change.
- Adds tests/e2e/test_model_slug.sh — 9 assertions across all 5 dispatch
  branches plus the override path. Verified to FAIL when any branch is
  flipped (manually regressed langgraph slash-form to confirm the test
  catches it; restored before commit).
- Wires the unit test into ci.yml's existing shellcheck job (only runs
  when tests/e2e/ or scripts/ change). Pure-bash, no live infra.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 12:04:12 -07:00

52 lines
2.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Per-runtime model slug dispatch for E2E provisioning.
#
# Different runtimes parse the model slug differently (PR #2571 incident,
# 2026-05-03):
#
# hermes → "openai/gpt-4o" (slash-form: derive-provider.sh splits
# on the prefix to set
# HERMES_INFERENCE_PROVIDER. Bare
# "gpt-4o" falls through to Anthropic
# default + 401, see PR #1714.)
#
# langgraph → "openai:gpt-4o" (colon-form: langchain init_chat_model
# requires "<provider>:<model>".
# Slash-form was misinterpreted as
# OpenRouter routing → fell through
# without auth, surfaced 2026-05-03
# after the a2a-sdk v1 contract bugs
# PR #2558+#2563+#2567 cleared the
# masking layers.)
#
# claude-code → "sonnet" (entry-id form: claude-code template's
# config.yaml uses bare model names,
# auth comes via CLAUDE_CODE_OAUTH_TOKEN
# or ANTHROPIC_API_KEY rather than the
# slug.)
#
# When E2E_MODEL_SLUG is set, it overrides this dispatch — useful when an
# operator dispatches the workflow to test a specific slug.
#
# Unit tested by tests/e2e/test_model_slug.sh — every branch must stay
# pinned because regressions silently mask as "Could not resolve
# authentication method" + the synth-E2E gate goes red without naming
# the slug-format mismatch.
# Usage: pick_model_slug <runtime>
# stdout: the slug string
# E2E_MODEL_SLUG (env): if set + non-empty, used as-is (operator override)
pick_model_slug() {
local runtime="${1:-}"
if [ -n "${E2E_MODEL_SLUG:-}" ]; then
printf '%s' "$E2E_MODEL_SLUG"
return 0
fi
case "$runtime" in
hermes) printf 'openai/gpt-4o' ;;
langgraph) printf 'openai:gpt-4o' ;;
claude-code) printf 'sonnet' ;;
*) printf 'openai/gpt-4o' ;; # safest fallback (matches hermes)
esac
}