feat: refresh max token

This commit is contained in:
archer
2023-07-14 10:05:29 +08:00
parent f3715731c4
commit 358c4716f9
7 changed files with 83 additions and 27 deletions

View File

@@ -45,8 +45,8 @@ export const triggerModelCollection = (appId: string) =>
POST<number>(`/app/share/collection?appId=${appId}`);
// ====================== data
export const getTokenUsage = (data: { appId: string }) =>
POST<{ tokenLen: number; date: Date }[]>(`/app/data/tokenUsage`, {
export const getAppTotalUsage = (data: { appId: string }) =>
POST<{ total: number; date: Date }[]>(`/app/data/totalUsage`, {
...data,
start: addDays(new Date(), -7),
end: new Date()

View File

@@ -84,6 +84,7 @@ export const HistoryModule: AppModuleTemplateItemType = {
]
};
const defaultModel = chatModelList[0];
export const ChatModule: AppModuleTemplateItemType = {
logo: '/imgs/module/AI.png',
name: 'AI 对话',
@@ -94,9 +95,9 @@ export const ChatModule: AppModuleTemplateItemType = {
inputs: [
{
key: 'model',
type: FlowInputItemTypeEnum.select,
type: FlowInputItemTypeEnum.custom,
label: '对话模型',
value: chatModelList[0]?.model,
value: defaultModel?.model,
list: chatModelList.map((item) => ({ label: item.name, value: item.model }))
},
{
@@ -116,13 +117,16 @@ export const ChatModule: AppModuleTemplateItemType = {
key: 'maxToken',
type: FlowInputItemTypeEnum.slider,
label: '回复上限',
value: 3000,
value: defaultModel ? defaultModel.contextMaxToken / 2 : 2000,
min: 0,
max: 4000,
max: defaultModel?.contextMaxToken || 4000,
step: 50,
markList: [
{ label: '0', value: 0 },
{ label: '4000', value: 4000 }
{
label: `${defaultModel?.contextMaxToken || 4000}`,
value: defaultModel?.contextMaxToken || 4000
}
]
},
{

View File

@@ -2,7 +2,6 @@ import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@/service/response';
import { connectToDatabase, Bill } from '@/service/mongo';
import { authUser } from '@/service/utils/auth';
import type { ChatHistoryItemType } from '@/types/chat';
import { Types } from 'mongoose';
/* get one app chat history content number. */
@@ -28,14 +27,14 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
month: { $month: '$time' },
day: { $dayOfMonth: '$time' }
},
tokenLen: { $sum: '$tokenLen' } // 对tokenLen的值求和
total: { $sum: '$total' }
}
},
{
$project: {
_id: 0,
date: { $dateFromParts: { year: '$_id.year', month: '$_id.month', day: '$_id.day' } },
tokenLen: 1
total: 1
}
},
{ $sort: { date: 1 } }

View File

@@ -15,7 +15,7 @@ import { Types } from 'mongoose';
import { moduleFetch } from '@/service/api/request';
import { AppModuleItemType, RunningModuleItemType } from '@/types/app';
import { FlowInputItemTypeEnum } from '@/constants/flow';
import { finishTaskBill, createTaskBill } from '@/service/events/pushBill';
import { finishTaskBill, createTaskBill, delTaskBill } from '@/service/events/pushBill';
import { BillSourceEnum } from '@/constants/user';
export type MessageItemType = ChatCompletionRequestMessage & { _id?: string };
@@ -56,6 +56,8 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
variables = {}
} = req.body as Props;
let billId = '';
try {
if (!messages) {
throw new Error('Prams Error');
@@ -108,11 +110,11 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
res.setHeader('newHistoryId', String(newHistoryId));
}
const billId = await createTaskBill({
billId = await createTaskBill({
userId,
appName: app.name,
appId,
source: BillSourceEnum.fastgpt
source: authType === 'apikey' ? BillSourceEnum.api : BillSourceEnum.fastgpt
});
/* start process */
@@ -125,7 +127,7 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
userChatInput: prompt.value
},
stream,
billId: ''
billId
});
// save chat
@@ -184,6 +186,8 @@ export default withNextCors(async function handler(req: NextApiRequest, res: Nex
billId
});
} catch (err: any) {
delTaskBill(billId);
if (stream) {
res.status(500);
sseErrRes(res, err);

View File

@@ -1,9 +1,10 @@
import React, { useEffect, useMemo, useRef } from 'react';
import * as echarts from 'echarts';
import { useGlobalStore } from '@/store/global';
import { getTokenUsage } from '@/api/app';
import { getAppTotalUsage } from '@/api/app';
import { useQuery } from '@tanstack/react-query';
import dayjs from 'dayjs';
import { formatPrice } from '@/utils/user';
const map = {
blue: {
@@ -98,7 +99,7 @@ const TokenUsage = ({ appId }: { appId: string }) => {
const Dom = useRef<HTMLDivElement>(null);
const myChart = useRef<echarts.ECharts>();
const { data = [] } = useQuery(['init'], () => getTokenUsage({ appId }));
const { data = [] } = useQuery(['init'], () => getAppTotalUsage({ appId }));
const option = useMemo(
() => ({
@@ -110,7 +111,7 @@ const TokenUsage = ({ appId }: { appId: string }) => {
},
yAxis: {
type: 'value',
max: Math.max(...data.map((item) => item.tokenLen)),
max: Math.max(...data.map((item) => item.total)),
min: 0
},
grid: {
@@ -132,14 +133,14 @@ const TokenUsage = ({ appId }: { appId: string }) => {
return `
<div>
<div>${dayjs(data.axisValue).format('YYYY/MM/DD')}</div>
<div>${((e[0]?.value || 0) / 1000).toFixed(2)}k Tokens</div>
<div>${formatPrice(e[0]?.value || 0)}</div>
</div>
`;
}
},
series: [
{
data: data.map((item) => item.tokenLen),
data: data.map((item) => item.total),
type: 'line',
showSymbol: true,
animationDuration: 300,
@@ -170,7 +171,7 @@ const TokenUsage = ({ appId }: { appId: string }) => {
if (!Dom.current || myChart?.current?.getOption()) return;
myChart.current = echarts.init(Dom.current);
myChart.current && myChart.current.setOption(option);
}, [Dom]);
}, []);
// data changed, update
useEffect(() => {

View File

@@ -14,8 +14,8 @@ import Avatar from '@/components/Avatar';
import MyIcon from '@/components/Icon';
const InfoModal = dynamic(() => import('./InfoModal'));
const TokenUsage = dynamic(() => import('./Charts/TokenUsage'));
const AppEdit = dynamic(() => import('./edit'));
const TotalUsage = dynamic(() => import('./Charts/TotalUsage'), { ssr: false });
const AppEdit = dynamic(() => import('./edit'), { ssr: false });
import styles from '../../list/index.module.scss';
const Settings = ({ appId }: { appId: string }) => {
@@ -143,10 +143,10 @@ const Settings = ({ appId }: { appId: string }) => {
</Box>
<Box>
<Box mb={2} fontSize={['md', 'xl']}>
7 Tokens
7
</Box>
<Box h={'150px'}>
<TokenUsage appId={appId} />
<Box h={'150px'} w={'100%'}>
<TotalUsage appId={appId} />
</Box>
</Box>
</Grid>

View File

@@ -7,6 +7,8 @@ import Container from './modules/Container';
import RenderInput from './render/RenderInput';
import RenderOutput from './render/RenderOutput';
import { FlowOutputItemTypeEnum } from '@/constants/flow';
import MySelect from '@/components/Select';
import { chatModelList } from '@/store/static';
const NodeChat = ({
data: { moduleId, inputs, outputs, onChangeNode, ...props }
@@ -15,11 +17,57 @@ const NodeChat = ({
() => outputs.filter((item) => item.type !== FlowOutputItemTypeEnum.hidden).length,
[outputs]
);
return (
<NodeCard minW={'400px'} logo={'/icon/logo.png'} name={'对话'} moduleId={moduleId} {...props}>
<NodeCard minW={'400px'} moduleId={moduleId} {...props}>
<Divider text="Input" />
<Container>
<RenderInput moduleId={moduleId} onChangeNode={onChangeNode} flowInputList={inputs} />
<RenderInput
moduleId={moduleId}
onChangeNode={onChangeNode}
flowInputList={inputs}
CustomComponent={{
model: (inputItem) => (
<MySelect
width={'100%'}
value={inputItem.value}
list={inputItem.list || []}
onchange={(e) => {
onChangeNode({
moduleId,
key: inputItem.key,
value: e
});
// update max tokens
const model = chatModelList.find((item) => item.model === e);
if (!model) return;
onChangeNode({
moduleId,
key: 'maxToken',
valueKey: 'markList',
value: [
{ label: '0', value: 0 },
{ label: `${model.contextMaxToken}`, value: model.contextMaxToken }
]
});
onChangeNode({
moduleId,
key: 'maxToken',
valueKey: 'max',
value: model.contextMaxToken
});
onChangeNode({
moduleId,
key: 'maxToken',
valueKey: 'value',
value: model.contextMaxToken / 2
});
}}
/>
)
}}
/>
</Container>
{outputsLen > 0 && (
<>