Commit 6ea57e46 by Archer Committed by archer

perf: ai proxy log remove retry log;perf: workflow type auto parse;add chunk spliter test (#4296)

* sync collection

* remove lock

* perf: workflow type auto parse

* add chunk spliter test

* perf: ai proxy log remove retry log

* udpate ai proxy field
parent 2fcf4216
...@@ -26,6 +26,9 @@ weight: 799 ...@@ -26,6 +26,9 @@ weight: 799
3. 无 SSL 证书时复制失败,会提示弹窗用于手动复制。 3. 无 SSL 证书时复制失败,会提示弹窗用于手动复制。
4. FastGPT 未内置 ai proxy 渠道时,也能正常展示其名称。 4. FastGPT 未内置 ai proxy 渠道时,也能正常展示其名称。
5. 升级 nextjs 版本至 14.2.25。 5. 升级 nextjs 版本至 14.2.25。
6. 工作流节点数组字符串类型,自动适配 string 输入。
7. 工作流节点数组类型,自动进行 JSON parse 解析 string 输入。
8. AI proxy 日志优化,去除重试失败的日志,仅保留最后一份错误日志。
## 🐛 修复 ## 🐛 修复
......
...@@ -20,6 +20,7 @@ export enum WorkflowIOValueTypeEnum { ...@@ -20,6 +20,7 @@ export enum WorkflowIOValueTypeEnum {
number = 'number', number = 'number',
boolean = 'boolean', boolean = 'boolean',
object = 'object', object = 'object',
arrayString = 'arrayString', arrayString = 'arrayString',
arrayNumber = 'arrayNumber', arrayNumber = 'arrayNumber',
arrayBoolean = 'arrayBoolean', arrayBoolean = 'arrayBoolean',
......
...@@ -78,7 +78,7 @@ export const Input_Template_Text_Quote: FlowNodeInputItemType = { ...@@ -78,7 +78,7 @@ export const Input_Template_Text_Quote: FlowNodeInputItemType = {
export const Input_Template_File_Link: FlowNodeInputItemType = { export const Input_Template_File_Link: FlowNodeInputItemType = {
key: NodeInputKeyEnum.fileUrlList, key: NodeInputKeyEnum.fileUrlList,
renderTypeList: [FlowNodeInputTypeEnum.reference], renderTypeList: [FlowNodeInputTypeEnum.reference, FlowNodeInputTypeEnum.input],
label: i18nT('app:workflow.user_file_input'), label: i18nT('app:workflow.user_file_input'),
debugLabel: i18nT('app:workflow.user_file_input'), debugLabel: i18nT('app:workflow.user_file_input'),
description: i18nT('app:workflow.user_file_input_desc'), description: i18nT('app:workflow.user_file_input_desc'),
......
...@@ -117,6 +117,9 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => { ...@@ -117,6 +117,9 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
return Boolean(value); return Boolean(value);
} }
try { try {
if (WorkflowIOValueTypeEnum.arrayString && typeof value === 'string') {
return [value];
}
if ( if (
type && type &&
[ [
...@@ -124,7 +127,12 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => { ...@@ -124,7 +127,12 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
WorkflowIOValueTypeEnum.chatHistory, WorkflowIOValueTypeEnum.chatHistory,
WorkflowIOValueTypeEnum.datasetQuote, WorkflowIOValueTypeEnum.datasetQuote,
WorkflowIOValueTypeEnum.selectApp, WorkflowIOValueTypeEnum.selectApp,
WorkflowIOValueTypeEnum.selectDataset WorkflowIOValueTypeEnum.selectDataset,
WorkflowIOValueTypeEnum.arrayString,
WorkflowIOValueTypeEnum.arrayNumber,
WorkflowIOValueTypeEnum.arrayBoolean,
WorkflowIOValueTypeEnum.arrayObject,
WorkflowIOValueTypeEnum.arrayAny
].includes(type) && ].includes(type) &&
typeof value !== 'object' typeof value !== 'object'
) { ) {
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"model_tokens": "Input/Output tokens", "model_tokens": "Input/Output tokens",
"request_at": "Request time", "request_at": "Request time",
"request_duration": "Request duration: {{duration}}s", "request_duration": "Request duration: {{duration}}s",
"retry_times": "Number of retry times",
"running_test": "In testing", "running_test": "In testing",
"search_model": "Search for models", "search_model": "Search for models",
"select_channel": "Select a channel name", "select_channel": "Select a channel name",
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
"model_tokens": "输入/输出 Tokens", "model_tokens": "输入/输出 Tokens",
"request_at": "请求时间", "request_at": "请求时间",
"request_duration": "请求时长: {{duration}}s", "request_duration": "请求时长: {{duration}}s",
"retry_times": "重试次数",
"running_test": "测试中", "running_test": "测试中",
"search_model": "搜索模型", "search_model": "搜索模型",
"select_channel": "选择渠道名", "select_channel": "选择渠道名",
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
"model_tokens": "輸入/輸出 Tokens", "model_tokens": "輸入/輸出 Tokens",
"request_at": "請求時間", "request_at": "請求時間",
"request_duration": "請求時長: {{duration}}s", "request_duration": "請求時長: {{duration}}s",
"retry_times": "重試次數",
"running_test": "測試中", "running_test": "測試中",
"search_model": "搜索模型", "search_model": "搜索模型",
"select_channel": "選擇渠道名", "select_channel": "選擇渠道名",
......
...@@ -30,6 +30,13 @@ export type CreateChannelProps = { ...@@ -30,6 +30,13 @@ export type CreateChannelProps = {
}; };
// Log // Log
export type ChannelLogUsageType = {
cache_creation_tokens?: number;
cached_tokens?: number;
input_tokens?: number;
output_tokens?: number;
total_tokens?: number;
};
export type ChannelLogListItemType = { export type ChannelLogListItemType = {
token_name: string; token_name: string;
model: string; model: string;
...@@ -40,8 +47,8 @@ export type ChannelLogListItemType = { ...@@ -40,8 +47,8 @@ export type ChannelLogListItemType = {
created_at: number; created_at: number;
request_at: number; request_at: number;
code: number; code: number;
prompt_tokens: number; usage?: ChannelLogUsageType;
completion_tokens: number;
endpoint: string; endpoint: string;
content?: string; content?: string;
retry_times?: number;
}; };
...@@ -33,6 +33,7 @@ import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time'; ...@@ -33,6 +33,7 @@ import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
import MyModal from '@fastgpt/web/components/common/MyModal'; import MyModal from '@fastgpt/web/components/common/MyModal';
import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip';
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput'; import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
import { ChannelLogUsageType } from '@/global/aiproxy/type';
type LogDetailType = { type LogDetailType = {
id: number; id: number;
...@@ -42,10 +43,10 @@ type LogDetailType = { ...@@ -42,10 +43,10 @@ type LogDetailType = {
duration: number; duration: number;
request_at: string; request_at: string;
code: number; code: number;
prompt_tokens: number; usage?: ChannelLogUsageType;
completion_tokens: number;
endpoint: string; endpoint: string;
retry_times?: number;
content?: string; content?: string;
request_body?: string; request_body?: string;
response_body?: string; response_body?: string;
...@@ -159,8 +160,7 @@ const ChannelLog = ({ Tab }: { Tab: React.ReactNode }) => { ...@@ -159,8 +160,7 @@ const ChannelLog = ({ Tab }: { Tab: React.ReactNode }) => {
duration: durationSecond, duration: durationSecond,
request_at: formatTime2YMDHMS(item.request_at), request_at: formatTime2YMDHMS(item.request_at),
code: item.code, code: item.code,
prompt_tokens: item.prompt_tokens, usage: item.usage,
completion_tokens: item.completion_tokens,
request_id: item.request_id, request_id: item.request_id,
endpoint: item.endpoint, endpoint: item.endpoint,
content: item.content content: item.content
...@@ -260,7 +260,7 @@ const ChannelLog = ({ Tab }: { Tab: React.ReactNode }) => { ...@@ -260,7 +260,7 @@ const ChannelLog = ({ Tab }: { Tab: React.ReactNode }) => {
<Td>{item.channelName}</Td> <Td>{item.channelName}</Td>
<Td>{item.model}</Td> <Td>{item.model}</Td>
<Td> <Td>
{item.prompt_tokens} / {item.completion_tokens} {item.usage?.input_tokens} / {item.usage?.output_tokens}
</Td> </Td>
<Td color={item.duration > 10 ? 'red.600' : ''}>{item.duration.toFixed(2)}s</Td> <Td color={item.duration > 10 ? 'red.600' : ''}>{item.duration.toFixed(2)}s</Td>
<Td color={item.code === 200 ? 'green.600' : 'red.600'}> <Td color={item.code === 200 ? 'green.600' : 'red.600'}>
...@@ -297,6 +297,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void ...@@ -297,6 +297,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void
const { t } = useTranslation(); const { t } = useTranslation();
const { data: detailData } = useRequest2( const { data: detailData } = useRequest2(
async () => { async () => {
console.log(data);
if (data.code === 200) return data; if (data.code === 200) return data;
try { try {
const res = await getLogDetail(data.id); const res = await getLogDetail(data.id);
...@@ -363,7 +364,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void ...@@ -363,7 +364,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void
<Title>RequestID</Title> <Title>RequestID</Title>
<Container>{detailData?.request_id}</Container> <Container>{detailData?.request_id}</Container>
</GridItem> </GridItem>
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px"> <GridItem display={'flex'} borderBottomWidth="1px">
<Title>{t('account_model:channel_status')}</Title> <Title>{t('account_model:channel_status')}</Title>
<Container color={detailData.code === 200 ? 'green.600' : 'red.600'}> <Container color={detailData.code === 200 ? 'green.600' : 'red.600'}>
{detailData?.code} {detailData?.code}
...@@ -373,7 +374,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void ...@@ -373,7 +374,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void
<Title>Endpoint</Title> <Title>Endpoint</Title>
<Container>{detailData?.endpoint}</Container> <Container>{detailData?.endpoint}</Container>
</GridItem> </GridItem>
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px"> <GridItem display={'flex'} borderBottomWidth="1px">
<Title>{t('account_model:channel_name')}</Title> <Title>{t('account_model:channel_name')}</Title>
<Container>{detailData?.channelName}</Container> <Container>{detailData?.channelName}</Container>
</GridItem> </GridItem>
...@@ -381,7 +382,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void ...@@ -381,7 +382,7 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void
<Title>{t('account_model:request_at')}</Title> <Title>{t('account_model:request_at')}</Title>
<Container>{detailData?.request_at}</Container> <Container>{detailData?.request_at}</Container>
</GridItem> </GridItem>
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px"> <GridItem display={'flex'} borderBottomWidth="1px">
<Title>{t('account_model:duration')}</Title> <Title>{t('account_model:duration')}</Title>
<Container>{detailData?.duration.toFixed(2)}s</Container> <Container>{detailData?.duration.toFixed(2)}s</Container>
</GridItem> </GridItem>
...@@ -389,20 +390,26 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void ...@@ -389,20 +390,26 @@ const LogDetail = ({ data, onClose }: { data: LogDetailType; onClose: () => void
<Title>{t('account_model:model')}</Title> <Title>{t('account_model:model')}</Title>
<Container>{detailData?.model}</Container> <Container>{detailData?.model}</Container>
</GridItem> </GridItem>
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px"> <GridItem display={'flex'} borderBottomWidth="1px">
<Title flex={'0 0 150px'}>{t('account_model:model_tokens')}</Title> <Title flex={'0 0 150px'}>{t('account_model:model_tokens')}</Title>
<Container> <Container>
{detailData?.prompt_tokens} / {detailData?.completion_tokens} {detailData?.usage?.input_tokens} / {detailData?.usage?.output_tokens}
</Container> </Container>
</GridItem> </GridItem>
{detailData?.retry_times !== undefined && (
<GridItem display={'flex'} borderBottomWidth="1px" colSpan={2}>
<Title>{t('account_model:retry_times')}</Title>
<Container>{detailData?.retry_times}</Container>
</GridItem>
)}
{detailData?.content && ( {detailData?.content && (
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px" colSpan={2}> <GridItem display={'flex'} borderBottomWidth="1px" colSpan={2}>
<Title>Content</Title> <Title>Content</Title>
<Container>{detailData?.content}</Container> <Container>{detailData?.content}</Container>
</GridItem> </GridItem>
)} )}
{detailData?.request_body && ( {detailData?.request_body && (
<GridItem display={'flex'} borderBottomWidth="1px" borderRightWidth="1px" colSpan={2}> <GridItem display={'flex'} borderBottomWidth="1px" colSpan={2}>
<Title>Request Body</Title> <Title>Request Body</Title>
<Container userSelect={'all'}>{detailData?.request_body}</Container> <Container userSelect={'all'}>{detailData?.request_body}</Container>
</GridItem> </GridItem>
......
...@@ -247,9 +247,9 @@ const MultipleReferenceSelector = ({ ...@@ -247,9 +247,9 @@ const MultipleReferenceSelector = ({
// Get valid item and remove invalid item // Get valid item and remove invalid item
const formatList = useMemo(() => { const formatList = useMemo(() => {
if (!value) return []; if (!value || !Array.isArray(value)) return [];
return value?.map((item) => { return value.map((item) => {
const [nodeName, outputName] = getSelectValue(item); const [nodeName, outputName] = getSelectValue(item);
return { return {
rawValue: item, rawValue: item,
......
...@@ -166,6 +166,7 @@ export const getChannelLog = (params: { ...@@ -166,6 +166,7 @@ export const getChannelLog = (params: {
logs: ChannelLogListItemType[]; logs: ChannelLogListItemType[];
total: number; total: number;
}>(`/logs/search`, { }>(`/logs/search`, {
result_only: true,
request_id: params.request_id, request_id: params.request_id,
channel: params.channel, channel: params.channel,
model_name: params.model_name, model_name: params.model_name,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment