adding new stat panel

This commit is contained in:
ecwu
2024-07-17 00:17:26 +08:00
parent a45785c607
commit 52d8c3280e
4 changed files with 120 additions and 48 deletions

View File

@@ -14,6 +14,7 @@ import {
TemplateAPI, TemplateAPI,
TemplateTools, TemplateTools,
addTotalCost, addTotalCost,
getTotalCost,
} from "./app"; } from "./app";
import ChatGPT, { import ChatGPT, {
calculate_token_length, calculate_token_length,
@@ -34,7 +35,15 @@ import { ListToolsTempaltes } from "./listToolsTemplates";
import { autoHeight } from "./textarea"; import { autoHeight } from "./textarea";
import Search from "./search"; import Search from "./search";
import { IDBPDatabase } from "idb"; import { IDBPDatabase } from "idb";
import { MagnifyingGlassIcon } from "@heroicons/react/24/outline"; import {
MagnifyingGlassIcon,
CubeIcon,
BanknotesIcon,
DocumentTextIcon,
ChatBubbleLeftEllipsisIcon,
ScissorsIcon,
SwatchIcon,
} from "@heroicons/react/24/outline";
export interface TemplateChatStore extends ChatStore { export interface TemplateChatStore extends ChatStore {
name: string; name: string;
@@ -465,7 +474,7 @@ export default function ChatBOX(props: {
/> />
)} )}
<div <div
className="relative cursor-pointer rounded p-2 bg-base-200" className="relative cursor-pointer rounded p-2"
onClick={() => setShowSettings(true)} onClick={() => setShowSettings(true)}
> >
<button <button
@@ -479,38 +488,97 @@ export default function ChatBOX(props: {
> >
<MagnifyingGlassIcon class="w-5 h-5" /> <MagnifyingGlassIcon class="w-5 h-5" />
</button> </button>
<div> <div class="stats shadow hidden lg:inline-grid">
<button className="underline"> <div class="stat">
{chatStore.systemMessageContent.length > 16 <div class="stat-figure text-secondary">
? chatStore.systemMessageContent.slice(0, 16) + ".." <CubeIcon class="h-10 w-10" />
: chatStore.systemMessageContent} </div>
</button>{" "} <div class="stat-title">Model</div>
<button className="underline"> <div class="stat-value">{chatStore.model}</div>
{chatStore.streamMode ? Tr("STREAM") : Tr("FETCH")} <div class="stat-desc">
</button>{" "} Prompt:{" "}
{chatStore.toolsString.trim() && ( {chatStore.systemMessageContent.length > 30
<button className="underline">TOOL</button> ? chatStore.systemMessageContent.slice(0, 30) + ".."
)} : chatStore.systemMessageContent}
</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<SwatchIcon class="h-10 w-10" />
</div>
<div class="stat-title">Mode</div>
<div class="stat-value">
{chatStore.streamMode ? Tr("STREAM") : Tr("FETCH")}
</div>
<div class="stat-desc">STREAM/FETCH</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<ChatBubbleLeftEllipsisIcon class="h-10 w-10" />
</div>
<div class="stat-title">Tokens</div>
<div class="stat-value">{chatStore.totalTokens}</div>
<div class="stat-desc">Max: {chatStore.maxTokens}</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<ScissorsIcon class="h-10 w-10" />
</div>
<div class="stat-title">Cut</div>
<div class="stat-value">{chatStore.postBeginIndex}</div>
<div class="stat-desc">
Max: {chatStore.history.filter(({ hide }) => !hide).length}
</div>
</div>
<div class="stat">
<div class="stat-figure text-secondary">
<BanknotesIcon class="h-10 w-10" />
</div>
<div class="stat-title">Cost</div>
<div class="stat-value">${chatStore.cost.toFixed(4)}</div>
<div class="stat-desc">
Accumulated: ${getTotalCost().toFixed(2)}
</div>
</div>
</div> </div>
<div className="text-xs"> <div class="lg:hidden">
<span className="underline">{chatStore.model}</span>{" "} <div>
<span> <button className="underline">
Tokens:{" "} {chatStore.systemMessageContent.length > 16
<span className="underline"> ? chatStore.systemMessageContent.slice(0, 16) + ".."
{chatStore.totalTokens}/{chatStore.maxTokens} : chatStore.systemMessageContent}
</span> </button>{" "}
</span>{" "} <button className="underline">
<span> {chatStore.streamMode ? Tr("STREAM") : Tr("FETCH")}
{Tr("Cut")}:{" "} </button>{" "}
<span className="underline"> {chatStore.toolsString.trim() && (
{chatStore.postBeginIndex}/ <button className="underline">TOOL</button>
{chatStore.history.filter(({ hide }) => !hide).length} )}
</div>
<div className="text-xs">
<span class="underline">{chatStore.model}</span>{" "}
<span>
Tokens:{" "}
<span class="underline">
{chatStore.totalTokens}/{chatStore.maxTokens}
</span>
</span>{" "} </span>{" "}
</span>{" "} <span>
<span> {Tr("Cut")}:{" "}
{Tr("Cost")}:{" "} <span class="underline">
<span className="underline">${chatStore.cost.toFixed(4)}</span> {chatStore.postBeginIndex}/
</span> {chatStore.history.filter(({ hide }) => !hide).length}
</span>{" "}
</span>{" "}
<span>
{Tr("Cost")}:{" "}
<span className="underline">${chatStore.cost.toFixed(4)}</span>
</span>
</div>
</div> </div>
</div> </div>
<div className="grow overflow-scroll"> <div className="grow overflow-scroll">
@@ -730,7 +798,7 @@ export default function ChatBOX(props: {
<p className="text-center"> <p className="text-center">
{chatStore.history.length > 0 && ( {chatStore.history.length > 0 && (
<button <button
className="btn btn-warning disabled:line-through disabled:btn-neutral disabled:text-white m-2 p-2" className="btn btn-outline btn-sm btn-warning disabled:line-through disabled:btn-neutral disabled:text-white m-2 p-2"
disabled={showGenerating} disabled={showGenerating}
onClick={async () => { onClick={async () => {
const messageIndex = chatStore.history.length - 1; const messageIndex = chatStore.history.length - 1;
@@ -1110,7 +1178,7 @@ export default function ChatBOX(props: {
</span> </span>
<span className={`flex justify-between p-2`}> <span className={`flex justify-between p-2`}>
<button <button
className="rounded m-1 p-1 border-2 bg-red-400 hover:bg-red-600" className="btn btn-info m-1 p-1"
onClick={() => setShowAddToolMsg(false)} onClick={() => setShowAddToolMsg(false)}
> >
{Tr("Cancle")} {Tr("Cancle")}

View File

@@ -20,7 +20,7 @@ export function ListAPIs({
keyField, keyField,
}: Props) { }: Props) {
return ( return (
<div className="break-all opacity-80 p-3 rounded bg-white my-3 text-left dark:text-black"> <div className="break-all opacity-80 p-3 rounded base-200 my-3 text-left">
<h2>{Tr(`Saved ${label} templates`)}</h2> <h2>{Tr(`Saved ${label} templates`)}</h2>
<hr className="my-2" /> <hr className="my-2" />
<div className="flex flex-wrap"> <div className="flex flex-wrap">
@@ -31,8 +31,8 @@ export function ListAPIs({
chatStore[apiField] === t.endpoint && chatStore[apiField] === t.endpoint &&
// @ts-ignore // @ts-ignore
chatStore[keyField] === t.key chatStore[keyField] === t.key
? "bg-red-600" ? "bg-info"
: "bg-red-400" : "bg-base-300"
} w-fit p-2 m-1 flex flex-col`} } w-fit p-2 m-1 flex flex-col`}
onClick={() => { onClick={() => {
// @ts-ignore // @ts-ignore
@@ -43,9 +43,9 @@ export function ListAPIs({
}} }}
> >
<span className="w-full text-center">{t.name}</span> <span className="w-full text-center">{t.name}</span>
<hr className="mt-2" /> <span className="flex justify-between gap-x-2">
<span className="flex justify-between">
<button <button
class="link"
onClick={() => { onClick={() => {
const name = prompt(`Give **${label}** template a name`); const name = prompt(`Give **${label}** template a name`);
if (!name) { if (!name) {
@@ -55,9 +55,10 @@ export function ListAPIs({
setTmps(structuredClone(tmps)); setTmps(structuredClone(tmps));
}} }}
> >
🖋 Edit
</button> </button>
<button <button
class="link"
onClick={() => { onClick={() => {
if ( if (
!confirm( !confirm(
@@ -70,7 +71,7 @@ export function ListAPIs({
setTmps(structuredClone(tmps)); setTmps(structuredClone(tmps));
}} }}
> >
Delete
</button> </button>
</span> </span>
</div> </div>

View File

@@ -33,8 +33,8 @@ export function ListToolsTempaltes({
<div <div
className={`cursor-pointer rounded ${ className={`cursor-pointer rounded ${
chatStore.toolsString === t.toolsString chatStore.toolsString === t.toolsString
? "bg-red-600" ? "bg-info"
: "bg-red-400" : "bg-base-300"
} w-fit p-2 m-1 flex flex-col`} } w-fit p-2 m-1 flex flex-col`}
onClick={() => { onClick={() => {
chatStore.toolsString = t.toolsString; chatStore.toolsString = t.toolsString;
@@ -42,9 +42,9 @@ export function ListToolsTempaltes({
}} }}
> >
<span className="w-full text-center">{t.name}</span> <span className="w-full text-center">{t.name}</span>
<hr className="mt-2" /> <span className="flex justify-between gap-x-2">
<span className="flex justify-between">
<button <button
class="link"
onClick={() => { onClick={() => {
const name = prompt(`Give **tools** template a name`); const name = prompt(`Give **tools** template a name`);
if (!name) { if (!name) {
@@ -54,9 +54,10 @@ export function ListToolsTempaltes({
setTemplateTools(structuredClone(templateTools)); setTemplateTools(structuredClone(templateTools));
}} }}
> >
🖋 Edit
</button> </button>
<button <button
class="link"
onClick={() => { onClick={() => {
if ( if (
!confirm(`Are you sure to delete this **tools** template?`) !confirm(`Are you sure to delete this **tools** template?`)
@@ -67,7 +68,7 @@ export function ListToolsTempaltes({
setTemplateTools(structuredClone(templateTools)); setTemplateTools(structuredClone(templateTools));
}} }}
> >
Delete
</button> </button>
</span> </span>
</div> </div>

View File

@@ -121,7 +121,9 @@ export default function Message(props: Props) {
<div <div
className={`chat-bubble ${ className={`chat-bubble ${
chat.role === "assistant" chat.role === "assistant"
? "chat-bubble-secondary" ? renderColor
? "chat-bubble-neutral"
: "chat-bubble-secondary"
: "chat-bubble-primary" : "chat-bubble-primary"
}`} }`}
> >