feat: async task pipeline for media and llm workflows

这个提交包含在:
cryptocommuniums-afk
2026-03-15 00:12:26 +08:00
父节点 1cc863e60e
当前提交 20e183d2da
修改 36 个文件,包含 1961 行新增339 行删除

查看文件

@@ -53,14 +53,40 @@ export type MediaSession = {
};
const MEDIA_BASE = (import.meta.env.VITE_MEDIA_BASE_URL || "/media").replace(/\/$/, "");
const RETRYABLE_STATUS = new Set([502, 503, 504]);
function sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function request<T>(path: string, init?: RequestInit): Promise<T> {
const response = await fetch(`${MEDIA_BASE}${path}`, init);
if (!response.ok) {
const errorBody = await response.json().catch(() => ({}));
throw new Error(errorBody.error || errorBody.message || `Media service error (${response.status})`);
let lastError: Error | null = null;
for (let attempt = 0; attempt < 3; attempt++) {
try {
const response = await fetch(`${MEDIA_BASE}${path}`, init);
if (!response.ok) {
const errorBody = await response.json().catch(() => ({}));
const error = new Error(errorBody.error || errorBody.message || `Media service error (${response.status})`);
if (RETRYABLE_STATUS.has(response.status) && attempt < 2) {
lastError = error;
await sleep(400 * (attempt + 1));
continue;
}
throw error;
}
return response.json() as Promise<T>;
} catch (error) {
lastError = error instanceof Error ? error : new Error("Media request failed");
if (attempt < 2) {
await sleep(400 * (attempt + 1));
continue;
}
throw lastError;
}
}
return response.json() as Promise<T>;
throw lastError || new Error("Media request failed");
}
export async function createMediaSession(payload: {