UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

108 lines (107 loc) • 2.87 kB
import { n as createQueuedDiagnosticPhaseEmitter } from "./diagnostic-events-DT4ejwoa.mjs"; import { performance } from "node:perf_hooks"; //#region src/gateway/server-methods/chat-send-diagnostics.ts const PHASES = [ "authority", "admission", "preparation", "attachments", "replyContext", "authoring", "persist", "runAdmission", "replyInitialization", "snapshot", "worktree", "effects", "response", "dispatch" ]; const requestDiagnostics = /* @__PURE__ */ new WeakMap(); /** Internal request attachment; handler spans do not expand the public plugin options. */ function bindChatSendDiagnostics(request, diagnostics) { if (diagnostics) requestDiagnostics.set(request, diagnostics); } function readChatSendDiagnostics(request) { return requestDiagnostics.get(request); } /** Request-owned totals; nested and parallel phases can overlap. */ function startChatSendDiagnostics(log) { const emit = createQueuedDiagnosticPhaseEmitter(); const totals = /* @__PURE__ */ new Map(); const active = /* @__PURE__ */ new Set(); let stage = "request"; let startedAt = performance.now(); let acknowledgedMs; let finished = false; const report = () => { const now = performance.now(); for (const flush of active) flush(now); const elapsedMs = now - startedAt; const endedAt = Date.now(); try { let message = `slow chat send ${Math.round(elapsedMs)}ms stage=${stage}`; if (acknowledgedMs !== void 0) message += ` ack=${Math.round(acknowledgedMs)}ms`; for (const phase of PHASES) { const durationMs = totals.get(phase); if (durationMs === void 0) continue; emit?.({ name: `chat.send.${phase}`, startedAt: endedAt - elapsedMs, endedAt, durationMs, details: { stage } }); message += ` ${phase}=${Math.round(durationMs)}ms`; } if (elapsedMs >= 1e3) log.info(message); } catch {} totals.clear(); startedAt = now; return elapsedMs; }; const finish = () => { if (!finished) { report(); finished = true; active.clear(); } }; return { scope(initialPhase) { if (finished) return; let phase = initialPhase; let phaseStartedAt = performance.now(); const flush = (now) => { if (phase) totals.set(phase, (totals.get(phase) ?? 0) + now - phaseStartedAt); phaseStartedAt = now; }; active.add(flush); const scope = { mark(nextPhase) { if (active.has(flush)) { flush(performance.now()); phase = nextPhase; } }, finish() { scope.mark(); active.delete(flush); } }; return scope; }, acknowledge() { if (!finished && stage === "request") { acknowledgedMs = report(); stage = "startup"; } }, finish, [Symbol.dispose]() { if (stage === "request") finish(); } }; } //#endregion export { readChatSendDiagnostics as n, startChatSendDiagnostics as r, bindChatSendDiagnostics as t };