mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-23 01:00:41 +08:00
4.8-alpha fix (#1424)
This commit is contained in:
@@ -1,24 +1,61 @@
|
|||||||
import { getErrText } from '../error/utils';
|
import { getErrText } from '../error/utils';
|
||||||
import { replaceRegChars } from './tools';
|
import { replaceRegChars } from './tools';
|
||||||
|
|
||||||
/**
|
export const CUSTOM_SPLIT_SIGN = '-----CUSTOM_SPLIT_SIGN-----';
|
||||||
* text split into chunks
|
|
||||||
* chunkLen - one chunk len. max: 3500
|
type SplitProps = {
|
||||||
* overlapLen - The size of the before and after Text
|
|
||||||
* chunkLen > overlapLen
|
|
||||||
* markdown
|
|
||||||
*/
|
|
||||||
export const splitText2Chunks = (props: {
|
|
||||||
text: string;
|
text: string;
|
||||||
chunkLen: number;
|
chunkLen: number;
|
||||||
overlapRatio?: number;
|
overlapRatio?: number;
|
||||||
customReg?: string[];
|
customReg?: string[];
|
||||||
}): {
|
};
|
||||||
|
|
||||||
|
type SplitResponse = {
|
||||||
chunks: string[];
|
chunks: string[];
|
||||||
chars: number;
|
chars: number;
|
||||||
overlapRatio?: number;
|
};
|
||||||
} => {
|
|
||||||
|
// 判断字符串是否为markdown的表格形式
|
||||||
|
const strIsMdTable = (str: string) => {
|
||||||
|
const regex = /^(\|.*\|[\r]*)$/m;
|
||||||
|
|
||||||
|
return regex.test(str);
|
||||||
|
};
|
||||||
|
const markdownTableSplit = (props: SplitProps): SplitResponse => {
|
||||||
|
let { text = '', chunkLen } = props;
|
||||||
|
const splitText2Lines = text.split('\n');
|
||||||
|
const header = splitText2Lines[0];
|
||||||
|
|
||||||
|
const headerSize = header.split('|').length - 2;
|
||||||
|
const mdSplitString = `| ${new Array(headerSize)
|
||||||
|
.fill(0)
|
||||||
|
.map(() => '---')
|
||||||
|
.join(' | ')} |`;
|
||||||
|
|
||||||
|
const chunks: string[] = [];
|
||||||
|
let chunk = `${header}
|
||||||
|
${mdSplitString}
|
||||||
|
`;
|
||||||
|
|
||||||
|
for (let i = 2; i < splitText2Lines.length; i++) {
|
||||||
|
if (chunk.length + splitText2Lines[i].length > chunkLen * 1.2) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
chunk = `${header}
|
||||||
|
${mdSplitString}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
chunk += `${splitText2Lines[i]}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
chunks,
|
||||||
|
chars: chunks.reduce((sum, chunk) => sum + chunk.length, 0)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const commonSplit = (props: SplitProps): SplitResponse => {
|
||||||
let { text = '', chunkLen, overlapRatio = 0.2, customReg = [] } = props;
|
let { text = '', chunkLen, overlapRatio = 0.2, customReg = [] } = props;
|
||||||
|
|
||||||
const splitMarker = 'SPLIT_HERE_SPLIT_HERE';
|
const splitMarker = 'SPLIT_HERE_SPLIT_HERE';
|
||||||
const codeBlockMarker = 'CODE_BLOCK_LINE_MARKER';
|
const codeBlockMarker = 'CODE_BLOCK_LINE_MARKER';
|
||||||
const overlapLen = Math.round(chunkLen * overlapRatio);
|
const overlapLen = Math.round(chunkLen * overlapRatio);
|
||||||
@@ -253,3 +290,29 @@ export const splitText2Chunks = (props: {
|
|||||||
throw new Error(getErrText(err));
|
throw new Error(getErrText(err));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* text split into chunks
|
||||||
|
* chunkLen - one chunk len. max: 3500
|
||||||
|
* overlapLen - The size of the before and after Text
|
||||||
|
* chunkLen > overlapLen
|
||||||
|
* markdown
|
||||||
|
*/
|
||||||
|
export const splitText2Chunks = (props: SplitProps): SplitResponse => {
|
||||||
|
let { text = '' } = props;
|
||||||
|
|
||||||
|
const splitWithCustomSign = text.split(CUSTOM_SPLIT_SIGN);
|
||||||
|
|
||||||
|
const splitResult = splitWithCustomSign.map((item) => {
|
||||||
|
if (strIsMdTable(text)) {
|
||||||
|
return markdownTableSplit(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonSplit(props);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
chunks: splitResult.map((item) => item.chunks).flat(),
|
||||||
|
chars: splitResult.reduce((sum, item) => sum + item.chars, 0)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export const countGptMessagesTokens = (
|
|||||||
|
|
||||||
// 检测是否有内存泄漏
|
// 检测是否有内存泄漏
|
||||||
// addLog.info(`Count token time: ${Date.now() - start}, token: ${data}`);
|
// addLog.info(`Count token time: ${Date.now() - start}, token: ${data}`);
|
||||||
// console.log(Object.keys(global.tiktokenWorker.callbackMap));
|
// console.log(process.memoryUsage());
|
||||||
};
|
};
|
||||||
|
|
||||||
worker.postMessage({
|
worker.postMessage({
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ export type InsertVectorProps = {
|
|||||||
export type EmbeddingRecallProps = {
|
export type EmbeddingRecallProps = {
|
||||||
teamId: string;
|
teamId: string;
|
||||||
datasetIds: string[];
|
datasetIds: string[];
|
||||||
similarity?: number;
|
// similarity?: number;
|
||||||
efSearch?: number;
|
// efSearch?: number;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -129,17 +129,15 @@ export const embeddingRecall = async (
|
|||||||
): Promise<{
|
): Promise<{
|
||||||
results: EmbeddingRecallItemType[];
|
results: EmbeddingRecallItemType[];
|
||||||
}> => {
|
}> => {
|
||||||
const { teamId, datasetIds, vectors, limit, similarity = 0, retry = 2, efSearch = 100 } = props;
|
const { datasetIds, vectors, limit, retry = 2 } = props;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const results: any = await PgClient.query(
|
const results: any = await PgClient.query(
|
||||||
`BEGIN;
|
`BEGIN;
|
||||||
SET LOCAL hnsw.ef_search = ${efSearch};
|
SET LOCAL hnsw.ef_search = ${global.systemEnv?.pgHNSWEfSearch || 100};
|
||||||
select id, collection_id, vector <#> '[${vectors[0]}]' AS score
|
select id, collection_id, vector <#> '[${vectors[0]}]' AS score
|
||||||
from ${PgDatasetTableName}
|
from ${PgDatasetTableName}
|
||||||
where team_id='${teamId}'
|
where dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
||||||
AND dataset_id IN (${datasetIds.map((id) => `'${String(id)}'`).join(',')})
|
|
||||||
AND vector <#> '[${vectors[0]}]' < -${similarity}
|
|
||||||
order by score limit ${limit};
|
order by score limit ${limit};
|
||||||
COMMIT;`
|
COMMIT;`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -85,8 +85,7 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
|||||||
teamId,
|
teamId,
|
||||||
datasetIds,
|
datasetIds,
|
||||||
vectors,
|
vectors,
|
||||||
limit,
|
limit
|
||||||
efSearch: global.systemEnv?.pgHNSWEfSearch
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// get q and a
|
// get q and a
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ const completions = async ({
|
|||||||
});
|
});
|
||||||
const answer = data.choices?.[0].message?.content || '';
|
const answer = data.choices?.[0].message?.content || '';
|
||||||
|
|
||||||
console.log(JSON.stringify(chats2GPTMessages({ messages, reserveId: false }), null, 2));
|
// console.log(JSON.stringify(chats2GPTMessages({ messages, reserveId: false }), null, 2));
|
||||||
console.log(answer, '----');
|
// console.log(answer, '----');
|
||||||
|
|
||||||
const id =
|
const id =
|
||||||
agents.find((item) => answer.includes(item.key))?.key ||
|
agents.find((item) => answer.includes(item.key))?.key ||
|
||||||
|
|||||||
@@ -10,9 +10,13 @@ export const readCsvRawText = async (params: ReadRawTextByBuffer): Promise<ReadF
|
|||||||
|
|
||||||
const header = csvArr[0];
|
const header = csvArr[0];
|
||||||
|
|
||||||
const formatText = header
|
// format to md table
|
||||||
? csvArr.map((item) => item.map((item, i) => `${header[i]}:${item}`).join('\n')).join('\n')
|
const formatText = `| ${header.join(' | ')} |
|
||||||
: '';
|
| ${header.map(() => '---').join(' | ')} |
|
||||||
|
${csvArr
|
||||||
|
.slice(1)
|
||||||
|
.map((row) => `| ${row.map((item) => item.replace(/\n/g, '\\n')).join(' | ')} |`)
|
||||||
|
.join('\n')}`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rawText,
|
rawText,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { CUSTOM_SPLIT_SIGN } from '@fastgpt/global/common/string/textSplitter';
|
||||||
import { ReadRawTextByBuffer, ReadFileResponse } from '../type';
|
import { ReadRawTextByBuffer, ReadFileResponse } from '../type';
|
||||||
import xlsx from 'node-xlsx';
|
import xlsx from 'node-xlsx';
|
||||||
import Papa from 'papaparse';
|
import Papa from 'papaparse';
|
||||||
@@ -18,25 +19,25 @@ export const readXlsxRawText = async ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const rawText = format2Csv.map((item) => item.csvText).join('\n');
|
const rawText = format2Csv.map((item) => item.csvText).join('\n');
|
||||||
|
|
||||||
const formatText = format2Csv
|
const formatText = format2Csv
|
||||||
.map((item) => {
|
.map((item) => {
|
||||||
const csvArr = Papa.parse(item.csvText).data as string[][];
|
const csvArr = Papa.parse(item.csvText).data as string[][];
|
||||||
const header = csvArr[0];
|
const header = csvArr[0];
|
||||||
|
|
||||||
const formatText = header
|
if (!header) return;
|
||||||
? csvArr
|
|
||||||
.map((item) =>
|
|
||||||
item
|
|
||||||
.map((item, i) => (item ? `${header[i]}:${item}` : ''))
|
|
||||||
.filter(Boolean)
|
|
||||||
.join('\n')
|
|
||||||
)
|
|
||||||
.join('\n')
|
|
||||||
: '';
|
|
||||||
|
|
||||||
return `${item.title}\n${formatText}`;
|
const formatText = `| ${header.join(' | ')} |
|
||||||
|
| ${header.map(() => '---').join(' | ')} |
|
||||||
|
${csvArr
|
||||||
|
.slice(1)
|
||||||
|
.map((row) => `| ${row.map((item) => item.replace(/\n/g, '\\n')).join(' | ')} |`)
|
||||||
|
.join('\n')}`;
|
||||||
|
|
||||||
|
return formatText;
|
||||||
})
|
})
|
||||||
.join('\n');
|
.filter(Boolean)
|
||||||
|
.join(CUSTOM_SPLIT_SIGN);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rawText: rawText,
|
rawText: rawText,
|
||||||
|
|||||||
@@ -67,5 +67,5 @@ parentPort?.on('message', async (props: ReadRawTextProps<Uint8Array>) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
global?.close?.();
|
process.exit();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,5 @@ parentPort?.on('message', (params: { html: string }) => {
|
|||||||
data: error
|
data: error
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
process.exit();
|
||||||
global?.close?.();
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,91 +26,96 @@ parentPort?.on(
|
|||||||
tools?: ChatCompletionTool[];
|
tools?: ChatCompletionTool[];
|
||||||
functionCall?: ChatCompletionCreateParams.Function[];
|
functionCall?: ChatCompletionCreateParams.Function[];
|
||||||
}) => {
|
}) => {
|
||||||
const start = Date.now();
|
try {
|
||||||
/* count one prompt tokens */
|
/* count one prompt tokens */
|
||||||
const countPromptTokens = (
|
const countPromptTokens = (
|
||||||
prompt: string | ChatCompletionContentPart[] | null | undefined = '',
|
prompt: string | ChatCompletionContentPart[] | null | undefined = '',
|
||||||
role: '' | `${ChatCompletionRequestMessageRoleEnum}` = ''
|
role: '' | `${ChatCompletionRequestMessageRoleEnum}` = ''
|
||||||
) => {
|
) => {
|
||||||
const promptText = (() => {
|
const promptText = (() => {
|
||||||
if (!prompt) return '';
|
if (!prompt) return '';
|
||||||
if (typeof prompt === 'string') return prompt;
|
if (typeof prompt === 'string') return prompt;
|
||||||
let promptText = '';
|
let promptText = '';
|
||||||
prompt.forEach((item) => {
|
prompt.forEach((item) => {
|
||||||
if (item.type === 'text') {
|
if (item.type === 'text') {
|
||||||
promptText += item.text;
|
promptText += item.text;
|
||||||
} else if (item.type === 'image_url') {
|
} else if (item.type === 'image_url') {
|
||||||
promptText += item.image_url.url;
|
promptText += item.image_url.url;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return promptText;
|
return promptText;
|
||||||
})();
|
|
||||||
|
|
||||||
const text = `${role}\n${promptText}`.trim();
|
|
||||||
|
|
||||||
try {
|
|
||||||
const encodeText = enc.encode(text);
|
|
||||||
const supplementaryToken = role ? 4 : 0;
|
|
||||||
return encodeText.length + supplementaryToken;
|
|
||||||
} catch (error) {
|
|
||||||
return text.length;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const countToolsTokens = (
|
|
||||||
tools?: ChatCompletionTool[] | ChatCompletionCreateParams.Function[]
|
|
||||||
) => {
|
|
||||||
if (!tools || tools.length === 0) return 0;
|
|
||||||
|
|
||||||
const toolText = tools
|
|
||||||
? JSON.stringify(tools)
|
|
||||||
.replace('"', '')
|
|
||||||
.replace('\n', '')
|
|
||||||
.replace(/( ){2,}/g, ' ')
|
|
||||||
: '';
|
|
||||||
|
|
||||||
return enc.encode(toolText).length;
|
|
||||||
};
|
|
||||||
|
|
||||||
const total =
|
|
||||||
messages.reduce((sum, item) => {
|
|
||||||
// Evaluates the text of toolcall and functioncall
|
|
||||||
const functionCallPrompt = (() => {
|
|
||||||
let prompt = '';
|
|
||||||
if (item.role === ChatCompletionRequestMessageRoleEnum.Assistant) {
|
|
||||||
const toolCalls = item.tool_calls;
|
|
||||||
prompt +=
|
|
||||||
toolCalls
|
|
||||||
?.map((item) => `${item?.function?.name} ${item?.function?.arguments}`.trim())
|
|
||||||
?.join('') || '';
|
|
||||||
|
|
||||||
const functionCall = item.function_call;
|
|
||||||
prompt += `${functionCall?.name} ${functionCall?.arguments}`.trim();
|
|
||||||
}
|
|
||||||
return prompt;
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const contentPrompt = (() => {
|
const text = `${role}\n${promptText}`.trim();
|
||||||
if (!item.content) return '';
|
|
||||||
if (typeof item.content === 'string') return item.content;
|
|
||||||
return item.content
|
|
||||||
.map((item) => {
|
|
||||||
if (item.type === 'text') return item.text;
|
|
||||||
return '';
|
|
||||||
})
|
|
||||||
.join('');
|
|
||||||
})();
|
|
||||||
|
|
||||||
return sum + countPromptTokens(`${contentPrompt}${functionCallPrompt}`, item.role);
|
try {
|
||||||
}, 0) +
|
const encodeText = enc.encode(text);
|
||||||
countToolsTokens(tools) +
|
const supplementaryToken = role ? 4 : 0;
|
||||||
countToolsTokens(functionCall);
|
return encodeText.length + supplementaryToken;
|
||||||
|
} catch (error) {
|
||||||
|
return text.length;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const countToolsTokens = (
|
||||||
|
tools?: ChatCompletionTool[] | ChatCompletionCreateParams.Function[]
|
||||||
|
) => {
|
||||||
|
if (!tools || tools.length === 0) return 0;
|
||||||
|
|
||||||
parentPort?.postMessage({
|
const toolText = tools
|
||||||
id,
|
? JSON.stringify(tools)
|
||||||
type: 'success',
|
.replace('"', '')
|
||||||
data: total
|
.replace('\n', '')
|
||||||
});
|
.replace(/( ){2,}/g, ' ')
|
||||||
|
: '';
|
||||||
|
|
||||||
global?.close?.();
|
return enc.encode(toolText).length;
|
||||||
|
};
|
||||||
|
|
||||||
|
const total =
|
||||||
|
messages.reduce((sum, item) => {
|
||||||
|
// Evaluates the text of toolcall and functioncall
|
||||||
|
const functionCallPrompt = (() => {
|
||||||
|
let prompt = '';
|
||||||
|
if (item.role === ChatCompletionRequestMessageRoleEnum.Assistant) {
|
||||||
|
const toolCalls = item.tool_calls;
|
||||||
|
prompt +=
|
||||||
|
toolCalls
|
||||||
|
?.map((item) => `${item?.function?.name} ${item?.function?.arguments}`.trim())
|
||||||
|
?.join('') || '';
|
||||||
|
|
||||||
|
const functionCall = item.function_call;
|
||||||
|
prompt += `${functionCall?.name} ${functionCall?.arguments}`.trim();
|
||||||
|
}
|
||||||
|
return prompt;
|
||||||
|
})();
|
||||||
|
|
||||||
|
const contentPrompt = (() => {
|
||||||
|
if (!item.content) return '';
|
||||||
|
if (typeof item.content === 'string') return item.content;
|
||||||
|
return item.content
|
||||||
|
.map((item) => {
|
||||||
|
if (item.type === 'text') return item.text;
|
||||||
|
return '';
|
||||||
|
})
|
||||||
|
.join('');
|
||||||
|
})();
|
||||||
|
|
||||||
|
return sum + countPromptTokens(`${contentPrompt}${functionCallPrompt}`, item.role);
|
||||||
|
}, 0) +
|
||||||
|
countToolsTokens(tools) +
|
||||||
|
countToolsTokens(functionCall);
|
||||||
|
|
||||||
|
parentPort?.postMessage({
|
||||||
|
id,
|
||||||
|
type: 'success',
|
||||||
|
data: total
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
parentPort?.postMessage({
|
||||||
|
id,
|
||||||
|
type: 'success',
|
||||||
|
data: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,9 +25,12 @@ export const runWorker = <T = any>(name: WorkerNameEnum, params?: Record<string,
|
|||||||
});
|
});
|
||||||
|
|
||||||
worker.on('error', (err) => {
|
worker.on('error', (err) => {
|
||||||
worker.terminate();
|
|
||||||
|
|
||||||
reject(err);
|
reject(err);
|
||||||
|
worker.terminate();
|
||||||
|
});
|
||||||
|
worker.on('messageerror', (err) => {
|
||||||
|
reject(err);
|
||||||
|
worker.terminate();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,10 +1,32 @@
|
|||||||
### FastGPT V4.7.1
|
### FastGPT V4.8
|
||||||
|
|
||||||
1. 新增 - 语音输入完整配置。支持选择是否打开语音输入(包括分享页面),支持语音输入后自动发送,支持语音输入后自动语音播放(流式)。
|
本次更新的重点是对工作流 (高级编排) 进行了重构,使其更加简洁和强大。但由于新旧工作流机制有较大变化,尽管我们进行了一定的自动转换,仍有部分工作流需要您手动重建。请尽快更新到新版本,并对工作流进行必要的调试和重新发布。
|
||||||
2. 新增 - Pptx 和 xlsx 文件读取。但所有文件读取都放服务端,会消耗更多的服务器资源,以及无法在上传时预览更多内容。
|
|
||||||
3. 新增 - 集成 Laf 云函数,可以读取 Laf 账号中的云函数作为 HTTP 模块。
|
❗ 重要提示:
|
||||||
4. 修改 - csv导入模板,取消 header 校验,自动获取前两列。
|
1️⃣ 旧工作流更新后暂不失效,打开旧工作流会弹出自动转换提示,重新编排后点 “发布” 按钮发布新工作流
|
||||||
5. 修复 - 问题补全历史记录BUG
|
2️⃣ 发布新工作流前,工作流自动保存功能暂不生效
|
||||||
6. [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
3️⃣ 应用和插件新增 version 字段,标识适用新/旧版工作流,以实现兼容
|
||||||
7. [使用文档](https://doc.fastgpt.in/docs/intro/)
|
|
||||||
8. [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
✨ 新增功能亮点:
|
||||||
|
1️⃣ 判断器:支持 if/elseIf/else 判断逻辑,工作流控制更灵活
|
||||||
|
2️⃣ 变量更新节点:运行中可动态修改工作流输出变量或全局变量值
|
||||||
|
3️⃣ 工作流自动保存和版本管理:自动保存修改,支持查看和回滚历史版本
|
||||||
|
4️⃣ 工作流调试模式:更直观高效,可调试单节点或逐步执行,实时查看输入输出数据
|
||||||
|
5️⃣ 定时执行应用:支持简单配置实现各种定时任务
|
||||||
|
|
||||||
|
🛠️ 其他优化与修复:
|
||||||
|
- 优化工作流节点连线方式,支持四向连接,易构建循环工作流
|
||||||
|
- 显著提升工作流上下文数据传递性能
|
||||||
|
- 简易模式下修改配置自动刷新调试框,免手动保存
|
||||||
|
- 改进 worker 进程管理,支持 Token 计算任务分配,提高效率
|
||||||
|
- 工具调用支持 string、boolean、number 数据类型
|
||||||
|
- 完善 completions 接口对 size 参数限制
|
||||||
|
- 重构 Node.js API 中间件和服务端代码
|
||||||
|
- 对话记录长度调整为偶数,最大长度增至 50 轮,避免奇数导致部分模型不兼容
|
||||||
|
- HTTP 节点出错将终止进程,避免异常影响
|
||||||
|
- 修复工具调用名称不能以数字开头问题
|
||||||
|
- 修复分享链接 query 参数缓存 bug
|
||||||
|
- 修复工具调用和 HTTP 模块兼容性问题
|
||||||
|
- [点击查看高级编排介绍文档](https://doc.fastgpt.in/docs/workflow/intro)
|
||||||
|
- [使用文档](https://doc.fastgpt.in/docs/intro/)
|
||||||
|
- [点击查看商业版](https://doc.fastgpt.in/docs/commercial/)
|
||||||
@@ -55,6 +55,8 @@ const MessageInput = ({
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const havInput = !!inputValue || fileList.length > 0;
|
const havInput = !!inputValue || fileList.length > 0;
|
||||||
|
const hasFileUploading = fileList.some((item) => !item.url);
|
||||||
|
const canSendMessage = havInput && !hasFileUploading;
|
||||||
|
|
||||||
/* file selector and upload */
|
/* file selector and upload */
|
||||||
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
const { File, onOpen: onOpenSelectFile } = useSelectFile({
|
||||||
@@ -142,7 +144,8 @@ const MessageInput = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
/* on send */
|
/* on send */
|
||||||
const handleSend = useCallback(async () => {
|
const handleSend = async () => {
|
||||||
|
if (!canSendMessage) return;
|
||||||
const textareaValue = TextareaDom.current?.value || '';
|
const textareaValue = TextareaDom.current?.value || '';
|
||||||
|
|
||||||
onSendMessage({
|
onSendMessage({
|
||||||
@@ -150,7 +153,7 @@ const MessageInput = ({
|
|||||||
files: fileList
|
files: fileList
|
||||||
});
|
});
|
||||||
replaceFile([]);
|
replaceFile([]);
|
||||||
}, [TextareaDom, fileList, onSendMessage, replaceFile]);
|
};
|
||||||
|
|
||||||
/* whisper init */
|
/* whisper init */
|
||||||
const {
|
const {
|
||||||
@@ -466,16 +469,20 @@ const MessageInput = ({
|
|||||||
h={['28px', '32px']}
|
h={['28px', '32px']}
|
||||||
w={['28px', '32px']}
|
w={['28px', '32px']}
|
||||||
borderRadius={'md'}
|
borderRadius={'md'}
|
||||||
bg={isSpeaking || isChatting ? '' : !havInput ? '#E5E5E5' : 'primary.500'}
|
bg={
|
||||||
|
isSpeaking || isChatting
|
||||||
|
? ''
|
||||||
|
: !havInput || hasFileUploading
|
||||||
|
? '#E5E5E5'
|
||||||
|
: 'primary.500'
|
||||||
|
}
|
||||||
cursor={havInput ? 'pointer' : 'not-allowed'}
|
cursor={havInput ? 'pointer' : 'not-allowed'}
|
||||||
lineHeight={1}
|
lineHeight={1}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (isChatting) {
|
if (isChatting) {
|
||||||
return onStop();
|
return onStop();
|
||||||
}
|
}
|
||||||
if (havInput) {
|
return handleSend();
|
||||||
return handleSend();
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isChatting ? (
|
{isChatting ? (
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ const Markdown = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const formatSource = source
|
const formatSource = source
|
||||||
.replace(/\\n/g, '\n ')
|
// .replace(/\\n/g, '\n')
|
||||||
.replace(/(http[s]?:\/\/[^\s,。]+)([。,])/g, '$1 $2')
|
.replace(/(http[s]?:\/\/[^\s,。]+)([。,])/g, '$1 $2')
|
||||||
.replace(/\n*(\[QUOTE SIGN\]\(.*\))/g, '$1');
|
.replace(/\n*(\[QUOTE SIGN\]\(.*\))/g, '$1');
|
||||||
|
|
||||||
|
|||||||
@@ -40,3 +40,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse<
|
|||||||
res.status(500).send(getErrText(err));
|
res.status(500).send(getErrText(err));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
api: {
|
||||||
|
responseLimit: '16mb'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -362,12 +362,6 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
}
|
}
|
||||||
export default NextAPI(handler);
|
export default NextAPI(handler);
|
||||||
|
|
||||||
export const config = {
|
|
||||||
api: {
|
|
||||||
responseLimit: '20mb'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const authShareChat = async ({
|
const authShareChat = async ({
|
||||||
chatId,
|
chatId,
|
||||||
...data
|
...data
|
||||||
@@ -526,3 +520,9 @@ const authHeaderRequest = async ({
|
|||||||
canWrite
|
canWrite
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const config = {
|
||||||
|
api: {
|
||||||
|
responseLimit: '20mb'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default React.memo(FileLocal);
|
|||||||
|
|
||||||
const csvTemplate = `"第一列内容","第二列内容"
|
const csvTemplate = `"第一列内容","第二列内容"
|
||||||
"必填列","可选列。CSV 中请注意内容不能包含双引号,双引号是列分割符号"
|
"必填列","可选列。CSV 中请注意内容不能包含双引号,双引号是列分割符号"
|
||||||
"只会讲第一和第二列内容导入,其余列会被忽略",""
|
"只会将第一和第二列内容导入,其余列会被忽略",""
|
||||||
"结合人工智能的演进历程,AIGC的发展大致可以分为三个阶段,即:早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期),以及快速发展展阶段(21世纪10年代中期至今)。",""
|
"结合人工智能的演进历程,AIGC的发展大致可以分为三个阶段,即:早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期),以及快速发展展阶段(21世纪10年代中期至今)。",""
|
||||||
"AIGC发展分为几个阶段?","早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期)、快速发展展阶段(21世纪10年代中期至今)"`;
|
"AIGC发展分为几个阶段?","早期萌芽阶段(20世纪50年代至90年代中期)、沉淀积累阶段(20世纪90年代中期至21世纪10年代中期)、快速发展展阶段(21世纪10年代中期至今)"`;
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export const useSearchTestStore = create<State>()(
|
|||||||
datasetTestList: [],
|
datasetTestList: [],
|
||||||
pushDatasetTestItem(data) {
|
pushDatasetTestItem(data) {
|
||||||
set((state) => {
|
set((state) => {
|
||||||
state.datasetTestList = [data, ...state.datasetTestList].slice(0, 100);
|
state.datasetTestList = [data, ...state.datasetTestList].slice(0, 50);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
delDatasetTestItemById(id) {
|
delDatasetTestItemById(id) {
|
||||||
|
|||||||
Reference in New Issue
Block a user