Compare commits

...

3 Commits

Author SHA1 Message Date
diegosouzapw 1d7bc5fed7 feat: add /v1/completions legacy endpoint + show all 3 OpenAI endpoints in dashboard
Build Electron Desktop App / Validate version (push) Failing after 38s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
- New route /v1/completions: accepts prompt string (legacy) + messages array
  Normalizes prompt format to chat/completions format automatically
- EndpointPageClient: Added 3rd card (Completions Legacy) in Core APIs section
  Dashboard now shows: /v1/chat/completions, /v1/responses, /v1/completions
- i18n: completionsLegacy/completionsLegacyDesc synced to 30 languages
2026-03-12 12:57:31 -03:00
diegosouzapw 763fdf3135 chore: release v2.3.8 — OAuthModal [object Object] fix
Build Electron Desktop App / Validate version (push) Failing after 39s
Build Electron Desktop App / Build Electron (macos-arm64) (push) Has been skipped
Build Electron Desktop App / Build Electron (linux) (push) Has been skipped
Build Electron Desktop App / Build Electron (macos-intel) (push) Has been skipped
Build Electron Desktop App / Build Electron (windows) (push) Has been skipped
Build Electron Desktop App / Create Release (push) Has been skipped
2026-03-12 12:42:40 -03:00
diegosouzapw 82314562e7 fix: OAuthModal [object Object] - extract message from error objects
All 3 throw new Error(data.error) replaced with proper extraction:
  typeof error === object ? error.message : error
