Skip to content

Commit

Permalink
feat(frontend): add skipped state to verify plugin UI (#244)
Browse files Browse the repository at this point in the history
Co-authored-by: Jagger <[email protected]>
  • Loading branch information
IANTHEREAL and 634750802 authored Aug 26, 2024
1 parent 226c209 commit 717760f
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 46 deletions.
9 changes: 7 additions & 2 deletions frontend/app/src/experimental/chat-verify-service/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export const enum VerifyState {
EXTRACTING = 'EXTRACTING',
VALIDATING = 'VALIDATING',
SUCCESS = 'SUCCESS',
FAILED = 'FAILED'
FAILED = 'FAILED',
SKIPPED = 'SKIPPED'
}

const verifyResponse = z.object({
Expand Down Expand Up @@ -48,5 +49,9 @@ export async function getVerify (id: string) {
}

export function isFinalVerifyState (state: VerifyState) {
return [VerifyState.SUCCESS, VerifyState.FAILED].includes(state);
return [VerifyState.SUCCESS, VerifyState.FAILED, VerifyState.SKIPPED].includes(state);
}

export function isVisibleVerifyState (state: VerifyState) {
return [VerifyState.SUCCESS, VerifyState.FAILED, VerifyState.VALIDATING].includes(state);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { ChatMessageController } from '@/components/chat/chat-message-contr
import { isNotFinished } from '@/components/chat/utils';
import { Button } from '@/components/ui/button';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import { getVerify, isFinalVerifyState, verify, VerifyState } from '@/experimental/chat-verify-service/api';
import { getVerify, isFinalVerifyState, isVisibleVerifyState, verify, VerifyState } from '@/experimental/chat-verify-service/api';
import { CheckCircle2Icon, CheckIcon, ChevronDownIcon, Loader2Icon, XIcon } from 'lucide-react';
import { InformationCircleIcon } from 'nextra/icons';
import { useEffect, useState } from 'react';
Expand All @@ -15,8 +15,6 @@ export function MessageVerify ({ user, assistant }: { user: ChatMessageControlle
const question = useChatMessageField(user, 'content');
const answer = useChatMessageField(assistant, 'content');

const messageFinished = !isNotFinished(messageState);

const me = useAuth();
const [verifyId, setVerifyId] = useState<string>();
const [verifying, setVerifying] = useState(false);
Expand All @@ -39,7 +37,10 @@ export function MessageVerify ({ user, assistant }: { user: ChatMessageControlle
},
},
);
const finished = result ? isFinalVerifyState(result.status) : false;

const messageFinished = !isNotFinished(messageState);
const verifyFinished = result ? isFinalVerifyState(result.status) : false;
const shouldDisplayContent = result ? isVisibleVerifyState(result.status) : false;

useEffect(() => {
if (enabled && !verifyId && question && answer && messageFinished && !verifying) {
Expand All @@ -53,56 +54,54 @@ export function MessageVerify ({ user, assistant }: { user: ChatMessageControlle
}
}, [enabled, verifyId, messageFinished, question, answer, verifying]);

const shouldDisplayContent = result?.status === VerifyState.VALIDATING ||
result?.status === VerifyState.SUCCESS ||
result?.status === VerifyState.FAILED;
useEffect(() => {
console.debug(`[message-verify] display=${shouldDisplayContent}:`, result);
}, [shouldDisplayContent, result]);

if (!isSuperuser || !enabled || !messageFinished || !shouldDisplayContent) {
return null;
}

return (
shouldDisplayContent && (
<Collapsible className="p-2 border rounded-lg">
<CollapsibleTrigger asChild>
<Button className="group gap-2 w-full" variant="ghost" disabled={!finished}>
{result?.status === VerifyState.VALIDATING
? <Loader2Icon className="size-4 animate-spin repeat-infinite" />
: result?.status === VerifyState.SUCCESS
? <CheckCircle2Icon className="size-4 text-green-500" />
: result?.status === VerifyState.FAILED
? <InformationCircleIcon className="size-4 text-yellow-500" />
: undefined}
{result?.message ?? 'Preparing verify chat result...'}
<ChevronDownIcon className="size-4 ml-auto transition-transform group-data-[state=open]:rotate-180" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
{result && <ul className="space-y-2">
{result.runs.map(((run, index) => (
<li key={index}>
<div className="p-2 space-y-1">
<Collapsible className="p-2 border rounded-lg">
<CollapsibleTrigger asChild>
<Button className="group gap-2 w-full" variant="ghost" disabled={!verifyFinished}>
{result?.status === VerifyState.VALIDATING
? <Loader2Icon className="size-4 animate-spin repeat-infinite" />
: result?.status === VerifyState.SUCCESS
? <CheckCircle2Icon className="size-4 text-green-500" />
: result?.status === VerifyState.FAILED
? <InformationCircleIcon className="size-4 text-yellow-500" />
: undefined}
{result?.message ?? 'Preparing verify chat result...'}
<ChevronDownIcon className="size-4 ml-auto transition-transform group-data-[state=open]:rotate-180" />
</Button>
</CollapsibleTrigger>
<CollapsibleContent>
{result && <ul className="space-y-2">
{result.runs.map(((run, index) => (
<li key={index}>
<div className="p-2 space-y-1">
<pre className="whitespace-pre-wrap text-xs text-accent-foreground rounded">
{run.success ? <CheckIcon className="inline-block mr-2 size-3 text-green-500" /> : <XIcon className="inline-block mr-2 size-3 text-red-500" />}
<code>{run.sql}</code>
</pre>
<p className="text-xs text-muted-foreground">
{run.explanation}
</p>
{run.success && <pre className="whitespace-pre-wrap text-xs bg-muted text-muted-foreground p-2 rounded">{JSON.stringify(run.results)}</pre>}
{!run.success && <pre className="whitespace-pre-wrap text-xs bg-muted text-muted-foreground p-2 rounded">{run.sql_error_code} {run.sql_error_message}</pre>}
</div>
</li>
)))}
</ul>}
{result && result.runs.length === 0 && (
<div className="p-2 text-muted-foreground text-xs">
Empty result.
</div>
)}
</CollapsibleContent>
</Collapsible>
)
<p className="text-xs text-muted-foreground">
{run.explanation}
</p>
{run.success && <pre className="whitespace-pre-wrap text-xs bg-muted text-muted-foreground p-2 rounded">{JSON.stringify(run.results)}</pre>}
{!run.success && <pre className="whitespace-pre-wrap text-xs bg-muted text-muted-foreground p-2 rounded">{run.sql_error_code} {run.sql_error_message}</pre>}
</div>
</li>
)))}
</ul>}
{result && result.runs.length === 0 && (
<div className="p-2 text-muted-foreground text-xs">
Empty result.
</div>
)}
</CollapsibleContent>
</Collapsible>
);
}

Expand Down

0 comments on commit 717760f

Please sign in to comment.