import type { QuoteCaptureSignals } from "@/workers/rpa/quote-capture/types"; const RAW_LOG_LIMIT = 4_000; /** 契约失败时输出诊断(json=0 时始终打 network summary) */ export function logQuoteDebugRaw(signals: QuoteCaptureSignals): void { const trace = signals.networkTrace ?? []; const reqCount = trace.filter((t) => t.kind === "req").length; const respCount = trace.filter((t) => t.kind === "resp").length; console.log( `[rpa] quote-debug: contract=${signals.contractPayloads.length} json=${signals.jsonPayloads.length} trace req=${reqCount} resp=${respCount} url=${signals.resultUrl}`, ); const quoteLike = trace.filter( (t) => /quote|rate|graphql|pricing|mothership/i.test(t.url) && !/segment|analytics|hotjar|sentry/i.test(t.url), ); if (quoteLike.length > 0) { for (const entry of quoteLike.slice(0, 20)) { console.log(`[rpa] quote-debug trace: ${JSON.stringify(entry)}`); } } else if (trace.length > 0) { console.log( `[rpa] quote-debug: 无 quote-like 请求;最近 RESP:${trace .filter((t) => t.kind === "resp") .slice(-8) .map((t) => t.url) .join(" | ")}`, ); } if (process.env.RPA_QUOTE_DEBUG_RAW !== "true") { return; } for (const payload of signals.jsonPayloads) { let serialized = ""; try { serialized = JSON.stringify(payload.body); } catch { serialized = String(payload.body); } const clipped = serialized.length > RAW_LOG_LIMIT ? `${serialized.slice(0, RAW_LOG_LIMIT)}…` : serialized; console.log(`[rpa] quote-debug raw url=${payload.url} body=${clipped}`); } }