提交一次代码

This commit is contained in:
andy
2026-07-12 09:57:54 +08:00
parent 9bd6bc1cd0
commit 6e47158d9e
46 changed files with 3524 additions and 48 deletions

View File

@@ -0,0 +1,345 @@
#!/usr/bin/env bash
set -Eeuo pipefail
# Direct SuperAgent Open API stream test.
# Purpose: bypass TH Hotel backend Debug EML / OSS / SourceMessage and test
# whether SuperAgent Open API itself times out or returns usable SSE events.
#
# Usage on test server:
# cd /home/th-hotel-simple
# bash ./superagent-direct-stream-test.sh
#
# You can either edit the variables below, or override them before running:
# ENV_FILE=/home/th-hotel-simple/th-hotel-server.env bash ./superagent-direct-stream-test.sh
#######################################
# Editable parameters
#######################################
# Your test server env file. It can be plain key=value format.
ENV_FILE="${ENV_FILE:-/home/th-hotel-simple/th-hotel-server.env}"
# Output directory for generated request bodies, response headers, and SSE body.
OUTPUT_DIR="${OUTPUT_DIR:-/tmp/th-hotel-superagent-direct}"
# Curl timeout. This is total curl max time, not SuperAgent's own timeout.
TIMEOUT_SECONDS="${TIMEOUT_SECONDS:-1900}"
CONNECT_TIMEOUT_SECONDS="${CONNECT_TIMEOUT_SECONDS:-30}"
# Optional hard overrides. Leave empty to read from ENV_FILE variables.
BASE_URL="${BASE_URL:-}"
API_KEY="${API_KEY:-}"
EXTERNAL_SUBJECT_ID="${EXTERNAL_SUBJECT_ID:-}"
# The direct test message. Keep it simple first; switch MESSAGE_PAYLOAD_FILE to
# a larger JSON later if you want to mimic Debug EML more closely. If you only
# have an .eml file, set EML_FILE and the script will embed the raw EML text in
# the message payload JSON.
MESSAGE_SUBJECT="${MESSAGE_SUBJECT:-timeout test}"
MESSAGE_TEXT="${MESSAGE_TEXT:-This is a direct curl timeout test. Please return a JSON result.}"
MESSAGE_PAYLOAD_FILE="${MESSAGE_PAYLOAD_FILE:-}"
EML_FILE="${EML_FILE:-}"
MESSAGE_PREFIX="${MESSAGE_PREFIX:-请基于以下 Debug 邮件 JSON 输出结构化任务抽取结果,只返回 JSON不要创建订单或任务}"
#######################################
# Helpers
#######################################
require_command() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Missing required command: $1" >&2
exit 1
fi
}
mask_secret() {
local value="${1:-}"
if [ -z "$value" ]; then
echo ""
return
fi
if [ "${#value}" -le 8 ]; then
echo "****"
return
fi
echo "${value:0:4}****${value: -4}"
}
load_env_file() {
if [ ! -f "$ENV_FILE" ]; then
echo "ENV_FILE not found: $ENV_FILE" >&2
echo "Edit ENV_FILE at the top of this script, or pass ENV_FILE=/path/to/file." >&2
exit 1
fi
# shellcheck disable=SC1090
set -a
source "$ENV_FILE"
set +a
}
normalize_config() {
BASE_URL="${BASE_URL:-${DEERFLOW_TEST_BASE_URL:-${DEERFLOW_BASE_URL:-}}}"
API_KEY="${API_KEY:-${DEERFLOW_TEST_OPEN_API_KEY:-${DEERFLOW_OPEN_API_KEY:-}}}"
if [ -z "$EXTERNAL_SUBJECT_ID" ]; then
EXTERNAL_SUBJECT_ID="${SUPERAGENT_TEST_DEBUG_EML_EXTERNAL_SUBJECT_ID:-${SUPERAGENT_DEBUG_EML_EXTERNAL_SUBJECT_ID:-th-hotel-debug-eml-upload}}"
fi
if [ -z "$BASE_URL" ]; then
echo "BASE_URL is empty. Set DEERFLOW_TEST_BASE_URL / DEERFLOW_BASE_URL or edit BASE_URL." >&2
exit 1
fi
if [ -z "$API_KEY" ]; then
echo "API_KEY is empty. Set DEERFLOW_TEST_OPEN_API_KEY / DEERFLOW_OPEN_API_KEY or edit API_KEY." >&2
exit 1
fi
if [ -z "$EXTERNAL_SUBJECT_ID" ]; then
echo "EXTERNAL_SUBJECT_ID is empty. Set SUPERAGENT_TEST_DEBUG_EML_EXTERNAL_SUBJECT_ID or edit it." >&2
exit 1
fi
if [ -n "$MESSAGE_PAYLOAD_FILE" ] && [ ! -f "$MESSAGE_PAYLOAD_FILE" ]; then
echo "MESSAGE_PAYLOAD_FILE not found: $MESSAGE_PAYLOAD_FILE" >&2
exit 1
fi
if [ -n "$EML_FILE" ] && [ ! -f "$EML_FILE" ]; then
echo "EML_FILE not found: $EML_FILE" >&2
exit 1
fi
BASE_URL="${BASE_URL%/}"
}
print_config() {
echo "=== Direct SuperAgent stream test ==="
echo "ENV_FILE=$ENV_FILE"
echo "OUTPUT_DIR=$OUTPUT_DIR"
echo "BASE_URL=$BASE_URL"
echo "EXTERNAL_SUBJECT_ID=$EXTERNAL_SUBJECT_ID"
echo "API_KEY=$(mask_secret "$API_KEY")"
echo "TIMEOUT_SECONDS=$TIMEOUT_SECONDS"
echo "CONNECT_TIMEOUT_SECONDS=$CONNECT_TIMEOUT_SECONDS"
echo "MESSAGE_SUBJECT=$MESSAGE_SUBJECT"
if [ -n "$MESSAGE_PAYLOAD_FILE" ]; then
echo "MESSAGE_PAYLOAD_FILE=$MESSAGE_PAYLOAD_FILE"
fi
if [ -n "$EML_FILE" ]; then
echo "EML_FILE=$EML_FILE"
fi
echo
}
write_create_body() {
python3 - <<'PY' > "$CREATE_BODY"
import json
import os
run_id = os.environ["RUN_ID"]
subject = os.environ["EXTERNAL_SUBJECT_ID"]
print(json.dumps({
"external_subject_id": subject,
"idempotency_key": f"{run_id}-session",
"metadata": {
"source": "direct-curl",
"debug_run_id": run_id
}
}, ensure_ascii=False))
PY
}
write_stream_body() {
python3 - <<'PY' > "$STREAM_BODY"
import json
import os
from pathlib import Path
run_id = os.environ["RUN_ID"]
payload_file = os.environ.get("MESSAGE_PAYLOAD_FILE", "").strip()
eml_file = os.environ.get("EML_FILE", "").strip()
prefix = os.environ["MESSAGE_PREFIX"]
if payload_file:
payload_text = Path(payload_file).read_text(encoding="utf-8")
elif eml_file:
eml_path = Path(eml_file)
raw_eml = eml_path.read_text(encoding="utf-8", errors="replace")
payload_text = json.dumps({
"source": "direct-curl",
"schema_version": "direct-raw-eml-v1",
"raw_eml_file_name": eml_path.name,
"raw_eml_size_bytes": eml_path.stat().st_size,
"raw_eml": raw_eml,
}, ensure_ascii=False)
else:
payload_text = json.dumps({
"source": "direct-curl",
"subject": os.environ["MESSAGE_SUBJECT"],
"text": os.environ["MESSAGE_TEXT"],
}, ensure_ascii=False)
message = prefix + "\n" + payload_text
print(json.dumps({
"message": message,
"idempotency_key": f"{run_id}-message",
"metadata": {
"source": "direct-curl",
"debug_run_id": run_id,
"source_message_id": "direct-curl",
"hotel_id": "DIRECT"
}
}, ensure_ascii=False))
PY
}
extract_session_id() {
python3 - "$CREATE_RESPONSE" <<'PY'
import json
import sys
path = sys.argv[1]
try:
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
except Exception:
print("")
raise SystemExit(0)
print(data.get("session_id") or data.get("id") or "")
PY
}
curl_create_session() {
local csrf="$RUN_ID-create"
echo "=== Creating SuperAgent session ==="
set +e
CREATE_HTTP_CODE="$(
curl -sS \
--connect-timeout "$CONNECT_TIMEOUT_SECONDS" \
--max-time "$TIMEOUT_SECONDS" \
-w "%{http_code}" \
-D "$CREATE_HEADERS" \
-o "$CREATE_RESPONSE" \
-X POST "$BASE_URL/api/open/agent-sessions" \
-H "Authorization: Bearer $API_KEY" \
-H "X-CSRF-Token: $csrf" \
-H "Cookie: csrf_token=$csrf" \
-H "Content-Type: application/json" \
--data-binary @"$CREATE_BODY"
)"
CREATE_CURL_EXIT=$?
set -e
echo "create curl exit=$CREATE_CURL_EXIT http=$CREATE_HTTP_CODE"
echo "create headers: $CREATE_HEADERS"
echo "create response: $CREATE_RESPONSE"
if [ "$CREATE_CURL_EXIT" -ne 0 ] || [ "$CREATE_HTTP_CODE" -lt 200 ] || [ "$CREATE_HTTP_CODE" -ge 300 ]; then
echo "Create session failed. Response body:" >&2
cat "$CREATE_RESPONSE" >&2 || true
exit 1
fi
SESSION_ID="$(extract_session_id)"
if [ -z "$SESSION_ID" ]; then
echo "Create session response does not contain session_id or id. Body:" >&2
cat "$CREATE_RESPONSE" >&2 || true
exit 1
fi
echo "SESSION_ID=$SESSION_ID"
echo
}
curl_stream_message() {
local csrf="$RUN_ID-message"
echo "=== Calling SuperAgent message stream ==="
echo "This may run for a long time. Output is saved to: $STREAM_RESPONSE"
local started_at ended_at elapsed
started_at="$(date +%s)"
set +e
STREAM_HTTP_CODE="$(
curl -sS -N --no-buffer \
--connect-timeout "$CONNECT_TIMEOUT_SECONDS" \
--max-time "$TIMEOUT_SECONDS" \
-w "%{http_code}" \
-D "$STREAM_HEADERS" \
-o "$STREAM_RESPONSE" \
-X POST "$BASE_URL/api/open/agent-sessions/$SESSION_ID/messages/stream" \
-H "Authorization: Bearer $API_KEY" \
-H "X-CSRF-Token: $csrf" \
-H "Cookie: csrf_token=$csrf" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
--data-binary @"$STREAM_BODY"
)"
STREAM_CURL_EXIT=$?
set -e
ended_at="$(date +%s)"
elapsed="$((ended_at - started_at))"
echo "stream curl exit=$STREAM_CURL_EXIT http=$STREAM_HTTP_CODE elapsed_seconds=$elapsed"
echo "stream headers: $STREAM_HEADERS"
echo "stream response: $STREAM_RESPONSE"
echo
}
summarize_stream() {
echo "=== Stream headers ==="
cat "$STREAM_HEADERS" || true
echo
echo "=== Stream event summary ==="
if [ -s "$STREAM_RESPONSE" ]; then
grep -E '^event:' "$STREAM_RESPONSE" | sort | uniq -c || true
echo
echo "Last 120 lines:"
tail -n 120 "$STREAM_RESPONSE" || true
else
echo "Stream response file is empty."
fi
echo
}
#######################################
# Main
#######################################
require_command curl
require_command python3
load_env_file
normalize_config
RUN_ID="${RUN_ID:-direct-curl-$(date +%Y%m%d-%H%M%S)}"
export BASE_URL API_KEY EXTERNAL_SUBJECT_ID RUN_ID
export MESSAGE_SUBJECT MESSAGE_TEXT MESSAGE_PAYLOAD_FILE EML_FILE MESSAGE_PREFIX
mkdir -p "$OUTPUT_DIR"
CREATE_BODY="$OUTPUT_DIR/$RUN_ID-create-body.json"
CREATE_HEADERS="$OUTPUT_DIR/$RUN_ID-create.headers"
CREATE_RESPONSE="$OUTPUT_DIR/$RUN_ID-create.json"
STREAM_BODY="$OUTPUT_DIR/$RUN_ID-stream-body.json"
STREAM_HEADERS="$OUTPUT_DIR/$RUN_ID-stream.headers"
STREAM_RESPONSE="$OUTPUT_DIR/$RUN_ID-stream.sse"
export CREATE_BODY STREAM_BODY CREATE_RESPONSE
print_config
write_create_body
write_stream_body
echo "create request body: $CREATE_BODY"
echo "stream request body: $STREAM_BODY"
echo
curl_create_session
curl_stream_message
summarize_stream
echo "Done."