mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-05-07 17:28:21 +00:00
Preserve backend upload/list/delete error details in the frontend API layer so users see the actual server failure instead of a generic message. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> Co-authored-by: Willem Jiang <willem.jiang@gmail.com>
109 lines
2.1 KiB
TypeScript
109 lines
2.1 KiB
TypeScript
/**
|
|
* API functions for file uploads
|
|
*/
|
|
|
|
import { getBackendBaseURL } from "../config";
|
|
|
|
export interface UploadedFileInfo {
|
|
filename: string;
|
|
size: number;
|
|
path: string;
|
|
virtual_path: string;
|
|
artifact_url: string;
|
|
extension?: string;
|
|
modified?: number;
|
|
markdown_file?: string;
|
|
markdown_path?: string;
|
|
markdown_virtual_path?: string;
|
|
markdown_artifact_url?: string;
|
|
}
|
|
|
|
export interface UploadResponse {
|
|
success: boolean;
|
|
files: UploadedFileInfo[];
|
|
message: string;
|
|
}
|
|
|
|
export interface ListFilesResponse {
|
|
files: UploadedFileInfo[];
|
|
count: number;
|
|
}
|
|
|
|
async function readErrorDetail(
|
|
response: Response,
|
|
fallback: string,
|
|
): Promise<string> {
|
|
const error = await response
|
|
.json()
|
|
.catch(() => ({ detail: fallback }));
|
|
return error.detail ?? fallback;
|
|
}
|
|
|
|
/**
|
|
* Upload files to a thread
|
|
*/
|
|
export async function uploadFiles(
|
|
threadId: string,
|
|
files: File[],
|
|
): Promise<UploadResponse> {
|
|
const formData = new FormData();
|
|
|
|
files.forEach((file) => {
|
|
formData.append("files", file);
|
|
});
|
|
|
|
const response = await fetch(
|
|
`${getBackendBaseURL()}/api/threads/${threadId}/uploads`,
|
|
{
|
|
method: "POST",
|
|
body: formData,
|
|
},
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await readErrorDetail(response, "Upload failed"));
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
/**
|
|
* List all uploaded files for a thread
|
|
*/
|
|
export async function listUploadedFiles(
|
|
threadId: string,
|
|
): Promise<ListFilesResponse> {
|
|
const response = await fetch(
|
|
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/list`,
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(
|
|
await readErrorDetail(response, "Failed to list uploaded files"),
|
|
);
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
/**
|
|
* Delete an uploaded file
|
|
*/
|
|
export async function deleteUploadedFile(
|
|
threadId: string,
|
|
filename: string,
|
|
): Promise<{ success: boolean; message: string }> {
|
|
const response = await fetch(
|
|
`${getBackendBaseURL()}/api/threads/${threadId}/uploads/${filename}`,
|
|
{
|
|
method: "DELETE",
|
|
},
|
|
);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(await readErrorDetail(response, "Failed to delete file"));
|
|
}
|
|
|
|
return response.json();
|
|
}
|