import { NextResponse } from "next/server";
import { safeGetJsonBody, errorResponses, validateRequestBody } from "@/lib/api-utils";
import {
  DEFAULT_AGENT_MAX_STEPS,
  MAX_AGENT_STEPS,
  MIN_AGENT_STEPS,
} from "@/lib/constants";
import { isConvexEnabled } from "@/lib/convex/enabled";
import { getAuthedConvexClient } from "@/lib/convex/route";
import {
  codexMessagesToPrompt,
  findWorkspaceRoot,
  startCodexJsonRun,
} from "@/lib/ai/codex/codexExec";
import { startHermesRun, streamHermesRunEvents, type HermesRunEvent } from "@/lib/ai-agent/hermes/bridge";
import {
  readHermesToolArgsFromEvent,
  readHermesToolResultFromEvent,
} from "@/lib/ai-agent/hermes/tool-result-recovery";
import { startDocumentAiOrchestratorRun } from "@/lib/server/document-ai-orchestrator";
import { buildDocumentBridgeContext } from "@/lib/documents/bridge";
import { executeRustBridgeTool } from "@/lib/documents/rust-runtime";
import type { PageOptionsState } from "@/types/page-options";
import { pickLeptosTiptapRuntimePageOptions } from "@/lib/documents/page-option-semantics";

export const dynamic = "force-dynamic";

type AgentMessage = { role: "user" | "assistant"; content: string };
type AgentScope = "global" | "mindmap" | "document" | "onlyoffice";
type RawAiProvider = "online" | "local" | "ollama" | "codex" | "hermes";
type RuntimeProvider = "agents" | "hermes" | "codex";
type CodexMode = "chat" | "test" | "dev";

type RequestPayload = {
  stream?: boolean;
  maxSteps?: number;
  scope?: AgentScope;
  messages: AgentMessage[];
  attachments?: Array<{
    id: string;
    title: string;
    fileUrl: string;
    mimeType?: string | null;
  }>;
  toolChoice?: {
    mode: "auto" | "manual";
    toolSets?: string[];
    tools?: string[];
  };
  context?: {
    documentId?: string;
    mindmapId?: string;
    selectedUids?: string[];
    documentBlocks?: unknown;
    pageOptions?: PageOptionsState;
    node?: unknown;
    subtree?: unknown;
    outline?: unknown;
    evidence?: unknown;
  };
  options?: {
    searxng?: boolean;
    ai?: {
      provider?: RawAiProvider;
      model?: string;
      sessionId?: string;
      modelKey?: string;
      profileId?: string;
    };
  };
};

type LegacyStreamEvent =
  | { type: "assistant_message"; data: { text: string } }
  | { type: "tool_call"; data: { id: string; tool: string; args: Record<string, unknown> } }
  | { type: "tool_result"; data: { id: string; tool: string; ok: boolean; ms: number; result: unknown } }
  | { type: "completion"; data: { ok: true; text: string; steps: number } }
  | { type: "error"; data: { ok: false; message: string } }
  | { type: "codex_session"; data: { sessionId: string } };

const sseHeaders = {
  "Content-Type": "text/event-stream; charset=utf-8",
  "Cache-Control": "no-cache, no-transform",
  Connection: "keep-alive",
  "X-Accel-Buffering": "no",
} as const;

const toSseFrame = (event: string, data: unknown) => {
  const json = JSON.stringify(data ?? null);
  return `event: ${event}\ndata: ${json}\n\n`;
};

const makeRunId = () => {
  try {
    if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
      return crypto.randomUUID();
    }
  } catch {
    // ignore
  }
  return `run_${Date.now()}_${Math.random().toString(16).slice(2, 10)}`;
};

const serializeContextSnapshot = (label: string, value: unknown, limit: number) => {
  if (value === undefined) {
    return null;
  }
  try {
    const text = JSON.stringify(value);
    return `${label}=${text.slice(0, limit)}`;
  } catch {
    return `${label}=provided`;
  }
};

const clampSteps = (raw: unknown) => {
  const parsed = Number(raw ?? DEFAULT_AGENT_MAX_STEPS);
  if (!Number.isFinite(parsed)) return DEFAULT_AGENT_MAX_STEPS;
  return Math.max(MIN_AGENT_STEPS, Math.min(MAX_AGENT_STEPS, Math.floor(parsed)));
};

