test(e2e): wire google-adk into the runtime e2e suite #2012
@@ -166,6 +166,10 @@ jobs:
|
||||
# canary path. The script picks the right blob shape based on
|
||||
# which key is non-empty.
|
||||
E2E_OPENAI_API_KEY: ${{ secrets.MOLECULE_STAGING_OPENAI_API_KEY }}
|
||||
# google-adk canary path — AI-Studio key (config model
|
||||
# google_genai:gemini-2.5-pro). PROD disallows API keys (Vertex+ADC);
|
||||
# the keyed path is CI-only. Dispatch with E2E_RUNTIME=google-adk.
|
||||
E2E_GOOGLE_API_KEY: ${{ secrets.MOLECULE_STAGING_GOOGLE_API_KEY }}
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
@@ -217,6 +221,10 @@ jobs:
|
||||
required_secret_name="MOLECULE_STAGING_OPENAI_API_KEY"
|
||||
required_secret_value="${E2E_OPENAI_API_KEY:-}"
|
||||
;;
|
||||
google-adk)
|
||||
required_secret_name="MOLECULE_STAGING_GOOGLE_API_KEY"
|
||||
required_secret_value="${E2E_GOOGLE_API_KEY:-}"
|
||||
;;
|
||||
*)
|
||||
echo "::warning::Unknown E2E_RUNTIME='${E2E_RUNTIME}' — skipping LLM-key check"
|
||||
required_secret_name=""
|
||||
|
||||
@@ -157,13 +157,18 @@ jobs:
|
||||
# E2E_RUNTIME=hermes or =codex via workflow_dispatch can still
|
||||
# exercise the OpenAI path.
|
||||
E2E_OPENAI_API_KEY: ${{ secrets.MOLECULE_STAGING_OPENAI_API_KEY }}
|
||||
# google-adk (operator-dispatched only) auths Gemini with an
|
||||
# AI-Studio key. Org policy disallows API keys in PROD (Vertex+ADC
|
||||
# there); CI uses the keyed AI-Studio path with config model
|
||||
# google_genai:gemini-2.5-pro. Vertex remains the supported prod path.
|
||||
E2E_GOOGLE_API_KEY: ${{ secrets.MOLECULE_STAGING_GOOGLE_API_KEY }}
|
||||
E2E_RUNTIME: ${{ github.event.inputs.runtime || 'claude-code' }}
|
||||
# Pin the model when running on the default claude-code path —
|
||||
# the per-runtime default ("sonnet") routes to direct Anthropic
|
||||
# and defeats the cost saving. Operators can override via the
|
||||
# workflow_dispatch flow (no input wired here yet — runtime
|
||||
# override is enough for ad-hoc).
|
||||
E2E_MODEL_SLUG: ${{ github.event.inputs.runtime == 'hermes' && 'openai/gpt-4o' || github.event.inputs.runtime == 'codex' && 'openai/gpt-4o' || 'MiniMax-M2' }}
|
||||
E2E_MODEL_SLUG: ${{ github.event.inputs.runtime == 'hermes' && 'openai/gpt-4o' || github.event.inputs.runtime == 'codex' && 'openai/gpt-4o' || github.event.inputs.runtime == 'google-adk' && 'google_genai:gemini-2.5-pro' || 'MiniMax-M2' }}
|
||||
E2E_RUN_ID: "${{ github.run_id }}-${{ github.run_attempt }}"
|
||||
E2E_KEEP_ORG: ${{ github.event.inputs.keep_org && '1' || '0' }}
|
||||
|
||||
@@ -212,6 +217,10 @@ jobs:
|
||||
required_secret_name="MOLECULE_STAGING_OPENAI_API_KEY"
|
||||
required_secret_value="${E2E_OPENAI_API_KEY:-}"
|
||||
;;
|
||||
google-adk)
|
||||
required_secret_name="MOLECULE_STAGING_GOOGLE_API_KEY"
|
||||
required_secret_value="${E2E_GOOGLE_API_KEY:-}"
|
||||
;;
|
||||
*)
|
||||
echo "::warning::Unknown E2E_RUNTIME='${E2E_RUNTIME}' — skipping LLM-key check"
|
||||
required_secret_name=""
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# E2E test: A2A round-trip parity across all four runtimes.
|
||||
# E2E test: A2A round-trip parity across all five runtimes.
|
||||
#
|
||||
# Validates that for each of {claude-code, hermes, codex, openclaw}:
|
||||
# Validates that for each of {claude-code, hermes, codex, openclaw, google-adk}:
|
||||
# 1. A workspace can be provisioned + brought online
|
||||
# 2. The adapter responds to A2A message/send
|
||||
# 3. The reply contains expected content (echo of the prompt)
|
||||
# 4. A SECOND message preserves session state where the runtime
|
||||
# supports it (currently: hermes via plugin path)
|
||||
# supports it (currently: hermes via plugin path; google-adk via
|
||||
# ADK InMemorySessionService keyed on A2A context_id)
|
||||
#
|
||||
# Targets a SaaS tenant subdomain. Provisions workspaces in the calling
|
||||
# tenant, runs the round-trip, deletes them on success.
|
||||
@@ -16,6 +17,10 @@
|
||||
# (e.g. https://demo-tenant.staging.moleculesai.app)
|
||||
# - $OPENROUTER_API_KEY (or $HERMES_API_KEY) for non-claude runtimes
|
||||
# - $OPENAI_API_KEY for claude-code peer
|
||||
# - $GOOGLE_API_KEY (AI Studio) for google-adk — the org disallows API
|
||||
# keys in PROD (Vertex+ADC there), but CI auths Gemini with an
|
||||
# AI-Studio key (config model google_genai:gemini-2.5-pro). Vertex
|
||||
# stays supported; this is the keyed CI path only.
|
||||
# - SaaS edge requires Origin header — see auto-memory
|
||||
# reference_saas_waf_origin_header.md
|
||||
#
|
||||
@@ -24,12 +29,13 @@
|
||||
# ./scripts/test-all-runtimes-a2a-e2e.sh
|
||||
#
|
||||
# Skip individual runtimes:
|
||||
# SKIP_HERMES=1 SKIP_OPENCLAW=1 ./scripts/test-all-runtimes-a2a-e2e.sh
|
||||
# SKIP_HERMES=1 SKIP_OPENCLAW=1 SKIP_GOOGLE_ADK=1 ./scripts/test-all-runtimes-a2a-e2e.sh
|
||||
set -euo pipefail
|
||||
|
||||
PLATFORM="${PLATFORM:-${1:-http://localhost:8080}}"
|
||||
HERMES_PROVIDER_KEY="${OPENROUTER_API_KEY:-${HERMES_API_KEY:-}}"
|
||||
PEER_OPENAI_KEY="${OPENAI_API_KEY:-}"
|
||||
GOOGLE_ADK_KEY="${GOOGLE_API_KEY:-}"
|
||||
# SaaS auth chain — TENANT_ADMIN_TOKEN + TENANT_ORG_ID required when
|
||||
# hitting *.moleculesai.app (per-tenant ADMIN_TOKEN, NOT
|
||||
# CP_ADMIN_API_TOKEN). Optional for localhost.
|
||||
@@ -48,6 +54,10 @@ if [ -z "$HERMES_PROVIDER_KEY" ] && [ -z "${SKIP_HERMES:-}${SKIP_CODEX:-}${SKIP_
|
||||
echo "FAIL: set OPENROUTER_API_KEY or HERMES_API_KEY for non-claude runtimes"
|
||||
exit 2
|
||||
fi
|
||||
if [ -z "$GOOGLE_ADK_KEY" ] && [ -z "${SKIP_GOOGLE_ADK:-}" ]; then
|
||||
echo "FAIL: set GOOGLE_API_KEY (AI Studio) for google-adk, or SKIP_GOOGLE_ADK=1"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
@@ -143,7 +153,7 @@ echo "=========================================="
|
||||
echo ""
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 1. Provision the four runtimes (skip via SKIP_* flags)
|
||||
# 1. Provision the five runtimes (skip via SKIP_* flags)
|
||||
# -------------------------------------------------------
|
||||
echo "--- 1. Provision workspaces ---"
|
||||
if [ -z "${SKIP_CLAUDE_CODE:-}" ]; then
|
||||
@@ -162,6 +172,10 @@ if [ -z "${SKIP_OPENCLAW:-}" ]; then
|
||||
WS_IDS[openclaw]=$(provision "ParityOpenClaw" "openclaw" "openclaw peer")
|
||||
echo " openclaw: ${WS_IDS[openclaw]}"
|
||||
fi
|
||||
if [ -z "${SKIP_GOOGLE_ADK:-}" ]; then
|
||||
WS_IDS[google-adk]=$(provision "ParityGoogleADK" "google-adk" "google-adk peer")
|
||||
echo " google-adk: ${WS_IDS[google-adk]}"
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 2. Set provider keys
|
||||
@@ -177,6 +191,12 @@ if [ -n "${WS_IDS[claude-code]:-}" ] && [ -n "$PEER_OPENAI_KEY" ]; then
|
||||
set_secret "${WS_IDS[claude-code]}" "OPENAI_API_KEY" "$PEER_OPENAI_KEY"
|
||||
echo " claude-code: OPENAI_API_KEY set"
|
||||
fi
|
||||
if [ -n "${WS_IDS[google-adk]:-}" ] && [ -n "$GOOGLE_ADK_KEY" ]; then
|
||||
# AI-Studio path: the adapter reads GOOGLE_API_KEY natively when the
|
||||
# config model is google_genai:gemini-2.5-pro (see _routing.resolve_model).
|
||||
set_secret "${WS_IDS[google-adk]}" "GOOGLE_API_KEY" "$GOOGLE_ADK_KEY"
|
||||
echo " google-adk: GOOGLE_API_KEY set"
|
||||
fi
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 3. Wait for online
|
||||
@@ -188,6 +208,9 @@ for runtime in "${!WS_IDS[@]}"; do
|
||||
[ -z "$id" ] && continue
|
||||
max=60
|
||||
[ "$runtime" = "hermes" ] && max=120
|
||||
# google-adk's first cold boot pulls a large fresh ADK image — give it
|
||||
# a hermes-class window so a slow first pull doesn't read as "failed".
|
||||
[ "$runtime" = "google-adk" ] && max=180
|
||||
if wait_online "$id" "$runtime" "$max"; then
|
||||
check "$runtime online" "ok" "ok"
|
||||
else
|
||||
@@ -200,7 +223,7 @@ done
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- 4. A2A round-trip (first message) ---"
|
||||
for runtime in claude-code hermes codex openclaw; do
|
||||
for runtime in claude-code hermes codex openclaw google-adk; do
|
||||
id="${WS_IDS[$runtime]:-}"
|
||||
[ -z "$id" ] && continue
|
||||
reply=$(a2a_send "$id" "Reply with just the word OK so we know you got this.")
|
||||
@@ -213,7 +236,7 @@ done
|
||||
# -------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- 5. Session continuity (second message recalls first) ---"
|
||||
for runtime in claude-code hermes codex openclaw; do
|
||||
for runtime in claude-code hermes codex openclaw google-adk; do
|
||||
id="${WS_IDS[$runtime]:-}"
|
||||
[ -z "$id" ] && continue
|
||||
# Set up: tell the agent a name.
|
||||
|
||||
Reference in New Issue
Block a user