Files
heicode-win/heicode/bin/acceptance_agnet_local.sh
T
gongzhiyong 1f21309597 refactor: rename manager codebase dir new-api → heicode, module github.com/heicode/manager
Remove user-facing new-api naming; Docker/network/container names use heicode.
Go imports updated; Dockerfiles and workflows ldflags fixed.

Made-with: Cursor
2026-05-01 01:47:23 +08:00

213 lines
5.7 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
# Local executable acceptance for Agnet integration matrix.
# Requires an authenticated admin cookie from heicode dashboard.
#
# Example:
# AUTH_COOKIE="session=xxxx" BASE_URL="http://localhost:3000" ./bin/acceptance_agnet_local.sh
BASE_URL="${BASE_URL:-http://localhost:3000}"
AUTH_COOKIE="${AUTH_COOKIE:-}"
TENANT_ID="${TENANT_ID:-ten_local}"
PROJECT_ID="${PROJECT_ID:-prj_local}"
CORRELATION_ID="${CORRELATION_ID:-corr_local_$(date +%s)}"
if [[ -z "${AUTH_COOKIE}" ]]; then
echo "ERROR: AUTH_COOKIE is required (admin session cookie)."
echo "Example: AUTH_COOKIE='session=xxxx' $0"
exit 1
fi
PASS=0
FAIL=0
report() {
local id="$1"
local result="$2"
local msg="$3"
if [[ "${result}" == "PASS" ]]; then
PASS=$((PASS + 1))
else
FAIL=$((FAIL + 1))
fi
printf '%-5s | %-4s | %s\n' "${id}" "${result}" "${msg}"
}
api_post() {
local path="$1"
local body="$2"
curl -sS \
-H "Content-Type: application/json" \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "X-Heicode-Correlation-Id: ${CORRELATION_ID}" \
-b "${AUTH_COOKIE}" \
-X POST \
"${BASE_URL}${path}" \
-d "${body}"
}
api_get() {
local path="$1"
curl -sS \
-H "X-Tenant-Id: ${TENANT_ID}" \
-H "X-Heicode-Correlation-Id: ${CORRELATION_ID}" \
-b "${AUTH_COOKIE}" \
"${BASE_URL}${path}"
}
echo "== Agnet acceptance start =="
echo "BASE_URL=${BASE_URL}"
echo "TENANT_ID=${TENANT_ID}"
echo "PROJECT_ID=${PROJECT_ID}"
# A01: agile_min deploy accepted
A01_PAYLOAD="$(cat <<EOF
{
"orchestration_plan": {
"intent_id": "intent_a01_$(date +%s)",
"template_hint": "agile_min",
"objective": "A01 happy path deployment",
"risk_level": "medium",
"budget": { "max_tokens": 20000, "max_cost_usd": 5, "max_duration_sec": 1800 },
"agents": [
{
"role_template": "AG-PO",
"goal": "Define acceptance",
"default_model_id": "mdl_claude_sonnet",
"sk_sources": [{ "type": "git", "artifact_id": "repo://sk/agile.md" }]
}
],
"constraints": { "allowed_model_ids": ["mdl_claude_sonnet", "mdl_claude_haiku"] },
"metadata": {
"tenant_id": "${TENANT_ID}",
"project_id": "${PROJECT_ID}",
"correlation_id": "${CORRELATION_ID}"
}
}
}
EOF
)"
A01_RES="$(api_post "/api/agnet/deployments" "${A01_PAYLOAD}")"
DEPLOYMENT_ID="$(python3 - <<'PY' "${A01_RES}"
import json,sys
try:
data=json.loads(sys.argv[1])
print((data.get("data") or {}).get("deployment_id",""))
except Exception:
print("")
PY
)"
if [[ -n "${DEPLOYMENT_ID}" ]]; then
report "A01" "PASS" "deployment accepted: ${DEPLOYMENT_ID}"
else
report "A01" "FAIL" "deployment rejected or malformed response"
fi
# A06: budget exceeded should be rejected
A06_PAYLOAD="$(cat <<EOF
{
"orchestration_plan": {
"intent_id": "intent_a06_$(date +%s)",
"template_hint": "agile_min",
"objective": "A06 budget exceed",
"risk_level": "medium",
"budget": { "max_tokens": 9999999, "max_cost_usd": 9999, "max_duration_sec": 999999 },
"agents": [{ "role_template": "AG-DEV", "goal": "Code", "default_model_id": "mdl_claude_sonnet" }],
"constraints": { "allowed_model_ids": ["mdl_claude_sonnet"] },
"metadata": {
"tenant_id": "${TENANT_ID}",
"project_id": "${PROJECT_ID}",
"correlation_id": "${CORRELATION_ID}"
}
}
}
EOF
)"
A06_RES="$(api_post "/api/agnet/deployments" "${A06_PAYLOAD}")"
A06_CODE="$(python3 - <<'PY' "${A06_RES}"
import json,sys
try:
data=json.loads(sys.argv[1])
print(((data.get("error") or {}).get("code")) or "")
except Exception:
print("")
PY
)"
if [[ "${A06_CODE}" == "BUDGET_EXCEEDED" ]]; then
report "A06" "PASS" "budget guard returned BUDGET_EXCEEDED"
else
report "A06" "FAIL" "expected BUDGET_EXCEEDED, got '${A06_CODE}'"
fi
# A07: duplicate intent_id should conflict (current implementation may not enforce; tracked as risk)
INTENT_DUP="intent_dup_$(date +%s)"
DUP_PAYLOAD="$(cat <<EOF
{
"orchestration_plan": {
"intent_id": "${INTENT_DUP}",
"template_hint": "agile_min",
"objective": "A07 idempotency",
"risk_level": "low",
"budget": { "max_tokens": 1000, "max_cost_usd": 1, "max_duration_sec": 300 },
"agents": [{ "role_template": "AG-QA", "goal": "verify" }],
"constraints": {},
"metadata": {
"tenant_id": "${TENANT_ID}",
"project_id": "${PROJECT_ID}",
"correlation_id": "${CORRELATION_ID}"
}
}
}
EOF
)"
_="$(api_post "/api/agnet/deployments" "${DUP_PAYLOAD}")"
A07_RES2="$(api_post "/api/agnet/deployments" "${DUP_PAYLOAD}")"
A07_CODE="$(python3 - <<'PY' "${A07_RES2}"
import json,sys
try:
data=json.loads(sys.argv[1])
print(((data.get("error") or {}).get("code")) or "")
except Exception:
print("")
PY
)"
if [[ "${A07_CODE}" == "DEPLOYMENT_CONFLICT" ]]; then
report "A07" "PASS" "idempotency conflict returned DEPLOYMENT_CONFLICT"
else
report "A07" "FAIL" "idempotency guard not enforced yet (got '${A07_CODE:-none}')"
fi
# A09/A10 minimal event verification for first deployment
if [[ -n "${DEPLOYMENT_ID}" ]]; then
EVENTS_RES="$(api_get "/api/agnet/deployments/${DEPLOYMENT_ID}/events")"
EVT_COUNT="$(python3 - <<'PY' "${EVENTS_RES}"
import json,sys
try:
data=json.loads(sys.argv[1])
items=(data.get("data") or {}).get("items") or []
print(len(items))
except Exception:
print(0)
PY
)"
if [[ "${EVT_COUNT}" -ge 1 ]]; then
report "A09" "PASS" "events visible (${EVT_COUNT})"
else
report "A09" "FAIL" "no events returned"
fi
else
report "A09" "FAIL" "skipped due to missing deployment_id"
fi
echo "-------------------------------------------"
echo "passed=${PASS} failed=${FAIL} total=$((PASS+FAIL))"
if [[ "${FAIL}" -gt 0 ]]; then
echo "Acceptance has failures. Fix before Azure deployment."
exit 2
fi
echo "Acceptance passed. Ready for Azure deployment gate."