Skip to content

Commit

Permalink
style(frontend): update experimental message verify component (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
634750802 authored Aug 27, 2024
1 parent 7b019ec commit 7f844ef
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 72 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

[![Backend Docker Image Version](https://img.shields.io/docker/v/tidbai/backend?sort=semver&arch=amd64&label=tidbai%2Fbackend&color=blue&logo=fastapi)](https://hub.docker.com/r/tidbai/backend)
[![Frontend Docker Image Version](https://img.shields.io/docker/v/tidbai/frontend?sort=semver&arch=amd64&label=tidbai%2Ffrontend&&color=blue&logo=next.js)](https://hub.docker.com/r/tidbai/frontend)
[![E2E Status](https://img.shields.io/github/check-runs/pingcap/tidb.ai/main?nameFilter=E2E%20Test&label=e2e)](https://github.com/pingcap/tidb.ai/actions/workflows/release.yml)
[![E2E Status](https://img.shields.io/github/check-runs/pingcap/tidb.ai/main?nameFilter=E2E%20Test&label=e2e)](https://tidb-ai-playwright.vercel.app/)

## Introduction

Expand Down
3 changes: 2 additions & 1 deletion frontend/app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ public/robots.txt
public/sitemap.xml
public/sitemap-*.xml

*storybook.log
*storybook.log
storybook-static
40 changes: 31 additions & 9 deletions frontend/app/src/experimental/chat-verify-service/api.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { handleResponse } from '@/lib/request';
import { z } from 'zod';
import { z, type ZodType } from 'zod';

const HOST = 'https://verify.tidb.ai';

export const enum VerifyState {
export const enum VerifyStatus {
CREATED = 'CREATED',
EXTRACTING = 'EXTRACTING',
VALIDATING = 'VALIDATING',
Expand All @@ -12,12 +12,34 @@ export const enum VerifyState {
SKIPPED = 'SKIPPED'
}

export interface MessageVerifyResponse {
status: VerifyStatus;
message?: string | null;
runs: MessageVerifyResponse.Run[];
}

export namespace MessageVerifyResponse {
export type Run = {
sql: string
explanation: string
} &
({
success: true,
results?: any[][]
} | {
success: false,
sql_error_code?: number | null,
sql_error_message?: string | null,
warnings: string[]
})
}

const verifyResponse = z.object({
job_id: z.string(),
});

const getVerifyResponse = z.object({
status: z.enum([VerifyState.CREATED, VerifyState.EXTRACTING, VerifyState.VALIDATING, VerifyState.SUCCESS, VerifyState.FAILED]),
status: z.enum([VerifyStatus.CREATED, VerifyStatus.EXTRACTING, VerifyStatus.VALIDATING, VerifyStatus.SUCCESS, VerifyStatus.FAILED, VerifyStatus.SKIPPED]),
message: z.string().nullish(),
runs: z.object({
sql: z.string(),
Expand All @@ -32,7 +54,7 @@ const getVerifyResponse = z.object({
sql_error_message: z.string().nullish(),
warnings: z.string().array(),
}))).array(),
});
}) satisfies ZodType<MessageVerifyResponse, any, any>;

export async function verify (question: string, answer: string) {
return await fetch(`${HOST}/api/v1/sqls-validation`, {
Expand All @@ -48,10 +70,10 @@ export async function getVerify (id: string) {
return await fetch(`${HOST}/api/v1/sqls-validation/${id}`).then(handleResponse(getVerifyResponse));
}

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

export function isVisibleVerifyState (state: VerifyState) {
return [VerifyState.SUCCESS, VerifyState.FAILED, VerifyState.VALIDATING].includes(state);
}
export function isVisibleVerifyState (state: VerifyStatus) {
return [VerifyStatus.SUCCESS, VerifyStatus.FAILED].includes(state);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AuthProvider } from '@/components/auth/AuthProvider';
import { ChatMessageController } from '@/components/chat/chat-message-controller';
import { getVerify, verify, VerifyState } from '@/experimental/chat-verify-service/api.mock';
import { getVerify, verify, VerifyStatus } from '@/experimental/chat-verify-service/api.mock';
import type { Meta, StoryObj } from '@storybook/react';
import { mutate } from 'swr';
import { MessageVerify } from './message-verify';
Expand Down Expand Up @@ -34,10 +34,12 @@ const meta = {
render (_, { id }) {
return (
<AuthProvider key={id} isLoading={false} isValidating={false} me={{ email: '[email protected]', is_active: true, is_superuser: true, is_verified: true, id: '000' }} reload={() => {}}>
<MessageVerify
user={new ChatMessageController({ finished_at: new Date(), id: 0, role: 'user', content: 'Question' } as any, undefined)}
assistant={new ChatMessageController({ finished_at: new Date(), id: 1, role: 'assistant', content: 'Answer' } as any, undefined)}
/>
<div style={{ width: 600 }}>
<MessageVerify
user={new ChatMessageController({ finished_at: new Date(), id: 0, role: 'user', content: 'Question' } as any, undefined)}
assistant={new ChatMessageController({ finished_at: new Date(), id: 1, role: 'assistant', content: 'Answer' } as any, undefined)}
/>
</div>
</AuthProvider>
);
},
Expand All @@ -46,33 +48,58 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;

// More on writing stories with args: https://storybook.js.org/docs/writing-stories/args
export const Verified: Story = {
export const Creating: Story = {
beforeEach: () => {
getVerify.mockReturnValue(new Promise(() => {}));
},
};

export const Created: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyState.SUCCESS,
message: 'This is a success message returned from server',
runs: [
{ sql: 'SOME A FROM B FROM C FROM D FROM E FROM F FROM G', results: [], success: true, explanation: 'some description for this SQL' },
],
status: VerifyStatus.CREATED,
message: 'This is a created message returned from server',
runs: [],
}));
},
};

export const Extracting: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyStatus.EXTRACTING,
message: 'This is a extracting message returned from server',
runs: [],
}));
},
};

export const Validating: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyState.VALIDATING,
status: VerifyStatus.VALIDATING,
message: 'This is a validating message returned from server',
runs: [],
}));
},
};

export const Verified: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyStatus.SUCCESS,
message: 'This is a success message returned from server',
runs: [
{ sql: 'SOME A FROM B FROM C FROM D FROM E FROM F FROM G', results: [], success: true, explanation: 'some description for this SQL' },
],
}));
},
};

export const Failed: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyState.FAILED,
status: VerifyStatus.FAILED,
message: 'This is a failed message returned from server',
runs: [
{ sql: 'SOME A FROM B FROM C FROM D FROM E FROM F FROM G', results: [], success: true, explanation: 'Some description for this SQL' },
Expand All @@ -82,3 +109,18 @@ export const Failed: Story = {
},
};

export const Skipped: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.resolve({
status: VerifyStatus.SKIPPED,
message: 'This is a skipped message returned from server',
runs: [],
}));
},
};

export const ApiError: Story = {
beforeEach: () => {
getVerify.mockReturnValue(Promise.reject(new Error('This is error from server')));
},
};
Loading

0 comments on commit 7f844ef

Please sign in to comment.