Fixes Cline and other OAuth providers showing [object Object] on connection failure
2026-03-12 12:39:42 -03:00
35 changed files with 245 additions and 34 deletions
+15
View File
@@ -1,5 +1,20 @@
# Changelog
## [2.3.8] - 2026-03-12
## [2.3.9] - 2026-03-12
### Added
- **/v1/completions**: New legacy OpenAI completions endpoint — accepts both `prompt` string and `messages` array, normalizes to chat format automatically
- **EndpointPage**: Now shows all 3 OpenAI-compatible endpoint types: Chat Completions, Responses API, and Legacy Completions
- **i18n**: Added `completionsLegacy/completionsLegacyDesc` to 30 language files
### Fixed
- **OAuthModal**: Fix `[object Object]` displayed on all OAuth connection errors — properly extract `.message` from error response objects in all 3 `throw new Error(data.error)` calls (exchange, device-code, authorize)
- Affects Cline, Codex, GitHub, Qwen, Kiro, and all other OAuth providers
## [2.3.7] - 2026-03-12
### Fixed
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "omniroute",
"version": "2.3.7",
"version": "2.3.9",
"description": "Smart AI Router with auto fallback — route to FREE & cheap models, zero downtime. Works with Cursor, Cline, Claude Desktop, Codex, and any OpenAI-compatible tool.",
"type": "module",
"bin": {
@@ -446,6 +446,27 @@ export default function APIPageClient({ machineId }) {
copied={copied}
baseUrl={currentEndpoint}
/>
{/* Legacy Completions */}
<EndpointSection
icon="text_fields"
iconColor="text-orange-500"
iconBg="bg-orange-500/10"
title={t("completionsLegacy") || "Completions (Legacy)"}
path="/v1/completions"
description={
t("completionsLegacyDesc") ||
"Legacy OpenAI text completions — accepts both prompt and messages format"
}
models={endpointData.chat}
expanded={expandedEndpoint === "completions"}
onToggle={() =>
setExpandedEndpoint(expandedEndpoint === "completions" ? null : "completions")
}
copy={copy}
copied={copied}
baseUrl={currentEndpoint}
/>
</div>
</div>
+97
View File
@@ -0,0 +1,97 @@
import { CORS_ORIGIN, CORS_HEADERS } from "@/shared/utils/cors";
import { handleChat } from "@/sse/handlers/chat";
import { initTranslators } from "@omniroute/open-sse/translator/index.ts";
import { createInjectionGuard } from "@/middleware/promptInjectionGuard";
let initPromise = null;
const injectionGuard = createInjectionGuard();
function ensureInitialized() {
if (!initPromise) {
initPromise = Promise.resolve(initTranslators()).then(() => {
console.log("[SSE] Translators initialized");
});
}
return initPromise;
}
/**
* Handle CORS preflight
*/
export async function OPTIONS() {
return new Response(null, {
headers: {
"Access-Control-Allow-Origin": CORS_ORIGIN,
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "*",
},
});
}
/**
* POST /v1/completions — Legacy OpenAI Completions API
*
* Accepts both the modern chat format (messages[]) and the legacy
* text-completions format (prompt string). Legacy requests are
* automatically normalized to chat/completions format before routing.
*
* @see https://platform.openai.com/docs/api-reference/completions
*/
export async function POST(request: Request) {
await ensureInitialized();
// Prompt injection guard
try {
const cloned = request.clone();
const body = await cloned.json().catch(() => null);
if (body) {
const { blocked, result } = injectionGuard(body);
if (blocked) {
return new Response(
JSON.stringify({
error: {
message: "Request blocked: potential prompt injection detected",
type: "injection_detected",
code: "SECURITY_001",
detections: result.detections.length,
},
}),
{ status: 400, headers: { ...CORS_HEADERS, "Content-Type": "application/json" } }
);
}
// Normalize legacy completions format: { prompt, model } → { messages, model }
// If the body has `prompt` but no `messages`, convert to chat format.
if (body.prompt !== undefined && !body.messages) {
const prompt = Array.isArray(body.prompt) ? body.prompt.join("\n") : String(body.prompt);
const normalized = {
...body,
messages: [{ role: "user", content: prompt }],
};
delete normalized.prompt;
const newRequest = new Request(request.url, {
method: request.method,
headers: request.headers,
body: JSON.stringify(normalized),
});
return await handleChat(newRequest);
}
}
} catch (error) {
console.error("[SECURITY] Prompt injection guard failed:", error);
return new Response(
JSON.stringify({
error: {
message: "Security validation temporarily unavailable",
type: "security_guard_unavailable",
code: "SECURITY_002",
},
}),
{ status: 503, headers: { ...CORS_HEADERS, "Content-Type": "application/json" } }
);
}
// Standard path: body already has messages[] (chat format)
return await handleChat(request);
}
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "البدء السريع",
"a2aQuickStartStep1": "اكتشف بطاقة الوكيل على `/.well-known/agent.json`.",
"a2aQuickStartStep2": "إرسال طلبات JSON - RPC إلى@@ PH0 @@ باستخدام @@PH1 @@ أو `message/stream`.",
"a2aQuickStartStep3": "تتبع المهام والتحكم فيها باستخدام `tasks/get` و `tasks/cancel`."
"a2aQuickStartStep3": "تتبع المهام والتحكم فيها باستخدام `tasks/get` و `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "جارٍ تحميل لوحة تحكم MCP...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "Button text: start playing a game",
"a2aQuickStartStep1": "Открийте картата на агента на @@PH0 @@.",
"a2aQuickStartStep2": "Изпратете JSON - RPC заявки до@@ PH0 @@, като използвате @@ PH1 @@ или @@ PH2 @@.",
"a2aQuickStartStep3": "Проследяване и контрол на задачите с помощта на @@ PH0 @@ и @@ PH1 @@."
"a2aQuickStartStep3": "Проследяване и контрол на задачите с помощта на @@ PH0 @@ и @@ PH1 @@.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Зареждане на таблото за управление на MCP...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "Hurtig start",
"a2aQuickStartStep1": "Find agentkortet på`/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC-anmodninger til`POST /a2a`vedhjælp af `message/send` eller `message/stream`.",
"a2aQuickStartStep3": "Spor og kontroller opgaver ved hjælp af `tasks/get` og `tasks/cancel`."
"a2aQuickStartStep3": "Spor og kontroller opgaver ved hjælp af `tasks/get` og `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Indlæser MCP-dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A-Schnellstart",
"a2aQuickStartStep1": "Entdecken Sie die Agentenkarte unter `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Senden Sie JSON-RPC-Anfragen an `POST /a2a` mit `message/send` oder `message/stream`.",
"a2aQuickStartStep3": "Verfolgen und steuern Sie Aufgaben mit `tasks/get` und `tasks/cancel`."
"a2aQuickStartStep3": "Verfolgen und steuern Sie Aufgaben mit `tasks/get` und `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "MCP-Dashboard wird geladen...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "Inicio rápido de A2A",
"a2aQuickStartStep1": "Descubra la tarjeta de agente en `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Envíe solicitudes JSON-RPC a `POST /a2a` usando `message/send` o `message/stream`.",
"a2aQuickStartStep3": "Realice un seguimiento y controle las tareas utilizando `tasks/get` y `tasks/cancel`."
"a2aQuickStartStep3": "Realice un seguimiento y controle las tareas utilizando `tasks/get` y `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Cargando el panel de MCP...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Pikaopas",
"a2aQuickStartStep1": "Tutustu agenttikorttiin osoitteessa `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Lähetä JSON-RPC-pyynnöt osoitteeseen `POST /a2a` käyttämällä `message/send` tai `message/stream`.",
"a2aQuickStartStep3": "Seuraa ja ohjaa tehtäviä käyttämällä `tasks/get` ja `tasks/cancel`."
"a2aQuickStartStep3": "Seuraa ja ohjaa tehtäviä käyttämällä `tasks/get` ja `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Ladataan MCP-hallintapaneelia...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "Démarrage rapide A2A",
"a2aQuickStartStep1": "Découvrez la carte d'agent sur `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Envoyez des requêtes JSON-RPC à `POST /a2a` en utilisant `message/send` ou `message/stream`.",
"a2aQuickStartStep3": "Suivez et contrôlez les tâches à laide de `tasks/get` et `tasks/cancel`."
"a2aQuickStartStep3": "Suivez et contrôlez les tâches à laide de `tasks/get` et `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Chargement du tableau de bord MCP...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Kövesse nyomon és vezérelje a feladatokat a `tasks/get` és `tasks/cancel` használatával."
"a2aQuickStartStep3": "Kövesse nyomon és vezérelje a feladatokat a `tasks/get` és `tasks/cancel` használatával.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Mula Pantas",
"a2aQuickStartStep1": "Temui kad ejen di `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Hantar permintaan JSON-RPC ke `POST /a2a` menggunakan `message/send` atau `message/stream`.",
"a2aQuickStartStep3": "Jejak dan kawal tugas menggunakan `tasks/get` dan `tasks/cancel`."
"a2aQuickStartStep3": "Jejak dan kawal tugas menggunakan `tasks/get` dan `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A hurtigstart",
"a2aQuickStartStep1": "Oppdag agentkortet på `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC-forespørsler til `POST /a2a` ved å bruke `message/send` eller `message/stream`.",
"a2aQuickStartStep3": "Spor og kontroller oppgaver ved å bruke `tasks/get` og `tasks/cancel`."
"a2aQuickStartStep3": "Spor og kontroller oppgaver ved å bruke `tasks/get` og `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Laster inn MCP-dashbordet ...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Subaybayan at kontrolin ang mga gawain gamit ang `tasks/get` at `tasks/cancel`."
"a2aQuickStartStep3": "Subaybayan at kontrolin ang mga gawain gamit ang `tasks/get` at `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Nilo-load ang MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Início rápido",
"a2aQuickStartStep1": "Descubra o agent card em `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Envie requisições JSON-RPC para `POST /a2a` usando `message/send` ou `message/stream`.",
"a2aQuickStartStep3": "Acompanhe e controle tarefas com `tasks/get` e `tasks/cancel`."
"a2aQuickStartStep3": "Acompanhe e controle tarefas com `tasks/get` e `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Carregando painel MCP...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"endpoints": {
"tabProxy": "Endpoint Proxy",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+3 -1
View File
@@ -858,7 +858,9 @@
"a2aQuickStartTitle": "A2A Quick Start",
"a2aQuickStartStep1": "Discover the agent card at `/.well-known/agent.json`.",
"a2aQuickStartStep2": "Send JSON-RPC requests to `POST /a2a` using `message/send` or `message/stream`.",
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`."
"a2aQuickStartStep3": "Track and control tasks using `tasks/get` and `tasks/cancel`.",
"completionsLegacy": "Completions (Legacy)",
"completionsLegacyDesc": "Legacy OpenAI text completions — accepts both prompt string and messages array format"
},
"mcpDashboard": {
"loading": "Loading MCP dashboard...",
+21 -3
View File
@@ -87,7 +87,13 @@ export default function OAuthModal({
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
if (!res.ok) {
const errMsg =
typeof data.error === "object" && data.error !== null
? (data.error as any).message || JSON.stringify(data.error)
: data.error || "Exchange failed";
throw new Error(errMsg);
}
setStep("success");
onSuccess?.();
@@ -180,7 +186,13 @@ export default function OAuthModal({
const res = await fetch(`/api/oauth/${provider}/device-code`);
const data = await res.json();
if (!res.ok) throw new Error(data.error);
if (!res.ok) {
const errMsg =
typeof data.error === "object" && data.error !== null
? (data.error as any).message || JSON.stringify(data.error)
: data.error || "Request failed";
throw new Error(errMsg);
}
setDeviceData(data);
@@ -281,7 +293,13 @@ export default function OAuthModal({
`/api/oauth/${provider}/authorize?redirect_uri=${encodeURIComponent(redirectUri)}`
);
const data = await res.json();
if (!res.ok) throw new Error(data.error);
if (!res.ok) {
const errMsg =
typeof data.error === "object" && data.error !== null
? (data.error as any).message || JSON.stringify(data.error)
: data.error || "Authorization failed";
throw new Error(errMsg);
}
setAuthData({ ...data, redirectUri });