Merge pull request #741 from LAION-AI/leaderboard

Use the new leaderboard api
This commit is contained in:
Keith Stevens
2023-01-16 08:38:23 +09:00
committed by GitHub
7 changed files with 149 additions and 96 deletions
+19
View File
@@ -41,6 +41,7 @@
"react-dom": "18.2.0",
"react-feature-flags": "^1.0.0",
"react-icons": "^4.7.1",
"react-table": "^7.8.0",
"sharp": "^0.31.3",
"swr": "^2.0.0",
"tailwindcss": "^3.2.4",
@@ -32625,6 +32626,18 @@
}
}
},
"node_modules/react-table": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
"integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.3 || ^17.0.0-0 || ^18.0.0"
}
},
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -61993,6 +62006,12 @@
"tslib": "^2.0.0"
}
},
"react-table": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
"integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
"requires": {}
},
"read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+1
View File
@@ -58,6 +58,7 @@
"react-dom": "18.2.0",
"react-feature-flags": "^1.0.0",
"react-icons": "^4.7.1",
"react-table": "^7.8.0",
"sharp": "^0.31.3",
"swr": "^2.0.0",
"tailwindcss": "^3.2.4",
@@ -1,97 +1,73 @@
import { Avatar, Box, Grid, GridItem, Text, useColorModeValue } from "@chakra-ui/react";
import { FiChevronDown } from "react-icons/fi";
import { Table, TableContainer, Tbody, Td, Th, Thead, Tr, useColorModeValue } from "@chakra-ui/react";
import React from "react";
import { useTable } from "react-table";
import { get } from "src/lib/api";
import useSWR from "swr";
import { LeaderboardEntity, LeaderboardTimeFrame } from "src/types/Leaderboard";
import useSWRImmutable from "swr/immutable";
const columns = [
{
Header: "Rank",
accessor: (item: LeaderboardEntity, rowIndex: number) => "#" + (item.user_rank + 1),
style: { width: "90px" },
},
{
Header: "Score",
accessor: "leader_score",
style: { width: "90px" },
},
{
Header: "User",
accessor: "display_name",
},
];
/**
* Presents a grid of leaderboard entries with more detailed information.
*/
const LeaderboardGridCell = () => {
const { data: leaderboardEntries } = useSWR("/api/leaderboard", get);
const LeaderboardGridCell = ({ timeFrame }: { timeFrame: LeaderboardTimeFrame }) => {
const { data } = useSWRImmutable<LeaderboardEntity[]>(`/api/leaderboard?time_frame=${timeFrame}`, get, {
fallbackData: [],
revalidateOnMount: true,
});
const backgroundColor = useColorModeValue("white", "gray.800");
const columns = `repeat(${FILTER.length}, 1fr)`;
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns, data });
return (
<>
<Grid>
<GridItem
colSpan={4}
bg={backgroundColor}
display="grid"
gridTemplateColumns={columns}
p="4"
borderRadius="lg"
mb="4"
shadow="base"
>
{FILTER.map(({ title, GridItemProps }, index) => (
<GridItem key={index} display="flex" {...GridItemProps}>
<Box display="flex" alignItems="center" gap="2" width="fit-content" borderRadius="md" cursor="pointer">
<Text fontSize="sm" fontWeight="bold" textTransform="uppercase">
{title}
</Text>
<FiChevronDown size="16" />
</Box>
</GridItem>
<TableContainer>
<Table {...getTableProps()}>
<Thead bg={backgroundColor}>
{headerGroups.map((headerGroup, idx) => (
<Tr key={idx} {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<Th {...column.getHeaderProps([{ style: column.style }])} key={column.id}>
{column.render("Header")}
</Th>
))}
</Tr>
))}
</GridItem>
</Grid>
<Grid templateColumns={columns} bg={backgroundColor} borderRadius="xl" shadow="base" p="4" gap="6">
{leaderboardEntries?.map(({ display_name, ranking, score }, index) => (
<GridItem key={index} colSpan={4} display="grid" gridTemplateColumns={columns} borderRadius="lg" p="2">
<GridItem overflow="hidden">
<Box display="flex" gap="2">
<Avatar size="xs" />
<Text>{display_name}</Text>
</Box>
</GridItem>
<GridItem>
<GridItem display="flex" justifyContent="center">
<Text>{ranking}</Text>
</GridItem>
</GridItem>
<GridItem display="flex" justifyContent="center">
<Text>{score}</Text>
</GridItem>
{/*
<GridItem display="flex" justifyContent="center">
<Text fontSize="xl">{item.medal}</Text>
</GridItem>
*/}
</GridItem>
))}
</Grid>
</>
</Thead>
<Tbody {...getTableBodyProps()}>
{rows.map((row) => {
prepareRow(row);
return (
<Tr key={row.id} {...row.getRowProps()}>
{row.cells.map((cell, idx) => {
return (
<Td key={row.id + idx} {...cell.getCellProps([{ style: cell.column.style }])}>
{cell.render("Cell")}
</Td>
);
})}
</Tr>
);
})}
</Tbody>
</Table>
</TableContainer>
);
};
/**
* Specifies the table headers in the grid.
*/
const FILTER = [
{
title: "User",
isActive: false,
GridItemProps: { justifyContent: "start" },
},
{
title: "Rank",
isActive: false,
GridItemProps: { justifyContent: "center" },
},
{
title: "Score",
isActive: false,
GridItemProps: { justifyContent: "center" },
},
/*
{
title: "Medal",
isActive: false,
GridItemProps: { justifyContent: "center" },
},
*/
];
export { LeaderboardGridCell };
+3 -2
View File
@@ -1,5 +1,6 @@
import { JWT } from "next-auth/jwt";
import type { Message } from "src/types/Conversation";
import { LeaderboardReply, LeaderboardTimeFrame } from "src/types/Leaderboard";
import type { BackendUser } from "src/types/Users";
export class OasstError {
@@ -187,8 +188,8 @@ export class OasstApiClient {
/**
* Returns the current leaderboard ranking.
*/
async fetch_leaderboard(): Promise<any> {
return this.get(`/api/v1/experimental/leaderboards/create/assistant`);
async fetch_leaderboard(time_frame: LeaderboardTimeFrame): Promise<LeaderboardReply> {
return this.get(`/api/v1/leaderboards/${time_frame}`);
}
}
+4 -8
View File
@@ -1,18 +1,14 @@
import { withoutRole } from "src/lib/auth";
import { oasstApiClient } from "src/lib/oasst_api_client";
import { LeaderboardTimeFrame } from "src/types/Leaderboard";
/**
* Returns the set of valid labels that can be applied to messages.
*/
const handler = withoutRole("banned", async (req, res) => {
const { leaderboard } = await oasstApiClient.fetch_leaderboard();
res.status(200).json(
leaderboard.map(({ display_name, ranking, score }) => ({
display_name,
ranking,
score,
}))
);
const time_frame = req.query.time_frame as LeaderboardTimeFrame;
const { leaderboard } = await oasstApiClient.fetch_leaderboard(time_frame);
res.status(200).json(leaderboard);
});
export default handler;
+25 -2
View File
@@ -1,7 +1,8 @@
import { Box, Heading } from "@chakra-ui/react";
import { Box, Heading, Tabs, TabList, TabPanels, Tab, TabPanel } from "@chakra-ui/react";
import Head from "next/head";
import { getDashboardLayout } from "src/components/Layout";
import { LeaderboardGridCell } from "src/components/LeaderboardGridCell";
import { LeaderboardTimeFrame } from "src/types/Leaderboard";
const Leaderboard = () => {
return (
@@ -14,7 +15,29 @@ const Leaderboard = () => {
<Heading fontSize="2xl" fontWeight="bold" pb="4">
Leaderboard
</Heading>
<LeaderboardGridCell />
<Tabs isFitted isLazy>
<TabList>
<Tab>Daily</Tab>
<Tab>Weekly</Tab>
<Tab>Monthly</Tab>
<Tab>Overall</Tab>
</TabList>
<TabPanels>
<TabPanel p="0">
<LeaderboardGridCell timeFrame={LeaderboardTimeFrame.day} />
</TabPanel>
<TabPanel p="0">
<LeaderboardGridCell timeFrame={LeaderboardTimeFrame.week} />
</TabPanel>
<TabPanel p="0">
<LeaderboardGridCell timeFrame={LeaderboardTimeFrame.month} />
</TabPanel>
<TabPanel p="0">
<LeaderboardGridCell timeFrame={LeaderboardTimeFrame.total} />
</TabPanel>
</TabPanels>
</Tabs>
</Box>
</>
);
+37
View File
@@ -3,3 +3,40 @@ export interface LeaderboardEntry {
ranking: number;
score: number;
}
export const enum LeaderboardTimeFrame {
day = "day",
week = "week",
month = "month",
total = "total",
}
export interface LeaderboardReply {
time_frame: LeaderboardTimeFrame;
leaderboard: LeaderboardEntity[];
}
export interface LeaderboardEntity {
user_rank: number;
user_id: string;
username: string;
auth_method: string;
display_name: string;
leader_score: number;
base_date: string;
modified_date: string;
prompts: number;
replies_assistant: number;
replies_prompter: number;
labels_simple: number;
labels_full: number;
rankings_total: number;
rankings_good: number;
accepted_prompts: number;
accepted_replies_assistant: number;
accepted_replies_prompter: number;
reply_ranked_1: number;
reply_ranked_2: number;
reply_ranked_3: number;
streak_last_day_date: number | null;
streak_days: number | null;
}