Compare commits
48 Commits
937d1e9373
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 0344ff2862 | |||
| 17bae862ed | |||
| fb64b1a768 | |||
| 05c1f339e6 | |||
| f822e319ba | |||
| 2962865857 | |||
| 5415da5b6c | |||
| 5149b68237 | |||
| a6e7cca92b | |||
| 2c3700f4f8 | |||
| 1bcc63d5de | |||
| 9db3dfe675 | |||
| 9ee93bea60 | |||
| 04fd9f8c0e | |||
| 5f8e55a3a3 | |||
| 01ae26e869 | |||
| bf61c4af4e | |||
| f566a33865 | |||
| d96fac324b | |||
| c8129ce658 | |||
| 5b0783097d | |||
| 9cde482dfe | |||
| 8e793ea37f | |||
| dde1212a57 | |||
| 6527eec133 | |||
| 2109903ba2 | |||
| 46dc2d4682 | |||
| 3c9d0dae22 | |||
| b6a81848ea | |||
| 096fbb661d | |||
| 035c4ab000 | |||
| 1efff107f9 | |||
| 1795cd73c7 | |||
| 5f21126a62 | |||
| 2085588556 | |||
| 025a67ce45 | |||
| cb806e19b1 | |||
| d4680d258c | |||
| a832883f17 | |||
| c086285340 | |||
| 7fa05b0004 | |||
| 65cf893a5f | |||
| e20ee8e065 | |||
| 7d8723715c | |||
| 49bb348707 | |||
| ef6de1d12b | |||
| c76a4e2018 | |||
| e504f806a9 |
11
.gitea/workflows/deploy.yaml
Normal file
11
.gitea/workflows/deploy.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
name: 自动部署
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
jobs:
|
||||||
|
部署应用:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: 启动部署
|
||||||
|
run: |
|
||||||
|
docker exec gitea-runner /opt/deploy.sh
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
name: 部署 admin-ui 到 K3s
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
deploy:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: 拉取代码
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 部署到 K3s
|
|
||||||
run: |
|
|
||||||
kubectl apply -f k8s/
|
|
||||||
kubectl rollout restart deployment admin-ui
|
|
||||||
@@ -119,8 +119,6 @@ export interface ModelModuleItem {
|
|||||||
/** 会话开关状态(列表接口返回,0 关 1 开;会话开关接口就绪后生效) */
|
/** 会话开关状态(列表接口返回,0 关 1 开;会话开关接口就绪后生效) */
|
||||||
chatSessionEnabled?: number;
|
chatSessionEnabled?: number;
|
||||||
enabled: number;
|
enabled: number;
|
||||||
/** 是否异步 0-同步 1-异步,依赖requestMapping */
|
|
||||||
isAsync?: number;
|
|
||||||
maxConcurrency: number;
|
maxConcurrency: number;
|
||||||
queueLimit: number;
|
queueLimit: number;
|
||||||
timeoutMs?: number;
|
timeoutMs?: number;
|
||||||
@@ -130,7 +128,7 @@ export interface ModelModuleItem {
|
|||||||
retryQueueMaxSeconds: number;
|
retryQueueMaxSeconds: number;
|
||||||
autoCleanSeconds: number;
|
autoCleanSeconds: number;
|
||||||
remark?: string;
|
remark?: string;
|
||||||
headMsg?: string | Record<string, string>;
|
headMsg?: string;
|
||||||
form?: ModelFormEntry[] | Record<string, { value: string }>;
|
form?: ModelFormEntry[] | Record<string, { value: string }>;
|
||||||
requestMapping?: Record<string, unknown>;
|
requestMapping?: Record<string, unknown>;
|
||||||
responseMapping?: Record<string, unknown>;
|
responseMapping?: Record<string, unknown>;
|
||||||
@@ -152,12 +150,10 @@ export interface CreateModelParams {
|
|||||||
operatorName?: string;
|
operatorName?: string;
|
||||||
baseUrl: string;
|
baseUrl: string;
|
||||||
httpMethod?: string;
|
httpMethod?: string;
|
||||||
headMsg?: Record<string, string>;
|
headMsg?: string;
|
||||||
isPrivate: number;
|
isPrivate: number;
|
||||||
enabled: number;
|
enabled: number;
|
||||||
isChatModel: number;
|
isChatModel: number;
|
||||||
/** 是否异步 0-同步 1-异步,依赖requestMapping,默认0 */
|
|
||||||
isAsync: number;
|
|
||||||
apiKey?: string;
|
apiKey?: string;
|
||||||
form: ModelFormEntry[];
|
form: ModelFormEntry[];
|
||||||
requestMapping?: Record<string, unknown>;
|
requestMapping?: Record<string, unknown>;
|
||||||
|
|||||||
@@ -402,49 +402,16 @@ const handleCreatePrivateModel = async () => {
|
|||||||
key: String(key),
|
key: String(key),
|
||||||
value: String(value ?? ''),
|
value: String(value ?? ''),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Parse headMsg to Record<string, string> - it might be stored as string or already as object
|
|
||||||
let headMsgRecord: Record<string, string> = {};
|
|
||||||
if (builtInModel.headMsg && typeof builtInModel.headMsg === 'string') {
|
|
||||||
// Try to parse as JSON first (new format stored as string)
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(builtInModel.headMsg);
|
|
||||||
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
||||||
Object.entries(parsed).forEach(([k, v]) => {
|
|
||||||
headMsgRecord[k] = String(v);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// If JSON parse fails, parse as old format "key1:value1,key2:value2"
|
|
||||||
const pairs = builtInModel.headMsg.split(',');
|
|
||||||
pairs.forEach((pair) => {
|
|
||||||
const idx = pair.indexOf(':');
|
|
||||||
if (idx === -1) return;
|
|
||||||
const key = pair.slice(0, idx).trim();
|
|
||||||
const value = pair.slice(idx + 1).trim();
|
|
||||||
if (key) {
|
|
||||||
headMsgRecord[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (builtInModel.headMsg && typeof builtInModel.headMsg === 'object' && !Array.isArray(builtInModel.headMsg)) {
|
|
||||||
// Already an object
|
|
||||||
Object.entries(builtInModel.headMsg).forEach(([k, v]) => {
|
|
||||||
headMsgRecord[k] = String(v);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const createParams: CreateModelParams = {
|
const createParams: CreateModelParams = {
|
||||||
modelName: apiKeyForm.modelName,
|
modelName: apiKeyForm.modelName,
|
||||||
modelType: builtInModel.modelType,
|
modelType: builtInModel.modelType,
|
||||||
operatorName: builtInModel.operatorName || '',
|
operatorName: builtInModel.operatorName || '',
|
||||||
baseUrl: builtInModel.baseUrl,
|
baseUrl: builtInModel.baseUrl,
|
||||||
httpMethod: builtInModel.httpMethod || 'POST',
|
httpMethod: builtInModel.httpMethod || 'POST',
|
||||||
headMsg: headMsgRecord,
|
headMsg: builtInModel.headMsg || '',
|
||||||
isPrivate: builtInModel.isPrivate ?? 1,
|
isPrivate: builtInModel.isPrivate ?? 1,
|
||||||
enabled: builtInModel.enabled ?? 1,
|
enabled: builtInModel.enabled ?? 1,
|
||||||
isChatModel: builtInModel.isChatModel || 0,
|
isChatModel: builtInModel.isChatModel || 0,
|
||||||
isAsync: builtInModel.isAsync ?? 0,
|
|
||||||
apiKey: apiKeyForm.apiKey,
|
apiKey: apiKeyForm.apiKey,
|
||||||
form: formList,
|
form: formList,
|
||||||
requestMapping: (builtInModel.requestMapping as Record<string, unknown>) || {},
|
requestMapping: (builtInModel.requestMapping as Record<string, unknown>) || {},
|
||||||
|
|||||||
@@ -83,14 +83,6 @@
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
|
||||||
<el-form-item label="执行模式" prop="isAsync">
|
|
||||||
<el-radio-group v-model="state.ruleForm.isAsync">
|
|
||||||
<el-radio :label="0">同步</el-radio>
|
|
||||||
<el-radio :label="1">异步</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="请求头绑定" prop="headMsg">
|
<el-form-item label="请求头绑定" prop="headMsg">
|
||||||
<el-button @click="showHeaderDialog = true" style="width: 100%"> 配置请求头 ({{ state.headers.length }}) </el-button>
|
<el-button @click="showHeaderDialog = true" style="width: 100%"> 配置请求头 ({{ state.headers.length }}) </el-button>
|
||||||
@@ -656,7 +648,6 @@ const state = reactive({
|
|||||||
apiKey: '',
|
apiKey: '',
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
isChatModel: 0,
|
isChatModel: 0,
|
||||||
isAsync: 0, // 0-同步 1-异步,默认0
|
|
||||||
maxConcurrency: 10,
|
maxConcurrency: 10,
|
||||||
queueLimit: 100,
|
queueLimit: 100,
|
||||||
timeoutSeconds: 30,
|
timeoutSeconds: 30,
|
||||||
@@ -868,58 +859,7 @@ const fieldsToObject = (fields: Array<{ key: string; value: string }>) => {
|
|||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 解析headers,支持多种格式:
|
const parseHeaders = (headMsg: string) => parseKeyValueString(headMsg);
|
||||||
// 1. 旧格式:逗号分隔的"key1:value1,key2:value2"字符串
|
|
||||||
// 2. JSON字符串:格式化为JSON对象的字符串
|
|
||||||
// 3. 新格式:直接是Record<string, string>对象
|
|
||||||
const parseHeaders = (raw: unknown): Array<{ key: string; value: string }> => {
|
|
||||||
if (!raw) return [];
|
|
||||||
|
|
||||||
// 如果是字符串,先尝试解析为JSON,如果失败则尝试解析为旧格式key:value,key2:value2
|
|
||||||
if (typeof raw === 'string') {
|
|
||||||
const trimmed = raw.trim();
|
|
||||||
if (!trimmed) return [];
|
|
||||||
// 试试JSON解析,如果开头是{或者[说明是JSON
|
|
||||||
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(trimmed);
|
|
||||||
return parseHeaders(parsed);
|
|
||||||
} catch {
|
|
||||||
// JSON解析失败,回退到旧格式解析
|
|
||||||
return parseKeyValueString(trimmed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 不是JSON格式,按旧格式解析
|
|
||||||
return parseKeyValueString(trimmed);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果是数组格式 [{ key, value }]
|
|
||||||
if (Array.isArray(raw)) {
|
|
||||||
return raw
|
|
||||||
.filter((item) => item && (item.key !== undefined || item.value !== undefined))
|
|
||||||
.map((item) => ({
|
|
||||||
key: String(item.key ?? '').trim(),
|
|
||||||
value: String(item.value ?? '').trim(),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果是对象格式 { key: value }
|
|
||||||
if (typeof raw === 'object') {
|
|
||||||
const fields: Array<{ key: string; value: string }> = [];
|
|
||||||
Object.keys(raw as Record<string, unknown>).forEach((key) => {
|
|
||||||
let v = (raw as Record<string, unknown>)[key];
|
|
||||||
// 处理 { key: { value: value } } 格式(后端可能返回这种结构)
|
|
||||||
if (v && typeof v === 'object' && !Array.isArray(v) && 'value' in v) {
|
|
||||||
v = (v as { value: unknown }).value;
|
|
||||||
}
|
|
||||||
const value = String(v ?? '');
|
|
||||||
fields.push({ key: key.trim(), value });
|
|
||||||
});
|
|
||||||
return fields;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [];
|
|
||||||
};
|
|
||||||
// 统一的字段解析函数:支持数组、对象、JSON字符串
|
// 统一的字段解析函数:支持数组、对象、JSON字符串
|
||||||
const parseFieldsUnified = (raw: unknown): Array<{ key: string; value: string }> => {
|
const parseFieldsUnified = (raw: unknown): Array<{ key: string; value: string }> => {
|
||||||
if (!raw) return [];
|
if (!raw) return [];
|
||||||
@@ -1258,16 +1198,6 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
|||||||
? Math.floor(Number(row.timeoutMs) / 1000)
|
? Math.floor(Number(row.timeoutMs) / 1000)
|
||||||
: 30;
|
: 30;
|
||||||
const isPrivate = row.isPrivate !== undefined && row.isPrivate !== null ? Number(row.isPrivate) : 0;
|
const isPrivate = row.isPrivate !== undefined && row.isPrivate !== null ? Number(row.isPrivate) : 0;
|
||||||
// headMsg might already be a Record<string, string> object (new format) or a string (old format)
|
|
||||||
let ruleFormHeadMsg = '';
|
|
||||||
if (typeof row.headMsg === 'string') {
|
|
||||||
ruleFormHeadMsg = row.headMsg;
|
|
||||||
} else if (row.headMsg && typeof row.headMsg === 'object') {
|
|
||||||
// If it's already an object, stringify for compatibility
|
|
||||||
ruleFormHeadMsg = JSON.stringify(row.headMsg);
|
|
||||||
} else {
|
|
||||||
ruleFormHeadMsg = '';
|
|
||||||
}
|
|
||||||
state.ruleForm = {
|
state.ruleForm = {
|
||||||
id: row.id as string,
|
id: row.id as string,
|
||||||
modelName: String(row.modelName ?? ''),
|
modelName: String(row.modelName ?? ''),
|
||||||
@@ -1277,12 +1207,11 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
|||||||
httpMethod: String(row.httpMethod || 'POST'),
|
httpMethod: String(row.httpMethod || 'POST'),
|
||||||
queryResponseType: String((row.queryConfig as Record<string, unknown>)?.responseType || 'sync'),
|
queryResponseType: String((row.queryConfig as Record<string, unknown>)?.responseType || 'sync'),
|
||||||
queryCallbackUrl: String((row.queryConfig as Record<string, unknown>)?.callbackUrl || ''),
|
queryCallbackUrl: String((row.queryConfig as Record<string, unknown>)?.callbackUrl || ''),
|
||||||
headMsg: ruleFormHeadMsg,
|
headMsg: String(row.headMsg || ''),
|
||||||
isPrivate,
|
isPrivate,
|
||||||
apiKey: isPrivate === 1 ? String(row.apiKey ?? '') : '',
|
apiKey: isPrivate === 1 ? String(row.apiKey ?? '') : '',
|
||||||
enabled: Number(row.enabled ?? 1),
|
enabled: Number(row.enabled ?? 1),
|
||||||
isChatModel: row.isChatModel !== undefined && row.isChatModel !== null ? Number(row.isChatModel) : 0,
|
isChatModel: row.isChatModel !== undefined && row.isChatModel !== null ? Number(row.isChatModel) : 0,
|
||||||
isAsync: row.isAsync !== undefined && row.isAsync !== null ? Number(row.isAsync) : 0,
|
|
||||||
maxConcurrency: Number(row.maxConcurrency ?? 10),
|
maxConcurrency: Number(row.maxConcurrency ?? 10),
|
||||||
queueLimit: Number(row.queueLimit ?? 100),
|
queueLimit: Number(row.queueLimit ?? 100),
|
||||||
timeoutSeconds,
|
timeoutSeconds,
|
||||||
@@ -1295,7 +1224,7 @@ const fillFormFromDetailRow = (row: Record<string, unknown>) => {
|
|||||||
responseTokenField: String(row.responseTokenField || ''),
|
responseTokenField: String(row.responseTokenField || ''),
|
||||||
tokenConfig: '{}',
|
tokenConfig: '{}',
|
||||||
};
|
};
|
||||||
state.headers = ensureKeyValueRows(parseHeaders(row.headMsg));
|
state.headers = ensureKeyValueRows(parseHeaders(String(row.headMsg || '')));
|
||||||
state.formFields = parseFormFieldsUnified(row.form);
|
state.formFields = parseFormFieldsUnified(row.form);
|
||||||
state.requestMappingFields = ensureKeyValueRows(parseRequestMappingFields(row.requestMapping));
|
state.requestMappingFields = ensureKeyValueRows(parseRequestMappingFields(row.requestMapping));
|
||||||
state.responseMappingFields = ensureKeyValueRows(parseResponseMappingFields(row.responseMapping));
|
state.responseMappingFields = ensureKeyValueRows(parseResponseMappingFields(row.responseMapping));
|
||||||
@@ -1400,7 +1329,6 @@ const openDialog = async (type: string, row?: Record<string, unknown>) => {
|
|||||||
apiKey: '',
|
apiKey: '',
|
||||||
enabled: 1,
|
enabled: 1,
|
||||||
isChatModel: 0,
|
isChatModel: 0,
|
||||||
isAsync: 0,
|
|
||||||
maxConcurrency: 10,
|
maxConcurrency: 10,
|
||||||
queueLimit: 100,
|
queueLimit: 100,
|
||||||
timeoutSeconds: 30,
|
timeoutSeconds: 30,
|
||||||
@@ -1502,25 +1430,16 @@ const onSubmit = () => {
|
|||||||
: undefined,
|
: undefined,
|
||||||
})) as unknown as ModelFormEntry[];
|
})) as unknown as ModelFormEntry[];
|
||||||
|
|
||||||
// 将headers转换为JSON对象格式
|
|
||||||
const headMsgObj: Record<string, string> = {};
|
|
||||||
state.headers
|
|
||||||
.filter((h) => h.key?.trim() && h.value?.trim())
|
|
||||||
.forEach((h) => {
|
|
||||||
headMsgObj[h.key.trim()] = h.value.trim();
|
|
||||||
});
|
|
||||||
|
|
||||||
const submitData: CreateModelParams = {
|
const submitData: CreateModelParams = {
|
||||||
modelName: state.ruleForm.modelName,
|
modelName: state.ruleForm.modelName,
|
||||||
modelType: state.ruleForm.modelType as number | string,
|
modelType: state.ruleForm.modelType as number | string,
|
||||||
operatorName: state.ruleForm.operatorName,
|
operatorName: state.ruleForm.operatorName,
|
||||||
baseUrl: state.ruleForm.baseUrl,
|
baseUrl: state.ruleForm.baseUrl,
|
||||||
httpMethod: state.ruleForm.httpMethod || 'POST',
|
httpMethod: state.ruleForm.httpMethod || 'POST',
|
||||||
headMsg: headMsgObj,
|
headMsg: state.ruleForm.headMsg,
|
||||||
isPrivate: state.ruleForm.isPrivate,
|
isPrivate: state.ruleForm.isPrivate,
|
||||||
enabled: state.ruleForm.enabled,
|
enabled: state.ruleForm.enabled,
|
||||||
isChatModel: state.ruleForm.isChatModel,
|
isChatModel: state.ruleForm.isChatModel,
|
||||||
isAsync: state.ruleForm.isAsync,
|
|
||||||
// 确保 API 密钥只在 isPrivate=1 时提交
|
// 确保 API 密钥只在 isPrivate=1 时提交
|
||||||
apiKey: state.ruleForm.isPrivate === 1 ? String(state.ruleForm.apiKey ?? '').trim() : '',
|
apiKey: state.ruleForm.isPrivate === 1 ? String(state.ruleForm.apiKey ?? '').trim() : '',
|
||||||
form: processedFormFields,
|
form: processedFormFields,
|
||||||
|
|||||||
@@ -240,48 +240,15 @@ const handleCreatePrivateModelAndSetChat = async () => {
|
|||||||
|
|
||||||
// 基于内置模型创建新模型(继承原模型的所有配置,只替换 apiKey)
|
// 基于内置模型创建新模型(继承原模型的所有配置,只替换 apiKey)
|
||||||
const builtInModel = builtInModelToClone.value;
|
const builtInModel = builtInModelToClone.value;
|
||||||
|
|
||||||
// Parse headMsg to Record<string, string> - it might be stored as string or already as object
|
|
||||||
let headMsgRecord: Record<string, string> = {};
|
|
||||||
if (builtInModel.headMsg && typeof builtInModel.headMsg === 'string') {
|
|
||||||
// Try to parse as JSON first (new format stored as string)
|
|
||||||
try {
|
|
||||||
const parsed = JSON.parse(builtInModel.headMsg);
|
|
||||||
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
||||||
Object.entries(parsed).forEach(([k, v]) => {
|
|
||||||
headMsgRecord[k] = String(v);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
// If JSON parse fails, parse as old format "key1:value1,key2:value2"
|
|
||||||
const pairs = builtInModel.headMsg.split(',');
|
|
||||||
pairs.forEach((pair: string) => {
|
|
||||||
const idx = pair.indexOf(':');
|
|
||||||
if (idx === -1) return;
|
|
||||||
const key = pair.slice(0, idx).trim();
|
|
||||||
const value = pair.slice(idx + 1).trim();
|
|
||||||
if (key) {
|
|
||||||
headMsgRecord[key] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (builtInModel.headMsg && typeof builtInModel.headMsg === 'object' && !Array.isArray(builtInModel.headMsg)) {
|
|
||||||
// Already an object
|
|
||||||
Object.entries(builtInModel.headMsg).forEach(([k, v]) => {
|
|
||||||
headMsgRecord[k] = String(v);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const createParams = {
|
const createParams = {
|
||||||
modelName: apiKeyForm.modelName,
|
modelName: apiKeyForm.modelName,
|
||||||
modelType: builtInModel.modelType,
|
modelType: builtInModel.modelType,
|
||||||
baseUrl: builtInModel.baseUrl,
|
baseUrl: builtInModel.baseUrl,
|
||||||
httpMethod: builtInModel.httpMethod || 'POST',
|
httpMethod: builtInModel.httpMethod || 'POST',
|
||||||
headMsg: headMsgRecord,
|
headMsg: builtInModel.headMsg || '',
|
||||||
isPrivate: builtInModel.isPrivate ?? 1,
|
isPrivate: builtInModel.isPrivate ?? 1,
|
||||||
enabled: builtInModel.enabled ?? 1,
|
enabled: builtInModel.enabled ?? 1,
|
||||||
isChatModel: 1, // 设置为会话模型
|
isChatModel: 1, // 设置为会话模型
|
||||||
isAsync: builtInModel.isAsync ?? 0,
|
|
||||||
apiKey: apiKeyForm.apiKey,
|
apiKey: apiKeyForm.apiKey,
|
||||||
form: builtInModel.form || {},
|
form: builtInModel.form || {},
|
||||||
requestMapping: builtInModel.requestMapping || {},
|
requestMapping: builtInModel.requestMapping || {},
|
||||||
|
|||||||
Reference in New Issue
Block a user