const normalizeProvider = (
  raw: unknown,
  scope: AgentScope,
  stream: boolean,
): RuntimeProvider => {
  const value = String(raw ?? "").trim().toLowerCase();
  if (value === "online" && scope === "document" && stream) {
    return "agents";
  }
  return value === "codex" ? "codex" : "hermes";
};

const proxySseResponse = (upstream: Response) => {
  const encoder = new TextEncoder();
  const body = new ReadableStream<Uint8Array>({
    async start(controller) {
      controller.enqueue(encoder.encode(toSseFrame("ready", { ok: true, requestId: makeRunId() })));
      const reader = upstream.body?.getReader();
      if (!reader) {
        controller.close();
        return;
      }

      try {
        while (true) {
          const { value, done } = await reader.read();
          if (done) break;
          if (value) {
            controller.enqueue(value);
          }
        }
      } finally {
        controller.close();
      }
    },
  });

  return new Response(body, { headers: sseHeaders });
};

const normalizeScope = (payload: RequestPayload): AgentScope => {
  const raw = String(payload.scope ?? "").trim();
  if (raw === "global" || raw === "mindmap" || raw === "document" || raw === "onlyoffice") {
    return raw;
  }
  return payload.context?.mindmapId ? "mindmap" : payload.context?.documentId ? "document" : "global";
};

