mirror of
https://github.com/labring/FastGPT.git
synced 2025-10-14 23:22:22 +00:00
V4.12.3 features (#5595)
* refactor: remove ModelProviderIdType and update related types (#5549) * perf: model provider * fix eval create split (#5570) * git rebase --continuedoc * add more variable types (#5540) * variable types * password * time picker * internal var * file * fix-test * time select default value & range * password & type render * fix * fix build * fix * move method * split date select * icon * perf: variable code * prompt editor add markdown plugin (#5556) * editor markdown * fix build * pnpm lock * add props * update code * fix list * editor ui * fix variable reset (#5586) * perf: variables type code * customize lexical indent (#5588) * perf: multiple selector * perf: tab plugin * doc * refactor: update workflow constants to use ToolTypeEnum (#5491) * refactor: replace FlowNodeTemplateTypeEnum with string literals in workflow templates * perf: tool type --------- Co-authored-by: archer <545436317@qq.com> * update doc * fix: make table's row more natural while dragging it (#5596) * feat: add APIGetTemplate function and refactor template fetching logic (#5498) * feat: add APIGetTemplate function and refactor template fetching logic * chore: adjust the code * chore: update sdk --------- Co-authored-by: FinleyGe <m13203533462@163.com> * perf init system * doc * remove log * remove i18n * perf: variables render --------- Co-authored-by: Ctrlz <143257420+ctrlz526@users.noreply.github.com> Co-authored-by: heheer <heheer@sealos.io> Co-authored-by: 伍闲犬 <whoeverimf5@gmail.com> Co-authored-by: FinleyGe <m13203533462@163.com>
This commit is contained in:
@@ -2,6 +2,7 @@ import { decryptSecret, encryptSecret } from './aes256gcm';
|
||||
import type { SecretValueType } from '@fastgpt/global/common/secret/type';
|
||||
import { type StoreSecretValueType } from '@fastgpt/global/common/secret/type';
|
||||
import { HeaderSecretTypeEnum } from '@fastgpt/global/common/secret/constants';
|
||||
import { isSecretValue } from '../../../global/common/secret/utils';
|
||||
|
||||
export const encryptSecretValue = (value: SecretValueType): SecretValueType => {
|
||||
if (!value.value) {
|
||||
@@ -48,3 +49,9 @@ export const getSecretValue = ({
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
export const anyValueDecrypt = (value: any) => {
|
||||
if (!isSecretValue(value)) return value;
|
||||
|
||||
return decryptSecret(value.secret);
|
||||
};
|
||||
|
@@ -11,7 +11,7 @@ import type {
|
||||
EmbeddingRecallResponse,
|
||||
InsertVectorControllerProps
|
||||
} from '../controller.d';
|
||||
import { delay, retryFn } from '@fastgpt/global/common/system/utils';
|
||||
import { retryFn } from '@fastgpt/global/common/system/utils';
|
||||
import { addLog } from '../../system/log';
|
||||
import { customNanoid } from '@fastgpt/global/common/string/tools';
|
||||
|
||||
|
@@ -9,7 +9,7 @@ import {
|
||||
type RerankModelItemType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
import { debounce } from 'lodash';
|
||||
import { getModelProvider } from '@fastgpt/global/core/ai/provider';
|
||||
import { getModelProvider } from '../../../core/app/provider/controller';
|
||||
import { findModelFromAlldata } from '../model';
|
||||
import {
|
||||
reloadFastGPTConfigBuffer,
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
import { delay } from '@fastgpt/global/common/system/utils';
|
||||
import { pluginClient } from '../../../thirdProvider/fastgptPlugin';
|
||||
import { setCron } from '../../../common/system/cron';
|
||||
import { preloadModelProviders } from '../../../core/app/provider/controller';
|
||||
|
||||
export const loadSystemModels = async (init = false, language = 'en') => {
|
||||
const pushModel = (model: SystemModelItemType) => {
|
||||
@@ -77,6 +78,8 @@ export const loadSystemModels = async (init = false, language = 'en') => {
|
||||
|
||||
if (!init && global.systemModelList) return;
|
||||
|
||||
await preloadModelProviders();
|
||||
|
||||
global.systemModelList = [];
|
||||
global.systemActiveModelList = [];
|
||||
global.llmModelMap = new Map<string, LLMModelItemType>();
|
||||
@@ -109,14 +112,13 @@ export const loadSystemModels = async (init = false, language = 'en') => {
|
||||
};
|
||||
|
||||
const dbModel = dbModels.find((item) => item.model === model.model);
|
||||
const provider = getModelProvider(dbModel?.metadata?.provider || model.provider, language);
|
||||
|
||||
const modelData: any = {
|
||||
...model,
|
||||
...dbModel?.metadata,
|
||||
provider: getModelProvider(
|
||||
dbModel?.metadata?.provider || (model.provider as any),
|
||||
language
|
||||
).id,
|
||||
provider: provider.id,
|
||||
avatar: provider.avatar,
|
||||
type: dbModel?.metadata?.type || model.type,
|
||||
isCustom: false,
|
||||
|
||||
|
11
packages/service/core/ai/type.d.ts
vendored
11
packages/service/core/ai/type.d.ts
vendored
@@ -6,6 +6,12 @@ import type {
|
||||
EmbeddingModelItemType,
|
||||
LLMModelItemType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
import type { ModelProviderListType } from '@fastgpt/global/core/app/model/type';
|
||||
import type {
|
||||
AiproxyMapProviderType,
|
||||
I18nStringStrictType
|
||||
} from '@fastgpt/global/sdk/fastgpt-plugin';
|
||||
import type { langType, ModelProviderItemType } from '@fastgpt/global/core/ai/provider';
|
||||
|
||||
export type SystemModelSchemaType = {
|
||||
_id: string;
|
||||
@@ -32,6 +38,11 @@ export type SystemDefaultModelType = {
|
||||
};
|
||||
|
||||
declare global {
|
||||
var ModelProviderRawCache: { provider: string; value: I18nStringStrictType }[];
|
||||
var ModelProviderListCache: Record<langType, ModelProviderItemType[]>;
|
||||
var ModelProviderMapCache: Record<langType, Record<string, ModelProviderItemType>>;
|
||||
var aiproxyIdMapCache: AiproxyMapProviderType;
|
||||
|
||||
var systemModelList: SystemModelItemType[];
|
||||
// var systemModelMap: Map<string, SystemModelItemType>;
|
||||
var llmModelMap: Map<string, LLMModelItemType>;
|
||||
|
147
packages/service/core/app/evaluation/utils.ts
Normal file
147
packages/service/core/app/evaluation/utils.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import { evaluationFileErrors } from '@fastgpt/global/core/app/evaluation/constants';
|
||||
import { getEvaluationFileHeader } from '@fastgpt/global/core/app/evaluation/utils';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/app/type';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import Papa from 'papaparse';
|
||||
|
||||
export const parseEvaluationCSV = (rawText: string) => {
|
||||
const parseResult = Papa.parse(rawText.trim(), {
|
||||
skipEmptyLines: true,
|
||||
header: false,
|
||||
transformHeader: (header: string) => header.trim()
|
||||
});
|
||||
|
||||
if (parseResult.errors.length > 0) {
|
||||
addLog.error('CSV parsing failed', parseResult.errors);
|
||||
throw new Error('CSV parsing failed');
|
||||
}
|
||||
|
||||
return parseResult.data as string[][];
|
||||
};
|
||||
|
||||
export const validateEvaluationFile = async (
|
||||
rawText: string,
|
||||
appVariables?: VariableItemType[]
|
||||
) => {
|
||||
// Parse CSV using Papa Parse
|
||||
const csvData = parseEvaluationCSV(rawText);
|
||||
const dataLength = csvData.length;
|
||||
|
||||
// Validate file header
|
||||
const expectedHeader = getEvaluationFileHeader(appVariables);
|
||||
const actualHeader = csvData[0]?.join(',') || '';
|
||||
if (actualHeader !== expectedHeader) {
|
||||
addLog.error(`Header mismatch. Expected: ${expectedHeader}, Got: ${actualHeader}`);
|
||||
return Promise.reject(evaluationFileErrors);
|
||||
}
|
||||
|
||||
// Validate data rows count
|
||||
if (dataLength <= 1) {
|
||||
addLog.error('No data rows found');
|
||||
return Promise.reject(evaluationFileErrors);
|
||||
}
|
||||
|
||||
const maxRows = 1000;
|
||||
if (dataLength - 1 > maxRows) {
|
||||
addLog.error(`Too many rows. Max: ${maxRows}, Got: ${dataLength - 1}`);
|
||||
return Promise.reject(evaluationFileErrors);
|
||||
}
|
||||
|
||||
const headers = csvData[0];
|
||||
|
||||
// Get required field indices
|
||||
const requiredFields = headers
|
||||
.map((header, index) => ({ header: header.trim(), index }))
|
||||
.filter(({ header }) => header.startsWith('*'));
|
||||
|
||||
const errors: string[] = [];
|
||||
|
||||
// Validate each data row
|
||||
for (let i = 1; i < csvData.length; i++) {
|
||||
const values = csvData[i];
|
||||
|
||||
// Check required fields
|
||||
requiredFields.forEach(({ header, index }) => {
|
||||
if (!values[index]?.trim()) {
|
||||
errors.push(`Row ${i + 1}: required field "${header}" is empty`);
|
||||
}
|
||||
});
|
||||
|
||||
// Validate app variables
|
||||
if (appVariables) {
|
||||
validateRowVariables({
|
||||
values,
|
||||
variables: appVariables,
|
||||
rowNum: i + 1,
|
||||
errors
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
addLog.error(`Validation failed: ${errors.join('; ')}`);
|
||||
return Promise.reject(evaluationFileErrors);
|
||||
}
|
||||
|
||||
return { csvData, dataLength };
|
||||
};
|
||||
|
||||
const validateRowVariables = ({
|
||||
values,
|
||||
variables,
|
||||
rowNum,
|
||||
errors
|
||||
}: {
|
||||
values: string[];
|
||||
variables: VariableItemType[];
|
||||
rowNum: number;
|
||||
errors: string[];
|
||||
}) => {
|
||||
variables.forEach((variable, index) => {
|
||||
const value = values[index]?.trim();
|
||||
|
||||
// Skip validation if value is empty and not required
|
||||
if (!value && !variable.required) return;
|
||||
|
||||
switch (variable.type) {
|
||||
case VariableInputEnum.input:
|
||||
// Validate string length
|
||||
if (variable.maxLength && value && value.length > variable.maxLength) {
|
||||
errors.push(
|
||||
`Row ${rowNum}: "${variable.label}" exceeds max length (${variable.maxLength})`
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case VariableInputEnum.numberInput:
|
||||
// Validate number type and range
|
||||
if (value) {
|
||||
const numValue = Number(value);
|
||||
if (isNaN(numValue)) {
|
||||
errors.push(`Row ${rowNum}: "${variable.label}" must be a number`);
|
||||
} else {
|
||||
if (variable.min !== undefined && numValue < variable.min) {
|
||||
errors.push(`Row ${rowNum}: "${variable.label}" below minimum (${variable.min})`);
|
||||
}
|
||||
if (variable.max !== undefined && numValue > variable.max) {
|
||||
errors.push(`Row ${rowNum}: "${variable.label}" exceeds maximum (${variable.max})`);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case VariableInputEnum.select:
|
||||
// Validate select options
|
||||
if (value && variable.enums?.length) {
|
||||
const validOptions = variable.enums.map((item) => item.value);
|
||||
if (!validOptions.includes(value)) {
|
||||
errors.push(
|
||||
`Row ${rowNum}: "${variable.label}" invalid option. Valid: [${validOptions.join(', ')}]`
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
};
|
@@ -504,17 +504,17 @@ const dbPluginFormat = (item: SystemPluginConfigSchemaType): SystemPluginTemplat
|
||||
|
||||
/* FastsGPT-Pluign api: */
|
||||
function getCachedSystemPlugins() {
|
||||
if (!global.systemPlugins_cache) {
|
||||
global.systemPlugins_cache = {
|
||||
if (!global.systemToolsCache) {
|
||||
global.systemToolsCache = {
|
||||
expires: 0,
|
||||
data: [] as SystemPluginTemplateItemType[]
|
||||
};
|
||||
}
|
||||
return global.systemPlugins_cache;
|
||||
return global.systemToolsCache;
|
||||
}
|
||||
|
||||
const cleanSystemPluginCache = () => {
|
||||
global.systemPlugins_cache = undefined;
|
||||
global.systemToolsCache = undefined;
|
||||
};
|
||||
|
||||
export const refetchSystemPlugins = () => {
|
||||
@@ -579,15 +579,20 @@ export const getSystemTools = async (): Promise<SystemPluginTemplateItemType[]>
|
||||
.filter((item) => item.customConfig?.associatedPluginId)
|
||||
.map((item) => dbPluginFormat(item));
|
||||
|
||||
const plugins = [...formatTools, ...dbPlugins];
|
||||
plugins.sort((a, b) => (a.pluginOrder ?? 0) - (b.pluginOrder ?? 0));
|
||||
const concatTools = [...formatTools, ...dbPlugins];
|
||||
concatTools.sort((a, b) => (a.pluginOrder ?? 0) - (b.pluginOrder ?? 0));
|
||||
|
||||
global.systemPlugins_cache = {
|
||||
global.systemToolsCache = {
|
||||
expires: Date.now() + 30 * 60 * 1000, // 30 minutes
|
||||
data: plugins
|
||||
data: concatTools
|
||||
};
|
||||
|
||||
return plugins;
|
||||
global.systemToolsTypeCache = {};
|
||||
concatTools.forEach((item) => {
|
||||
global.systemToolsTypeCache[item.templateType] = 1;
|
||||
});
|
||||
|
||||
return concatTools;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -608,10 +613,11 @@ export const getSystemToolById = async (id: string): Promise<SystemPluginTemplat
|
||||
};
|
||||
|
||||
declare global {
|
||||
var systemPlugins_cache:
|
||||
var systemToolsCache:
|
||||
| {
|
||||
expires: number;
|
||||
data: SystemPluginTemplateItemType[];
|
||||
}
|
||||
| undefined;
|
||||
var systemToolsTypeCache: Record<string, 1>;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
|
||||
import { type PluginGroupSchemaType, type TGroupType } from './type';
|
||||
import { type SystemToolGroupSchemaType, type TGroupType } from './type';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const collectionName = 'app_plugin_groups';
|
||||
@@ -29,7 +29,7 @@ const PluginGroupSchema = new Schema({
|
||||
|
||||
PluginGroupSchema.index({ groupId: 1 }, { unique: true });
|
||||
|
||||
export const MongoPluginGroups = getMongoModel<PluginGroupSchemaType>(
|
||||
export const MongoToolGroups = getMongoModel<SystemToolGroupSchemaType>(
|
||||
collectionName,
|
||||
PluginGroupSchema
|
||||
);
|
||||
|
5
packages/service/core/app/plugin/type.d.ts
vendored
5
packages/service/core/app/plugin/type.d.ts
vendored
@@ -2,6 +2,7 @@ import { SystemPluginListItemType } from '@fastgpt/global/core/app/type';
|
||||
import { FlowNodeTemplateTypeEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
||||
import type { InputConfigType } from '@fastgpt/global/core/workflow/type/io';
|
||||
import type { I18nStringStrictType } from '@fastgpt/global/sdk/fastgpt-plugin';
|
||||
|
||||
export type SystemPluginConfigSchemaType = {
|
||||
pluginId: string;
|
||||
@@ -38,11 +39,11 @@ export type SystemPluginConfigSchemaType = {
|
||||
};
|
||||
|
||||
export type TGroupType = {
|
||||
typeName: string;
|
||||
typeName: I18nStringStrictType | string;
|
||||
typeId: string;
|
||||
};
|
||||
|
||||
export type PluginGroupSchemaType = {
|
||||
export type SystemToolGroupSchemaType = {
|
||||
groupId: string;
|
||||
groupAvatar: string;
|
||||
groupName: string;
|
||||
|
29
packages/service/core/app/provider/controller.ts
Normal file
29
packages/service/core/app/provider/controller.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { loadModelProviders } from '../../../thirdProvider/fastgptPlugin/model';
|
||||
import {
|
||||
type langType,
|
||||
defaultProvider,
|
||||
formatModelProviders
|
||||
} from '@fastgpt/global/core/ai/provider';
|
||||
|
||||
// Preload model providers
|
||||
export async function preloadModelProviders(): Promise<void> {
|
||||
const { modelProviders, aiproxyIdMap } = await loadModelProviders();
|
||||
|
||||
const { ModelProviderListCache, ModelProviderMapCache } = formatModelProviders(modelProviders);
|
||||
global.ModelProviderRawCache = modelProviders;
|
||||
global.ModelProviderListCache = ModelProviderListCache;
|
||||
global.ModelProviderMapCache = ModelProviderMapCache;
|
||||
|
||||
global.aiproxyIdMapCache = aiproxyIdMap;
|
||||
}
|
||||
|
||||
export const getModelProviders = (language = 'en') => {
|
||||
return global.ModelProviderListCache[language as langType] || [];
|
||||
};
|
||||
export const getModelProvider = (provider?: string, language = 'en') => {
|
||||
if (!provider) {
|
||||
return defaultProvider;
|
||||
}
|
||||
|
||||
return ModelProviderMapCache[language as langType][provider] ?? defaultProvider;
|
||||
};
|
69
packages/service/core/app/templates/register.ts
Normal file
69
packages/service/core/app/templates/register.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { isProduction } from '@fastgpt/global/common/system/constants';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/app/plugin/constants';
|
||||
import { type AppTemplateSchemaType } from '@fastgpt/global/core/app/type';
|
||||
import { MongoAppTemplate } from './templateSchema';
|
||||
import { pluginClient } from '../../../thirdProvider/fastgptPlugin';
|
||||
|
||||
const getFileTemplates = async (): Promise<AppTemplateSchemaType[]> => {
|
||||
const res = await pluginClient.workflow.getTemplateList();
|
||||
if (res.status === 200) return res.body as AppTemplateSchemaType[];
|
||||
else return Promise.reject(res.body);
|
||||
};
|
||||
|
||||
const getAppTemplates = async () => {
|
||||
const communityTemplates = await getFileTemplates();
|
||||
|
||||
const dbTemplates = await MongoAppTemplate.find();
|
||||
|
||||
// Merge db data to community templates
|
||||
const communityTemplateConfig = communityTemplates.map((template) => {
|
||||
const config = dbTemplates.find((t) => t.templateId === template.templateId);
|
||||
|
||||
if (config) {
|
||||
return {
|
||||
...template,
|
||||
isActive: config.isActive ?? template.isActive,
|
||||
tags: config.tags ?? template.tags,
|
||||
userGuide: config.userGuide ?? template.userGuide,
|
||||
isQuickTemplate: config.isQuickTemplate ?? template.isQuickTemplate,
|
||||
order: config.order ?? template.order
|
||||
};
|
||||
}
|
||||
|
||||
return template;
|
||||
});
|
||||
|
||||
const res = [
|
||||
...communityTemplateConfig,
|
||||
...dbTemplates.filter((t) => !isCommunityTemplate(t.templateId))
|
||||
].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getAppTemplatesAndLoadThem = async (refresh = false) => {
|
||||
if (isProduction && global.appTemplates && global.appTemplates.length > 0 && !refresh)
|
||||
return global.appTemplates;
|
||||
|
||||
if (!global.appTemplates) {
|
||||
global.appTemplates = [];
|
||||
}
|
||||
|
||||
try {
|
||||
const appTemplates = await getAppTemplates();
|
||||
global.appTemplates = appTemplates;
|
||||
return appTemplates;
|
||||
} catch (error) {
|
||||
// @ts-ignore
|
||||
global.appTemplates = undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const isCommunityTemplate = (templateId: string) => {
|
||||
return templateId.startsWith(PluginSourceEnum.community);
|
||||
};
|
||||
|
||||
declare global {
|
||||
var appTemplates: AppTemplateSchemaType[];
|
||||
}
|
@@ -1,6 +1,9 @@
|
||||
import type { I18nStringStrictType, ToolTypeEnum } from '@fastgpt/global/sdk/fastgpt-plugin';
|
||||
import { RunToolWithStream } from '@fastgpt/global/sdk/fastgpt-plugin';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/app/plugin/constants';
|
||||
import { pluginClient, BASE_URL, TOKEN } from '../../../thirdProvider/fastgptPlugin';
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { retryFn } from '@fastgpt/global/common/system/utils';
|
||||
|
||||
export async function APIGetSystemToolList() {
|
||||
const res = await pluginClient.tool.list();
|
||||
@@ -27,3 +30,24 @@ const runToolInstance = new RunToolWithStream({
|
||||
token: TOKEN
|
||||
});
|
||||
export const APIRunSystemTool = runToolInstance.run.bind(runToolInstance);
|
||||
|
||||
// Tool Types Cache
|
||||
type SystemToolTypeItem = {
|
||||
type: ToolTypeEnum;
|
||||
name: I18nStringStrictType;
|
||||
};
|
||||
|
||||
export const getSystemToolTypes = (): Promise<SystemToolTypeItem[]> => {
|
||||
return retryFn(async () => {
|
||||
const res = await pluginClient.tool.getType();
|
||||
|
||||
if (res.status === 200) {
|
||||
const toolTypes = res.body || [];
|
||||
|
||||
return toolTypes;
|
||||
}
|
||||
|
||||
addLog.error('Get system tool type error', res.body);
|
||||
return [];
|
||||
});
|
||||
};
|
||||
|
@@ -7,7 +7,7 @@ import type {
|
||||
ToolRunResponseItemType
|
||||
} from '@fastgpt/global/core/chat/type.d';
|
||||
import type { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { NodeInputKeyEnum, VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
@@ -43,9 +43,10 @@ import type { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type
|
||||
import { addLog } from '../../../common/system/log';
|
||||
import { surrenderProcess } from '../../../common/system/tools';
|
||||
import type { DispatchFlowResponse, WorkflowDebugResponse } from './type';
|
||||
import { removeSystemVariable, rewriteRuntimeWorkFlow } from './utils';
|
||||
import { rewriteRuntimeWorkFlow, removeSystemVariable } from './utils';
|
||||
import { getHandleId } from '@fastgpt/global/core/workflow/utils';
|
||||
import { callbackMap } from './constants';
|
||||
import { anyValueDecrypt } from '../../../common/secret/utils';
|
||||
|
||||
type Props = Omit<ChatDispatchProps, 'workflowDispatchDeep'> & {
|
||||
runtimeNodes: RuntimeNodeItemType[];
|
||||
@@ -147,7 +148,11 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
|
||||
[DispatchNodeResponseKeyEnum.runTimes]: 1,
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]: [],
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]: null,
|
||||
newVariables: removeSystemVariable(variables, externalProvider.externalWorkflowVariables),
|
||||
newVariables: removeSystemVariable(
|
||||
variables,
|
||||
externalProvider.externalWorkflowVariables,
|
||||
data.chatConfig?.variables
|
||||
),
|
||||
durationSeconds: 0
|
||||
};
|
||||
}
|
||||
@@ -903,6 +908,12 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
|
||||
});
|
||||
}
|
||||
|
||||
const encryptedNewVariables = removeSystemVariable(
|
||||
variables,
|
||||
externalProvider.externalWorkflowVariables,
|
||||
data.chatConfig?.variables
|
||||
);
|
||||
|
||||
return {
|
||||
flowResponses: workflowQueue.chatResponses,
|
||||
flowUsages: workflowQueue.chatNodeUsages,
|
||||
@@ -913,10 +924,7 @@ export const runWorkflow = async (data: RunWorkflowProps): Promise<DispatchFlowR
|
||||
workflowQueue.chatAssistantResponse
|
||||
),
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]: workflowQueue.toolRunResponse,
|
||||
[DispatchNodeResponseKeyEnum.newVariables]: removeSystemVariable(
|
||||
variables,
|
||||
externalProvider.externalWorkflowVariables
|
||||
),
|
||||
[DispatchNodeResponseKeyEnum.newVariables]: encryptedNewVariables,
|
||||
[DispatchNodeResponseKeyEnum.memories]:
|
||||
Object.keys(workflowQueue.system_memories).length > 0
|
||||
? workflowQueue.system_memories
|
||||
@@ -937,10 +945,18 @@ const getSystemVariables = ({
|
||||
variables
|
||||
}: Props): SystemVariablesType => {
|
||||
// Get global variables(Label -> key; Key -> key)
|
||||
const globalVariables = chatConfig?.variables || [];
|
||||
const variablesMap = globalVariables.reduce<Record<string, any>>((acc, item) => {
|
||||
const variablesConfig = chatConfig?.variables || [];
|
||||
|
||||
const variablesMap = variablesConfig.reduce<Record<string, any>>((acc, item) => {
|
||||
// For internal variables, ignore external input and use default value
|
||||
if (item.type === VariableInputEnum.password) {
|
||||
const val = variables[item.label] || variables[item.key] || item.defaultValue;
|
||||
const actualValue = anyValueDecrypt(val);
|
||||
acc[item.key] = valueTypeFormat(actualValue, item.valueType);
|
||||
}
|
||||
|
||||
// API
|
||||
if (variables[item.label] !== undefined) {
|
||||
else if (variables[item.label] !== undefined) {
|
||||
acc[item.key] = valueTypeFormat(variables[item.label], item.valueType);
|
||||
}
|
||||
// Web
|
||||
|
@@ -22,6 +22,7 @@ type Response = DispatchNodeResultType<{}>;
|
||||
|
||||
export const dispatchUpdateVariable = async (props: Props): Promise<Response> => {
|
||||
const {
|
||||
chatConfig,
|
||||
params,
|
||||
variables,
|
||||
runtimeNodes,
|
||||
@@ -91,7 +92,11 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
if (!runningAppInfo.isChildApp) {
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.updateVariables,
|
||||
data: removeSystemVariable(variables, externalProvider.externalWorkflowVariables)
|
||||
data: removeSystemVariable(
|
||||
variables,
|
||||
externalProvider.externalWorkflowVariables,
|
||||
chatConfig?.variables
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,9 @@
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import type { ChatItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { NodeOutputKeyEnum, VariableInputEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { VariableItemType } from '@fastgpt/global/core/app/type';
|
||||
import { encryptSecret } from '../../../common/secret/aes256gcm';
|
||||
import {
|
||||
type RuntimeEdgeItemType,
|
||||
type RuntimeNodeItemType,
|
||||
@@ -115,9 +117,12 @@ export const checkQuoteQAValue = (quoteQA?: SearchDataResponseItemType[]) => {
|
||||
/* remove system variable */
|
||||
export const removeSystemVariable = (
|
||||
variables: Record<string, any>,
|
||||
removeObj: Record<string, string> = {}
|
||||
removeObj: Record<string, string> = {},
|
||||
userVariablesConfigs: VariableItemType[] = []
|
||||
) => {
|
||||
const copyVariables = { ...variables };
|
||||
|
||||
// Delete system variables
|
||||
delete copyVariables.userId;
|
||||
delete copyVariables.appId;
|
||||
delete copyVariables.chatId;
|
||||
@@ -125,13 +130,25 @@ export const removeSystemVariable = (
|
||||
delete copyVariables.histories;
|
||||
delete copyVariables.cTime;
|
||||
|
||||
// delete external provider workflow variables
|
||||
// Delete special variables
|
||||
Object.keys(removeObj).forEach((key) => {
|
||||
delete copyVariables[key];
|
||||
});
|
||||
|
||||
// Encrypt password variables
|
||||
userVariablesConfigs.forEach((item) => {
|
||||
const val = copyVariables[item.key];
|
||||
if (item.type === VariableInputEnum.password && typeof val === 'string') {
|
||||
copyVariables[item.key] = {
|
||||
value: '',
|
||||
secret: encryptSecret(val)
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return copyVariables;
|
||||
};
|
||||
|
||||
export const filterSystemVariables = (variables: Record<string, any>): SystemVariablesType => {
|
||||
return {
|
||||
userId: variables.userId,
|
||||
|
@@ -3,7 +3,6 @@ import { countPromptTokens } from '../../common/string/tiktoken/index';
|
||||
import type { RuntimeNodeItemType } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { getSystemPluginByIdAndVersionId, getSystemTools } from '../app/plugin/controller';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { parseI18nString } from '@fastgpt/global/common/i18n/utils';
|
||||
import type { localeType } from '@fastgpt/global/common/i18n/type';
|
||||
|
11
packages/service/thirdProvider/fastgptPlugin/model.ts
Normal file
11
packages/service/thirdProvider/fastgptPlugin/model.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { pluginClient } from '.';
|
||||
|
||||
export const loadModelProviders = async () => {
|
||||
const res = await pluginClient.model.getProviders();
|
||||
|
||||
if (res.status === 200) {
|
||||
return res.body;
|
||||
}
|
||||
|
||||
return Promise.reject(res.body);
|
||||
};
|
@@ -1,24 +1,41 @@
|
||||
import { getWorkerController, WorkerNameEnum } from './utils';
|
||||
|
||||
export const preLoadWorker = async () => {
|
||||
const max = Math.min(Number(global.systemEnv?.tokenWorkers || 30), 100);
|
||||
const start = Date.now();
|
||||
const max = Math.min(Number(global.systemEnv?.tokenWorkers || 30), 500);
|
||||
const workerController = getWorkerController({
|
||||
name: WorkerNameEnum.countGptMessagesTokens,
|
||||
maxReservedThreads: max
|
||||
});
|
||||
|
||||
for await (const item of new Array(max).fill(0)) {
|
||||
const worker = workerController.createWorker();
|
||||
await workerController.run({
|
||||
workerId: worker.id,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: '1'
|
||||
}
|
||||
]
|
||||
});
|
||||
console.log(`Preload worker ${workerController.workerQueue.length}`);
|
||||
// Batch size for concurrent loading
|
||||
const batchSize = 5;
|
||||
|
||||
for (let i = 0; i < max; i += batchSize) {
|
||||
const currentBatchSize = Math.min(batchSize, max - i);
|
||||
const promises = [];
|
||||
|
||||
// Create batch of promises for concurrent loading
|
||||
for (let j = 0; j < currentBatchSize; j++) {
|
||||
const promise = (async () => {
|
||||
const worker = workerController.createWorker();
|
||||
await workerController.run({
|
||||
workerId: worker.id,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: '1'
|
||||
}
|
||||
]
|
||||
});
|
||||
})();
|
||||
promises.push(promise);
|
||||
}
|
||||
|
||||
// Wait for current batch to complete
|
||||
await Promise.all(promises);
|
||||
console.log('Preload worker', workerController.workerQueue.length);
|
||||
}
|
||||
console.log('Preload worker success');
|
||||
|
||||
console.log('Preload worker success', workerController.workerQueue.length, Date.now() - start);
|
||||
};
|
||||
|
Reference in New Issue
Block a user