import { resolveModel, sanitizeSettings } from "../settings"; import type { AnalysisDetails, AnalysisJob, AnalysisKind, AppSettings } from "../types"; import { apiFetch, downloadBlob } from "./http"; export interface AnalysisOptions { kind: AnalysisKind; optimizeTask: boolean; strictFullMarks: boolean; ignoreTaskComplexityForFullMarks: boolean; feedback: string; } export async function createAnalysisJob(files: File[], requestedMode: AnalysisKind): Promise<{ jobId: string; items: AnalysisJob["items"]; }> { const form = new FormData(); form.append("requestedMode", requestedMode); files.forEach((file) => form.append("files", file, file.name)); const response = await fetch("/api/analysis/jobs", { method: "POST", body: form }); const payload = await response.json().catch(() => null); if (!response.ok || !payload || payload.code !== 0) { throw new Error(payload?.msg || `HTTP ${response.status}`); } return payload.data; } export async function startAnalysisJob(jobId: string, settings: AppSettings, options: AnalysisOptions): Promise { await apiFetch("/api/analysis/jobs/" + encodeURIComponent(jobId) + "/start", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ optionsSnapshot: buildOptionsSnapshot(settings, options) }), }); } export async function getAnalysisJob(jobId: string): Promise { return apiFetch("/api/analysis/jobs/" + encodeURIComponent(jobId)); } export async function getAnalysisItemResult(jobId: string, itemId: string): Promise { return apiFetch("/api/analysis/jobs/" + encodeURIComponent(jobId) + "/items/" + encodeURIComponent(itemId) + "/result"); } export async function cancelAnalysisJob(jobId: string): Promise { await apiFetch("/api/analysis/jobs/" + encodeURIComponent(jobId) + "/cancel", { method: "POST" }); } export async function retryAnalysisItem(jobId: string, itemId: string): Promise { await apiFetch("/api/analysis/jobs/" + encodeURIComponent(jobId) + "/items/" + encodeURIComponent(itemId) + "/retry", { method: "POST", }); } export async function downloadAnalysisItem(jobId: string, itemId: string, filename: string): Promise { await downloadBlob( "/api/analysis/jobs/" + encodeURIComponent(jobId) + "/items/" + encodeURIComponent(itemId) + "/download", filename.replace(/\.zip$/i, "") + ".task-package.zip", ); } export async function downloadAnalysisJob(jobId: string): Promise { await downloadBlob("/api/analysis/jobs/" + encodeURIComponent(jobId) + "/download-all", "all-results.zip"); } export function buildOptionsSnapshot(settings: AppSettings, options: AnalysisOptions): Record { const cleanSettings = sanitizeSettings(settings); return { requestedMode: options.kind, model: resolveModel(cleanSettings), baseURL: cleanSettings.baseURL, apiKey: cleanSettings.apiKey, apiMode: cleanSettings.apiMode, concurrency: cleanSettings.concurrency, temperature: cleanSettings.temperature, topP: cleanSettings.topP, maxTokens: cleanSettings.maxTokens, enableThinking: cleanSettings.enableThinking, clearThinking: cleanSettings.clearThinking, ruleProfile: cleanSettings.ruleProfile, optimizeTask: options.optimizeTask, feedback: options.feedback, strictFullMarks: options.strictFullMarks, ignoreTaskComplexityForFullMarks: options.ignoreTaskComplexityForFullMarks, }; }