Move LLM-assisted column mapping from silent /check-format automation to an explicit "AI Assist" button in the dataset mapping dialog. This makes the feature transparent and user-controlled. - Remove llm_classify_columns() from check_dataset_format() (heuristic-only) - Remove auto-save suggested_mapping from use-training-actions.ts - Add POST /api/datasets/ai-assist-mapping endpoint (receives preview samples from frontend, no dataset re-loading needed) - Add AiAssistMappingRequest/Response models - Add aiAssistMapping() frontend API function - Add Sparkles AI Assist button to DatasetMappingCard with loading state - Wire up handleAiAssist handler in dataset-preview-dialog.tsx
109 lines
2.8 KiB
TypeScript
109 lines
2.8 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-only - See /studio/LICENSE.AGPL-3.0
|
|
// Copyright © 2025 Unsloth AI
|
|
|
|
import type {
|
|
CheckFormatResponse,
|
|
LocalDatasetsResponse,
|
|
UploadDatasetResponse,
|
|
} from "../types/datasets";
|
|
import { authFetch } from "@/features/auth";
|
|
|
|
type CheckDatasetFormatArgs = {
|
|
datasetName: string;
|
|
hfToken: string | null;
|
|
subset?: string | null;
|
|
split?: string | null;
|
|
isVlm?: boolean;
|
|
};
|
|
|
|
export async function checkDatasetFormat({
|
|
datasetName,
|
|
hfToken,
|
|
subset,
|
|
split,
|
|
isVlm,
|
|
}: CheckDatasetFormatArgs): Promise<CheckFormatResponse> {
|
|
const res = await authFetch("/api/datasets/check-format", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
dataset_name: datasetName,
|
|
hf_token: hfToken || undefined,
|
|
subset: subset || undefined,
|
|
split: split || "train",
|
|
is_vlm: !!isVlm,
|
|
}),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => null);
|
|
throw new Error(body?.detail || `Request failed (${res.status})`);
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
export async function uploadTrainingDataset(
|
|
file: File,
|
|
): Promise<UploadDatasetResponse> {
|
|
const form = new FormData();
|
|
form.append("file", file);
|
|
|
|
const res = await authFetch("/api/datasets/upload", {
|
|
method: "POST",
|
|
body: form,
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => null);
|
|
throw new Error(body?.detail || `Upload failed (${res.status})`);
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
// ── AI Assist ────────────────────────────────────────────────────────
|
|
|
|
type AiAssistMappingArgs = {
|
|
columns: string[];
|
|
samples: Record<string, unknown>[];
|
|
datasetName?: string | null;
|
|
};
|
|
|
|
export type AiAssistMappingResponse = {
|
|
success: boolean;
|
|
suggested_mapping?: Record<string, string> | null;
|
|
warning?: string | null;
|
|
};
|
|
|
|
export async function aiAssistMapping({
|
|
columns,
|
|
samples,
|
|
datasetName,
|
|
}: AiAssistMappingArgs): Promise<AiAssistMappingResponse> {
|
|
const res = await authFetch("/api/datasets/ai-assist-mapping", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
columns,
|
|
samples: samples.slice(0, 5),
|
|
dataset_name: datasetName || undefined,
|
|
}),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => null);
|
|
throw new Error(body?.detail || `AI assist failed (${res.status})`);
|
|
}
|
|
|
|
return res.json();
|
|
}
|
|
|
|
export async function listLocalDatasets(): Promise<LocalDatasetsResponse> {
|
|
const res = await authFetch("/api/datasets/local");
|
|
if (!res.ok) {
|
|
const body = await res.json().catch(() => null);
|
|
throw new Error(body?.detail || `Request failed (${res.status})`);
|
|
}
|
|
return res.json();
|
|
}
|