feat(recipe-studio): add support for naming full runs, enhance empty states, and refine UI components
This commit is contained in:
parent
df553fc955
commit
6997919c65
16 changed files with 192 additions and 73 deletions
|
|
@ -15,6 +15,7 @@ import {
|
|||
type Database02Icon,
|
||||
DragDropVerticalIcon,
|
||||
PlusSignIcon,
|
||||
Search01Icon,
|
||||
Tick02Icon,
|
||||
Upload01Icon,
|
||||
} from "@hugeicons/core-free-icons";
|
||||
|
|
@ -373,12 +374,18 @@ export function BlockSheet({
|
|||
)}
|
||||
<SheetTitle>{sheetTitle}</SheetTitle>
|
||||
</div>
|
||||
<Input
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.target.value)}
|
||||
placeholder="Search blocks..."
|
||||
className="corner-squircle mt-3 h-9"
|
||||
/>
|
||||
<div className="relative mt-3">
|
||||
<HugeiconsIcon
|
||||
icon={Search01Icon}
|
||||
className="pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground"
|
||||
/>
|
||||
<Input
|
||||
value={search}
|
||||
onChange={(event) => setSearch(event.target.value)}
|
||||
placeholder="Search blocks..."
|
||||
className="corner-squircle h-9 pl-8"
|
||||
/>
|
||||
</div>
|
||||
</SheetHeader>
|
||||
<div className=" py-4">
|
||||
<div className="mt-4 flex flex-col gap-2">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ import type { ReactElement } from "react";
|
|||
import { Badge } from "@/components/ui/badge";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { RecipeExecutionRecord } from "../../execution-types";
|
||||
import { isExecutionInProgress } from "../../executions/execution-helpers";
|
||||
import {
|
||||
executionLabel,
|
||||
isExecutionInProgress,
|
||||
normalizeRunName,
|
||||
} from "../../executions/execution-helpers";
|
||||
import {
|
||||
formatStatus,
|
||||
formatTimestamp,
|
||||
|
|
@ -34,43 +38,50 @@ export function ExecutionSidebar({
|
|||
No executions yet.
|
||||
</div>
|
||||
) : (
|
||||
executions.map((execution) => (
|
||||
<button
|
||||
key={execution.id}
|
||||
type="button"
|
||||
onClick={() => onSelectExecution(execution.id)}
|
||||
className={cn(
|
||||
"w-full rounded-xl corner-squircle border border-r-2 border-border/60 bg-card/60 p-3 text-left transition-colors",
|
||||
selectedExecutionId === execution.id
|
||||
? "border-primary/35 bg-primary/[0.045]"
|
||||
: "hover:bg-muted/25",
|
||||
statusRightBorder(execution.status),
|
||||
)}
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between gap-2">
|
||||
<p className="truncate text-sm font-medium capitalize">
|
||||
{execution.kind}
|
||||
</p>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={cn("capitalize text-[11px]", statusTone(execution.status))}
|
||||
>
|
||||
{formatStatus(execution.status)}
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">{execution.rows} rows</p>
|
||||
{isExecutionInProgress(execution.status) &&
|
||||
typeof execution.batch?.total === "number" &&
|
||||
execution.batch.total > 1 && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Batch {execution.batch.idx ?? "--"}/{execution.batch.total}
|
||||
</p>
|
||||
executions.map((execution) => {
|
||||
const title =
|
||||
execution.kind === "full"
|
||||
? (normalizeRunName(execution.run_name) ??
|
||||
executionLabel(execution.kind))
|
||||
: executionLabel(execution.kind);
|
||||
return (
|
||||
<button
|
||||
key={execution.id}
|
||||
type="button"
|
||||
onClick={() => onSelectExecution(execution.id)}
|
||||
className={cn(
|
||||
"w-full rounded-xl corner-squircle border border-r-2 border-border/60 bg-card/60 p-3 text-left transition-colors",
|
||||
selectedExecutionId === execution.id
|
||||
? "border-primary/35 bg-primary/[0.045]"
|
||||
: "hover:bg-muted/25",
|
||||
statusRightBorder(execution.status),
|
||||
)}
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatTimestamp(execution.createdAt)}
|
||||
</p>
|
||||
</button>
|
||||
))
|
||||
>
|
||||
<div className="mb-2 flex items-center justify-between gap-2">
|
||||
<p className="truncate text-sm font-medium">
|
||||
{title}
|
||||
</p>
|
||||
<Badge
|
||||
variant="outline"
|
||||
className={cn("capitalize text-[11px]", statusTone(execution.status))}
|
||||
>
|
||||
{formatStatus(execution.status)}
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">{execution.rows} rows</p>
|
||||
{isExecutionInProgress(execution.status) &&
|
||||
typeof execution.batch?.total === "number" &&
|
||||
execution.batch.total > 1 && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Batch {execution.batch.idx ?? "--"}/{execution.batch.total}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{formatTimestamp(execution.createdAt)}
|
||||
</p>
|
||||
</button>
|
||||
);
|
||||
})
|
||||
)}
|
||||
</div>
|
||||
</aside>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,11 @@
|
|||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Empty,
|
||||
EmptyContent,
|
||||
EmptyDescription,
|
||||
EmptyHeader,
|
||||
EmptyTitle,
|
||||
} from "@/components/ui/empty";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { type ReactElement } from "react";
|
||||
|
|
@ -91,14 +98,26 @@ export function LlmScoresTab({
|
|||
label="Scorers"
|
||||
hint="Rubrics used by LLM Judge to score each generated row."
|
||||
/>
|
||||
<Button type="button" size="xs" variant="outline" onClick={addScore}>
|
||||
Add scorer
|
||||
</Button>
|
||||
{scores.length > 0 && (
|
||||
<Button type="button" size="xs" variant="outline" onClick={addScore}>
|
||||
Add scorer
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
{scores.length === 0 && (
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Add at least one scorer.
|
||||
</p>
|
||||
<Empty className="rounded-xl border border-dashed border-border/70 p-5">
|
||||
<EmptyHeader>
|
||||
<EmptyTitle className="text-sm">No scorers yet</EmptyTitle>
|
||||
<EmptyDescription className="text-xs">
|
||||
Add a scorer rubric before running judge generation.
|
||||
</EmptyDescription>
|
||||
</EmptyHeader>
|
||||
<EmptyContent className="max-w-none">
|
||||
<Button type="button" size="sm" onClick={addScore}>
|
||||
Add first scorer
|
||||
</Button>
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
)}
|
||||
{scores.map((score, index) => (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ export function ModelConfigDialog({
|
|||
return (
|
||||
<div className="space-y-4">
|
||||
<NameField
|
||||
label="Model alias"
|
||||
value={config.name}
|
||||
onChange={(value) => onUpdate({ name: value })}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ export function ModelProviderDialog({
|
|||
return (
|
||||
<div className="space-y-4">
|
||||
<NameField
|
||||
label="Provider name"
|
||||
value={config.name}
|
||||
onChange={(value) => onUpdate({ name: value })}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ type RunDialogProps = {
|
|||
kind: RecipeExecutionKind;
|
||||
onKindChange: (kind: RecipeExecutionKind) => void;
|
||||
rows: number;
|
||||
fullRunName: string;
|
||||
onFullRunNameChange: (name: string) => void;
|
||||
onRowsChange: (rows: number) => void;
|
||||
settings: RecipeRunSettings;
|
||||
onSettingsChange: (patch: Partial<RecipeRunSettings>) => void;
|
||||
|
|
@ -207,6 +209,8 @@ export function RunDialog({
|
|||
kind,
|
||||
onKindChange,
|
||||
rows,
|
||||
fullRunName,
|
||||
onFullRunNameChange,
|
||||
onRowsChange,
|
||||
settings,
|
||||
onSettingsChange,
|
||||
|
|
@ -304,6 +308,23 @@ export function RunDialog({
|
|||
/>
|
||||
</div>
|
||||
|
||||
{kind === "full" && (
|
||||
<div className="grid gap-2">
|
||||
<FieldLabel
|
||||
label="Run name"
|
||||
htmlFor="run-name"
|
||||
hint="Optional label shown in executions list."
|
||||
/>
|
||||
<Input
|
||||
id="run-name"
|
||||
type="text"
|
||||
value={fullRunName}
|
||||
onChange={(event) => onFullRunNameChange(event.target.value)}
|
||||
placeholder="Sprint dataset v2"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="grid gap-4 md:grid-cols-2">
|
||||
<div className="grid gap-2">
|
||||
<FieldLabel label="Records" htmlFor="run-rows" hint={rowHint} />
|
||||
|
|
|
|||
|
|
@ -102,6 +102,29 @@ function truncatePreviewValue(value: string): string {
|
|||
return `${value.slice(0, PREVIEW_TRUNCATE_AT)}…`;
|
||||
}
|
||||
|
||||
function getPreviewEmptyStateCopy(mode: SeedConfig["seed_source_type"]): {
|
||||
title: string;
|
||||
description: string;
|
||||
} {
|
||||
if (mode === "local") {
|
||||
return {
|
||||
title: "No local preview yet",
|
||||
description: "Choose a CSV/JSON/JSONL file, then click Load to fetch 10 rows.",
|
||||
};
|
||||
}
|
||||
if (mode === "unstructured") {
|
||||
return {
|
||||
title: "No chunk preview yet",
|
||||
description:
|
||||
"Choose a TXT/PDF/DOCX file, then click Load to extract + preview chunk_text rows.",
|
||||
};
|
||||
}
|
||||
return {
|
||||
title: "No dataset preview yet",
|
||||
description: "Pick a Hugging Face dataset and click Load to fetch 10 sample rows.",
|
||||
};
|
||||
}
|
||||
|
||||
function parseChunkNumber(
|
||||
value: string | undefined,
|
||||
fallback: number,
|
||||
|
|
@ -196,6 +219,7 @@ export function SeedDialog({ config, onUpdate, open }: SeedDialogProps): ReactEl
|
|||
const [unstructuredFile, setUnstructuredFile] = useState<File | null>(null);
|
||||
|
||||
const mode = config.seed_source_type ?? "hf";
|
||||
const previewEmpty = getPreviewEmptyStateCopy(mode);
|
||||
|
||||
useEffect(() => {
|
||||
setInspectError(null);
|
||||
|
|
@ -753,12 +777,14 @@ export function SeedDialog({ config, onUpdate, open }: SeedDialogProps): ReactEl
|
|||
<div className="flex w-full items-center justify-center">
|
||||
<Empty className="max-w-lg">
|
||||
<EmptyHeader>
|
||||
<EmptyTitle>Seed preview</EmptyTitle>
|
||||
<EmptyTitle>{previewEmpty.title}</EmptyTitle>
|
||||
<EmptyDescription>
|
||||
Use the load button next to the source input to fetch 10 rows.
|
||||
{previewEmpty.description}
|
||||
</EmptyDescription>
|
||||
</EmptyHeader>
|
||||
<EmptyContent />
|
||||
<EmptyContent className="text-xs text-muted-foreground">
|
||||
Preview appears here after loading source metadata.
|
||||
</EmptyContent>
|
||||
</Empty>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ type NameFieldProps = {
|
|||
id?: string;
|
||||
value: string;
|
||||
onChange: (value: string) => void;
|
||||
label?: string;
|
||||
hint?: string;
|
||||
};
|
||||
|
||||
|
|
@ -13,6 +14,7 @@ export function NameField({
|
|||
id,
|
||||
value,
|
||||
onChange,
|
||||
label,
|
||||
hint,
|
||||
}: NameFieldProps): ReactElement {
|
||||
const fallbackId = useId();
|
||||
|
|
@ -20,7 +22,7 @@ export function NameField({
|
|||
return (
|
||||
<div className="grid gap-2">
|
||||
<FieldLabel
|
||||
label="Column name"
|
||||
label={label ?? "Column name"}
|
||||
htmlFor={inputId}
|
||||
hint={
|
||||
hint ??
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ export type RecipeExecutionRecord = {
|
|||
// biome-ignore lint/style/useNamingConvention: backend schema
|
||||
jobId: string | null;
|
||||
kind: RecipeExecutionKind;
|
||||
// ui-only display label for full runs
|
||||
// biome-ignore lint/style/useNamingConvention: ui schema
|
||||
run_name: string | null;
|
||||
status: RecipeExecutionStatus;
|
||||
rows: number;
|
||||
createdAt: number;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,14 @@ export function executionLabel(kind: "preview" | "full"): string {
|
|||
return kind === "preview" ? "Preview" : "Full run";
|
||||
}
|
||||
|
||||
export function normalizeRunName(value: unknown): string | null {
|
||||
if (typeof value !== "string") {
|
||||
return null;
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
return trimmed.length > 0 ? trimmed : null;
|
||||
}
|
||||
|
||||
function executionSortWeight(status: RecipeExecutionStatus): number {
|
||||
if (isExecutionInProgress(status)) {
|
||||
return 0;
|
||||
|
|
@ -133,6 +141,7 @@ export function withExecutionDefaults(
|
|||
|
||||
return {
|
||||
...record,
|
||||
run_name: normalizeRunName(record.run_name),
|
||||
dataset,
|
||||
log_lines: logLines,
|
||||
datasetTotal,
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ export function createBaseExecutionRecord(input: {
|
|||
kind: RecipeExecutionKind;
|
||||
rows: number;
|
||||
currentSignature: string;
|
||||
runName?: string | null;
|
||||
}): RecipeExecutionRecord {
|
||||
const createdAt = Date.now();
|
||||
return {
|
||||
|
|
@ -121,6 +122,7 @@ export function createBaseExecutionRecord(input: {
|
|||
recipeId: input.recipeId,
|
||||
jobId: null,
|
||||
kind: input.kind,
|
||||
run_name: input.runName ?? null,
|
||||
status: "pending",
|
||||
rows: input.rows,
|
||||
createdAt,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import type {
|
|||
import {
|
||||
DATASET_PAGE_SIZE,
|
||||
executionLabel,
|
||||
normalizeRunName,
|
||||
normalizeDatasetRows,
|
||||
toErrorMessage,
|
||||
withExecutionDefaults,
|
||||
|
|
@ -50,8 +51,10 @@ type UseRecipeExecutionsResult = {
|
|||
setRunDialogOpen: (open: boolean) => void;
|
||||
previewRows: number;
|
||||
fullRows: number;
|
||||
fullRunName: string;
|
||||
setPreviewRows: (rows: number) => void;
|
||||
setFullRows: (rows: number) => void;
|
||||
setFullRunName: (name: string) => void;
|
||||
runErrors: string[];
|
||||
runSettings: RecipeRunSettings;
|
||||
setRunSettings: (patch: Partial<RecipeRunSettings>) => void;
|
||||
|
|
@ -109,6 +112,7 @@ export function useRecipeExecutions({
|
|||
runDialogKind,
|
||||
previewRows,
|
||||
fullRows,
|
||||
fullRunName,
|
||||
runErrors,
|
||||
runSettings,
|
||||
previewLoading,
|
||||
|
|
@ -119,6 +123,7 @@ export function useRecipeExecutions({
|
|||
setRunDialogKind,
|
||||
setPreviewRows,
|
||||
setFullRows,
|
||||
setFullRunName,
|
||||
setRunErrors,
|
||||
setRunSettings,
|
||||
setPreviewLoading,
|
||||
|
|
@ -133,6 +138,7 @@ export function useRecipeExecutions({
|
|||
runDialogKind: state.runDialogKind,
|
||||
previewRows: state.previewRows,
|
||||
fullRows: state.fullRows,
|
||||
fullRunName: state.fullRunName,
|
||||
runErrors: state.runErrors,
|
||||
runSettings: state.runSettings,
|
||||
previewLoading: state.previewLoading,
|
||||
|
|
@ -143,6 +149,7 @@ export function useRecipeExecutions({
|
|||
setRunDialogKind: state.setRunDialogKind,
|
||||
setPreviewRows: state.setPreviewRows,
|
||||
setFullRows: state.setFullRows,
|
||||
setFullRunName: state.setFullRunName,
|
||||
setRunErrors: state.setRunErrors,
|
||||
setRunSettings: state.setRunSettings,
|
||||
setPreviewLoading: state.setPreviewLoading,
|
||||
|
|
@ -238,10 +245,12 @@ export function useRecipeExecutions({
|
|||
payload: RecipePayload;
|
||||
rows: number;
|
||||
settings: RecipeRunSettings;
|
||||
runName: string | null;
|
||||
}): Promise<boolean> => {
|
||||
const { kind, payload, rows, settings } = input;
|
||||
const { kind, payload, rows, settings, runName } = input;
|
||||
const setLoading = kind === "preview" ? setPreviewLoading : setFullLoading;
|
||||
const label = executionLabel(kind);
|
||||
const normalizedRunName = kind === "full" ? normalizeRunName(runName) : null;
|
||||
|
||||
setLoading(true);
|
||||
const baseExecution = createBaseExecutionRecord({
|
||||
|
|
@ -249,6 +258,7 @@ export function useRecipeExecutions({
|
|||
kind,
|
||||
rows,
|
||||
currentSignature,
|
||||
runName: normalizedRunName,
|
||||
});
|
||||
|
||||
upsertAndPersist(baseExecution);
|
||||
|
|
@ -309,7 +319,11 @@ export function useRecipeExecutions({
|
|||
);
|
||||
|
||||
const runWithValidation = useCallback(
|
||||
async (kind: RecipeExecutionKind, rows: number): Promise<boolean> => {
|
||||
async (
|
||||
kind: RecipeExecutionKind,
|
||||
rows: number,
|
||||
runName: string | null,
|
||||
): Promise<boolean> => {
|
||||
const payload = readExecutablePayload();
|
||||
if (!payload) {
|
||||
return false;
|
||||
|
|
@ -345,18 +359,19 @@ export function useRecipeExecutions({
|
|||
payload,
|
||||
rows: normalizedRows,
|
||||
settings: runSettings,
|
||||
runName,
|
||||
});
|
||||
},
|
||||
[readExecutablePayload, runExecution, runSettings, setRunErrors],
|
||||
);
|
||||
|
||||
const runPreview = useCallback(async (): Promise<boolean> => {
|
||||
return runWithValidation("preview", previewRows);
|
||||
return runWithValidation("preview", previewRows, null);
|
||||
}, [previewRows, runWithValidation]);
|
||||
|
||||
const runFull = useCallback(async (): Promise<boolean> => {
|
||||
return runWithValidation("full", fullRows);
|
||||
}, [fullRows, runWithValidation]);
|
||||
return runWithValidation("full", fullRows, fullRunName);
|
||||
}, [fullRows, fullRunName, runWithValidation]);
|
||||
|
||||
const runFromDialog = useCallback(async (): Promise<boolean> => {
|
||||
setValidateResult(null);
|
||||
|
|
@ -509,8 +524,10 @@ export function useRecipeExecutions({
|
|||
setRunDialogOpen,
|
||||
previewRows,
|
||||
fullRows,
|
||||
fullRunName,
|
||||
setPreviewRows,
|
||||
setFullRows,
|
||||
setFullRunName,
|
||||
runErrors,
|
||||
runSettings,
|
||||
setRunSettings,
|
||||
|
|
|
|||
|
|
@ -48,8 +48,10 @@ type UseRecipeStudioActionsResult = {
|
|||
setRunDialogOpen: (open: boolean) => void;
|
||||
previewRows: number;
|
||||
fullRows: number;
|
||||
fullRunName: string;
|
||||
setPreviewRows: (rows: number) => void;
|
||||
setFullRows: (rows: number) => void;
|
||||
setFullRunName: (name: string) => void;
|
||||
runErrors: string[];
|
||||
runSettings: RecipeRunSettings;
|
||||
setRunSettings: (patch: Partial<RecipeRunSettings>) => void;
|
||||
|
|
@ -125,8 +127,10 @@ export function useRecipeStudioActions({
|
|||
setRunDialogOpen: executions.setRunDialogOpen,
|
||||
previewRows: executions.previewRows,
|
||||
fullRows: executions.fullRows,
|
||||
fullRunName: executions.fullRunName,
|
||||
setPreviewRows: executions.setPreviewRows,
|
||||
setFullRows: executions.setFullRows,
|
||||
setFullRunName: executions.setFullRunName,
|
||||
runErrors: executions.runErrors,
|
||||
runSettings: executions.runSettings,
|
||||
setRunSettings: executions.setRunSettings,
|
||||
|
|
|
|||
|
|
@ -261,8 +261,10 @@ export function RecipeStudioPage({
|
|||
setRunDialogOpen,
|
||||
previewRows,
|
||||
fullRows,
|
||||
fullRunName,
|
||||
setPreviewRows,
|
||||
setFullRows,
|
||||
setFullRunName,
|
||||
runErrors,
|
||||
runSettings,
|
||||
setRunSettings,
|
||||
|
|
@ -652,6 +654,8 @@ export function RecipeStudioPage({
|
|||
kind={runDialogKind}
|
||||
onKindChange={setRunDialogKind}
|
||||
rows={runDialogRows}
|
||||
fullRunName={fullRunName}
|
||||
onFullRunNameChange={setFullRunName}
|
||||
onRowsChange={(rows) => {
|
||||
if (runDialogKind === "preview") {
|
||||
setPreviewRows(rows);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ type RecipeExecutionsState = {
|
|||
runDialogKind: RecipeExecutionKind;
|
||||
previewRows: number;
|
||||
fullRows: number;
|
||||
fullRunName: string;
|
||||
runErrors: string[];
|
||||
runSettings: RecipeRunSettings;
|
||||
previewLoading: boolean;
|
||||
|
|
@ -44,6 +45,7 @@ type RecipeExecutionsState = {
|
|||
setRunDialogKind: (kind: RecipeExecutionKind) => void;
|
||||
setPreviewRows: (rows: number) => void;
|
||||
setFullRows: (rows: number) => void;
|
||||
setFullRunName: (name: string) => void;
|
||||
setRunErrors: (errors: string[]) => void;
|
||||
setRunSettings: (patch: Partial<RecipeRunSettings>) => void;
|
||||
setPreviewLoading: (loading: boolean) => void;
|
||||
|
|
@ -59,6 +61,7 @@ const INITIAL_STATE = {
|
|||
runDialogKind: "preview",
|
||||
previewRows: 5,
|
||||
fullRows: 1000,
|
||||
fullRunName: "",
|
||||
runErrors: [],
|
||||
runSettings: DEFAULT_RUN_SETTINGS,
|
||||
previewLoading: false,
|
||||
|
|
@ -71,6 +74,7 @@ const INITIAL_STATE = {
|
|||
| "runDialogKind"
|
||||
| "previewRows"
|
||||
| "fullRows"
|
||||
| "fullRunName"
|
||||
| "runErrors"
|
||||
| "runSettings"
|
||||
| "previewLoading"
|
||||
|
|
@ -87,6 +91,7 @@ export const useRecipeExecutionsStore = create<RecipeExecutionsState>((set) => (
|
|||
set({ previewRows: Number.isFinite(rows) && rows > 0 ? Math.floor(rows) : 1 }),
|
||||
setFullRows: (rows) =>
|
||||
set({ fullRows: Number.isFinite(rows) && rows > 0 ? Math.floor(rows) : 1 }),
|
||||
setFullRunName: (name) => set({ fullRunName: name }),
|
||||
setRunErrors: (errors) => set({ runErrors: errors }),
|
||||
setRunSettings: (patch) =>
|
||||
set((state) => ({
|
||||
|
|
|
|||
|
|
@ -216,20 +216,7 @@ export function makeLlmConfig(
|
|||
with_trace: "none",
|
||||
// biome-ignore lint/style/useNamingConvention: api schema
|
||||
extract_reasoning_content: false,
|
||||
scores:
|
||||
llmType === "judge"
|
||||
? [
|
||||
{
|
||||
name: "Quality",
|
||||
description: "Overall quality based on the criteria.",
|
||||
options: [
|
||||
{ value: "1", description: "Poor" },
|
||||
{ value: "3", description: "Acceptable" },
|
||||
{ value: "5", description: "Excellent" },
|
||||
],
|
||||
},
|
||||
]
|
||||
: undefined,
|
||||
scores: llmType === "judge" ? [] : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -268,7 +255,7 @@ export function makeModelConfig(
|
|||
// biome-ignore lint/style/useNamingConvention: api schema
|
||||
inference_temperature: "0.7",
|
||||
// biome-ignore lint/style/useNamingConvention: api schema
|
||||
inference_max_tokens: "256",
|
||||
inference_max_tokens: "",
|
||||
// biome-ignore lint/style/useNamingConvention: api schema
|
||||
inference_top_p: "",
|
||||
// biome-ignore lint/style/useNamingConvention: api schema
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue