#!/usr/bin/env bash # 无 Docker 的最小任务流演示:devnats(内嵌NATS) + gateway + dispatcher + mcp-go。 # 提交一个 DSL 任务,验证 Gateway → NATS → Dispatcher → MCP 工具 全链路。 set -euo pipefail cd "$(dirname "$0")/.." mkdir -p .bin echo "== 编译 ==" ( cd sundynix-shared && go build -o ../.bin/devnats ./cmd/devnats ) ( cd sundynix-gateway && go build -o ../.bin/gateway ./cmd/server ) ( cd sundynix-dispatcher && go build -o ../.bin/dispatcher ./cmd/dispatcher ) ( cd sundynix-mcp-go && go build -o ../.bin/mcp-go ./cmd/server ) cleanup() { kill "${GW_PID:-}" "${DISP_PID:-}" "${MCP_PID:-}" "${NATS_PID:-}" 2>/dev/null || true; } trap cleanup EXIT # 若 :4222 已有 NATS(docker compose 的容器),直接复用;否则起内嵌 devnats。 if nc -z 127.0.0.1 4222 2>/dev/null; then echo "== 检测到已运行的 NATS(:4222),复用之 ==" else echo "== 启动内嵌 devnats ==" .bin/devnats > .bin/devnats.log 2>&1 & NATS_PID=$! for _ in $(seq 1 30); do nc -z 127.0.0.1 4222 2>/dev/null && break || sleep 0.2; done fi echo "== 启动 mcp-go / dispatcher / gateway ==" .bin/mcp-go > .bin/mcp-go.log 2>&1 & MCP_PID=$! .bin/dispatcher > .bin/dispatcher.log 2>&1 & DISP_PID=$! .bin/gateway > .bin/gateway.log 2>&1 & GW_PID=$! for _ in $(seq 1 30); do curl -s -o /dev/null http://127.0.0.1:8080/api/v1/billing && break || sleep 0.3 done # 等 mcp-go 订阅就绪后再提交,否则工具调用会撞上启动竞态而降级。 for _ in $(seq 1 30); do grep -q "tools ready" .bin/mcp-go.log 2>/dev/null && break || sleep 0.1 done USER="wt" echo "== 登记用户偏好记忆 (→ mcp-go memory_upsert → sundynix_user_profile) ==" curl -s -X PUT http://127.0.0.1:8080/api/v1/memory \ -H 'Content-Type: application/json' -H "X-User-ID: $USER" \ -d '{"key":"称呼","value":"老王"}'; echo curl -s -X PUT http://127.0.0.1:8080/api/v1/memory \ -H 'Content-Type: application/json' -H "X-User-ID: $USER" \ -d '{"key":"回答偏好","value":"简洁、中文、多给要点"}'; echo SESSION="sess-demo" # 清掉上一次 demo 的会话历史,让本次轮次计数从 0 起(best-effort,无 Redis 容器则跳过)。 docker exec sundynix_agentix-redis-1 redis-cli DEL "sundynix:history:$SESSION" >/dev/null 2>&1 || true submit_and_stream() { local prompt="$1" local resp task_id resp=$(curl -s -X POST http://127.0.0.1:8080/api/v1/tasks \ -H 'Content-Type: application/json' -H "X-User-ID: $USER" -H "X-Session-ID: $SESSION" \ -d "{\"nodes\":[{\"id\":\"n1\",\"type\":\"agent\",\"data\":{\"prompt\":\"$prompt\"}}],\"edges\":[]}") echo "$resp" task_id=$(echo "$resp" | sed -n 's/.*"task_id":"\([^"]*\)".*/\1/p') # 客户端在 TTFT(700ms) 内连上即可收全部 token;--max-time 超时(exit 28) 属正常 curl -sN --max-time 12 "http://127.0.0.1:8080/api/v1/tasks/$task_id/stream" || true echo } echo "== 第 1 轮提交 (带 X-User-ID + X-Session-ID,召回画像) ==" submit_and_stream "你好" sleep 1 # 等写回把第 1 轮落进会话历史 echo "== 第 2 轮提交 (同会话,应召回到第 1 轮历史) ==" submit_and_stream "继续" echo "== mcp-go 日志 (工具被调用) ==" cat .bin/mcp-go.log echo "== dispatcher 日志 ==" cat .bin/dispatcher.log