diff --git a/docSite/content/zh-cn/docs/development/upgrading/4912.md b/docSite/content/zh-cn/docs/development/upgrading/4912.md index 44ccdb435..4b5b203fc 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4912.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4912.md @@ -1,5 +1,5 @@ --- -title: 'V4.9.12(进行中)' +title: 'V4.9.12' description: 'FastGPT V4.9.12 更新说明' icon: 'upgrade' draft: false @@ -7,6 +7,16 @@ toc: true weight: 788 --- +## 更新指南 + +### 1. 更新镜像: + +- 更新 FastGPT 镜像 tag: v4.9.12 +- 更新 FastGPT 商业版镜像 tag: v4.9.12 +- mcp_server 无需更新 +- Sandbox 无需更新 +- 更新 AIProxy 镜像 tag: v0.2.2 + ## 🚀 新增内容 1. AI proxy 监控完善,支持以图表/表格形式查看模型调用和性能情况。 diff --git a/docSite/content/zh-cn/docs/development/upgrading/4913.md b/docSite/content/zh-cn/docs/development/upgrading/4913.md new file mode 100644 index 000000000..050c25612 --- /dev/null +++ b/docSite/content/zh-cn/docs/development/upgrading/4913.md @@ -0,0 +1,23 @@ +--- +title: 'V4.9.13(进行中)' +description: 'FastGPT V4.9.13 更新说明' +icon: 'upgrade' +draft: false +toc: true +weight: 787 +--- + + +## 🚀 新增内容 + + +## ⚙️ 优化 + +1. 所有 NodeId 调整随机值生成,避免首字母数字开头。 +2. 知识库集合搜索,支持嵌套搜索。 + +## 🐛 修复 + +1. 对话日志,日期范围选择问题。 +2. API 调用时,传入的 system 提示词可能会重复。 +3. AI 对话/工具调用,未选择文件链接时,也会从历史记录读取文件。 \ No newline at end of file diff --git a/packages/global/core/app/mcpTools/utils.ts b/packages/global/core/app/mcpTools/utils.ts index 12dc89483..af1ffa3ae 100644 --- a/packages/global/core/app/mcpTools/utils.ts +++ b/packages/global/core/app/mcpTools/utils.ts @@ -8,12 +8,12 @@ import { FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from '../../workflow/node/constant'; -import { nanoid } from 'nanoid'; import { type McpToolConfigType } from '../type'; import { i18nT } from '../../../../web/i18n/utils'; import { type RuntimeNodeItemType } from '../../workflow/runtime/type'; import { type StoreSecretValueType } from '../../../common/secret/type'; import { jsonSchema2NodeInput } from '../jsonschema'; +import { getNanoid } from '../../../common/string/tools'; export const getMCPToolSetRuntimeNode = ({ url, @@ -29,7 +29,7 @@ export const getMCPToolSetRuntimeNode = ({ avatar?: string; }): RuntimeNodeItemType => { return { - nodeId: nanoid(16), + nodeId: getNanoid(16), flowNodeType: FlowNodeTypeEnum.toolSet, avatar, intro: 'MCP Tools', @@ -64,7 +64,7 @@ export const getMCPToolRuntimeNode = ({ avatar?: string; }): RuntimeNodeItemType => { return { - nodeId: nanoid(16), + nodeId: getNanoid(16), flowNodeType: FlowNodeTypeEnum.tool, avatar, intro: tool.description, diff --git a/packages/global/tsconfig.json b/packages/global/tsconfig.json index 1ceb835fe..6f5dee2ff 100644 --- a/packages/global/tsconfig.json +++ b/packages/global/tsconfig.json @@ -1,10 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": ".", - "paths": { - "@fastgpt/global/*": ["./*"] - } + "baseUrl": "." }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"] } diff --git a/packages/plugins/tsconfig.json b/packages/plugins/tsconfig.json index cfe1809ee..13c4daa3b 100644 --- a/packages/plugins/tsconfig.json +++ b/packages/plugins/tsconfig.json @@ -14,10 +14,7 @@ "isolatedModules": true, "jsx": "preserve", "incremental": true, - "baseUrl": ".", - "paths": { - "@fastgpt/plugins/*": ["./*"] - } + "baseUrl": "." }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"], "exclude": ["node_modules"] diff --git a/packages/service/core/chat/utils.ts b/packages/service/core/chat/utils.ts index 0d22134be..701a9f525 100644 --- a/packages/service/core/chat/utils.ts +++ b/packages/service/core/chat/utils.ts @@ -105,8 +105,9 @@ export const loadRequestMessages = async ({ const arrayContent = content .filter((item) => item.text) - .map((item) => ({ ...item, text: addEndpointToImageUrl(item.text) })); - if (arrayContent.length === 0) return; + .map((item) => addEndpointToImageUrl(item.text)) + .join('\n'); + return arrayContent; }; // Parse user content(text and img) Store history => api messages diff --git a/packages/service/core/workflow/dispatch/agent/runTool/index.ts b/packages/service/core/workflow/dispatch/agent/runTool/index.ts index 8905160f3..20941ab12 100644 --- a/packages/service/core/workflow/dispatch/agent/runTool/index.ts +++ b/packages/service/core/workflow/dispatch/agent/runTool/index.ts @@ -42,8 +42,8 @@ type Response = DispatchNodeResultType<{ }>; export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise => { - const { - node: { nodeId, name, isEntry, version }, + let { + node: { nodeId, name, isEntry, version, inputs }, runtimeNodes, runtimeEdges, histories, @@ -70,6 +70,11 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise< props.params.aiChatVision = aiChatVision && toolModel.vision; props.params.aiChatReasoning = aiChatReasoning && toolModel.reasoning; + const fileUrlInput = inputs.find((item) => item.key === NodeInputKeyEnum.fileUrlList); + if (!fileUrlInput || !fileUrlInput.value || fileUrlInput.value.length === 0) { + fileLinks = undefined; + } + console.log(fileLinks, 22); const toolNodeIds = filterToolNodeIdByEdges({ nodeId, edges: runtimeEdges }); diff --git a/packages/service/core/workflow/dispatch/chat/oneapi.ts b/packages/service/core/workflow/dispatch/chat/oneapi.ts index c68646be8..88e8e3709 100644 --- a/packages/service/core/workflow/dispatch/chat/oneapi.ts +++ b/packages/service/core/workflow/dispatch/chat/oneapi.ts @@ -13,7 +13,6 @@ import { createChatCompletion } from '../../../ai/config'; import type { ChatCompletionMessageParam, CompletionFinishReason, - CompletionUsage, StreamChatType } from '@fastgpt/global/core/ai/type.d'; import { formatModelChars2Points } from '../../../../support/wallet/usage/utils'; @@ -45,7 +44,8 @@ import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/ import { responseWriteController } from '../../../../common/response'; import { getLLMModel } from '../../../ai/model'; import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type'; -import type { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; +import type { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants'; +import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants'; import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants'; import { checkQuoteQAValue, getHistories } from '../utils'; import { filterSearchResultsByMaxChars } from '../../utils'; @@ -82,7 +82,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise item.key === NodeInputKeyEnum.fileUrlList); + if (!fileUrlInput || !fileUrlInput.value || fileUrlInput.value.length === 0) { + fileLinks = undefined; + } const chatHistories = getHistories(history, histories); quoteQA = checkQuoteQAValue(quoteQA); diff --git a/packages/service/core/workflow/dispatch/utils.ts b/packages/service/core/workflow/dispatch/utils.ts index a08b0f034..d96494d79 100644 --- a/packages/service/core/workflow/dispatch/utils.ts +++ b/packages/service/core/workflow/dispatch/utils.ts @@ -84,10 +84,12 @@ export const filterToolNodeIdByEdges = ({ export const getHistories = (history?: ChatItemType[] | number, histories: ChatItemType[] = []) => { if (!history) return []; - const systemHistories = histories.filter((item) => item.obj === ChatRoleEnum.System); + const systemHistoryIndex = histories.findIndex((item) => item.obj !== ChatRoleEnum.System); + const systemHistories = histories.slice(0, systemHistoryIndex); + const chatHistories = histories.slice(systemHistoryIndex); const filterHistories = (() => { - if (typeof history === 'number') return histories.slice(-(history * 2)); + if (typeof history === 'number') return chatHistories.slice(-(history * 2)); if (Array.isArray(history)) return history; return []; })(); diff --git a/packages/service/tsconfig.json b/packages/service/tsconfig.json index 8a9d86611..3e496cf7c 100644 --- a/packages/service/tsconfig.json +++ b/packages/service/tsconfig.json @@ -1,10 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": ".", - "paths": { - "@fastgpt/servive/*": ["./*"] - } + "baseUrl": "." }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../../**/*.d.ts"] } diff --git a/packages/web/components/common/DateRangePicker/index.tsx b/packages/web/components/common/DateRangePicker/index.tsx index 52e5caff0..e39daa7ed 100644 --- a/packages/web/components/common/DateRangePicker/index.tsx +++ b/packages/web/components/common/DateRangePicker/index.tsx @@ -1,12 +1,17 @@ import React, { useState, useMemo, useRef, useEffect } from 'react'; import { Box, Card, Flex, useTheme, useOutsideClick, Button } from '@chakra-ui/react'; import { addDays, format } from 'date-fns'; -import { type DateRange, DayPicker } from 'react-day-picker'; +import { DayPicker } from 'react-day-picker'; import 'react-day-picker/dist/style.css'; import zhCN from 'date-fns/locale/zh-CN'; import { useTranslation } from 'next-i18next'; import MyIcon from '../Icon'; +export type DateRangeType = { + from: Date; + to: Date; +}; + const DateRangePicker = ({ onChange, onSuccess, @@ -17,16 +22,16 @@ const DateRangePicker = ({ }, dateRange }: { - onChange?: (date: DateRange) => void; - onSuccess?: (date: DateRange) => void; + onChange?: (date: DateRangeType) => void; + onSuccess?: (date: DateRangeType) => void; position?: 'bottom' | 'top'; - defaultDate?: DateRange; - dateRange?: DateRange; + defaultDate?: DateRangeType; + dateRange?: DateRangeType; }) => { const { t } = useTranslation(); const theme = useTheme(); const OutRangeRef = useRef(null); - const [range, setRange] = useState(defaultDate); + const [range, setRange] = useState(defaultDate); const [showSelected, setShowSelected] = useState(false); useEffect(() => { @@ -87,28 +92,30 @@ const DateRangePicker = ({ defaultMonth={defaultDate.to} selected={range} disabled={[ - { from: new Date(2022, 3, 1), to: addDays(new Date(), -90) }, + { from: new Date(2022, 3, 1), to: addDays(new Date(), -180) }, { from: addDays(new Date(), 1), to: new Date(2099, 1, 1) } ]} onSelect={(date) => { - if (date?.from === undefined) { - date = { + let typeDate = date as DateRangeType; + if (!typeDate || typeDate?.from === undefined) { + typeDate = { from: range?.from, to: range?.from }; } - if (date?.to === undefined) { - date.to = date.from; + if (typeDate?.to === undefined) { + typeDate.to = typeDate.from; } - if (date?.from) { - date.from = new Date(date.from.setHours(0, 0, 0, 0)); + if (typeDate?.from) { + typeDate.from = new Date(typeDate.from.setHours(0, 0, 0, 0)); } - if (date?.to) { - date.to = new Date(date.to.setHours(23, 59, 59, 999)); + if (typeDate?.to) { + typeDate.to = new Date(typeDate.to.setHours(23, 59, 59, 999)); } - setRange(date); - onChange?.(date); + + setRange(typeDate); + onChange?.(typeDate); }} footer={ @@ -139,4 +146,3 @@ const DateRangePicker = ({ }; export default DateRangePicker; -export type DateRangeType = DateRange; diff --git a/packages/web/hooks/usePagination.tsx b/packages/web/hooks/usePagination.tsx index e7aa7cef9..7258e6386 100644 --- a/packages/web/hooks/usePagination.tsx +++ b/packages/web/hooks/usePagination.tsx @@ -258,6 +258,7 @@ export function usePagination( return { pageNum, + setPageNum, pageSize, total: totalDataLength, data, diff --git a/packages/web/tsconfig.json b/packages/web/tsconfig.json index 6594d82b9..4a17ed65a 100644 --- a/packages/web/tsconfig.json +++ b/packages/web/tsconfig.json @@ -1,10 +1,7 @@ { "extends": "../../tsconfig.json", "compilerOptions": { - "baseUrl": ".", - "paths": { - "@fastgpt/web/*": ["./*"] - } + "baseUrl": "." }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"] } diff --git a/projects/app/src/components/core/app/VariableEdit.tsx b/projects/app/src/components/core/app/VariableEdit.tsx index 9025af0b5..3ea40a800 100644 --- a/projects/app/src/components/core/app/VariableEdit.tsx +++ b/projects/app/src/components/core/app/VariableEdit.tsx @@ -21,7 +21,6 @@ import { import type { VariableItemType } from '@fastgpt/global/core/app/type.d'; import MyIcon from '@fastgpt/web/components/common/Icon'; import { useForm, type UseFormReset } from 'react-hook-form'; -import { customAlphabet } from 'nanoid'; import MyModal from '@fastgpt/web/components/common/MyModal'; import { useTranslation } from 'next-i18next'; import { useToast } from '@fastgpt/web/hooks/useToast'; @@ -36,11 +35,10 @@ import DndDrag, { type DraggableProvided, type DraggableStateSnapshot } from '@fastgpt/web/components/common/DndDrag'; - -const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 6); +import { getNanoid } from '@fastgpt/global/common/string/tools'; export const defaultVariable: VariableItemType = { - id: nanoid(), + id: getNanoid(6), key: '', label: '', type: VariableInputEnum.input, @@ -136,7 +134,7 @@ const VariableEdit = ({ } else { onChangeVariable.push({ ...data, - id: nanoid() + id: getNanoid(6) }); } diff --git a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx index 3b6f3b97a..d4938cb56 100644 --- a/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx +++ b/projects/app/src/components/core/chat/ChatContainer/ChatBox/Input/ChatInput.tsx @@ -306,7 +306,7 @@ const ChatInput = ({ isChatting ? 'primary.50' : canSendMessage ? 'primary.500' : 'rgba(17, 24, 36, 0.1)' } borderRadius={['md', 'lg']} - cursor={canSendMessage ? 'pointer' : 'not-allowed'} + cursor={isChatting ? 'pointer' : canSendMessage ? 'pointer' : 'not-allowed'} onClick={() => { if (isChatting) { return onStop(); diff --git a/projects/app/src/pageComponents/app/detail/Logs/index.tsx b/projects/app/src/pageComponents/app/detail/Logs/index.tsx index 940475440..61c84e6ed 100644 --- a/projects/app/src/pageComponents/app/detail/Logs/index.tsx +++ b/projects/app/src/pageComponents/app/detail/Logs/index.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import { Flex, Box, @@ -46,8 +46,8 @@ const Logs = () => { const appId = useContextSelector(AppContext, (v) => v.appId); const [dateRange, setDateRange] = useState({ - from: addDays(new Date(), -7), - to: new Date() + from: new Date(addDays(new Date(), -6).setHours(0, 0, 0, 0)), + to: new Date(new Date().setHours(23, 59, 59, 999)) }); const [detailLogsId, setDetailLogsId] = useState(); @@ -69,6 +69,16 @@ const Logs = () => { [t] ); + const params = useMemo( + () => ({ + appId, + dateStart: dateRange.from!, + dateEnd: dateRange.to!, + sources: isSelectAllSource ? undefined : chatSources, + logTitle + }), + [appId, chatSources, dateRange.from, dateRange.to, isSelectAllSource, logTitle] + ); const { data: logs, isLoading, @@ -78,14 +88,8 @@ const Logs = () => { total } = usePagination(getAppChatLogs, { pageSize: 20, - params: { - appId, - dateStart: dateRange.from || new Date(), - dateEnd: addDays(dateRange.to || new Date(), 1), - sources: isSelectAllSource ? undefined : chatSources, - logTitle - }, - refreshDeps: [chatSources, logTitle] + params, + refreshDeps: [params] }); const { runAsync: exportLogs } = useRequest2( @@ -116,7 +120,7 @@ const Logs = () => { refreshDeps: [chatSources, logTitle] } ); - + console.log(dateRange, 111); return ( { getData(1)} + onSuccess={(date) => { + setDateRange(date); + }} /> diff --git a/projects/app/src/pageComponents/dataset/detail/Test.tsx b/projects/app/src/pageComponents/dataset/detail/Test.tsx index ab99ebca4..05b761fbd 100644 --- a/projects/app/src/pageComponents/dataset/detail/Test.tsx +++ b/projects/app/src/pageComponents/dataset/detail/Test.tsx @@ -30,8 +30,7 @@ import { useContextSelector } from 'use-context-selector'; import { DatasetPageContext } from '@/web/core/dataset/context/datasetPageContext'; import EmptyTip from '@fastgpt/web/components/common/EmptyTip'; import QuestionTip from '@fastgpt/web/components/common/MyTooltip/QuestionTip'; - -const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 12); +import { getNanoid } from '@fastgpt/global/common/string/tools'; const DatasetParamsModal = dynamic(() => import('@/components/core/app/DatasetParamsModal')); @@ -108,7 +107,7 @@ const Test = ({ datasetId }: { datasetId: string }) => { } const testItem: SearchTestStoreItemType = { - id: nanoid(), + id: getNanoid(), datasetId, text: getValues('inputText').trim(), time: new Date(), diff --git a/projects/app/src/pages/api/core/dataset/collection/list.ts b/projects/app/src/pages/api/core/dataset/collection/list.ts index 117e10268..a29f85e20 100644 --- a/projects/app/src/pages/api/core/dataset/collection/list.ts +++ b/projects/app/src/pages/api/core/dataset/collection/list.ts @@ -38,13 +38,14 @@ async function handler(req: NextApiRequest) { const match = { teamId: new Types.ObjectId(teamId), datasetId: new Types.ObjectId(datasetId), - parentId: parentId ? new Types.ObjectId(parentId) : null, ...(selectFolder ? { type: DatasetCollectionTypeEnum.folder } : {}), ...(searchText ? { name: new RegExp(searchText, 'i') } - : {}), + : { + parentId: parentId ? new Types.ObjectId(parentId) : null + }), ...(filterTags.length ? { tags: { $in: filterTags } } : {}) }; diff --git a/projects/app/src/pages/api/core/dataset/collection/listV2.ts b/projects/app/src/pages/api/core/dataset/collection/listV2.ts index 0c97c698e..304ec5a07 100644 --- a/projects/app/src/pages/api/core/dataset/collection/listV2.ts +++ b/projects/app/src/pages/api/core/dataset/collection/listV2.ts @@ -43,13 +43,14 @@ async function handler( const match = { teamId: new Types.ObjectId(teamId), datasetId: new Types.ObjectId(datasetId), - parentId: parentId ? new Types.ObjectId(parentId) : null, ...(selectFolder ? { type: DatasetCollectionTypeEnum.folder } : {}), ...(searchText ? { name: new RegExp(searchText, 'i') } - : {}), + : { + parentId: parentId ? new Types.ObjectId(parentId) : null + }), ...(filterTags.length ? { tags: { $in: filterTags } } : {}) }; diff --git a/projects/app/src/pages/api/support/outLink/create.ts b/projects/app/src/pages/api/support/outLink/create.ts index c36860d48..3858e7ed8 100644 --- a/projects/app/src/pages/api/support/outLink/create.ts +++ b/projects/app/src/pages/api/support/outLink/create.ts @@ -1,7 +1,6 @@ import { MongoOutLink } from '@fastgpt/service/support/outLink/schema'; import { authApp } from '@fastgpt/service/support/permission/app/auth'; import type { OutLinkEditType } from '@fastgpt/global/support/outLink/type.d'; -import { customAlphabet } from 'nanoid'; import type { PublishChannelEnum } from '@fastgpt/global/support/outLink/constant'; import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant'; import type { ApiRequestProps } from '@fastgpt/service/type/next'; @@ -9,8 +8,7 @@ import { NextAPI } from '@/service/middleware/entry'; import { addOperationLog } from '@fastgpt/service/support/operationLog/addOperationLog'; import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants'; import { getI18nAppType } from '@fastgpt/service/support/operationLog/util'; -/* create a shareChat */ -const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz1234567890', 24); +import { getNanoid } from '@fastgpt/global/common/string/tools'; export type OutLinkCreateQuery = {}; export type OutLinkCreateBody = OutLinkEditType & @@ -32,7 +30,7 @@ async function handler( per: ManagePermissionVal }); - const shareId = nanoid(); + const shareId = getNanoid(24); await MongoOutLink.create({ shareId, teamId, diff --git a/tsconfig.json b/tsconfig.json index 9b4dcca57..aa81d8e09 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,7 +16,6 @@ "incremental": true, "baseUrl": ".", "paths": { - "@/*": ["projects/app/src/*"], "@fastgpt/*": ["packages/*"], "@test": ["test/*"] }