From 190c1dc3c8e99049dd58fe08b2428d73bde91b35 Mon Sep 17 00:00:00 2001 From: 1445043649 <> Date: Sun, 28 Jun 2026 20:07:20 +0800 Subject: [PATCH] feat(frontend): migrate API calls to /api/v1 (Stage 1 PR5) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/app/api/memory/[...path]/route.ts | 20 +++++++++++++++---- frontend/src/app/api/memory/route.ts | 4 ++-- .../src/components/workspace/input-box.tsx | 2 +- frontend/src/core/agents/api.ts | 12 +++++------ frontend/src/core/api/feedback.ts | 4 ++-- frontend/src/core/artifacts/utils.ts | 4 ++-- frontend/src/core/mcp/api.ts | 4 ++-- frontend/src/core/memory/api.ts | 14 ++++++------- frontend/src/core/models/api.ts | 2 +- frontend/src/core/skills/api.ts | 6 +++--- frontend/src/core/threads/hooks.ts | 4 ++-- frontend/src/core/uploads/api.ts | 6 +++--- 12 files changed, 47 insertions(+), 35 deletions(-) diff --git a/frontend/src/app/api/memory/[...path]/route.ts b/frontend/src/app/api/memory/[...path]/route.ts index 8de48d74..dda5664d 100644 --- a/frontend/src/app/api/memory/[...path]/route.ts +++ b/frontend/src/app/api/memory/[...path]/route.ts @@ -30,26 +30,38 @@ export async function GET( request: NextRequest, { params }: { params: Promise<{ path: string[] }> }, ) { - return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`); + return proxyRequest( + request, + `/api/v1/memory/${(await params).path.join("/")}`, + ); } export async function POST( request: NextRequest, { params }: { params: Promise<{ path: string[] }> }, ) { - return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`); + return proxyRequest( + request, + `/api/v1/memory/${(await params).path.join("/")}`, + ); } export async function DELETE( request: NextRequest, { params }: { params: Promise<{ path: string[] }> }, ) { - return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`); + return proxyRequest( + request, + `/api/v1/memory/${(await params).path.join("/")}`, + ); } export async function PATCH( request: NextRequest, { params }: { params: Promise<{ path: string[] }> }, ) { - return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`); + return proxyRequest( + request, + `/api/v1/memory/${(await params).path.join("/")}`, + ); } diff --git a/frontend/src/app/api/memory/route.ts b/frontend/src/app/api/memory/route.ts index 2957c69c..2df00592 100644 --- a/frontend/src/app/api/memory/route.ts +++ b/frontend/src/app/api/memory/route.ts @@ -27,9 +27,9 @@ async function proxyRequest(request: NextRequest, pathname: string) { } export async function GET(request: NextRequest) { - return proxyRequest(request, "/api/memory"); + return proxyRequest(request, "/api/v1/memory"); } export async function DELETE(request: NextRequest) { - return proxyRequest(request, "/api/memory"); + return proxyRequest(request, "/api/v1/memory"); } diff --git a/frontend/src/components/workspace/input-box.tsx b/frontend/src/components/workspace/input-box.tsx index a5da4e0e..f260013a 100644 --- a/frontend/src/components/workspace/input-box.tsx +++ b/frontend/src/components/workspace/input-box.tsx @@ -408,7 +408,7 @@ export function InputBox({ setFollowupsLoading(true); setFollowups([]); - fetch(`${getBackendBaseURL()}/api/threads/${threadId}/suggestions`, { + fetch(`${getBackendBaseURL()}/api/v1/threads/${threadId}/suggestions`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ diff --git a/frontend/src/core/agents/api.ts b/frontend/src/core/agents/api.ts index 5cfc4046..cbf27d8e 100644 --- a/frontend/src/core/agents/api.ts +++ b/frontend/src/core/agents/api.ts @@ -27,20 +27,20 @@ function isAgentsApiDisabledDetail(detail: string | undefined): boolean { } export async function listAgents(): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/agents`); + const res = await fetch(`${getBackendBaseURL()}/api/v1/agents`); if (!res.ok) throw new Error(`Failed to load agents: ${res.statusText}`); const data = (await res.json()) as { agents: Agent[] }; return data.agents; } export async function getAgent(name: string): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`); + const res = await fetch(`${getBackendBaseURL()}/api/v1/agents/${name}`); if (!res.ok) throw new Error(`Agent '${name}' not found`); return res.json() as Promise; } export async function createAgent(request: CreateAgentRequest): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/agents`, { + const res = await fetch(`${getBackendBaseURL()}/api/v1/agents`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(request), @@ -59,7 +59,7 @@ export async function updateAgent( name: string, request: UpdateAgentRequest, ): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { + const res = await fetch(`${getBackendBaseURL()}/api/v1/agents/${name}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(request), @@ -72,7 +72,7 @@ export async function updateAgent( } export async function deleteAgent(name: string): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { + const res = await fetch(`${getBackendBaseURL()}/api/v1/agents/${name}`, { method: "DELETE", }); if (!res.ok) throw new Error(`Failed to delete agent: ${res.statusText}`); @@ -84,7 +84,7 @@ export async function checkAgentName( let res: Response; try { res = await fetch( - `${getBackendBaseURL()}/api/agents/check?name=${encodeURIComponent(name)}`, + `${getBackendBaseURL()}/api/v1/agents/check?name=${encodeURIComponent(name)}`, ); } catch { throw new AgentNameCheckError( diff --git a/frontend/src/core/api/feedback.ts b/frontend/src/core/api/feedback.ts index bc6021d9..9b7be725 100644 --- a/frontend/src/core/api/feedback.ts +++ b/frontend/src/core/api/feedback.ts @@ -15,7 +15,7 @@ export async function upsertFeedback( comment?: string, ): Promise { const res = await fetch( - `${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}/runs/${encodeURIComponent(runId)}/feedback`, + `${getBackendBaseURL()}/api/v1/threads/${encodeURIComponent(threadId)}/runs/${encodeURIComponent(runId)}/feedback`, { method: "PUT", headers: { "Content-Type": "application/json" }, @@ -33,7 +33,7 @@ export async function deleteFeedback( runId: string, ): Promise { const res = await fetch( - `${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}/runs/${encodeURIComponent(runId)}/feedback`, + `${getBackendBaseURL()}/api/v1/threads/${encodeURIComponent(threadId)}/runs/${encodeURIComponent(runId)}/feedback`, { method: "DELETE" }, ); if (!res.ok && res.status !== 404) { diff --git a/frontend/src/core/artifacts/utils.ts b/frontend/src/core/artifacts/utils.ts index 40269650..a0f1f1d8 100644 --- a/frontend/src/core/artifacts/utils.ts +++ b/frontend/src/core/artifacts/utils.ts @@ -15,7 +15,7 @@ export function urlOfArtifact({ if (isMock) { return `${getBackendBaseURL()}/mock/api/threads/${threadId}/artifacts${filepath}${download ? "?download=true" : ""}`; } - return `${getBackendBaseURL()}/api/threads/${threadId}/artifacts${filepath}${download ? "?download=true" : ""}`; + return `${getBackendBaseURL()}/api/v1/threads/${threadId}/artifacts${filepath}${download ? "?download=true" : ""}`; } export function extractArtifactsFromThread(thread: AgentThread) { @@ -23,5 +23,5 @@ export function extractArtifactsFromThread(thread: AgentThread) { } export function resolveArtifactURL(absolutePath: string, threadId: string) { - return `${getBackendBaseURL()}/api/threads/${threadId}/artifacts${absolutePath}`; + return `${getBackendBaseURL()}/api/v1/threads/${threadId}/artifacts${absolutePath}`; } diff --git a/frontend/src/core/mcp/api.ts b/frontend/src/core/mcp/api.ts index 284c9fd2..d89dda8c 100644 --- a/frontend/src/core/mcp/api.ts +++ b/frontend/src/core/mcp/api.ts @@ -4,12 +4,12 @@ import { getBackendBaseURL } from "@/core/config"; import type { MCPConfig } from "./types"; export async function loadMCPConfig() { - const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`); + const response = await fetch(`${getBackendBaseURL()}/api/v1/mcp/config`); return response.json() as Promise; } export async function updateMCPConfig(config: MCPConfig) { - const response = await fetch(`${getBackendBaseURL()}/api/mcp/config`, { + const response = await fetch(`${getBackendBaseURL()}/api/v1/mcp/config`, { method: "PUT", headers: { "Content-Type": "application/json", diff --git a/frontend/src/core/memory/api.ts b/frontend/src/core/memory/api.ts index a68a0bab..5022d10a 100644 --- a/frontend/src/core/memory/api.ts +++ b/frontend/src/core/memory/api.ts @@ -81,12 +81,12 @@ async function readMemoryResponse( } export async function loadMemory(): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/memory`); + const response = await fetch(`${getBackendBaseURL()}/api/v1/memory`); return readMemoryResponse(response, "Failed to fetch memory"); } export async function clearMemory(): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/memory`, { + const response = await fetch(`${getBackendBaseURL()}/api/v1/memory`, { method: "DELETE", }); return readMemoryResponse(response, "Failed to clear memory"); @@ -94,7 +94,7 @@ export async function clearMemory(): Promise { export async function deleteMemoryFact(factId: string): Promise { const response = await fetch( - `${getBackendBaseURL()}/api/memory/facts/${encodeURIComponent(factId)}`, + `${getBackendBaseURL()}/api/v1/memory/facts/${encodeURIComponent(factId)}`, { method: "DELETE", }, @@ -103,12 +103,12 @@ export async function deleteMemoryFact(factId: string): Promise { } export async function exportMemory(): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/memory/export`); + const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/export`); return readMemoryResponse(response, "Failed to export memory"); } export async function importMemory(memory: UserMemory): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/memory/import`, { + const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/import`, { method: "POST", headers: { "Content-Type": "application/json", @@ -121,7 +121,7 @@ export async function importMemory(memory: UserMemory): Promise { export async function createMemoryFact( input: MemoryFactInput, ): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/memory/facts`, { + const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/facts`, { method: "POST", headers: { "Content-Type": "application/json", @@ -136,7 +136,7 @@ export async function updateMemoryFact( input: MemoryFactPatchInput, ): Promise { const response = await fetch( - `${getBackendBaseURL()}/api/memory/facts/${encodeURIComponent(factId)}`, + `${getBackendBaseURL()}/api/v1/memory/facts/${encodeURIComponent(factId)}`, { method: "PATCH", headers: { diff --git a/frontend/src/core/models/api.ts b/frontend/src/core/models/api.ts index 46675bf6..c1b5e5b1 100644 --- a/frontend/src/core/models/api.ts +++ b/frontend/src/core/models/api.ts @@ -3,7 +3,7 @@ import { getBackendBaseURL } from "../config"; import type { ModelsResponse } from "./types"; export async function loadModels(): Promise { - const res = await fetch(`${getBackendBaseURL()}/api/models`); + const res = await fetch(`${getBackendBaseURL()}/api/v1/models`); const data = (await res.json()) as Partial; return { models: data.models ?? [], diff --git a/frontend/src/core/skills/api.ts b/frontend/src/core/skills/api.ts index 2fe334a6..94543aaf 100644 --- a/frontend/src/core/skills/api.ts +++ b/frontend/src/core/skills/api.ts @@ -4,14 +4,14 @@ import { getBackendBaseURL } from "@/core/config"; import type { Skill } from "./type"; export async function loadSkills() { - const skills = await fetch(`${getBackendBaseURL()}/api/skills`); + const skills = await fetch(`${getBackendBaseURL()}/api/v1/skills`); const json = await skills.json(); return json.skills as Skill[]; } export async function enableSkill(skillName: string, enabled: boolean) { const response = await fetch( - `${getBackendBaseURL()}/api/skills/${skillName}`, + `${getBackendBaseURL()}/api/v1/skills/${skillName}`, { method: "PUT", headers: { @@ -39,7 +39,7 @@ export interface InstallSkillResponse { export async function installSkill( request: InstallSkillRequest, ): Promise { - const response = await fetch(`${getBackendBaseURL()}/api/skills/install`, { + const response = await fetch(`${getBackendBaseURL()}/api/v1/skills/install`, { method: "POST", headers: { "Content-Type": "application/json", diff --git a/frontend/src/core/threads/hooks.ts b/frontend/src/core/threads/hooks.ts index 249ea366..96800040 100644 --- a/frontend/src/core/threads/hooks.ts +++ b/frontend/src/core/threads/hooks.ts @@ -570,7 +570,7 @@ export function useThreadHistory(threadId: string) { try { setLoading(true); const result: { data: RunMessage[]; hasMore: boolean } = await fetch( - `${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadIdRef.current)}/runs/${encodeURIComponent(run.run_id)}/messages`, + `${getBackendBaseURL()}/api/v1/threads/${encodeURIComponent(threadIdRef.current)}/runs/${encodeURIComponent(run.run_id)}/messages`, { method: "GET", headers: { @@ -721,7 +721,7 @@ export function useDeleteThread() { await apiClient.threads.delete(threadId); const response = await fetch( - `${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}`, + `${getBackendBaseURL()}/api/v1/threads/${encodeURIComponent(threadId)}`, { method: "DELETE", }, diff --git a/frontend/src/core/uploads/api.ts b/frontend/src/core/uploads/api.ts index 0ff01fd6..88e9f7de 100644 --- a/frontend/src/core/uploads/api.ts +++ b/frontend/src/core/uploads/api.ts @@ -52,7 +52,7 @@ export async function uploadFiles( }); const response = await fetch( - `${getBackendBaseURL()}/api/threads/${threadId}/uploads`, + `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads`, { method: "POST", body: formData, @@ -73,7 +73,7 @@ export async function listUploadedFiles( threadId: string, ): Promise { const response = await fetch( - `${getBackendBaseURL()}/api/threads/${threadId}/uploads/list`, + `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads/list`, ); if (!response.ok) { @@ -93,7 +93,7 @@ export async function deleteUploadedFile( filename: string, ): Promise<{ success: boolean; message: string }> { const response = await fetch( - `${getBackendBaseURL()}/api/threads/${threadId}/uploads/${filename}`, + `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads/${filename}`, { method: "DELETE", },