const stripCodexModePrefix = (text: string): { mode: CodexMode | null; text: string } => {
  const value = String(text ?? "");
  const match = value.match(/^\s*#(chat|test|dev)\b[\s:：\-–—]*/i);
  if (!match) return { mode: null, text: value };
  const mode = String(match[1] ?? "").toLowerCase() as CodexMode;
  return { mode, text: value.slice(match[0].length).trimStart() };
};

const extractCodexModeFromMessages = (messages: AgentMessage[]) => {
  const lastUser = [...messages].reverse().find((item) => item.role === "user")?.content ?? "";
  const picked = stripCodexModePrefix(lastUser);
  const cleanedMessages = messages.map((item) => {
    if (item.role !== "user") return item;
    const cleaned = stripCodexModePrefix(item.content);
    return { ...item, content: cleaned.text };
  });
  return {
    mode: picked.mode ?? "chat",
    cleanedMessages,
  };
};

const buildHermesInstructions = (
  payload: RequestPayload,
  userId: string,
  scope: AgentScope,
  maxSteps: number,
) => {
  const attachments = Array.isArray(payload.attachments) ? payload.attachments.slice(0, 12) : [];
  const selectedUids = Array.isArray(payload.context?.selectedUids)
    ? payload.context?.selectedUids.map((item) => String(item)).filter(Boolean).slice(0, 12)
    : [];

  const lines: string[] = [
    "你当前运行在 mnote Web 前端的 Hermes bridge 后面。请始终使用简体中文。",
    "当前前端已经收口为轻桥接层，不要再假设存在旧的前端 builtin registry、toolset 静态映射或 create*ServerTools 编排逻辑。",
    "除非工具结果明确表明已完成写入，否则不要声称已经修改页面、思维导图或 OnlyOffice 文档。",
    "不要把本机终端、文件系统或其他 Hermes 默认工具当成 mnote 业务真执行面。mnote 业务写入应视为独立桥能力。",
    `当前调用用户：${userId}`,
    `当前 scope：${scope}`,
    `本轮最大步数提示：${maxSteps}`,
  ];

  if (payload.context?.documentId) {
    lines.push(`documentId=${String(payload.context.documentId).trim()}`);
  }
  if (payload.context?.mindmapId) {
    lines.push(`mindmapId=${String(payload.context.mindmapId).trim()}`);
  }
  if (selectedUids.length > 0) {
    lines.push(`selectedUids=${selectedUids.join(",")}`);
  }
  if (payload.context?.documentBlocks !== undefined) {
    lines.push(serializeContextSnapshot("documentBlocksSnapshot", payload.context.documentBlocks, 4000) ?? "documentBlocksSnapshot=provided");
  }
  if (payload.context?.node !== undefined) {
    lines.push(serializeContextSnapshot("kernelNode", payload.context.node, 1800) ?? "kernelNode=provided");
  }
  if (payload.context?.subtree !== undefined) {
    lines.push(serializeContextSnapshot("kernelSubtree", payload.context.subtree, 5000) ?? "kernelSubtree=provided");
  }
  if (payload.context?.outline !== undefined) {
    lines.push(serializeContextSnapshot("kernelOutline", payload.context.outline, 2500) ?? "kernelOutline=provided");
  }
  if (payload.context?.evidence !== undefined) {
    lines.push(serializeContextSnapshot("kernelEvidence", payload.context.evidence, 2500) ?? "kernelEvidence=provided");
  }
  if (payload.context?.pageOptions !== undefined) {
    lines.push(
      serializeContextSnapshot(
        "pageOptions",
        payload.context.pageOptions,
        2000,
      ) ?? "pageOptions=provided",
    );
    lines.push(
      serializeContextSnapshot(
        "editorRuntimePageOptions",
        pickLeptosTiptapRuntimePageOptions(payload.context.pageOptions),
        1200,
      ) ?? "editorRuntimePageOptions=provided",
    );
  }
  if (attachments.length > 0) {
    lines.push(
      [
        "attachments:",
        ...attachments.map(
          (item, index) =>
            `${index + 1}. id=${String(item.id)} title=${String(item.title)} mime=${String(item.mimeType ?? "")} url=${String(item.fileUrl)}`,
        ),
      ].join("\n"),
    );
  }

  if (payload.toolChoice?.mode === "manual") {
    const tools = Array.isArray(payload.toolChoice.tools) ? payload.toolChoice.tools.filter(Boolean) : [];
    const toolSets = Array.isArray(payload.toolChoice.toolSets) ? payload.toolChoice.toolSets.filter(Boolean) : [];
    if (tools.length > 0 || toolSets.length > 0) {
      lines.push(
        `前端兼容提示：manual toolChoice tools=[${tools.join(", ")}] toolSets=[${toolSets.join(", ")}]. 这些只是旧前端兼容字段，不代表当前 Hermes 一定具备同名工具。`,
      );
    }
  }

  if (scope === "onlyoffice") {
    lines.push("OnlyOffice 浏览器专属 client capability 仍在单独桥接；若当前后端没有明确写入结果，请直接说明限制，不要伪造选区修改。\n");
  }

  return lines.join("\n\n").trim();
};

const buildHermesInput = (messages: AgentMessage[]) => {
  return messages
    .slice(-50)
    .filter((item) => item.role === "user" || item.role === "assistant")
    .map((item) => ({ role: item.role, content: String(item.content ?? "") }));
};

type PendingHermesToolCall = {
  preview: string;
  argsJson: Record<string, unknown> | null;
};

const recoverStructuredHermesToolResult = async (input: {
  request: Request;
  payload: RequestPayload;
  userId: string;
  client: ReturnType<typeof getAuthedConvexClient> extends Promise<infer T>
    ? T["client"]
    : never;
  tool: string;
  argsJson: Record<string, unknown> | null;
  fallbackRequestId: string;
  fallbackTraceId: string;
}): Promise<unknown | null> => {
  if (!input.argsJson) {
    return null;
  }
  if (
    input.tool !== "slash_run" &&
    input.tool !== "doc_insert_blocks" &&
    input.tool !== "doc_replace_range"
  ) {
    return null;
  }

  const documentId = String(input.payload.context?.documentId ?? "").trim() || null;
  const data =
    input.tool === "slash_run"
      ? { source: "ai-agent-route" }
      : input.payload.context?.documentBlocks ?? null;

  if ((input.tool === "doc_insert_blocks" || input.tool === "doc_replace_range") && data == null) {
    return null;
  }

  return buildDocumentBridgeContext({
    request: input.request,
    workspaceId: null,
  })
    .then((context) =>
      executeRustBridgeTool({
        context: {
          ...context,
          requestId: context.requestId || input.fallbackRequestId,
          traceId: context.traceId || input.fallbackTraceId,
          actor: {
            ...context.actor,
            actorId: input.userId,
          },
        },
        toolName: input.tool,
        invocationKind: "command",
        args: input.argsJson,
        data: (data && typeof data === "object" && !Array.isArray(data) ? data : { data }) as Record<
          string,
          unknown
        >,
        target: documentId
          ? {
              pageId: documentId,
              blockId:
                input.tool === "doc_replace_range"
                  ? String(input.argsJson.blockId ?? "").trim() || null
                  : null,
            }
          : null,
      }),
    )
    .then((result) => result.result)
    .catch(() => null);
};

const streamHermesLegacyEvents = async ({
  messages,
  instructions,
  sessionId,
  request,
  payload,
  userId,
  onEvent,
}: {
  messages: AgentMessage[];
  instructions: string;
  sessionId: string | null;
  request: Request;
  payload: RequestPayload;
  userId: string;
  onEvent: (event: LegacyStreamEvent) => Promise<void> | void;
}) => {
  const input = buildHermesInput(messages);
  const { runId } = await startHermesRun({
    input,
    instructions,
    ...(sessionId ? { session_id: sessionId } : {}),
  });

  const pendingToolIds = new Map<string, string[]>();
  const pendingToolCalls = new Map<string, PendingHermesToolCall>();
  let toolCount = 0;
  let assistantBuffer = "";
  let failureMessage = "";
  let completed = false;

  await streamHermesRunEvents(runId, async (event: HermesRunEvent) => {
    if (event.event === "tool.started") {
      const tool = String(event.tool ?? "").trim() || "unknown_tool";
      const id = `hermes_${runId}_${++toolCount}`;
      const queue = pendingToolIds.get(tool) ?? [];
      queue.push(id);
      pendingToolIds.set(tool, queue);
      const preview = typeof event.preview === "string" ? event.preview : "";
      pendingToolCalls.set(id, {
        preview,
        argsJson: readHermesToolArgsFromEvent(event, tool),
      });
      await onEvent({
        type: "tool_call",
        data: {
          id,
          tool,
          args: preview ? { preview } : {},
        },
      });
      return;
    }

    if (event.event === "tool.completed") {
      const tool = String(event.tool ?? "").trim() || "unknown_tool";
      const queue = pendingToolIds.get(tool) ?? [];
      const id = queue.shift() ?? `hermes_${runId}_${toolCount}`;
      pendingToolIds.set(tool, queue);
      const pendingToolCall = pendingToolCalls.get(id) ?? null;
      pendingToolCalls.delete(id);
      const preview = pendingToolCall?.preview ?? "";
      const duration = Number(event.duration ?? 0);
      const structuredResultFromEvent = !Boolean(event.error) ? readHermesToolResultFromEvent(event) : null;
      const recoveredResult =
        structuredResultFromEvent ??
        (await recoverStructuredHermesToolResult({
          request,
          payload,
          userId,
          tool,
          argsJson: pendingToolCall?.argsJson ?? null,
          fallbackRequestId: makeRunId(),
          fallbackTraceId: makeRunId(),
        }));
      await onEvent({
        type: "tool_result",
        data: {
          id,
          tool,
          ok: !Boolean(event.error),
          ms: Number.isFinite(duration) ? Math.max(0, Math.round(duration * 1000)) : 0,
          result:
            recoveredResult ??
            (preview ? { preview, error: Boolean(event.error) } : { error: Boolean(event.error) }),
        },
      });
      return;
    }

    if (event.event === "message.delta") {
      assistantBuffer += typeof event.delta === "string" ? event.delta : "";
      return;
    }

    if (event.event === "run.failed") {
      failureMessage = String(event.error ?? "Hermes run 失败");
      await onEvent({ type: "error", data: { ok: false, message: failureMessage } });
      completed = true;
      return;
    }

    if (event.event === "run.completed") {
      const fallbackOutput = typeof event.output === "string" ? event.output : "";
      const finalText = (assistantBuffer || fallbackOutput || "（无输出）").trim();
      if (finalText) {
        await onEvent({ type: "assistant_message", data: { text: finalText } });
      }
      await onEvent({
        type: "completion",
        data: { ok: true, text: finalText, steps: Math.max(1, toolCount || 1) },
      });
      completed = true;
    }
  });

  if (!completed && !failureMessage) {
    const finalText = (assistantBuffer || "（无输出）").trim();
    if (finalText) {
      await onEvent({ type: "assistant_message", data: { text: finalText } });
    }
    await onEvent({
      type: "completion",
      data: { ok: true, text: finalText, steps: Math.max(1, toolCount || 1) },
    });
  }
};

const runCodexBridge = async ({
  payload,
  request,
  stream,
}: {
  payload: RequestPayload;
  request: Request;
  stream: boolean;
}) => {
  const { mode, cleanedMessages } = extractCodexModeFromMessages(payload.messages.slice(0, 50));
  const workspaceRoot = await findWorkspaceRoot(process.cwd());
  const sessionIdRaw = String(payload.options?.ai?.sessionId ?? "").trim();
  const requestMode = mode;
  const sys =
    requestMode === "dev"
      ? "你当前处于 #dev 模式：可在工作区内读取/修改文件并执行命令，但只能影响当前工作区。请用简体中文输出。"
      : requestMode === "test"
        ? "你当前处于 #test 模式：只做分析与回答，不要执行命令，不要修改文件，不要伪造工具执行。请用简体中文输出。"
        : "你当前处于 #chat 模式：只聊天，不要执行命令，不要修改文件，不要输出 diff。请用简体中文输出。";

  const buildPrompt = () => {
    if (!sessionIdRaw) {
      return codexMessagesToPrompt([{ role: "system", content: sys }, ...cleanedMessages]);
    }
    const lastUser = [...cleanedMessages].reverse().find((item) => item.role === "user")?.content ?? "";
    const nextUserText = String(lastUser || "").trim();
    if (!nextUserText) {
      return codexMessagesToPrompt([{ role: "system", content: sys }, ...cleanedMessages]);
    }
    return codexMessagesToPrompt([
      { role: "system", content: sys },
      { role: "user", content: nextUserText },
    ]);
  };

  if (!stream) {
    const run = startCodexJsonRun({
      cwd: workspaceRoot,
      sandbox: "workspace-write",
      prompt: buildPrompt(),
      model: null,
      sessionId: sessionIdRaw || null,
    });
    const result = await run.done;
    if (!result.ok) {
      return NextResponse.json({ error: result.error }, { status: 500 });
    }
    return NextResponse.json({
      text: result.text,
      steps: 1,
      events: [],
      sessionId: result.threadId || sessionIdRaw || null,
    });
  }

  const encoder = new TextEncoder();
  let killActiveRun: (() => void) | null = null;
  const body = new ReadableStream<Uint8Array>({
    start(controller) {
      const send = (event: string, data: unknown) => {
        controller.enqueue(encoder.encode(toSseFrame(event, data)));
      };

      const requestId = makeRunId();
      send("ready", { ok: true, requestId });

      let sessionSent = false;
      let assistantSent = false;
      const toolStartAt = new Map<string, number>();

      const stopRun = () => {
        try {
          killActiveRun?.();
        } catch {
          // ignore
        }
      };

      const onAbort = () => {
        stopRun();
      };
      try {
        request.signal?.addEventListener("abort", onAbort, { once: true });
      } catch {
        // ignore
      }

      (async () => {
        const run = startCodexJsonRun({
          cwd: workspaceRoot,
          sandbox: "workspace-write",
          prompt: buildPrompt(),
          model: null,
          sessionId: sessionIdRaw || null,
          onJsonLine: (line) => {
            if (line.type === "thread.started") {
              const sid = String((line as { thread_id?: string }).thread_id ?? "").trim();
              if (sid && !sessionSent) {
                sessionSent = true;
                send("codex_session", { sessionId: sid });
              }
              return;
            }

            if (line.type === "item.started" && (line as { item?: { type?: string; id?: string; command?: string } }).item?.type === "command_execution") {
              const item = (line as { item?: { type?: string; id?: string; command?: string } }).item;
              const id = String(item?.id ?? "").trim();
              const command = String(item?.command ?? "");
              if (!id) return;
              toolStartAt.set(id, Date.now());
              send("tool_call", { id, tool: "codex_command", args: { command } });
              return;
            }

            if (line.type === "item.completed" && (line as { item?: { type?: string; id?: string; exit_code?: number; aggregated_output?: string } }).item?.type === "command_execution") {
              const item = (line as { item?: { type?: string; id?: string; exit_code?: number; aggregated_output?: string } }).item;
              const id = String(item?.id ?? "").trim();
              if (!id) return;
              const startedAt = toolStartAt.get(id) ?? Date.now();
              const ms = Math.max(0, Date.now() - startedAt);
              const exitCode = Number(item?.exit_code ?? 0);
              send("tool_result", {
                id,
                tool: "codex_command",
                ok: exitCode === 0,
                ms,
                result: {
                  exitCode,
                  output: String(item?.aggregated_output ?? ""),
                },
              });
              return;
            }

            if (line.type === "item.completed" && (line as { item?: { type?: string; text?: string } }).item?.type === "agent_message") {
              const item = (line as { item?: { type?: string; text?: string } }).item;
              const text = String(item?.text ?? "").trim();
              if (text) {
                assistantSent = true;
                send("assistant_message", { text });
              }
            }
          },
        });
        killActiveRun = run.kill;

        const result = await run.done;
        if (!result.ok) {
          send("error", { ok: false, message: result.error });
          return;
        }

        if (result.threadId && !sessionSent) {
          sessionSent = true;
          send("codex_session", { sessionId: result.threadId });
        }
        if (!assistantSent && result.text) {
          assistantSent = true;
          send("assistant_message", { text: result.text });
        }
        send("completion", { ok: true, text: result.text, steps: 1 });
      })()
        .catch((error) => {
          const message = error instanceof Error ? error.message : String(error);
          send("error", { ok: false, message });
        })
        .finally(() => {
          try {
            request.signal?.removeEventListener("abort", onAbort);
          } catch {
            // ignore
          }
          stopRun();
          controller.close();
        });
    },
    cancel() {
      try {
        killActiveRun?.();
      } catch {
        // ignore
      }
    },
  });

  return new Response(body, { headers: sseHeaders });
};

export async function POST(request: Request) {
  const payload = await safeGetJsonBody<RequestPayload>(request);
  if (!payload) {
    return errorResponses.badRequest("请求体不能为空");
  }
  const validationError = validateRequestBody(payload, ["messages"] as const);
  if (validationError) return validationError;
  if (!Array.isArray(payload.messages) || payload.messages.length === 0) {
    return errorResponses.badRequest("缺少 messages");
  }

  let userId = "";
  if (isConvexEnabled()) {
    const { auth } = await getAuthedConvexClient();
    userId = auth.userId ?? "";
  }
  if (!userId) {
    return errorResponses.unauthorized();
  }

  const stream = payload.stream !== false;
  const scope = normalizeScope(payload);
  const provider = normalizeProvider(payload.options?.ai?.provider, scope, stream);
  if (provider === "codex") {
    return await runCodexBridge({ payload, request, stream });
  }

  if (provider === "agents") {
    try {
      const upstream = await startDocumentAiOrchestratorRun({
        request,
        userId,
        payload,
      });
      return proxySseResponse(upstream);
    } catch (error) {
      console.warn(
        "document ai orchestrator 不可用，回退 Hermes",
        error instanceof Error ? error.message : String(error),
      );
    }
  }

  const maxSteps = clampSteps(payload.maxSteps);
  const instructions = buildHermesInstructions(payload, userId, scope, maxSteps);
  const sessionId = String(payload.options?.ai?.sessionId ?? "").trim() || null;

  if (!stream) {
    const events: LegacyStreamEvent[] = [];
    await streamHermesLegacyEvents({
      messages: payload.messages,
      instructions,
      sessionId,
      request,
      payload,
      userId,
      onEvent: (event) => {
        events.push(event);
      },
    }).catch((error) => {
      throw error instanceof Error ? error : new Error(String(error));
    });

    const completion = [...events].reverse().find((event) => event.type === "completion") as Extract<LegacyStreamEvent, { type: "completion" }> | undefined;
    const assistant = [...events].reverse().find((event) => event.type === "assistant_message") as Extract<LegacyStreamEvent, { type: "assistant_message" }> | undefined;
    return NextResponse.json({
      text: completion?.data.text ?? assistant?.data.text ?? "",
      steps: completion?.data.steps ?? Math.max(1, events.filter((event) => event.type === "tool_call").length || 1),
      events,
    });
  }

  const encoder = new TextEncoder();
  const body = new ReadableStream<Uint8Array>({
    start(controller) {
      const send = (event: string, data: unknown) => {
        controller.enqueue(encoder.encode(toSseFrame(event, data)));
      };

      send("ready", { ok: true, requestId: makeRunId() });

      const ping = setInterval(() => {
        try {
          controller.enqueue(encoder.encode(`: ping ${Date.now()}\n\n`));
        } catch {
          // ignore
        }
      }, 15_000);

      (async () => {
        await streamHermesLegacyEvents({
          messages: payload.messages,
          instructions,
          sessionId,
          request,
          payload,
          userId,
          onEvent: (event) => {
            send(event.type, event.data ?? null);
          },
        });
      })()
        .catch((error) => {
          const message = error instanceof Error ? error.message : String(error);
          send("error", { ok: false, message });
        })
        .finally(() => {
          clearInterval(ping);
          controller.close();
        });
    },
  });

  return new Response(body, { headers: sseHeaders });
}
