diff --git a/docSite/assets/imgs/appid.png b/docSite/assets/imgs/appid.png new file mode 100644 index 000000000..79c39c262 Binary files /dev/null and b/docSite/assets/imgs/appid.png differ diff --git a/docSite/content/zh-cn/docs/development/openapi/chat.md b/docSite/content/zh-cn/docs/development/openapi/chat.md index f97a7465d..7a54c312d 100644 --- a/docSite/content/zh-cn/docs/development/openapi/chat.md +++ b/docSite/content/zh-cn/docs/development/openapi/chat.md @@ -7,6 +7,12 @@ toc: true weight: 852 --- +# 如何获取 AppId + +可在应用详情的路径里获取 AppId。 + +![](/imgs/appid.png) + # 发起对话 {{% alert icon="🤖 " context="success" %}} @@ -102,8 +108,8 @@ curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \ {{% alert context="info" %}} - headers.Authorization: Bearer {{apikey}} - chatId: string | undefined 。 - - 为 `undefined` 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。 不会将你的记录存储到数据库中,你也无法在记录汇总中查阅到。 - - 为`非空字符串`时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录,并使用 messages 数组最后一个内容作为用户问题。请自行确保 chatId 唯一,长度小于250,通常可以是自己系统的对话框ID。 + - 为 `undefined` 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。 + - 为`非空字符串`时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录,并使用 messages 数组最后一个内容作为用户问题,其余 message 会被忽略。请自行确保 chatId 唯一,长度小于250,通常可以是自己系统的对话框ID。 - messages: 结构与 [GPT接口](https://platform.openai.com/docs/api-reference/chat/object) chat模式一致。 - responseChatItemId: string | undefined 。如果传入,则会将该值作为本次对话的响应消息的 ID,FastGPT 会自动将该 ID 存入数据库。请确保,在当前`chatId`下,`responseChatItemId`是唯一的。 - detail: 是否返回中间值(模块状态,响应的完整结果等),`stream模式`下会通过`event`进行区分,`非stream模式`结果保存在`responseData`中。 diff --git a/docSite/content/zh-cn/docs/development/openapi/auth.md b/docSite/content/zh-cn/docs/development/openapi/intro.md similarity index 96% rename from docSite/content/zh-cn/docs/development/openapi/auth.md rename to docSite/content/zh-cn/docs/development/openapi/intro.md index aa7014e80..abc5cf3ad 100644 --- a/docSite/content/zh-cn/docs/development/openapi/auth.md +++ b/docSite/content/zh-cn/docs/development/openapi/intro.md @@ -1,6 +1,6 @@ --- -title: 'Api Key 使用与鉴权' -description: 'FastGPT Api Key 使用与鉴权' +title: 'OpenAPI 介绍' +description: 'FastGPT OpenAPI 介绍' icon: 'key' draft: false toc: true @@ -27,6 +27,7 @@ FastGPT 的 API Key **有 2 类**,一类是全局通用的 key (无法直接 | --------------------- | --------------------- | | ![](/imgs/fastgpt-api2.jpg) | ![](/imgs/fastgpt-api1.jpg) | + ## 基本配置 OpenAPI 中,所有的接口都通过 Header.Authorization 进行鉴权。 diff --git a/docSite/content/zh-cn/docs/development/upgrading/4822.md b/docSite/content/zh-cn/docs/development/upgrading/4822.md index 381f7268c..c7eec15bf 100644 --- a/docSite/content/zh-cn/docs/development/upgrading/4822.md +++ b/docSite/content/zh-cn/docs/development/upgrading/4822.md @@ -17,19 +17,37 @@ weight: 802 - 更新 fastgpt-pro 商业版镜像 tag: v4.8.22-alpha - Sandbox 镜像无需更新 +### 3. 运行升级脚本 + +仅商业版,并提供 Saas 服务的用户需要运行该升级脚本。 + +从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 域名**。 + +```bash +curl --location --request POST 'https://{{host}}/api/admin/initv4822' \ +--header 'rootkey: {{rootkey}}' \ +--header 'Content-Type: application/json' +``` + +会迁移联系方式到对应用户表中。 ## 🚀 新增内容 1. AI 对话节点解析 `` 标签内容作为思考链,便于各类模型进行思考链输出。需主动开启模型输出思考。 -2. ppio 模型提供商 by @saikidev +2. 对话 API 优化,无论是否传递 chatId,都会保存对话日志。未传递 chatId,则随机生成一个 chatId 来进行存储。 +3. ppio 模型提供商 by ## ⚙️ 优化 -1. 模型未配置时提示,减少冲突提示。 +1. 模型未配置时提示,减少冲突提示。 2. 使用记录代码。 +3. 内容提取节点,字段描述过长时换行。同时修改其输出名用 key,而不是 description。 +4. 团队管理交互。 +5. 对话接口,非流响应,增加报错字段。 ## 🐛 修复 -1. 思考内容未进入到输出 Tokens. + +1. 思考内容未进入到输出 Tokens. 2. 思考链流输出时,有时与正文顺序偏差。 3. API 调用工作流,如果传递的图片不支持 Head 检测时,图片会被过滤。已增加该类错误检测,避免被错误过滤。 4. 模板市场部分模板错误。 @@ -37,4 +55,7 @@ weight: 802 6. 对话日志导出,未兼容 sub path。 7. 切换团队时未刷新成员列表 8. list 接口在联查 member 时,存在空指针可能性。 -9. 工作流基础节点无法升级。 \ No newline at end of file +9. 工作流基础节点无法升级。 +10. 向量检索结果未去重。 +11. 用户选择节点无法正常连线。 +12. 对话记录保存时,source 未正常记录。 \ No newline at end of file diff --git a/packages/global/core/ai/provider.ts b/packages/global/core/ai/provider.ts index cf38e54eb..a85faae22 100644 --- a/packages/global/core/ai/provider.ts +++ b/packages/global/core/ai/provider.ts @@ -72,11 +72,6 @@ export const ModelProviderList: ModelProviderType[] = [ name: 'Groq', avatar: 'model/groq' }, - { - id: 'AliCloud', - name: i18nT('common:model_alicloud'), - avatar: 'model/alicloud' - }, { id: 'Qwen', name: i18nT('common:model_qwen'), @@ -87,6 +82,11 @@ export const ModelProviderList: ModelProviderType[] = [ name: i18nT('common:model_doubao'), avatar: 'model/doubao' }, + { + id: 'DeepSeek', + name: 'DeepSeek', + avatar: 'model/deepseek' + }, { id: 'ChatGLM', name: i18nT('common:model_chatglm'), @@ -97,11 +97,6 @@ export const ModelProviderList: ModelProviderType[] = [ name: i18nT('common:model_ernie'), avatar: 'model/ernie' }, - { - id: 'DeepSeek', - name: 'DeepSeek', - avatar: 'model/deepseek' - }, { id: 'Moonshot', name: i18nT('common:model_moonshot'), @@ -163,6 +158,11 @@ export const ModelProviderList: ModelProviderType[] = [ name: i18nT('common:model_moka'), avatar: 'model/moka' }, + { + id: 'AliCloud', + name: i18nT('common:model_alicloud'), + avatar: 'model/alicloud' + }, { id: 'Siliconflow', name: i18nT('common:model_siliconflow'), diff --git a/packages/service/core/chat/chatSchema.ts b/packages/service/core/chat/chatSchema.ts index b370c1e43..52baa5a71 100644 --- a/packages/service/core/chat/chatSchema.ts +++ b/packages/service/core/chat/chatSchema.ts @@ -1,7 +1,7 @@ import { connectionMongo, getMongoModel } from '../../common/mongo'; const { Schema } = connectionMongo; import { ChatSchema as ChatType } from '@fastgpt/global/core/chat/type.d'; -import { ChatSourceMap } from '@fastgpt/global/core/chat/constants'; +import { ChatSourceEnum, ChatSourceMap } from '@fastgpt/global/core/chat/constants'; import { TeamCollectionName, TeamMemberCollectionName @@ -52,11 +52,10 @@ const ChatSchema = new Schema({ }, source: { type: String, - required: true - }, - sourceName: { - type: String + required: true, + enum: Object.values(ChatSourceEnum) }, + sourceName: String, shareId: { type: String }, diff --git a/packages/service/core/chat/saveChat.ts b/packages/service/core/chat/saveChat.ts index efb5c0605..48bbcc8f4 100644 --- a/packages/service/core/chat/saveChat.ts +++ b/packages/service/core/chat/saveChat.ts @@ -1,6 +1,10 @@ import type { AIChatItemType, UserChatItemType } from '@fastgpt/global/core/chat/type.d'; import { MongoApp } from '../app/schema'; -import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants'; +import { + ChatItemValueTypeEnum, + ChatRoleEnum, + ChatSourceEnum +} from '@fastgpt/global/core/chat/constants'; import { MongoChatItem } from './chatItemSchema'; import { MongoChat } from './chatSchema'; import { addLog } from '../../common/system/log'; @@ -22,8 +26,8 @@ type Props = { variables?: Record; isUpdateUseTime: boolean; newTitle: string; - source: string; - sourceName: string; + source: `${ChatSourceEnum}`; + sourceName?: string; shareId?: string; outLinkUid?: string; content: [UserChatItemType & { dataId?: string }, AIChatItemType & { dataId?: string }]; diff --git a/packages/service/core/dataset/search/controller.ts b/packages/service/core/dataset/search/controller.ts index e39084121..762ae687d 100644 --- a/packages/service/core/dataset/search/controller.ts +++ b/packages/service/core/dataset/search/controller.ts @@ -383,6 +383,7 @@ export async function searchDatasetData( ).lean() ]); + const set = new Map(); const formatResult = results .map((item, index) => { const collection = collections.find((col) => String(col._id) === String(item.collectionId)); @@ -398,8 +399,6 @@ export async function searchDatasetData( return; } - const score = item?.score || 0; - const result: SearchDataResponseItemType = { id: String(data._id), updateTime: data.updateTime, @@ -409,12 +408,24 @@ export async function searchDatasetData( datasetId: String(data.datasetId), collectionId: String(data.collectionId), ...getCollectionSourceData(collection), - score: [{ type: SearchScoreTypeEnum.embedding, value: score, index }] + score: [{ type: SearchScoreTypeEnum.embedding, value: item?.score || 0, index }] }; return result; }) - .filter(Boolean) as SearchDataResponseItemType[]; + .filter((item) => { + if (!item) return false; + if (set.has(item.id)) return false; + set.set(item.id, 1); + return true; + }) + .map((item, index) => { + if (!item) return; + return { + ...item, + score: item.score.map((item) => ({ ...item, index })) + }; + }) as SearchDataResponseItemType[]; return { embeddingRecallResults: formatResult, @@ -717,11 +728,12 @@ export const defaultSearchDatasetData = async ({ ? getLLMModel(datasetSearchExtensionModel) : undefined; - const { concatQueries, rewriteQuery, aiExtensionResult } = await datasetSearchQueryExtension({ - query, - extensionModel, - extensionBg: datasetSearchExtensionBg - }); + const { concatQueries, extensionQueries, rewriteQuery, aiExtensionResult } = + await datasetSearchQueryExtension({ + query, + extensionModel, + extensionBg: datasetSearchExtensionBg + }); const result = await searchDatasetData({ ...props, @@ -736,7 +748,7 @@ export const defaultSearchDatasetData = async ({ model: aiExtensionResult.model, inputTokens: aiExtensionResult.inputTokens, outputTokens: aiExtensionResult.outputTokens, - query: concatQueries.join('\n') + query: extensionQueries.join('\n') } : undefined }; diff --git a/packages/service/core/dataset/search/utils.ts b/packages/service/core/dataset/search/utils.ts index e0c1abcab..9101131df 100644 --- a/packages/service/core/dataset/search/utils.ts +++ b/packages/service/core/dataset/search/utils.ts @@ -72,12 +72,15 @@ Human: ${query} if (result.extensionQueries?.length === 0) return; return result; })(); + + const extensionQueries = filterSamQuery(aiExtensionResult?.extensionQueries || []); if (aiExtensionResult) { - queries = filterSamQuery(queries.concat(aiExtensionResult.extensionQueries)); + queries = filterSamQuery(queries.concat(extensionQueries)); rewriteQuery = queries.join('\n'); } return { + extensionQueries, concatQueries: queries, rewriteQuery, aiExtensionResult diff --git a/packages/web/i18n/en/common.json b/packages/web/i18n/en/common.json index 9470e5502..2ac7c2e70 100644 --- a/packages/web/i18n/en/common.json +++ b/packages/web/i18n/en/common.json @@ -1182,7 +1182,6 @@ "support.wallet.usage.Audio Speech": "Voice Playback", "support.wallet.usage.Bill Module": "Billing Module", "support.wallet.usage.Duration": "Duration (seconds)", - "support.wallet.usage.Extension result": "Question Optimization Result", "support.wallet.usage.Module name": "Module Name", "support.wallet.usage.Source": "Source", "support.wallet.usage.Text Length": "Text Length", diff --git a/packages/web/i18n/zh-CN/common.json b/packages/web/i18n/zh-CN/common.json index c9fdd1ea8..e51c43488 100644 --- a/packages/web/i18n/zh-CN/common.json +++ b/packages/web/i18n/zh-CN/common.json @@ -1185,7 +1185,6 @@ "support.wallet.usage.Audio Speech": "语音播放", "support.wallet.usage.Bill Module": "扣费模块", "support.wallet.usage.Duration": "时长(秒)", - "support.wallet.usage.Extension result": "问题优化结果", "support.wallet.usage.Module name": "模块名", "support.wallet.usage.Source": "来源", "support.wallet.usage.Text Length": "文本长度", diff --git a/packages/web/i18n/zh-Hant/common.json b/packages/web/i18n/zh-Hant/common.json index a5ec9dd94..1065ce1e1 100644 --- a/packages/web/i18n/zh-Hant/common.json +++ b/packages/web/i18n/zh-Hant/common.json @@ -1181,7 +1181,6 @@ "support.wallet.usage.Audio Speech": "語音播放", "support.wallet.usage.Bill Module": "計費模組", "support.wallet.usage.Duration": "時長(秒)", - "support.wallet.usage.Extension result": "問題最佳化結果", "support.wallet.usage.Module name": "模組名稱", "support.wallet.usage.Source": "來源", "support.wallet.usage.Text Length": "文字長度", diff --git a/projects/app/src/components/Layout/index.tsx b/projects/app/src/components/Layout/index.tsx index 0a9c284f5..883e77d75 100644 --- a/projects/app/src/components/Layout/index.tsx +++ b/projects/app/src/components/Layout/index.tsx @@ -78,7 +78,7 @@ const Layout = ({ children }: { children: JSX.Element }) => { isUpdateNotification && feConfigs?.bind_notification_method && feConfigs?.bind_notification_method.length > 0 && - !userInfo?.team.notificationAccount && + !userInfo?.contact && !!userInfo?.team.permission.isOwner; useMount(() => { diff --git a/projects/app/src/components/core/chat/components/WholeResponseModal.tsx b/projects/app/src/components/core/chat/components/WholeResponseModal.tsx index c987992e8..b01870bb0 100644 --- a/projects/app/src/components/core/chat/components/WholeResponseModal.tsx +++ b/projects/app/src/components/core/chat/components/WholeResponseModal.tsx @@ -250,7 +250,7 @@ export const WholeResponseContent = ({ value={`${activeModule.queryExtensionResult.inputTokens}/${activeModule.queryExtensionResult.outputTokens}`} /> @@ -259,10 +259,7 @@ export const WholeResponseContent = ({ label={t('common:core.chat.response.Extension model')} value={activeModule?.extensionModel} /> - + {activeModule.quoteList && activeModule.quoteList.length > 0 && ( {t(SearchScoreTypeMap[score.primaryScore.type]?.label as any)} {SearchScoreTypeMap[score.primaryScore.type]?.showScore - ? ` ${score.primaryScore.value.toFixed(4)}` + ? ` ${score.primaryScore.value?.toFixed(4)}` : ''} diff --git a/projects/app/src/components/support/permission/MemberManager/MemberItemCard.tsx b/projects/app/src/components/support/permission/MemberManager/MemberItemCard.tsx index d928953e5..df64909be 100644 --- a/projects/app/src/components/support/permission/MemberManager/MemberItemCard.tsx +++ b/projects/app/src/components/support/permission/MemberManager/MemberItemCard.tsx @@ -43,10 +43,10 @@ function MemberItemCard({ {isChecked !== undefined && } - - {name} - {orgs && orgs.length > 0 && } - + + {name} + {orgs && orgs.length > 0 && } + {permission && } {onDelete !== undefined && ( ([]); const filterMembers = useMemo(() => { if (searchText) { - return searchedData?.members; + return searchedData?.members || []; } if (!searchText && filterClass !== 'member' && filterClass !== 'org') return []; if (currentOrg && filterClass === 'org') { @@ -320,122 +320,124 @@ function MemberModal({ )} - - {filterOrgs?.map((org) => { - const onChange = () => { - setSelectedOrgIdList((state) => { - if (state.includes(org._id)) { - return state.filter((v) => v !== org._id); - } - return [...state, org._id]; - }); - }; - const collaborator = collaboratorList?.find((v) => v.orgId === org._id); - return ( - - - - - {org.name} + {(filterClass === 'org' || filterClass === 'member') && ( + + {filterOrgs?.map((org) => { + const onChange = () => { + setSelectedOrgIdList((state) => { + if (state.includes(org._id)) { + return state.filter((v) => v !== org._id); + } + return [...state, org._id]; + }); + }; + const collaborator = collaboratorList?.find((v) => v.orgId === org._id); + return ( + + + + + {org.name} + {org.count && ( + <> + + {org.count} + + + )} + + {org.count && ( - <> - - {org.count} - - + { + setParentPath(getOrgChildrenPath(org)); + e.stopPropagation(); + }} + /> )} - - {org.count && ( - { - setParentPath(getOrgChildrenPath(org)); - e.stopPropagation(); - }} - /> - )} - - ); - })} - {filterMembers?.map((member) => { - const onChange = () => { - setSelectedMembers((state) => { - if (state.includes(member.tmbId)) { - return state.filter((v) => v !== member.tmbId); - } - return [...state, member.tmbId]; - }); - }; - const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId); - const memberOrgs = orgs.filter((org) => - org.members.find((v) => String(v.tmbId) === String(member.tmbId)) - ); - const memberPathIds = memberOrgs.map((org) => - (org.path + '/' + org.pathId).split('/').slice(0) - ); - const memberOrgNames = memberPathIds.map((pathIds) => - pathIds.map((id) => orgs.find((v) => v.pathId === id)?.name).join('/') - ); - return ( - - ); - })} - {filterGroups?.map((group) => { - const onChange = () => { - setSelectedGroupIdList((state) => { - if (state.includes(group._id)) { - return state.filter((v) => v !== group._id); - } - return [...state, group._id]; - }); - }; - const collaborator = collaboratorList?.find((v) => v.groupId === group._id); - return ( - - ); - })} - + ); + })} + {filterMembers?.map((member) => { + const onChange = () => { + setSelectedMembers((state) => { + if (state.includes(member.tmbId)) { + return state.filter((v) => v !== member.tmbId); + } + return [...state, member.tmbId]; + }); + }; + const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId); + const memberOrgs = orgs.filter((org) => + org.members.find((v) => String(v.tmbId) === String(member.tmbId)) + ); + const memberPathIds = memberOrgs.map((org) => + (org.path + '/' + org.pathId).split('/').slice(0) + ); + const memberOrgNames = memberPathIds.map((pathIds) => + pathIds.map((id) => orgs.find((v) => v.pathId === id)?.name).join('/') + ); + return ( + + ); + })} + + )} + {filterGroups?.map((group) => { + const onChange = () => { + setSelectedGroupIdList((state) => { + if (state.includes(group._id)) { + return state.filter((v) => v !== group._id); + } + return [...state, group._id]; + }); + }; + const collaborator = collaboratorList?.find((v) => v.groupId === group._id); + return ( + + ); + })} diff --git a/projects/app/src/components/support/user/team/OrgTags/index.tsx b/projects/app/src/components/support/user/team/OrgTags/index.tsx index 4347f22e9..eebd6a26e 100644 --- a/projects/app/src/components/support/user/team/OrgTags/index.tsx +++ b/projects/app/src/components/support/user/team/OrgTags/index.tsx @@ -18,12 +18,18 @@ function OrgTags({ orgs, type = 'simple' }: { orgs: string[]; type?: 'simple' | } > {type === 'simple' ? ( - + {orgs .map((org) => org.split('/').pop()) .join(', ') .slice(0, 30)} - {orgs.length > 1 && '...'} ) : ( diff --git a/projects/app/src/pageComponents/account/team/MemberTable.tsx b/projects/app/src/pageComponents/account/team/MemberTable.tsx index a3f95acbd..78c48265a 100644 --- a/projects/app/src/pageComponents/account/team/MemberTable.tsx +++ b/projects/app/src/pageComponents/account/team/MemberTable.tsx @@ -194,19 +194,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) { {t('account_team:user_team_invite_member')} )} - {!userInfo?.team.permission.isOwner && ( - - )} - {userInfo?.team.permission.hasManagePer && ( + {userInfo?.team.permission.isOwner && isSyncMember && ( + )} diff --git a/projects/app/src/pageComponents/account/team/PermissionManage/index.tsx b/projects/app/src/pageComponents/account/team/PermissionManage/index.tsx index e480ff3e2..28232854e 100644 --- a/projects/app/src/pageComponents/account/team/PermissionManage/index.tsx +++ b/projects/app/src/pageComponents/account/team/PermissionManage/index.tsx @@ -87,7 +87,7 @@ function PermissionManage({ const groupList = collaboratorList.filter( (item) => Object.keys(item).includes('groupId') && - (!searchKey || searchResult?.groups.find((group) => group.groupId === item.groupId)) + (!searchKey || searchResult?.groups.find((group) => group._id === item.groupId)) ); const orgList = collaboratorList.filter( (item) => diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/ExtractFieldModal.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/ExtractFieldModal.tsx index a783a810f..2666643ae 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/ExtractFieldModal.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/ExtractFieldModal.tsx @@ -96,6 +96,7 @@ const ExtractFieldModal = ({ diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/index.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/index.tsx index 4d0c2ad58..1a825c945 100644 --- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/index.tsx +++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/NodeExtract/index.tsx @@ -35,6 +35,7 @@ import IOTitle from '../../components/IOTitle'; import { useContextSelector } from 'use-context-selector'; import { WorkflowContext } from '../../../context'; import MyIconButton from '@fastgpt/web/components/common/Icon/button'; +import MyTooltip from '@fastgpt/web/components/common/MyTooltip'; const NodeExtract = ({ data, selected }: NodeProps) => { const { inputs, outputs, nodeId } = data; @@ -71,7 +72,7 @@ const NodeExtract = ({ data, selected }: NodeProps) => { - + @@ -85,19 +86,23 @@ const NodeExtract = ({ data, selected }: NodeProps) => { {extractKeys.map((item, index) => ( - +
- + {item.key} {item.desc} + + {item.desc} + + {item.required ? ( ) : ( - '' + '-' )} @@ -197,7 +202,7 @@ const NodeExtract = ({ data, selected }: NodeProps) => { const newOutput: FlowNodeOutputItemType = { id: getNanoid(), key: data.key, - label: `${t('common:extraction_results')}-${data.desc}`, + label: `${t('common:extraction_results')}-${data.key}`, valueType: data.valueType || WorkflowIOValueTypeEnum.string, type: FlowNodeOutputTypeEnum.static }; diff --git a/projects/app/src/pages/api/admin/initv4822.ts b/projects/app/src/pages/api/admin/initv4822.ts index 8da6e2998..9ea018480 100644 --- a/projects/app/src/pages/api/admin/initv4822.ts +++ b/projects/app/src/pages/api/admin/initv4822.ts @@ -11,6 +11,9 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { await authCert({ req, authRoot: true }); const users = await MongoUser.find(); const teams = await MongoTeam.find(); + + console.log('Total users:', users.length); + let success = 0; for await (const user of users) { try { const team = teams.find((team) => String(team.ownerId) === String(user._id)); @@ -18,6 +21,7 @@ async function handler(req: NextApiRequest, _res: NextApiResponse) { user.contact = team.notificationAccount; } await user.save(); + console.log('Success:', ++success); } catch (error) { console.error(error); } diff --git a/projects/app/src/pages/api/core/dataset/collection/sync.ts b/projects/app/src/pages/api/core/dataset/collection/sync.ts index 84740129c..417baa4ff 100644 --- a/projects/app/src/pages/api/core/dataset/collection/sync.ts +++ b/projects/app/src/pages/api/core/dataset/collection/sync.ts @@ -6,12 +6,12 @@ import { ApiRequestProps } from '@fastgpt/service/type/next'; import { syncCollection } from '@fastgpt/service/core/dataset/collection/utils'; /* - Collection sync - 1. Check collection type: link, api dataset collection - 2. Get collection and raw text - 3. Check whether the original text is the same: skip if same - 4. Create new collection - 5. Delete old collection + Collection sync + 1. Check collection type: link, api dataset collection + 2. Get collection and raw text + 3. Check whether the original text is the same: skip if same + 4. Create new collection + 5. Delete old collection */ export type CollectionSyncBody = { collectionId: string; @@ -27,6 +27,7 @@ async function handler(req: ApiRequestProps) { const { collection } = await authDatasetCollection({ req, authToken: true, + authApiKey: true, collectionId, per: WritePermissionVal }); diff --git a/projects/app/src/pages/api/support/user/account/tokenLogin.ts b/projects/app/src/pages/api/support/user/account/tokenLogin.ts index f3532848d..d6017b786 100644 --- a/projects/app/src/pages/api/support/user/account/tokenLogin.ts +++ b/projects/app/src/pages/api/support/user/account/tokenLogin.ts @@ -16,13 +16,13 @@ async function handler( const user = await getUserDetail({ tmbId }); // Remove sensitive information - if (user.team.lafAccount) { - user.team.lafAccount = { - appid: user.team.lafAccount.appid, - token: '', - pat: '' - }; - } + // if (user.team.lafAccount) { + // user.team.lafAccount = { + // appid: user.team.lafAccount.appid, + // token: '', + // pat: '' + // }; + // } if (user.team.openaiAccount) { user.team.openaiAccount = { key: '', diff --git a/projects/app/src/pages/api/v1/chat/completions.ts b/projects/app/src/pages/api/v1/chat/completions.ts index 6e3b143d4..5657a2783 100644 --- a/projects/app/src/pages/api/v1/chat/completions.ts +++ b/projects/app/src/pages/api/v1/chat/completions.ts @@ -302,65 +302,64 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { })(); // save chat - if (chatId) { - const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId); - const source = (() => { - if (shareId) { - return ChatSourceEnum.share; - } - if (authType === 'apikey') { - return ChatSourceEnum.api; - } - if (spaceTeamId) { - return ChatSourceEnum.team; - } - return ChatSourceEnum.online; - })(); - - const isInteractiveRequest = !!getLastInteractiveValue(histories); - const { text: userInteractiveVal } = chatValue2RuntimePrompt(userQuestion.value); - - const newTitle = isPlugin - ? variables.cTime ?? getSystemTime(timezone) - : getChatTitleFromChatMessage(userQuestion); - - const aiResponse: AIChatItemType & { dataId?: string } = { - dataId: responseChatItemId, - obj: ChatRoleEnum.AI, - value: assistantResponses, - [DispatchNodeResponseKeyEnum.nodeResponse]: flowResponses - }; - - if (isInteractiveRequest) { - await updateInteractiveChat({ - chatId, - appId: app._id, - userInteractiveVal, - aiResponse, - newVariables - }); - } else { - await saveChat({ - chatId, - appId: app._id, - teamId, - tmbId: tmbId, - nodes, - appChatConfig: chatConfig, - variables: newVariables, - isUpdateUseTime: isOwnerUse && source === ChatSourceEnum.online, // owner update use time - newTitle, - shareId, - outLinkUid: outLinkUserId, - source: source, - sourceName: sourceName || '', - content: [userQuestion, aiResponse], - metadata: { - originIp, - ...metadata - } - }); + const isOwnerUse = !shareId && !spaceTeamId && String(tmbId) === String(app.tmbId); + const source = (() => { + if (shareId) { + return ChatSourceEnum.share; } + if (authType === 'apikey') { + return ChatSourceEnum.api; + } + if (spaceTeamId) { + return ChatSourceEnum.team; + } + return ChatSourceEnum.online; + })(); + + const isInteractiveRequest = !!getLastInteractiveValue(histories); + const { text: userInteractiveVal } = chatValue2RuntimePrompt(userQuestion.value); + + const newTitle = isPlugin + ? variables.cTime ?? getSystemTime(timezone) + : getChatTitleFromChatMessage(userQuestion); + + const aiResponse: AIChatItemType & { dataId?: string } = { + dataId: responseChatItemId, + obj: ChatRoleEnum.AI, + value: assistantResponses, + [DispatchNodeResponseKeyEnum.nodeResponse]: flowResponses + }; + + const saveChatId = chatId || getNanoid(24); + if (isInteractiveRequest) { + await updateInteractiveChat({ + chatId: saveChatId, + appId: app._id, + userInteractiveVal, + aiResponse, + newVariables + }); + } else { + await saveChat({ + chatId: saveChatId, + appId: app._id, + teamId, + tmbId: tmbId, + nodes, + appChatConfig: chatConfig, + variables: newVariables, + isUpdateUseTime: isOwnerUse && source === ChatSourceEnum.online, // owner update use time + newTitle, + shareId, + outLinkUid: outLinkUserId, + source, + sourceName: sourceName || '', + content: [userQuestion, aiResponse], + metadata: { + originIp, + ...metadata + } + }); } addLog.info(`completions running time: ${(Date.now() - startTime) / 1000}s`); @@ -407,9 +406,11 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { return assistantResponses; })(); + const error = flowResponses[flowResponses.length - 1]?.error; res.json({ ...(detail ? { responseData: feResponseData, newVariables } : {}), + error, id: chatId || '', model: '', usage: { prompt_tokens: 1, completion_tokens: 1, total_tokens: 1 },