blanchon's picture
Evaluation: 4-round policy, validations store, prev/next, copy/clear, build flag
6d55c38
<script lang="ts">
import { Button } from '$lib/components/ui/button';
import * as Tooltip from '$lib/components/ui/tooltip';
import SunIcon from 'phosphor-svelte/lib/SunIcon';
import MoonIcon from 'phosphor-svelte/lib/MoonIcon';
import CaretLeftIcon from 'phosphor-svelte/lib/CaretLeftIcon';
import ListChecksIcon from 'phosphor-svelte/lib/ListChecksIcon';
import { mode, toggleMode } from 'mode-watcher';
import { goto } from '$app/navigation';
import { page } from '$app/state';
import HfLogo from '$lib/components/hf-logo.svelte';
import { site } from '$lib/site';
import type { Match } from '$lib/types';
import { buildEvalQueue, evalUrl, firstUnreviewed, EVAL_ENABLED } from '$lib/eval';
import { toast } from 'svelte-sonner';
const inEval = $derived(page.url.searchParams.get('eval') === '1');
const matches = $derived((page.data?.matches ?? []) as Match[]);
function toggleEval() {
if (inEval) {
const url = new URL(page.url);
url.searchParams.delete('eval');
url.searchParams.delete('i');
goto(url.pathname + (url.searchParams.size ? '?' + url.searchParams.toString() : ''));
return;
}
const queue = buildEvalQueue(matches);
if (!queue.length) return;
// Resume on the first un-reviewed candidate so prior sessions aren't replayed.
const start = firstUnreviewed(queue);
if (start < 0) {
toast.success('All eval candidates already reviewed', {
description: `${queue.length} total. Clear local data in the Flag dialog to redo.`
});
return;
}
goto(evalUrl(queue[start], start));
}
</script>
<header class="border-b border-border/60">
<div class="mx-auto flex h-12 w-full max-w-[1600px] items-center gap-3 px-4">
<a
href="/"
class="inline-flex items-center gap-1.5 text-xs font-medium text-muted-foreground transition hover:text-foreground"
aria-label="Back to dataset home"
>
<CaretLeftIcon size={12} weight="bold" />
<span>{site.name}</span>
</a>
<div class="ml-auto flex items-center gap-1">
{#if EVAL_ENABLED}
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button
{...props}
variant="ghost"
size="icon-sm"
onclick={toggleEval}
disabled={!matches.length}
data-active={inEval || undefined}
class="data-active:bg-amber-500/15 data-active:text-amber-700 dark:data-active:text-amber-300"
aria-label={inEval ? 'Exit evaluation' : 'Start evaluation'}
>
<ListChecksIcon size={16} weight="duotone" />
</Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content side="bottom">
{inEval ? 'Exit evaluation' : 'Start evaluation'}
</Tooltip.Content>
</Tooltip.Root>
{/if}
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button
{...props}
href={site.datasetUrl}
target="_blank"
rel="noreferrer noopener"
variant="ghost"
size="icon-sm"
aria-label="Dataset on Hugging Face"
>
<HfLogo class="size-4" />
</Button>
{/snippet}
</Tooltip.Trigger>
<Tooltip.Content side="bottom">View on Hugging Face</Tooltip.Content>
</Tooltip.Root>
<Button variant="ghost" size="icon-sm" onclick={toggleMode} aria-label="Toggle theme">
{#if mode.current === 'dark'}
<SunIcon size={16} weight="duotone" />
{:else}
<MoonIcon size={16} weight="duotone" />
{/if}
</Button>
</div>
</div>
</header>