125 lines
5.0 KiB
Bash
Executable File
125 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
# shellcheck disable=SC1091
|
|
source "$ROOT_DIR/scripts/acceptance/route_acceptance_lib.sh"
|
|
|
|
CRM_BASE="${CRM_BASE:-https://sub.tksea.top/portal-admin-api}"
|
|
TS="${TS:-$(timestamp_token)}"
|
|
ARTIFACT_DIR="${ARTIFACT_DIR:-$ROUTE_MATRIX_ROOT/${TS}_route_data_plane}"
|
|
|
|
GROUP_ID="${GROUP_ID:-p2t4-dp-${TS}}"
|
|
ROUTE_ID="${ROUTE_ID:-primary-${TS}}"
|
|
PUBLIC_MODEL="${PUBLIC_MODEL:-gpt-5.4}"
|
|
SHADOW_MODEL="${SHADOW_MODEL:-gpt-5.4}"
|
|
SHADOW_HOST_ID="${SHADOW_HOST_ID:?SHADOW_HOST_ID required}"
|
|
SHADOW_GROUP_ID="${SHADOW_GROUP_ID:?SHADOW_GROUP_ID required}"
|
|
REQUEST_ID="${REQUEST_ID:-req-p2t4-dp-${TS}}"
|
|
SUBJECT_ID="${SUBJECT_ID:-conv-p2t4-dp-${TS}}"
|
|
SUBSCRIPTION_USER_ID="${SUBSCRIPTION_USER_ID:-}"
|
|
GATEWAY_API_KEY="${GATEWAY_API_KEY:-}"
|
|
|
|
if [[ -z "$SUBSCRIPTION_USER_ID" && -z "$GATEWAY_API_KEY" ]]; then
|
|
echo "missing data-plane auth: set SUBSCRIPTION_USER_ID or GATEWAY_API_KEY" >&2
|
|
exit 1
|
|
fi
|
|
|
|
crm_auth_init
|
|
ensure_artifact_dir
|
|
|
|
create_group_payload="$(python3 - "$GROUP_ID" <<'PY'
|
|
import json, sys
|
|
group_id = sys.argv[1]
|
|
print(json.dumps({
|
|
"logical_group_id": group_id,
|
|
"display_name": f"P2T4 Data Plane {group_id}",
|
|
"status": "active",
|
|
"description": "P2-T4 data plane verification group",
|
|
"route_policy": "priority",
|
|
"sticky_mode": "conversation_preferred",
|
|
"conversation_ttl_seconds": 1200,
|
|
"user_model_ttl_seconds": 600,
|
|
"failover_threshold": 2,
|
|
"cooldown_seconds": 300,
|
|
}, ensure_ascii=False))
|
|
PY
|
|
)"
|
|
save_json 01-create-group "$(crm_curl_json POST "/api/logical-groups" "$create_group_payload")"
|
|
save_json 02-add-group-model "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/models" "{\"public_model\":\"$PUBLIC_MODEL\",\"status\":\"active\"}")"
|
|
save_json 03-create-route "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/routes" "{\"route_id\":\"$ROUTE_ID\",\"name\":\"Primary $ROUTE_ID\",\"status\":\"active\",\"priority\":10,\"weight\":100,\"shadow_group_id\":\"$SHADOW_GROUP_ID\",\"shadow_host_id\":\"$SHADOW_HOST_ID\",\"upstream_base_url_hint\":\"https://real-shadow.example/v1\"}")"
|
|
save_json 04-add-route-model "$(crm_curl_json POST "/api/logical-groups/$GROUP_ID/routes/$ROUTE_ID/models" "{\"public_model\":\"$PUBLIC_MODEL\",\"shadow_model\":\"$SHADOW_MODEL\",\"status\":\"active\"}")"
|
|
|
|
chat_payload="$(python3 - "$GROUP_ID" "$PUBLIC_MODEL" "$REQUEST_ID" "$SUBJECT_ID" "$SUBSCRIPTION_USER_ID" "$GATEWAY_API_KEY" <<'PY'
|
|
import json, sys
|
|
logical_group_id, model, request_id, subject_id, subscription_user_id, gateway_api_key = sys.argv[1:7]
|
|
payload = {
|
|
"logical_group_id": logical_group_id,
|
|
"model": model,
|
|
"request_id": request_id,
|
|
"scope": "conversation",
|
|
"subject_id": subject_id,
|
|
"messages": [{"role": "user", "content": "ping"}],
|
|
"sync": True,
|
|
}
|
|
if subscription_user_id:
|
|
payload["subscription_user_id"] = subscription_user_id
|
|
if gateway_api_key:
|
|
payload["gateway_api_key"] = gateway_api_key
|
|
print(json.dumps(payload, ensure_ascii=False))
|
|
PY
|
|
)"
|
|
save_json 05-route-chat "$(crm_curl_json POST "/api/routing/chat/completions" "$chat_payload")"
|
|
save_json 06-decision-logs "$(crm_curl_json GET "/api/routing/logs/decisions?request_id=$REQUEST_ID&limit=5")"
|
|
|
|
python3 - "$ARTIFACT_DIR" "$GROUP_ID" "$ROUTE_ID" "$PUBLIC_MODEL" "$SHADOW_MODEL" "$SHADOW_HOST_ID" "$SHADOW_GROUP_ID" "$REQUEST_ID" "$SUBSCRIPTION_USER_ID" "$GATEWAY_API_KEY" >"$ARTIFACT_DIR/07-summary.json" <<'PY'
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
(
|
|
art_dir,
|
|
group_id,
|
|
route_id,
|
|
public_model,
|
|
shadow_model,
|
|
shadow_host_id,
|
|
shadow_group_id,
|
|
request_id,
|
|
subscription_user_id,
|
|
gateway_api_key,
|
|
) = sys.argv[1:11]
|
|
art = Path(art_dir)
|
|
chat = json.loads((art / "05-route-chat.json").read_text())
|
|
logs = json.loads((art / "06-decision-logs.json").read_text())["decision_logs"]
|
|
|
|
assert chat["request_id"] == request_id
|
|
assert chat["logical_group_id"] == group_id
|
|
assert chat["model"] == public_model
|
|
assert chat["selected_route"]["route_id"] == route_id
|
|
assert chat["selected_route"]["shadow_host_id"] == shadow_host_id
|
|
assert chat["selected_route"]["shadow_group_id"] == shadow_group_id
|
|
assert chat["selected_route"]["shadow_model"] == shadow_model
|
|
assert chat["forward"]["upstream_status"] == 200
|
|
assert logs, logs
|
|
assert logs[0]["request_id"] == request_id
|
|
assert logs[0]["selected_route_id"] == route_id
|
|
|
|
expected_source = "managed_subscription" if subscription_user_id else "provided_gateway_key"
|
|
summary = {
|
|
"group_id": group_id,
|
|
"route_id": route_id,
|
|
"request_id": request_id,
|
|
"auth_mode": expected_source,
|
|
"forward_upstream_status": chat["forward"]["upstream_status"],
|
|
"selected_shadow_host_id": chat["selected_route"]["shadow_host_id"],
|
|
"selected_shadow_group_id": chat["selected_route"]["shadow_group_id"],
|
|
"selected_shadow_model": chat["selected_route"]["shadow_model"],
|
|
"effective_gateway_key_source": chat["forward"].get("effective_gateway_key_source"),
|
|
"decision_log_count": len(logs),
|
|
}
|
|
print(json.dumps(summary, ensure_ascii=False, indent=2))
|
|
PY
|
|
|
|
cat "$ARTIFACT_DIR/07-summary.json"
|