mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-11 03:38:38 +00:00
fix(lens): feed the live run from the reviews endpoint and keep View run open
LiveRun now gets its reviews from useJobReviews instead of the list, which no longer carries them. View run stays clickable while a run is queued or running, and before the first trace the opened view says what the worker is doing.
This commit is contained in:
parent
2f5fb3ef44
commit
7ef76eabff
8 changed files with 65 additions and 12 deletions
|
|
@ -282,6 +282,7 @@ export function InvestigationsView({
|
|||
results={results}
|
||||
agents={Array.isArray(agents.data) ? agents.data : []}
|
||||
queue={{
|
||||
api,
|
||||
lenses,
|
||||
workers: query.data?.workers ?? [],
|
||||
onConnect: () => setWorkerSetup(true),
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|||
import { RunsTab } from "./RunsTab";
|
||||
import { InvestigationProgress } from "../InvestigationProgress";
|
||||
import { LiveRun } from "../live/LiveRun";
|
||||
import { LiveRunLoader } from "../live/LiveRunLoader";
|
||||
import { type QueueContext } from "../useQueueReason";
|
||||
import { liveJob } from "../../model/live";
|
||||
import { RunNowDialog } from "./RunNowDialog";
|
||||
|
|
@ -109,7 +110,12 @@ export function InvestigationDetail({
|
|||
onCancel={readOnly ? undefined : () => void update((api) => api.cancelRun(lens.id))}
|
||||
/>
|
||||
)}
|
||||
{live && <LiveRun key={live.id} job={live} reviews={live.reviews} name={lens.settings.name} queue={queue} />}
|
||||
{live &&
|
||||
(queue ? (
|
||||
<LiveRunLoader key={live.id} lensId={lens.id} job={live} name={lens.settings.name} queue={queue} />
|
||||
) : (
|
||||
<LiveRun key={live.id} job={live} reviews={live.reviews} name={lens.settings.name} />
|
||||
))}
|
||||
{runNow && (
|
||||
<RunNowDialog
|
||||
lens={lens}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useState, type ReactNode } from "react";
|
||||
|
||||
import { StatusBadge, type StatusTone } from "@/components/shared/table_cells";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
@ -38,9 +38,11 @@ export function LiveDrawer({
|
|||
groups,
|
||||
decided,
|
||||
scope,
|
||||
waiting,
|
||||
onPick,
|
||||
onFollow,
|
||||
}: {
|
||||
waiting?: ReactNode;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
name: string;
|
||||
|
|
@ -86,7 +88,10 @@ export function LiveDrawer({
|
|||
phase={following ? phase : SETTLED}
|
||||
/>
|
||||
) : (
|
||||
<p className="py-6 text-[12px] text-muted-foreground">Waiting for the first trace review.</p>
|
||||
<div className="flex flex-col gap-1 py-6 text-[12px] text-muted-foreground">
|
||||
<p className="text-[13px] text-foreground">Waiting for the first trace…</p>
|
||||
{waiting}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
<section aria-label="Conclusions so far" className="flex min-h-0 flex-col gap-5 overflow-y-auto px-5 py-4">
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ export function LiveRun({
|
|||
if (review) pin(review);
|
||||
setDrawerOpen(true);
|
||||
};
|
||||
const waiting = reason && (
|
||||
<>
|
||||
<QueueReasonText reason={reason} onConnect={queue?.onConnect} />
|
||||
<WorkerTasks reason={reason} queue={queue} />
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -57,14 +63,7 @@ export function LiveRun({
|
|||
<LiveStrip
|
||||
model={model}
|
||||
state={stripState(withReviews, model, reason ? queueReasonText(reason) : undefined)}
|
||||
waiting={
|
||||
reason && (
|
||||
<>
|
||||
<QueueReasonText reason={reason} onConnect={queue?.onConnect} />
|
||||
<WorkerTasks reason={reason} queue={queue} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
waiting={waiting}
|
||||
playback={playback}
|
||||
reviewed={reviewed}
|
||||
selected={job.coverage.selected}
|
||||
|
|
@ -97,6 +96,7 @@ export function LiveRun({
|
|||
groups={conclusions(decided, job.settings.checks)}
|
||||
decided={decided.length}
|
||||
scope={job.reviewed > reviews.length ? `From the latest ${reviews.length} of ${job.reviewed} reviewed traces` : ""}
|
||||
waiting={waiting}
|
||||
onPick={pin}
|
||||
onFollow={() => setPinned(null)}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
"use client";
|
||||
|
||||
import type { Job } from "../../model/types";
|
||||
import type { QueueContext } from "../useQueueReason";
|
||||
import { LiveRun } from "./LiveRun";
|
||||
import { useJobReviews } from "./useJobReviews";
|
||||
|
||||
export function LiveRunLoader({
|
||||
lensId,
|
||||
job,
|
||||
name,
|
||||
queue,
|
||||
}: {
|
||||
lensId: string;
|
||||
job: Job;
|
||||
name: string;
|
||||
queue: QueueContext;
|
||||
}) {
|
||||
const reviews = useJobReviews(queue.api, lensId, job);
|
||||
return <LiveRun job={job} reviews={reviews} name={name} queue={queue} />;
|
||||
}
|
||||
|
|
@ -112,7 +112,7 @@ export function LiveStrip({
|
|||
)}
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1">
|
||||
<Button variant="outline" size="xs" onClick={() => onOpen()} disabled={!recent.length}>
|
||||
<Button variant="outline" size="xs" onClick={() => onOpen()} disabled={state.kind === "done" && !recent.length}>
|
||||
<PanelRight />
|
||||
View run
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
"use client";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
|
||||
import { lensQueries } from "../../api/queries";
|
||||
import type { LensApi } from "../../api/service";
|
||||
import { appendPage, EMPTY_FEED, type ReviewFeed } from "../../model/live";
|
||||
import type { Job, Review } from "../../model/types";
|
||||
|
||||
export function useJobReviews(api: LensApi, lensId: string, job: Pick<Job, "id" | "status">): readonly Review[] {
|
||||
const [feed, setFeed] = useState<ReviewFeed>(EMPTY_FEED);
|
||||
const live = job.status === "queued" || job.status === "running";
|
||||
const { data } = useQuery(lensQueries.reviews(api, { lensId, jobId: job.id, after: feed.cursor, live }));
|
||||
const next = data ? appendPage(feed, data) : feed;
|
||||
if (next !== feed) setFeed(next);
|
||||
return next.reviews;
|
||||
}
|
||||
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
import { useNow } from "@/hooks/useNow";
|
||||
|
||||
import type { LensApi } from "../api/service";
|
||||
import { queueReason, type QueueReason } from "../model/status";
|
||||
import type { Job, Lens, LensList } from "../model/types";
|
||||
|
||||
export interface QueueContext {
|
||||
api: LensApi;
|
||||
lenses: readonly Lens[];
|
||||
workers: readonly LensList["workers"][number][];
|
||||
onConnect: () => void;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue