|
diff --git a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx
index 846ed3105..1d8296aa8 100644
--- a/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx
+++ b/projects/app/src/pageComponents/app/detail/WorkflowComponents/Flow/nodes/render/RenderInput/templates/SettingQuotePrompt.tsx
@@ -79,6 +79,16 @@ const EditModal = ({ onClose, ...props }: RenderInputProps & { onClose: () => vo
}>();
const quoteTemplateVariables = useMemo(
() => [
+ {
+ key: 'id',
+ label: 'id',
+ icon: 'core/app/simpleMode/variable'
+ },
+ {
+ key: 'source',
+ label: t('common:core.dataset.search.Source name'),
+ icon: 'core/app/simpleMode/variable'
+ },
{
key: 'q',
label: 'q',
@@ -90,13 +100,8 @@ const EditModal = ({ onClose, ...props }: RenderInputProps & { onClose: () => vo
icon: 'core/app/simpleMode/variable'
},
{
- key: 'source',
- label: t('common:core.dataset.search.Source name'),
- icon: 'core/app/simpleMode/variable'
- },
- {
- key: 'sourceId',
- label: t('common:core.dataset.search.Source id'),
+ key: 'updateTime',
+ label: t('app:source_updateTime'),
icon: 'core/app/simpleMode/variable'
},
{
diff --git a/projects/app/src/pages/api/core/ai/model/list.ts b/projects/app/src/pages/api/core/ai/model/list.ts
index 504668990..e19622be9 100644
--- a/projects/app/src/pages/api/core/ai/model/list.ts
+++ b/projects/app/src/pages/api/core/ai/model/list.ts
@@ -20,6 +20,11 @@ export type listResponse = {
isActive: boolean;
isCustom: boolean;
+
+ // Tag
+ contextToken?: number;
+ vision?: boolean;
+ toolChoice?: boolean;
}[];
async function handler(
@@ -39,7 +44,13 @@ async function handler(
inputPrice: model.inputPrice,
outputPrice: model.outputPrice,
isActive: model.isActive ?? false,
- isCustom: model.isCustom ?? false
+ isCustom: model.isCustom ?? false,
+
+ // Tag
+ contextToken:
+ 'maxContext' in model ? model.maxContext : 'maxToken' in model ? model.maxToken : undefined,
+ vision: 'vision' in model ? model.vision : undefined,
+ toolChoice: 'toolChoice' in model ? model.toolChoice : undefined
}));
}
diff --git a/projects/app/src/pages/api/core/ai/model/test.ts b/projects/app/src/pages/api/core/ai/model/test.ts
new file mode 100644
index 000000000..9895ac971
--- /dev/null
+++ b/projects/app/src/pages/api/core/ai/model/test.ts
@@ -0,0 +1,126 @@
+import type { ApiRequestProps, ApiResponseType } from '@fastgpt/service/type/next';
+import { NextAPI } from '@/service/middleware/entry';
+import { authSystemAdmin } from '@fastgpt/service/support/permission/user/auth';
+import { findModelFromAlldata } from '@fastgpt/service/core/ai/model';
+import {
+ EmbeddingModelItemType,
+ LLMModelItemType,
+ ReRankModelItemType,
+ STTModelType,
+ TTSModelType
+} from '@fastgpt/global/core/ai/model.d';
+import { getAIApi } from '@fastgpt/service/core/ai/config';
+import { addLog } from '@fastgpt/service/common/system/log';
+import { getVectorsByText } from '@fastgpt/service/core/ai/embedding';
+import { reRankRecall } from '@fastgpt/service/core/ai/rerank';
+import { aiTranscriptions } from '@fastgpt/service/core/ai/audio/transcriptions';
+import { isProduction } from '@fastgpt/global/common/system/constants';
+import * as fs from 'fs';
+
+export type testQuery = { model: string };
+
+export type testBody = {};
+
+export type testResponse = any;
+
+async function handler(
+ req: ApiRequestProps,
+ res: ApiResponseType
+): Promise {
+ await authSystemAdmin({ req });
+
+ const { model } = req.query;
+ const modelData = findModelFromAlldata(model);
+
+ if (!modelData) return Promise.reject('Model not found');
+
+ if (modelData.type === 'llm') {
+ return testLLMModel(modelData);
+ }
+ if (modelData.type === 'embedding') {
+ return testEmbeddingModel(modelData);
+ }
+ if (modelData.type === 'tts') {
+ return testTTSModel(modelData);
+ }
+ if (modelData.type === 'stt') {
+ return testSTTModel(modelData);
+ }
+ if (modelData.type === 'rerank') {
+ return testReRankModel(modelData);
+ }
+
+ return Promise.reject('Model type not supported');
+}
+
+export default NextAPI(handler);
+
+const testLLMModel = async (model: LLMModelItemType) => {
+ const ai = getAIApi({});
+ const response = await ai.chat.completions.create(
+ {
+ model: model.model,
+ messages: [{ role: 'user', content: 'hi' }],
+ stream: false,
+ max_tokens: 10
+ },
+ {
+ ...(model.requestUrl ? { path: model.requestUrl } : {}),
+ headers: {
+ ...(model.requestAuth ? { Authorization: `Bearer ${model.requestAuth}` } : {})
+ }
+ }
+ );
+
+ const responseText = response.choices?.[0]?.message?.content;
+
+ if (!responseText) {
+ return Promise.reject('Model response empty');
+ }
+
+ addLog.info(`Model test response: ${responseText}`);
+};
+
+const testEmbeddingModel = async (model: EmbeddingModelItemType) => {
+ return getVectorsByText({
+ input: 'Hi',
+ model
+ });
+};
+
+const testTTSModel = async (model: TTSModelType) => {
+ const ai = getAIApi();
+ await ai.audio.speech.create(
+ {
+ model: model.model,
+ voice: model.voices[0]?.value as any,
+ input: 'Hi',
+ response_format: 'mp3',
+ speed: 1
+ },
+ model.requestUrl && model.requestAuth
+ ? {
+ path: model.requestUrl,
+ headers: {
+ Authorization: `Bearer ${model.requestAuth}`
+ }
+ }
+ : {}
+ );
+};
+
+const testSTTModel = async (model: STTModelType) => {
+ const path = isProduction ? '/app/data/test.mp3' : 'data/test.mp3';
+ const { text } = await aiTranscriptions({
+ model: model.model,
+ fileStream: fs.createReadStream(path)
+ });
+ addLog.info(`STT result: ${text}`);
+};
+
+const testReRankModel = async (model: ReRankModelItemType) => {
+ await reRankRecall({
+ query: 'Hi',
+ documents: [{ id: '1', text: 'Hi' }]
+ });
+};
diff --git a/projects/app/src/pages/api/core/ai/model/updateWithJson.ts b/projects/app/src/pages/api/core/ai/model/updateWithJson.ts
index 74e05546f..1efd3b109 100644
--- a/projects/app/src/pages/api/core/ai/model/updateWithJson.ts
+++ b/projects/app/src/pages/api/core/ai/model/updateWithJson.ts
@@ -39,6 +39,9 @@ async function handler(
return Promise.reject(`${item.model} metadata.provider is required`);
}
item.metadata.model = item.model.trim();
+ if (!item.metadata.name) {
+ item.metadata.name = item.model;
+ }
}
await mongoSessionRun(async (session) => {
diff --git a/projects/app/src/pages/api/core/dataset/data/getQuoteData.ts b/projects/app/src/pages/api/core/dataset/data/getQuoteData.ts
new file mode 100644
index 000000000..d99642979
--- /dev/null
+++ b/projects/app/src/pages/api/core/dataset/data/getQuoteData.ts
@@ -0,0 +1,34 @@
+import type { NextApiRequest } from 'next';
+import { NextAPI } from '@/service/middleware/entry';
+import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
+import { authDatasetData } from '@fastgpt/service/support/permission/dataset/auth';
+import { CollectionWithDatasetType } from '@fastgpt/global/core/dataset/type';
+
+export type GetQuoteDataResponse = {
+ collection: CollectionWithDatasetType;
+ q: string;
+ a: string;
+};
+
+async function handler(req: NextApiRequest): Promise {
+ const { id: dataId } = req.query as {
+ id: string;
+ };
+
+ // 凭证校验
+ const { datasetData, collection } = await authDatasetData({
+ req,
+ authToken: true,
+ authApiKey: true,
+ dataId,
+ per: ReadPermissionVal
+ });
+
+ return {
+ collection,
+ q: datasetData.q,
+ a: datasetData.a
+ };
+}
+
+export default NextAPI(handler);
diff --git a/projects/app/src/service/common/system/index.ts b/projects/app/src/service/common/system/index.ts
index eb33103ce..83337c470 100644
--- a/projects/app/src/service/common/system/index.ts
+++ b/projects/app/src/service/common/system/index.ts
@@ -1,14 +1,12 @@
import { initHttpAgent } from '@fastgpt/service/common/middle/httpAgent';
-import fs, { existsSync, readdirSync } from 'fs';
+import fs, { existsSync } from 'fs';
import type { FastGPTFeConfigsType } from '@fastgpt/global/common/system/types/index.d';
import type { FastGPTConfigFileType } from '@fastgpt/global/common/system/types/index.d';
-import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
import { getFastGPTConfigFromDB } from '@fastgpt/service/common/system/config/controller';
import { FastGPTProUrl } from '@fastgpt/service/common/system/constants';
import { isProduction } from '@fastgpt/global/common/system/constants';
import { initFastGPTConfig } from '@fastgpt/service/common/system/tools';
import json5 from 'json5';
-import { SystemPluginTemplateItemType } from '@fastgpt/global/core/workflow/type';
import { defaultGroup, defaultTemplateTypes } from '@fastgpt/web/core/workflow/constants';
import { MongoPluginGroups } from '@fastgpt/service/core/app/plugin/pluginGroupSchema';
import { MongoTemplateTypes } from '@fastgpt/service/core/app/templates/templateTypeSchema';
@@ -48,14 +46,7 @@ export function initGlobalVariables() {
/* Init system data(Need to connected db). It only needs to run once */
export async function getInitConfig() {
- return Promise.all([
- initSystemConfig(),
- getSystemVersion(),
- loadSystemModels(),
-
- // abandon
- getSystemPlugin()
- ]);
+ return Promise.all([initSystemConfig(), getSystemVersion(), loadSystemModels()]);
}
const defaultFeConfigs: FastGPTFeConfigsType = {
@@ -129,34 +120,6 @@ async function getSystemVersion() {
}
}
-async function getSystemPlugin() {
- if (global.communityPlugins && global.communityPlugins.length > 0) return;
-
- const basePath =
- process.env.NODE_ENV === 'development' ? 'data/pluginTemplates' : '/app/data/pluginTemplates';
- // read data/pluginTemplates directory, get all json file
- const files = readdirSync(basePath);
- // filter json file
- const filterFiles = files.filter((item) => item.endsWith('.json'));
-
- // read json file
- const fileTemplates = await Promise.all(
- filterFiles.map>(async (filename) => {
- const content = await fs.promises.readFile(`${basePath}/${filename}`, 'utf-8');
- return {
- ...json5.parse(content),
- originCost: 0,
- currentCost: 0,
- id: `${PluginSourceEnum.community}-${filename.replace('.json', '')}`
- };
- })
- );
-
- fileTemplates.sort((a, b) => (b.weight || 0) - (a.weight || 0));
-
- global.communityPlugins = fileTemplates;
-}
-
export async function initSystemPluginGroups() {
try {
const { groupOrder, ...restDefaultGroup } = defaultGroup;
diff --git a/projects/app/src/web/core/ai/config.ts b/projects/app/src/web/core/ai/config.ts
index 30a2cc2f9..62afaad31 100644
--- a/projects/app/src/web/core/ai/config.ts
+++ b/projects/app/src/web/core/ai/config.ts
@@ -1,4 +1,4 @@
-import { GET, PUT, DELETE } from '@/web/common/api/request';
+import { GET, PUT, DELETE, POST } from '@/web/common/api/request';
import type { listResponse } from '@/pages/api/core/ai/model/list';
import type { updateBody } from '@/pages/api/core/ai/model/update';
import type { deleteQuery } from '@/pages/api/core/ai/model/delete';
@@ -16,3 +16,5 @@ export const deleteSystemModel = (data: deleteQuery) => DELETE('/core/ai/model/d
export const getModelConfigJson = () => GET('/core/ai/model/getConfigJson');
export const putUpdateWithJson = (data: updateWithJsonBody) =>
PUT('/core/ai/model/updateWithJson', data);
+
+export const getTestModel = (model: String) => GET('/core/ai/model/test', { model });
diff --git a/projects/app/src/web/core/dataset/api.ts b/projects/app/src/web/core/dataset/api.ts
index ac40e1a02..966b3361b 100644
--- a/projects/app/src/web/core/dataset/api.ts
+++ b/projects/app/src/web/core/dataset/api.ts
@@ -65,6 +65,7 @@ import type {
listExistIdQuery,
listExistIdResponse
} from '@/pages/api/core/dataset/apiDataset/listExistId';
+import { GetQuoteDataResponse } from '@/pages/api/core/dataset/data/getQuoteData';
/* ======================== dataset ======================= */
export const getDatasets = (data: GetDatasetListBody) =>
@@ -203,6 +204,10 @@ export const putDatasetDataById = (data: UpdateDatasetDataProps) =>
export const delOneDatasetDataById = (id: string) =>
DELETE(`/core/dataset/data/delete`, { id });
+// Get quote data
+export const getQuoteData = (id: string) =>
+ GET(`/core/dataset/data/getQuoteData`, { id });
+
/* ================ training ==================== */
export const postRebuildEmbedding = (data: rebuildEmbeddingBody) =>
POST(`/core/dataset/training/rebuildEmbedding`, data);
|