{title}
diff --git a/src/app/(dashboard)/dashboard/translator/components/ChatTesterMode.tsx b/src/app/(dashboard)/dashboard/translator/components/ChatTesterMode.tsx deleted file mode 100644 index 205783b0af..0000000000 --- a/src/app/(dashboard)/dashboard/translator/components/ChatTesterMode.tsx +++ /dev/null @@ -1,543 +0,0 @@ -"use client"; - -import { useTranslations } from "next-intl"; - -import { useState, useEffect, useRef } from "react"; -import { Card, Button, Select, Badge } from "@/shared/components"; -import { FORMAT_META, FORMAT_OPTIONS } from "../exampleTemplates"; -import { useProviderOptions } from "../hooks/useProviderOptions"; -import { useAvailableModels } from "../hooks/useAvailableModels"; -import Editor from "@/shared/components/MonacoEditor"; - -/** - * Chat Tester Mode: - * - Left: Chat interface (send messages as a specific client format) - * - Right: {t("pipelineVisualization")} showing each translation step - * - * How it works: - * 1. You type a message and select a "Client Format" (how the request is structured) - * 2. The message is built into a request body matching the client format - * 3. OmniRoute detects the format, translates it through the pipeline, and sends to the provider - * 4. Each pipeline step is shown on the right: Client → Detect → OpenAI → Provider → Response - */ - -export default function ChatTesterMode() { - const t = useTranslations("translator"); - const { provider, setProvider, providerOptions } = useProviderOptions("openai"); - const { model, setModel, availableModels, pickModelForFormat } = useAvailableModels(); - const [clientFormat, setClientFormat] = useState("openai"); - const [message, setMessage] = useState(""); - const [sending, setSending] = useState(false); - const [chatHistory, setChatHistory] = useState([]); - const [pipeline, setPipeline] = useState(null); - const [expandedStep, setExpandedStep] = useState(null); - const messagesEndRef = useRef(null); - - // Pick a smart default model when format changes or models finish loading - useEffect(() => { - const picked = pickModelForFormat(clientFormat); - if (picked) setModel(picked); - }, [clientFormat, pickModelForFormat, setModel]); - - const scrollToBottom = () => { - messagesEndRef.current?.scrollIntoView({ behavior: "smooth" }); - }; - - const handleSend = async () => { - if (!message.trim() || sending) return; - - const userMessage = message.trim(); - setMessage(""); - setSending(true); - setChatHistory((prev) => [...prev, { role: "user", content: userMessage }]); - - const steps = []; - - try { - // Build the messages array - const allMessages = [ - ...chatHistory.map((m) => ({ role: m.role, content: m.content })), - { role: "user", content: userMessage }, - ]; - - // Step 1: Build client request in the chosen format - let clientRequest; - if (clientFormat === "claude") { - clientRequest = { - model, - max_tokens: 1024, - messages: allMessages, - stream: true, - }; - } else if (clientFormat === "gemini") { - clientRequest = { - model, - contents: allMessages.map((m) => ({ - role: m.role === "assistant" ? "model" : "user", - parts: [{ text: m.content }], - })), - }; - } else if (clientFormat === "antigravity") { - clientRequest = { - request: { - contents: allMessages.map((m) => ({ - role: m.role === "assistant" ? "model" : "user", - parts: [{ text: m.content }], - })), - }, - model, - userAgent: "antigravity", - }; - } else if (clientFormat === "openai-responses") { - clientRequest = { - model, - input: allMessages.map((m) => ({ - type: "message", - role: m.role, - content: [{ type: "input_text", text: m.content }], - })), - stream: true, - }; - } else if (clientFormat === "cursor" || clientFormat === "kiro") { - clientRequest = { - model, - messages: allMessages, - stream: true, - }; - } else { - clientRequest = { - model, - messages: allMessages, - stream: true, - }; - } - - steps.push({ - id: 1, - name: t("clientRequest"), - description: t("clientRequestDescription"), - format: clientFormat, - content: JSON.stringify(clientRequest, null, 2), - status: "done", - }); - - // Step 2: Detect source format - const detectRes = await fetch("/api/translator/detect", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ body: clientRequest }), - }); - const detectData = await detectRes.json(); - const detectedFormat = detectData.format || clientFormat; - - steps.push({ - id: 2, - name: t("formatDetected"), - description: t("formatDetectedDescription"), - format: detectedFormat, - content: JSON.stringify( - { detectedFormat, clientFormat, match: detectedFormat === clientFormat }, - null, - 2 - ), - status: "done", - }); - - // Step 3: Translate to OpenAI intermediate - const toOpenaiRes = await fetch("/api/translator/translate", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - step: "direct", - sourceFormat: detectedFormat, - targetFormat: "openai", - body: clientRequest, - }), - }); - const toOpenaiData = await toOpenaiRes.json(); - - steps.push({ - id: 3, - name: t("openaiIntermediate"), - description: t("openaiIntermediateDescription"), - format: "openai", - content: JSON.stringify(toOpenaiData.result || toOpenaiData, null, 2), - status: toOpenaiData.success ? "done" : "error", - }); - - // Step 4: Translate to provider target format - const providerTargetRes = await fetch("/api/translator/translate", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ - step: "direct", - sourceFormat: "openai", - provider, - body: toOpenaiData.result, - }), - }); - const providerTargetData = await providerTargetRes.json(); - const targetFmt = providerTargetData.targetFormat || "openai"; - - steps.push({ - id: 4, - name: t("providerFormat"), - description: t("providerFormatDescription"), - format: targetFmt, - content: JSON.stringify(providerTargetData.result || providerTargetData, null, 2), - status: providerTargetData.success ? "done" : "error", - }); - - // Step 5: Send to provider - const sendRes = await fetch("/api/translator/send", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ provider, body: providerTargetData.result || toOpenaiData.result }), - }); - - if (!sendRes.ok) { - const errData = await sendRes.json().catch(() => ({ error: t("requestFailed") })); - steps.push({ - id: 5, - name: t("providerResponse"), - description: t("providerResponseRawDescription"), - format: targetFmt, - content: JSON.stringify(errData, null, 2), - status: "error", - }); - setChatHistory((prev) => [ - ...prev, - { - role: "assistant", - content: t("errorMessage", { message: errData.error || t("requestFailed") }), - }, - ]); - } else { - // Read streaming response - const reader = sendRes.body.getReader(); - const decoder = new TextDecoder(); - let fullResponse = ""; - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - fullResponse += decoder.decode(value, { stream: true }); - } - - steps.push({ - id: 5, - name: t("providerResponse"), - description: t("providerResponseSseDescription"), - format: targetFmt, - content: - fullResponse.slice(0, 5000) + (fullResponse.length > 5000 ? "\n... (truncated)" : ""), - status: "done", - }); - - // Extract assistant text from SSE - const assistantText = extractAssistantText(fullResponse); - setChatHistory((prev) => [ - ...prev, - { role: "assistant", content: assistantText || t("noTextExtracted") }, - ]); - } - } catch (err) { - steps.push({ - id: steps.length + 1, - name: t("error"), - description: t("unexpectedError"), - format: "error", - content: JSON.stringify({ error: err.message }, null, 2), - status: "error", - }); - setChatHistory((prev) => [ - ...prev, - { role: "assistant", content: t("errorMessage", { message: err.message }) }, - ]); - } - - setPipeline(steps); - setExpandedStep(steps.length > 0 ? steps[steps.length - 1].id : null); - setSending(false); - setTimeout(scrollToBottom, 100); - }; - - return ( -{t("pipelineDebugger")}
-{t("chatTesterDescription")}
-- {t("chatTesterFlow")}.{" "} - {t("clickStepToInspect")} -
-{t("sendMessageToSeePipeline")}
-- {t("chatMessageHintPrefix")} {FORMAT_META[clientFormat]?.label}{" "} - {t("chatMessageHintSuffix")} -
-- {msg.role === "user" - ? t("youWithFormat", { format: FORMAT_META[clientFormat]?.label }) - : t("assistant")} -
-{msg.content}
-{t("clickStepToInspect")}
-{t("pipelineVisualization")}
-{t("pipelineVisualizationHint")}
-{t("realtime")}
-- {t("liveMonitorDescriptionPrefix")}{" "} - {t("chatTester")},{" "} - {t("testBench")} - {t("liveMonitorDescriptionSuffix")} -
-- {t("liveMonitorMemoryNote")}{" "} - {t("liveMonitorMemoryCapNote")} -
-{t("noTranslations")}
-{t("eventsAppearHint")}
-- {t("eventSourcesLabel")} -
-{t("inMemoryNote")}
-| {t("time")} | -{translateOrFallback("routeDetails", "Route")} | -{t("source")} | -{t("target")} | -{t("model")} | -{t("status")} | -{t("latency")} | -
|---|---|---|---|---|---|---|
| - {event.timestamp - ? new Date(event.timestamp).toLocaleTimeString() - : notAvailable} - | -
-
-
-
-
-
-
- {translateOrFallback("routeEndpointLabel", "Endpoint")}:{" "}
- {event.routeEndpoint || event.endpoint || notAvailable}
-
- {event.routeConnectionShortId ? (
-
- {translateOrFallback("routeConnectionLabel", "Conn")}:{" "}
- {event.routeConnectionShortId}
-
- ) : null}
-
- |
-
- |
-
- |
- - {event.model || notAvailable} - | -
- {event.status === "success" ? (
- |
- - {event.latency ? formatLatency(event.latency) : notAvailable} - | -
{value}
-{label}
-{t("formatConverter")}
-{t("formatConverterDescription")}
-- {translateOrFallback("streamTransformerTitle", "Responses Stream Transformer")} -
-- {translateOrFallback( - "streamTransformerDescription", - "Paste a chat completions SSE stream, run it through OmniRoute's Responses transformer, and inspect the emitted response.* events before wiring a client." - )} -
-
- {transformedSse || translateOrFallback("noResultsYet", "No results yet")}
-
- - {translateOrFallback( - "transformerTimelineHint", - "Run the transformer to inspect emitted response.output_* events in order." - )} -
- ) : ( -| # | -{translateOrFallback("eventType", "Event type")} | -{translateOrFallback("eventPreview", "Preview")} | -
|---|---|---|
| {index + 1} | -{frame.event} | -{frame.preview} | -
{value}
-{label}
-{t("compatibilityTester")}
-{t("testBenchDescription")}
-- {scenarioLabels[scenario.id] || scenario.id} -
-- {srcMeta.label} →{" "} - {providerOptions.find((o) => o.value === provider)?.label || provider} -
-❌ {result.error}
-{result.latency}ms
-