import { responsesFixture } from "./responses-fixture"; 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("http://127.0.0.1:8787/api/v1/**", 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; if (pathname.endsWith("/topics") && route.request().method() === "GET") { await route.fulfill({ headers: corsHeaders, json: { topics: [] } }); return; } if (pathname.endsWith("/suggestions") && route.request().method() === "POST") { await route.fulfill({ headers: corsHeaders, json: { suggestions: [ { question: "分析当前管网需要优先核对的压力监测点。", activity_id: null }, { question: "检查近期供水任务的证据与待确认事项。", activity_id: null }, { question: "解读近期分析成果并列出进一步验证的问题。", activity_id: null }, ], generated_at: "2026-10-09T07:00:00Z", } }); return; } 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-"); const stored = options.sessions?.find((session) => (session.session_id ?? session.id) === sessionMatch[1]); await route.fulfill({ headers: corsHeaders, json: { id: sessionMatch[1], session_id: sessionMatch[1], title: stored?.title ?? (collaboration ? "任务协作问答" : "水质投诉事件调查"), purpose: stored?.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("/responses")) { await route.fulfill({ status: 200, headers: { ...corsHeaders, "Cache-Control": "no-cache", "Content-Type": "text/event-stream" }, body: responsesFixture([ { 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" } ]) }); 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.fallback(); }); }