feat(frontend): migrate API calls to /api/v1 (Stage 1 PR5)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1445043649
2026-06-28 20:07:20 +08:00
parent e6a12b9a7c
commit 190c1dc3c8
12 changed files with 47 additions and 35 deletions
+16 -4
View File
@@ -30,26 +30,38 @@ export async function GET(
request: NextRequest, request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }, { 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( export async function POST(
request: NextRequest, request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }, { 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( export async function DELETE(
request: NextRequest, request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }, { 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( export async function PATCH(
request: NextRequest, request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }, { params }: { params: Promise<{ path: string[] }> },
) { ) {
return proxyRequest(request, `/api/memory/${(await params).path.join("/")}`); return proxyRequest(
request,
`/api/v1/memory/${(await params).path.join("/")}`,
);
} }
+2 -2
View File
@@ -27,9 +27,9 @@ async function proxyRequest(request: NextRequest, pathname: string) {
} }
export async function GET(request: NextRequest) { export async function GET(request: NextRequest) {
return proxyRequest(request, "/api/memory"); return proxyRequest(request, "/api/v1/memory");
} }
export async function DELETE(request: NextRequest) { export async function DELETE(request: NextRequest) {
return proxyRequest(request, "/api/memory"); return proxyRequest(request, "/api/v1/memory");
} }
@@ -408,7 +408,7 @@ export function InputBox({
setFollowupsLoading(true); setFollowupsLoading(true);
setFollowups([]); setFollowups([]);
fetch(`${getBackendBaseURL()}/api/threads/${threadId}/suggestions`, { fetch(`${getBackendBaseURL()}/api/v1/threads/${threadId}/suggestions`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
+6 -6
View File
@@ -27,20 +27,20 @@ function isAgentsApiDisabledDetail(detail: string | undefined): boolean {
} }
export async function listAgents(): Promise<Agent[]> { export async function listAgents(): Promise<Agent[]> {
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}`); if (!res.ok) throw new Error(`Failed to load agents: ${res.statusText}`);
const data = (await res.json()) as { agents: Agent[] }; const data = (await res.json()) as { agents: Agent[] };
return data.agents; return data.agents;
} }
export async function getAgent(name: string): Promise<Agent> { export async function getAgent(name: string): Promise<Agent> {
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`); if (!res.ok) throw new Error(`Agent '${name}' not found`);
return res.json() as Promise<Agent>; return res.json() as Promise<Agent>;
} }
export async function createAgent(request: CreateAgentRequest): Promise<Agent> { export async function createAgent(request: CreateAgentRequest): Promise<Agent> {
const res = await fetch(`${getBackendBaseURL()}/api/agents`, { const res = await fetch(`${getBackendBaseURL()}/api/v1/agents`, {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(request), body: JSON.stringify(request),
@@ -59,7 +59,7 @@ export async function updateAgent(
name: string, name: string,
request: UpdateAgentRequest, request: UpdateAgentRequest,
): Promise<Agent> { ): Promise<Agent> {
const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { const res = await fetch(`${getBackendBaseURL()}/api/v1/agents/${name}`, {
method: "PUT", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify(request), body: JSON.stringify(request),
@@ -72,7 +72,7 @@ export async function updateAgent(
} }
export async function deleteAgent(name: string): Promise<void> { export async function deleteAgent(name: string): Promise<void> {
const res = await fetch(`${getBackendBaseURL()}/api/agents/${name}`, { const res = await fetch(`${getBackendBaseURL()}/api/v1/agents/${name}`, {
method: "DELETE", method: "DELETE",
}); });
if (!res.ok) throw new Error(`Failed to delete agent: ${res.statusText}`); if (!res.ok) throw new Error(`Failed to delete agent: ${res.statusText}`);
@@ -84,7 +84,7 @@ export async function checkAgentName(
let res: Response; let res: Response;
try { try {
res = await fetch( res = await fetch(
`${getBackendBaseURL()}/api/agents/check?name=${encodeURIComponent(name)}`, `${getBackendBaseURL()}/api/v1/agents/check?name=${encodeURIComponent(name)}`,
); );
} catch { } catch {
throw new AgentNameCheckError( throw new AgentNameCheckError(
+2 -2
View File
@@ -15,7 +15,7 @@ export async function upsertFeedback(
comment?: string, comment?: string,
): Promise<FeedbackData> { ): Promise<FeedbackData> {
const res = await fetch( 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", method: "PUT",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
@@ -33,7 +33,7 @@ export async function deleteFeedback(
runId: string, runId: string,
): Promise<void> { ): Promise<void> {
const res = await fetch( 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" }, { method: "DELETE" },
); );
if (!res.ok && res.status !== 404) { if (!res.ok && res.status !== 404) {
+2 -2
View File
@@ -15,7 +15,7 @@ export function urlOfArtifact({
if (isMock) { if (isMock) {
return `${getBackendBaseURL()}/mock/api/threads/${threadId}/artifacts${filepath}${download ? "?download=true" : ""}`; 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) { export function extractArtifactsFromThread(thread: AgentThread) {
@@ -23,5 +23,5 @@ export function extractArtifactsFromThread(thread: AgentThread) {
} }
export function resolveArtifactURL(absolutePath: string, threadId: string) { export function resolveArtifactURL(absolutePath: string, threadId: string) {
return `${getBackendBaseURL()}/api/threads/${threadId}/artifacts${absolutePath}`; return `${getBackendBaseURL()}/api/v1/threads/${threadId}/artifacts${absolutePath}`;
} }
+2 -2
View File
@@ -4,12 +4,12 @@ import { getBackendBaseURL } from "@/core/config";
import type { MCPConfig } from "./types"; import type { MCPConfig } from "./types";
export async function loadMCPConfig() { 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<MCPConfig>; return response.json() as Promise<MCPConfig>;
} }
export async function updateMCPConfig(config: MCPConfig) { 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", method: "PUT",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
+7 -7
View File
@@ -81,12 +81,12 @@ async function readMemoryResponse(
} }
export async function loadMemory(): Promise<UserMemory> { export async function loadMemory(): Promise<UserMemory> {
const response = await fetch(`${getBackendBaseURL()}/api/memory`); const response = await fetch(`${getBackendBaseURL()}/api/v1/memory`);
return readMemoryResponse(response, "Failed to fetch memory"); return readMemoryResponse(response, "Failed to fetch memory");
} }
export async function clearMemory(): Promise<UserMemory> { export async function clearMemory(): Promise<UserMemory> {
const response = await fetch(`${getBackendBaseURL()}/api/memory`, { const response = await fetch(`${getBackendBaseURL()}/api/v1/memory`, {
method: "DELETE", method: "DELETE",
}); });
return readMemoryResponse(response, "Failed to clear memory"); return readMemoryResponse(response, "Failed to clear memory");
@@ -94,7 +94,7 @@ export async function clearMemory(): Promise<UserMemory> {
export async function deleteMemoryFact(factId: string): Promise<UserMemory> { export async function deleteMemoryFact(factId: string): Promise<UserMemory> {
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/memory/facts/${encodeURIComponent(factId)}`, `${getBackendBaseURL()}/api/v1/memory/facts/${encodeURIComponent(factId)}`,
{ {
method: "DELETE", method: "DELETE",
}, },
@@ -103,12 +103,12 @@ export async function deleteMemoryFact(factId: string): Promise<UserMemory> {
} }
export async function exportMemory(): Promise<UserMemory> { export async function exportMemory(): Promise<UserMemory> {
const response = await fetch(`${getBackendBaseURL()}/api/memory/export`); const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/export`);
return readMemoryResponse(response, "Failed to export memory"); return readMemoryResponse(response, "Failed to export memory");
} }
export async function importMemory(memory: UserMemory): Promise<UserMemory> { export async function importMemory(memory: UserMemory): Promise<UserMemory> {
const response = await fetch(`${getBackendBaseURL()}/api/memory/import`, { const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/import`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -121,7 +121,7 @@ export async function importMemory(memory: UserMemory): Promise<UserMemory> {
export async function createMemoryFact( export async function createMemoryFact(
input: MemoryFactInput, input: MemoryFactInput,
): Promise<UserMemory> { ): Promise<UserMemory> {
const response = await fetch(`${getBackendBaseURL()}/api/memory/facts`, { const response = await fetch(`${getBackendBaseURL()}/api/v1/memory/facts`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@@ -136,7 +136,7 @@ export async function updateMemoryFact(
input: MemoryFactPatchInput, input: MemoryFactPatchInput,
): Promise<UserMemory> { ): Promise<UserMemory> {
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/memory/facts/${encodeURIComponent(factId)}`, `${getBackendBaseURL()}/api/v1/memory/facts/${encodeURIComponent(factId)}`,
{ {
method: "PATCH", method: "PATCH",
headers: { headers: {
+1 -1
View File
@@ -3,7 +3,7 @@ import { getBackendBaseURL } from "../config";
import type { ModelsResponse } from "./types"; import type { ModelsResponse } from "./types";
export async function loadModels(): Promise<ModelsResponse> { export async function loadModels(): Promise<ModelsResponse> {
const res = await fetch(`${getBackendBaseURL()}/api/models`); const res = await fetch(`${getBackendBaseURL()}/api/v1/models`);
const data = (await res.json()) as Partial<ModelsResponse>; const data = (await res.json()) as Partial<ModelsResponse>;
return { return {
models: data.models ?? [], models: data.models ?? [],
+3 -3
View File
@@ -4,14 +4,14 @@ import { getBackendBaseURL } from "@/core/config";
import type { Skill } from "./type"; import type { Skill } from "./type";
export async function loadSkills() { export async function loadSkills() {
const skills = await fetch(`${getBackendBaseURL()}/api/skills`); const skills = await fetch(`${getBackendBaseURL()}/api/v1/skills`);
const json = await skills.json(); const json = await skills.json();
return json.skills as Skill[]; return json.skills as Skill[];
} }
export async function enableSkill(skillName: string, enabled: boolean) { export async function enableSkill(skillName: string, enabled: boolean) {
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/skills/${skillName}`, `${getBackendBaseURL()}/api/v1/skills/${skillName}`,
{ {
method: "PUT", method: "PUT",
headers: { headers: {
@@ -39,7 +39,7 @@ export interface InstallSkillResponse {
export async function installSkill( export async function installSkill(
request: InstallSkillRequest, request: InstallSkillRequest,
): Promise<InstallSkillResponse> { ): Promise<InstallSkillResponse> {
const response = await fetch(`${getBackendBaseURL()}/api/skills/install`, { const response = await fetch(`${getBackendBaseURL()}/api/v1/skills/install`, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
+2 -2
View File
@@ -570,7 +570,7 @@ export function useThreadHistory(threadId: string) {
try { try {
setLoading(true); setLoading(true);
const result: { data: RunMessage[]; hasMore: boolean } = await fetch( 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", method: "GET",
headers: { headers: {
@@ -721,7 +721,7 @@ export function useDeleteThread() {
await apiClient.threads.delete(threadId); await apiClient.threads.delete(threadId);
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/threads/${encodeURIComponent(threadId)}`, `${getBackendBaseURL()}/api/v1/threads/${encodeURIComponent(threadId)}`,
{ {
method: "DELETE", method: "DELETE",
}, },
+3 -3
View File
@@ -52,7 +52,7 @@ export async function uploadFiles(
}); });
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/threads/${threadId}/uploads`, `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads`,
{ {
method: "POST", method: "POST",
body: formData, body: formData,
@@ -73,7 +73,7 @@ export async function listUploadedFiles(
threadId: string, threadId: string,
): Promise<ListFilesResponse> { ): Promise<ListFilesResponse> {
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/list`, `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads/list`,
); );
if (!response.ok) { if (!response.ok) {
@@ -93,7 +93,7 @@ export async function deleteUploadedFile(
filename: string, filename: string,
): Promise<{ success: boolean; message: string }> { ): Promise<{ success: boolean; message: string }> {
const response = await fetch( const response = await fetch(
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/${filename}`, `${getBackendBaseURL()}/api/v1/threads/${threadId}/uploads/${filename}`,
{ {
method: "DELETE", method: "DELETE",
}, },