import type { Page } from "@playwright/test"; type MockAgentApiOptions = { model?: { id: string; label: string; description: string; icon: "bolt" | "sparkle"; }; sessions?: Array>; }; export async function mockAgentApi(page: Page, options: MockAgentApiOptions = {}) { const corsHeaders = { "Access-Control-Allow-Origin": "*" }; const model = options.model ?? { id: "test/model", label: "测试模型", description: "Playwright 浏览器测试", icon: "bolt" as const }; const triggeredSessions = new Map(); await page.route("**/api/v1/agent/chat/**", async (route) => { if (route.request().method() === "OPTIONS") { await route.fulfill({ status: 204, headers: { "Access-Control-Allow-Headers": "Authorization, Content-Type, X-Project-Id", "Access-Control-Allow-Methods": "DELETE, GET, PATCH, POST, OPTIONS", "Access-Control-Allow-Origin": "*" } }); return; } const pathname = new URL(route.request().url()).pathname; const collaborationMatch = pathname.match(/\/task\/([^/]+)\/collaboration\/session$/); if (collaborationMatch && route.request().method() === "POST") { await route.fulfill({ status: 201, headers: corsHeaders, json: { id: `collaboration-${collaborationMatch[1]}`, session_id: `collaboration-${collaborationMatch[1]}`, title: "任务协作问答", purpose: "task_collaboration", task_id: collaborationMatch[1], status: "active", created_at: "2026-09-23T01:11:00Z", updated_at: "2026-09-23T01:11:00Z" } }); return; } if (pathname.endsWith("/session") && route.request().method() === "POST") { const body = (route.request().postDataJSON() ?? {}) as { trigger_context?: { trigger_id?: string }; }; const triggerId = body.trigger_context?.trigger_id; const existing = triggerId ? triggeredSessions.get(triggerId) : undefined; const sessionId = existing?.sessionId ?? `browser-session-${triggeredSessions.size + 1}`; if (triggerId && !existing) triggeredSessions.set(triggerId, { sessionId, triggerId }); await route.fulfill({ status: existing ? 200 : 201, headers: corsHeaders, json: { session_id: sessionId, title: "水质投诉事件调查", status: "active", created_at: "2026-09-22T02:00:00Z", updated_at: "2026-09-22T02:00:00Z", created: !existing, event_duplicate: Boolean(existing), trigger_id: triggerId } }); return; } const sessionMatch = pathname.match(/\/session\/([^/]+)$/); if (sessionMatch && route.request().method() === "GET") { const collaboration = sessionMatch[1].startsWith("collaboration-"); await route.fulfill({ headers: corsHeaders, json: { id: sessionMatch[1], session_id: sessionMatch[1], title: collaboration ? "任务协作问答" : "水质投诉事件调查", purpose: collaboration ? "task_collaboration" : "ordinary_chat", task_id: collaboration ? sessionMatch[1].slice("collaboration-".length) : undefined, status: "active", created_at: "2026-09-22T02:00:00Z", updated_at: "2026-09-22T02:00:00Z", messages: [], is_streaming: false } }); return; } if (pathname.endsWith("/stream")) { await route.fulfill({ status: 200, headers: { ...corsHeaders, "Cache-Control": "no-cache", "Content-Type": "text/event-stream", "X-Vercel-AI-UI-Message-Stream": "v1" }, body: [ { type: "start", messageId: "assistant-browser-test" }, { type: "text-start", id: "answer" }, { type: "text-delta", id: "answer", delta: "已收到工况汇总请求。" }, { type: "text-end", id: "answer" }, { type: "finish", finishReason: "stop" } ] .map((part) => `data: ${JSON.stringify(part)}\n\n`) .join("") }); return; } if (pathname.endsWith("/sessions")) { await route.fulfill({ headers: corsHeaders, json: { sessions: options.sessions ?? [] } }); return; } if (pathname.endsWith("/models")) { await route.fulfill({ headers: corsHeaders, json: { default_model: model.id, models: [model] } }); return; } if (pathname.endsWith("/ui-registry")) { await route.fulfill({ headers: corsHeaders, json: { schema_version: "agent-ui-registry@1", chart_grammars: [], components: [], actions: [] } }); return; } if (pathname.endsWith("/frontend-action-registry")) { await route.fulfill({ headers: corsHeaders, json: { schema_version: "frontend-action-registry@1", actions: [] } }); return; } await route.fulfill({ headers: corsHeaders, json: {} }); }); }