show cost
This commit is contained in:
@@ -4,7 +4,7 @@ import "./global.css";
|
|||||||
import { calculate_token_length, Message } from "./chatgpt";
|
import { calculate_token_length, Message } from "./chatgpt";
|
||||||
import getDefaultParams from "./getDefaultParam";
|
import getDefaultParams from "./getDefaultParam";
|
||||||
import ChatBOX from "./chatbox";
|
import ChatBOX from "./chatbox";
|
||||||
import { options } from "./settings";
|
import models from "./models";
|
||||||
|
|
||||||
import CHATGPT_API_WEB_VERSION from "./CHATGPT_API_WEB_VERSION";
|
import CHATGPT_API_WEB_VERSION from "./CHATGPT_API_WEB_VERSION";
|
||||||
|
|
||||||
@@ -26,6 +26,7 @@ export interface ChatStore {
|
|||||||
streamMode: boolean;
|
streamMode: boolean;
|
||||||
model: string;
|
model: string;
|
||||||
responseModelName: string;
|
responseModelName: string;
|
||||||
|
cost: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions";
|
const _defaultAPIEndpoint = "https://api.openai.com/v1/chat/completions";
|
||||||
@@ -43,12 +44,13 @@ const newChatStore = (
|
|||||||
postBeginIndex: 0,
|
postBeginIndex: 0,
|
||||||
tokenMargin: 1024,
|
tokenMargin: 1024,
|
||||||
totalTokens: 0,
|
totalTokens: 0,
|
||||||
maxTokens: options[getDefaultParams("model", model)],
|
maxTokens: models[getDefaultParams("model", model)].maxToken,
|
||||||
apiKey: getDefaultParams("key", apiKey),
|
apiKey: getDefaultParams("key", apiKey),
|
||||||
apiEndpoint: getDefaultParams("api", apiEndpoint),
|
apiEndpoint: getDefaultParams("api", apiEndpoint),
|
||||||
streamMode: getDefaultParams("mode", streamMode),
|
streamMode: getDefaultParams("mode", streamMode),
|
||||||
model: getDefaultParams("model", model),
|
model: getDefaultParams("model", model),
|
||||||
responseModelName: "",
|
responseModelName: "",
|
||||||
|
cost: 0,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,6 +101,7 @@ export function App() {
|
|||||||
if (message.token === undefined)
|
if (message.token === undefined)
|
||||||
message.token = calculate_token_length(message.content);
|
message.token = calculate_token_length(message.content);
|
||||||
}
|
}
|
||||||
|
if (ret.cost === undefined) ret.cost = 0;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import ChatGPT, {
|
|||||||
FetchResponse,
|
FetchResponse,
|
||||||
} from "./chatgpt";
|
} from "./chatgpt";
|
||||||
import Message from "./message";
|
import Message from "./message";
|
||||||
|
import models from "./models";
|
||||||
import Settings from "./settings";
|
import Settings from "./settings";
|
||||||
|
|
||||||
export default function ChatBOX(props: {
|
export default function ChatBOX(props: {
|
||||||
@@ -102,6 +103,13 @@ export default function ChatBOX(props: {
|
|||||||
chatStore.streamMode = false;
|
chatStore.streamMode = false;
|
||||||
const data = (await response.json()) as FetchResponse;
|
const data = (await response.json()) as FetchResponse;
|
||||||
chatStore.responseModelName = data.model ?? "";
|
chatStore.responseModelName = data.model ?? "";
|
||||||
|
if (data.model) {
|
||||||
|
chatStore.cost +=
|
||||||
|
(data.usage.prompt_tokens ?? 0) * models[data.model].price.prompt;
|
||||||
|
chatStore.cost +=
|
||||||
|
(data.usage.completion_tokens ?? 0) *
|
||||||
|
models[data.model].price.completion;
|
||||||
|
}
|
||||||
const content = client.processFetchResponse(data);
|
const content = client.processFetchResponse(data);
|
||||||
chatStore.history.push({
|
chatStore.history.push({
|
||||||
role: "assistant",
|
role: "assistant",
|
||||||
@@ -239,9 +247,10 @@ export default function ChatBOX(props: {
|
|||||||
</span>{" "}
|
</span>{" "}
|
||||||
<span>{chatStore.model}</span>{" "}
|
<span>{chatStore.model}</span>{" "}
|
||||||
<span>
|
<span>
|
||||||
Messages: {chatStore.history.filter(({ hide }) => !hide).length}
|
Msg: {chatStore.history.filter(({ hide }) => !hide).length}
|
||||||
</span>{" "}
|
</span>{" "}
|
||||||
<span>Cut: {chatStore.postBeginIndex}</span>
|
<span>Cut: {chatStore.postBeginIndex}</span>{" "}
|
||||||
|
<span className="underline">${chatStore.cost.toFixed(4)}</span>
|
||||||
</div>
|
</div>
|
||||||
</p>
|
</p>
|
||||||
<div className="grow overflow-scroll">
|
<div className="grow overflow-scroll">
|
||||||
|
|||||||
36
src/models.ts
Normal file
36
src/models.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
interface Model {
|
||||||
|
maxToken: number;
|
||||||
|
price: {
|
||||||
|
prompt: number;
|
||||||
|
completion: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const models: Record<string, Model> = {
|
||||||
|
"gpt-3.5-turbo": {
|
||||||
|
maxToken: 4096,
|
||||||
|
price: { prompt: 0.002 / 1000, completion: 0.002 / 1000 },
|
||||||
|
},
|
||||||
|
"gpt-3.5-turbo-0301": {
|
||||||
|
maxToken: 4096,
|
||||||
|
price: { prompt: 0.002 / 1000, completion: 0.002 / 1000 },
|
||||||
|
},
|
||||||
|
"gpt-4": {
|
||||||
|
maxToken: 8192,
|
||||||
|
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
|
||||||
|
},
|
||||||
|
"gpt-4-0314": {
|
||||||
|
maxToken: 8192,
|
||||||
|
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
|
||||||
|
},
|
||||||
|
"gpt-4-32k": {
|
||||||
|
maxToken: 8192,
|
||||||
|
price: { prompt: 0.03 / 1000, completion: 0.06 / 1000 },
|
||||||
|
},
|
||||||
|
"gpt-4-32k-0314": {
|
||||||
|
maxToken: 8192,
|
||||||
|
price: { prompt: 0.06 / 1000, completion: 0.12 / 1000 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default models;
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createRef } from "preact";
|
import { createRef } from "preact";
|
||||||
import { StateUpdater } from "preact/hooks";
|
import { StateUpdater } from "preact/hooks";
|
||||||
import { ChatStore } from "./app";
|
import { ChatStore } from "./app";
|
||||||
|
import models from "./models";
|
||||||
|
|
||||||
const Help = (props: { children: any; help: string }) => {
|
const Help = (props: { children: any; help: string }) => {
|
||||||
return (
|
return (
|
||||||
@@ -18,16 +19,6 @@ const Help = (props: { children: any; help: string }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// model and their max token
|
|
||||||
export const options: Record<string, number> = {
|
|
||||||
"gpt-3.5-turbo": 4096,
|
|
||||||
"gpt-3.5-turbo-0301": 4096,
|
|
||||||
"gpt-4": 8192,
|
|
||||||
"gpt-4-0314": 8192,
|
|
||||||
"gpt-4-32k": 32768,
|
|
||||||
"gpt-4-32k-0314": 32768,
|
|
||||||
};
|
|
||||||
|
|
||||||
const SelectModel = (props: {
|
const SelectModel = (props: {
|
||||||
chatStore: ChatStore;
|
chatStore: ChatStore;
|
||||||
setChatStore: (cs: ChatStore) => void;
|
setChatStore: (cs: ChatStore) => void;
|
||||||
@@ -42,11 +33,11 @@ const SelectModel = (props: {
|
|||||||
onChange={(event: any) => {
|
onChange={(event: any) => {
|
||||||
const model = event.target.value as string;
|
const model = event.target.value as string;
|
||||||
props.chatStore.model = model;
|
props.chatStore.model = model;
|
||||||
props.chatStore.maxTokens = options[model];
|
props.chatStore.maxTokens = models[model].maxToken;
|
||||||
props.setChatStore({ ...props.chatStore });
|
props.setChatStore({ ...props.chatStore });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.keys(options).map((opt) => (
|
{Object.keys(models).map((opt) => (
|
||||||
<option value={opt}>{opt}</option>
|
<option value={opt}>{opt}</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
@@ -149,6 +140,9 @@ export default (props: {
|
|||||||
<div className="m-2 p-2 bg-white rounded-lg h-fit">
|
<div className="m-2 p-2 bg-white rounded-lg h-fit">
|
||||||
<h3 className="text-xl">Settings</h3>
|
<h3 className="text-xl">Settings</h3>
|
||||||
<hr />
|
<hr />
|
||||||
|
<p className="m-2 p-2">
|
||||||
|
Total cost in this section ${props.chatStore.cost.toFixed(4)}
|
||||||
|
</p>
|
||||||
<div className="box">
|
<div className="box">
|
||||||
<Input
|
<Input
|
||||||
field="systemMessageContent"
|
field="systemMessageContent"
|
||||||
@@ -269,6 +263,10 @@ export default (props: {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
<p className="text-center m-2 p-2">
|
||||||
|
chatgpt-api-web ChatStore Version{" "}
|
||||||
|
{props.chatStore.chatgpt_api_web_version}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<hr />
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
|
|||||||
Reference in New Issue
Block a user