Commit 9f2adcd5 by Archer Committed by GitHub

perf: request llm (#6191)

* perf: request error info

* perf: request llm'

* perf: request llm'

* openapi doc
parent f7e46ec7
...@@ -20,6 +20,7 @@ description: 'FastGPT V4.14.5 更新说明' ...@@ -20,6 +20,7 @@ description: 'FastGPT V4.14.5 更新说明'
2. MongoDB, Redis 和 MQ 的重连逻辑优化。 2. MongoDB, Redis 和 MQ 的重连逻辑优化。
3. 变量输入框禁用状态可复制。 3. 变量输入框禁用状态可复制。
4. LLM 请求空响应判断,排除敏感过滤错误被误认为无响应。 4. LLM 请求空响应判断,排除敏感过滤错误被误认为无响应。
5. 完善 AI 对话和工具调用的错误提示,提供更多原始数据。
## 🐛 修复 ## 🐛 修复
......
...@@ -120,7 +120,7 @@ ...@@ -120,7 +120,7 @@
"document/content/docs/upgrading/4-14/4142.mdx": "2025-11-18T19:27:14+08:00", "document/content/docs/upgrading/4-14/4142.mdx": "2025-11-18T19:27:14+08:00",
"document/content/docs/upgrading/4-14/4143.mdx": "2025-11-26T20:52:05+08:00", "document/content/docs/upgrading/4-14/4143.mdx": "2025-11-26T20:52:05+08:00",
"document/content/docs/upgrading/4-14/4144.mdx": "2025-12-16T14:56:04+08:00", "document/content/docs/upgrading/4-14/4144.mdx": "2025-12-16T14:56:04+08:00",
"document/content/docs/upgrading/4-14/4145.mdx": "2026-01-05T13:44:33+08:00", "document/content/docs/upgrading/4-14/4145.mdx": "2026-01-05T15:39:04+08:00",
"document/content/docs/upgrading/4-8/40.mdx": "2025-08-02T19:38:37+08:00", "document/content/docs/upgrading/4-8/40.mdx": "2025-08-02T19:38:37+08:00",
"document/content/docs/upgrading/4-8/41.mdx": "2025-08-02T19:38:37+08:00", "document/content/docs/upgrading/4-8/41.mdx": "2025-08-02T19:38:37+08:00",
"document/content/docs/upgrading/4-8/42.mdx": "2025-08-02T19:38:37+08:00", "document/content/docs/upgrading/4-8/42.mdx": "2025-08-02T19:38:37+08:00",
......
...@@ -41,6 +41,7 @@ export enum EmbeddingTypeEnm { ...@@ -41,6 +41,7 @@ export enum EmbeddingTypeEnm {
} }
export const completionFinishReasonMap = { export const completionFinishReasonMap = {
error: i18nT('chat:completion_finish_error'),
close: i18nT('chat:completion_finish_close'), close: i18nT('chat:completion_finish_close'),
stop: i18nT('chat:completion_finish_stop'), stop: i18nT('chat:completion_finish_stop'),
length: i18nT('chat:completion_finish_length'), length: i18nT('chat:completion_finish_length'),
......
import openai from 'openai'; import openai from 'openai';
import type { import type {
ChatCompletion as SdkChatCompletion,
ChatCompletionMessageToolCall, ChatCompletionMessageToolCall,
ChatCompletionMessageParam as SdkChatCompletionMessageParam, ChatCompletionMessageParam as SdkChatCompletionMessageParam,
ChatCompletionToolMessageParam, ChatCompletionToolMessageParam,
...@@ -70,10 +71,16 @@ export type ChatCompletionMessageFunctionCall = ...@@ -70,10 +71,16 @@ export type ChatCompletionMessageFunctionCall =
}; };
// Stream response // Stream response
export type StreamChatType = Stream<openai.Chat.Completions.ChatCompletionChunk>; export type StreamChatType = Stream<openai.Chat.Completions.ChatCompletionChunk & { error?: any }>;
export type UnStreamChatType = openai.Chat.Completions.ChatCompletion; export type UnStreamChatType = openai.Chat.Completions.ChatCompletion;
// UnStream response
export type ChatCompletion = SdkChatCompletion & {
error?: any;
};
export type CompletionFinishReason = export type CompletionFinishReason =
| 'error'
| 'close' | 'close'
| 'stop' | 'stop'
| 'length' | 'length'
......
...@@ -2,6 +2,31 @@ import { OutLinkChatAuthSchema } from '../../../../support/permission/chat'; ...@@ -2,6 +2,31 @@ import { OutLinkChatAuthSchema } from '../../../../support/permission/chat';
import { ObjectIdSchema } from '../../../../common/type/mongo'; import { ObjectIdSchema } from '../../../../common/type/mongo';
import z from 'zod'; import z from 'zod';
/* Init */
// Online chat
export const InitChatQuerySchema = z
.object({
appId: ObjectIdSchema.describe('应用ID'),
chatId: z.string().min(1).describe('对话ID'),
loadCustomFeedbacks: z.boolean().optional().describe('是否加载自定义反馈')
})
.meta({
example: {
appId: '1234567890',
chatId: '1234567890',
loadCustomFeedbacks: true
}
});
export type InitChatQueryType = z.infer<typeof InitChatQuerySchema>;
export const InitChatResponseSchema = z.object({
chatId: z.string().min(1).describe('对话ID'),
appId: ObjectIdSchema.describe('应用ID'),
userAvatar: z.string().optional().describe('用户头像'),
title: z.string().min(1).describe('对话标题'),
variables: z.record(z.string(), z.any()).optional().describe('全局变量值'),
app: z.object({}).describe('应用配置')
});
/* ============ v2/chat/stop ============ */ /* ============ v2/chat/stop ============ */
export const StopV2ChatSchema = z export const StopV2ChatSchema = z
.object({ .object({
......
...@@ -28,7 +28,13 @@ export const openAPIDocument = createDocument({ ...@@ -28,7 +28,13 @@ export const openAPIDocument = createDocument({
}, },
{ {
name: '对话管理', name: '对话管理',
tags: [TagsMap.chatHistory, TagsMap.chatPage, TagsMap.chatFeedback, TagsMap.chatSetting] tags: [
TagsMap.chatPage,
TagsMap.chatHistory,
TagsMap.chatController,
TagsMap.chatFeedback,
TagsMap.chatSetting
]
}, },
{ {
name: '知识库', name: '知识库',
......
...@@ -6,11 +6,11 @@ export const TagsMap = { ...@@ -6,11 +6,11 @@ export const TagsMap = {
appCommon: 'Agent 管理', appCommon: 'Agent 管理',
// Chat - home // Chat - home
chatPage: '对话页', chatPage: '对话页面通用',
chatController: '对话框操作', chatHistory: '历史记录管理',
chatHistory: '对话历史管理', chatController: '对话操作',
chatSetting: '门户页配置',
chatFeedback: '对话反馈', chatFeedback: '对话反馈',
chatSetting: '门户页配置',
// Dataset // Dataset
datasetCollection: '集合', datasetCollection: '集合',
......
...@@ -55,6 +55,7 @@ type RunAgentCallProps = { ...@@ -55,6 +55,7 @@ type RunAgentCallProps = {
} & ResponseEvents; } & ResponseEvents;
type RunAgentResponse = { type RunAgentResponse = {
error?: any;
completeMessages: ChatCompletionMessageParam[]; // Step request complete messages completeMessages: ChatCompletionMessageParam[]; // Step request complete messages
assistantMessages: ChatCompletionMessageParam[]; // Step assistant response messages assistantMessages: ChatCompletionMessageParam[]; // Step assistant response messages
interactiveResponse?: ToolCallChildrenInteractive; interactiveResponse?: ToolCallChildrenInteractive;
...@@ -134,6 +135,7 @@ export const runAgentCall = async ({ ...@@ -134,6 +135,7 @@ export const runAgentCall = async ({
let inputTokens: number = 0; let inputTokens: number = 0;
let outputTokens: number = 0; let outputTokens: number = 0;
let finish_reason: CompletionFinishReason | undefined; let finish_reason: CompletionFinishReason | undefined;
let requestError: any;
const subAppUsages: ChatNodeUsageType[] = []; const subAppUsages: ChatNodeUsageType[] = [];
// 处理 tool 里的交互 // 处理 tool 里的交互
...@@ -213,8 +215,10 @@ export const runAgentCall = async ({ ...@@ -213,8 +215,10 @@ export const runAgentCall = async ({
usage, usage,
responseEmptyTip, responseEmptyTip,
assistantMessage: llmAssistantMessage, assistantMessage: llmAssistantMessage,
finish_reason: finishReason finish_reason: finishReason,
error
} = await createLLMResponse({ } = await createLLMResponse({
throwError: false,
body: { body: {
...body, ...body,
max_tokens: maxTokens, max_tokens: maxTokens,
...@@ -234,7 +238,11 @@ export const runAgentCall = async ({ ...@@ -234,7 +238,11 @@ export const runAgentCall = async ({
}); });
finish_reason = finishReason; finish_reason = finishReason;
requestError = error;
if (requestError) {
break;
}
if (responseEmptyTip) { if (responseEmptyTip) {
return Promise.reject(responseEmptyTip); return Promise.reject(responseEmptyTip);
} }
...@@ -303,6 +311,7 @@ export const runAgentCall = async ({ ...@@ -303,6 +311,7 @@ export const runAgentCall = async ({
} }
return { return {
error: requestError,
inputTokens, inputTokens,
outputTokens, outputTokens,
subAppUsages, subAppUsages,
......
...@@ -39,6 +39,7 @@ export type ResponseEvents = { ...@@ -39,6 +39,7 @@ export type ResponseEvents = {
}; };
export type CreateLLMResponseProps<T extends CompletionsBodyType = CompletionsBodyType> = { export type CreateLLMResponseProps<T extends CompletionsBodyType = CompletionsBodyType> = {
throwError?: boolean;
userKey?: OpenaiAccountType; userKey?: OpenaiAccountType;
body: LLMRequestBodyType<T>; body: LLMRequestBodyType<T>;
isAborted?: () => boolean | undefined; isAborted?: () => boolean | undefined;
...@@ -46,6 +47,7 @@ export type CreateLLMResponseProps<T extends CompletionsBodyType = CompletionsBo ...@@ -46,6 +47,7 @@ export type CreateLLMResponseProps<T extends CompletionsBodyType = CompletionsBo
} & ResponseEvents; } & ResponseEvents;
type LLMResponse = { type LLMResponse = {
error?: any;
isStreamResponse: boolean; isStreamResponse: boolean;
answerText: string; answerText: string;
reasoningText: string; reasoningText: string;
...@@ -69,7 +71,7 @@ type LLMResponse = { ...@@ -69,7 +71,7 @@ type LLMResponse = {
export const createLLMResponse = async <T extends CompletionsBodyType>( export const createLLMResponse = async <T extends CompletionsBodyType>(
args: CreateLLMResponseProps<T> args: CreateLLMResponseProps<T>
): Promise<LLMResponse> => { ): Promise<LLMResponse> => {
const { body, custonHeaders, userKey } = args; const { throwError = true, body, custonHeaders, userKey } = args;
const { messages, useVision, requestOrigin, tools, toolCallMode } = body; const { messages, useVision, requestOrigin, tools, toolCallMode } = body;
// Messages process // Messages process
...@@ -104,7 +106,7 @@ export const createLLMResponse = async <T extends CompletionsBodyType>( ...@@ -104,7 +106,7 @@ export const createLLMResponse = async <T extends CompletionsBodyType>(
} }
}); });
const { answerText, reasoningText, toolCalls, finish_reason, usage } = await (async () => { let { answerText, reasoningText, toolCalls, finish_reason, usage, error } = await (async () => {
if (isStreamResponse) { if (isStreamResponse) {
return createStreamResponse({ return createStreamResponse({
response, response,
...@@ -151,6 +153,14 @@ export const createLLMResponse = async <T extends CompletionsBodyType>( ...@@ -151,6 +153,14 @@ export const createLLMResponse = async <T extends CompletionsBodyType>(
usage?.prompt_tokens || (await countGptMessagesTokens(requestBody.messages, requestBody.tools)); usage?.prompt_tokens || (await countGptMessagesTokens(requestBody.messages, requestBody.tools));
const outputTokens = usage?.completion_tokens || (await countGptMessagesTokens(assistantMessage)); const outputTokens = usage?.completion_tokens || (await countGptMessagesTokens(assistantMessage));
if (error) {
finish_reason = 'error';
if (throwError) {
throw error;
}
}
const getEmptyResponseTip = () => { const getEmptyResponseTip = () => {
if (userKey?.baseUrl) { if (userKey?.baseUrl) {
addLog.warn(`User LLM response empty`, { addLog.warn(`User LLM response empty`, {
...@@ -172,10 +182,12 @@ export const createLLMResponse = async <T extends CompletionsBodyType>( ...@@ -172,10 +182,12 @@ export const createLLMResponse = async <T extends CompletionsBodyType>(
!answerText && !answerText &&
!reasoningText && !reasoningText &&
!toolCalls?.length && !toolCalls?.length &&
!error &&
(finish_reason === 'stop' || !finish_reason); (finish_reason === 'stop' || !finish_reason);
const responseEmptyTip = isNotResponse ? getEmptyResponseTip() : undefined; const responseEmptyTip = isNotResponse ? getEmptyResponseTip() : undefined;
return { return {
error,
isStreamResponse, isStreamResponse,
responseEmptyTip, responseEmptyTip,
answerText, answerText,
...@@ -183,8 +195,8 @@ export const createLLMResponse = async <T extends CompletionsBodyType>( ...@@ -183,8 +195,8 @@ export const createLLMResponse = async <T extends CompletionsBodyType>(
toolCalls, toolCalls,
finish_reason, finish_reason,
usage: { usage: {
inputTokens, inputTokens: error ? 0 : inputTokens,
outputTokens outputTokens: error ? 0 : outputTokens
}, },
requestMessages, requestMessages,
...@@ -200,6 +212,7 @@ type CompleteResponse = Pick< ...@@ -200,6 +212,7 @@ type CompleteResponse = Pick<
'answerText' | 'reasoningText' | 'toolCalls' | 'finish_reason' 'answerText' | 'reasoningText' | 'toolCalls' | 'finish_reason'
> & { > & {
usage?: CompletionUsage; usage?: CompletionUsage;
error?: any;
}; };
export const createStreamResponse = async ({ export const createStreamResponse = async ({
...@@ -217,83 +230,88 @@ export const createStreamResponse = async ({ ...@@ -217,83 +230,88 @@ export const createStreamResponse = async ({
const { retainDatasetCite = true, tools, toolCallMode = 'toolChoice', model } = body; const { retainDatasetCite = true, tools, toolCallMode = 'toolChoice', model } = body;
const modelData = getLLMModel(model); const modelData = getLLMModel(model);
const { parsePart, getResponseData, updateFinishReason } = parseLLMStreamResponse(); const { parsePart, getResponseData, updateFinishReason, updateError } = parseLLMStreamResponse();
if (tools?.length) { if (tools?.length) {
if (toolCallMode === 'toolChoice') { if (toolCallMode === 'toolChoice') {
let callingTool: ChatCompletionMessageToolCall['function'] | null = null; let callingTool: ChatCompletionMessageToolCall['function'] | null = null;
const toolCalls: ChatCompletionMessageToolCall[] = []; const toolCalls: ChatCompletionMessageToolCall[] = [];
for await (const part of response) { try {
if (isAborted?.()) { for await (const part of response) {
response.controller?.abort(); if (isAborted?.()) {
updateFinishReason('close'); response.controller?.abort();
break; updateFinishReason('close');
} break;
}
const { reasoningContent, responseContent } = parsePart({ const { reasoningContent, responseContent } = parsePart({
part, part,
parseThinkTag: modelData.reasoning, parseThinkTag: modelData.reasoning,
retainDatasetCite retainDatasetCite
}); });
if (reasoningContent) { if (reasoningContent) {
onReasoning?.({ text: reasoningContent }); onReasoning?.({ text: reasoningContent });
} }
if (responseContent) { if (responseContent) {
onStreaming?.({ text: responseContent }); onStreaming?.({ text: responseContent });
} }
const responseChoice = part.choices?.[0]?.delta; const responseChoice = part.choices?.[0]?.delta;
// Parse tool calls // Parse tool calls
if (responseChoice?.tool_calls?.length) { if (responseChoice?.tool_calls?.length) {
responseChoice.tool_calls.forEach((toolCall, i) => { responseChoice.tool_calls.forEach((toolCall, i) => {
const index = toolCall.index ?? i; const index = toolCall.index ?? i;
// Call new tool
const hasNewTool = toolCall?.function?.name || callingTool;
if (hasNewTool) {
// Call new tool // Call new tool
if (toolCall?.function?.name) { const hasNewTool = toolCall?.function?.name || callingTool;
callingTool = { if (hasNewTool) {
name: toolCall.function?.name || '', // Call new tool
arguments: toolCall.function?.arguments || '' if (toolCall?.function?.name) {
}; callingTool = {
} else if (callingTool) { name: toolCall.function?.name || '',
// Continue call(Perhaps the name of the previous function was incomplete) arguments: toolCall.function?.arguments || ''
callingTool.name += toolCall.function?.name || ''; };
callingTool.arguments += toolCall.function?.arguments || ''; } else if (callingTool) {
} // Continue call(Perhaps the name of the previous function was incomplete)
callingTool.name += toolCall.function?.name || '';
// New tool, add to list. callingTool.arguments += toolCall.function?.arguments || '';
if (tools.find((item) => item.function.name === callingTool!.name)) { }
const call: ChatCompletionMessageToolCall = {
id: getNanoid(), // New tool, add to list.
type: 'function', if (tools.find((item) => item.function.name === callingTool!.name)) {
function: callingTool! const call: ChatCompletionMessageToolCall = {
}; id: getNanoid(),
toolCalls[index] = call; type: 'function',
onToolCall?.({ call }); function: callingTool!
callingTool = null; };
} toolCalls[index] = call;
} else { onToolCall?.({ call });
/* arg 追加到当前工具的参数里 */ callingTool = null;
const arg: string = toolCall?.function?.arguments ?? ''; }
const currentTool = toolCalls[index]; } else {
if (currentTool && arg) { /* arg 追加到当前工具的参数里 */
currentTool.function.arguments += arg; const arg: string = toolCall?.function?.arguments ?? '';
const currentTool = toolCalls[index];
onToolParam?.({ tool: currentTool, params: arg }); if (currentTool && arg) {
currentTool.function.arguments += arg;
onToolParam?.({ tool: currentTool, params: arg });
}
} }
} });
}); }
} }
} catch (error: any) {
updateError(error?.error || error);
} }
const { reasoningContent, content, finish_reason, usage } = getResponseData(); const { reasoningContent, content, finish_reason, usage, error } = getResponseData();
return { return {
error,
answerText: content, answerText: content,
reasoningText: reasoningContent, reasoningText: reasoningContent,
finish_reason, finish_reason,
...@@ -304,56 +322,60 @@ export const createStreamResponse = async ({ ...@@ -304,56 +322,60 @@ export const createStreamResponse = async ({
let startResponseWrite = false; let startResponseWrite = false;
let answer = ''; let answer = '';
for await (const part of response) { try {
if (isAborted?.()) { for await (const part of response) {
response.controller?.abort(); if (isAborted?.()) {
updateFinishReason('close'); response.controller?.abort();
break; updateFinishReason('close');
} break;
}
const { reasoningContent, content, responseContent } = parsePart({ const { reasoningContent, content, responseContent } = parsePart({
part, part,
parseThinkTag: modelData.reasoning, parseThinkTag: modelData.reasoning,
retainDatasetCite retainDatasetCite
}); });
answer += content; answer += content;
if (reasoningContent) { if (reasoningContent) {
onReasoning?.({ text: reasoningContent }); onReasoning?.({ text: reasoningContent });
} }
if (content) { if (content) {
if (startResponseWrite) { if (startResponseWrite) {
if (responseContent) { if (responseContent) {
onStreaming?.({ text: responseContent }); onStreaming?.({ text: responseContent });
} }
} else if (answer.length >= 3) { } else if (answer.length >= 3) {
answer = answer.trimStart(); answer = answer.trimStart();
// Not call tool // Not call tool
if (/0(:|:)/.test(answer)) { if (/0(:|:)/.test(answer)) {
startResponseWrite = true; startResponseWrite = true;
// find first : index // find first : index
const firstIndex = const firstIndex =
answer.indexOf('0:') !== -1 ? answer.indexOf('0:') : answer.indexOf('0:'); answer.indexOf('0:') !== -1 ? answer.indexOf('0:') : answer.indexOf('0:');
answer = answer.substring(firstIndex + 2).trim(); answer = answer.substring(firstIndex + 2).trim();
onStreaming?.({ text: answer }); onStreaming?.({ text: answer });
} }
// Not response tool // Not response tool
else if (/1(:|:)/.test(answer)) { else if (/1(:|:)/.test(answer)) {
} }
// Not start 1/0, start response // Not start 1/0, start response
else { else {
startResponseWrite = true; startResponseWrite = true;
onStreaming?.({ text: answer }); onStreaming?.({ text: answer });
}
} }
} }
} }
} catch (error: any) {
updateError(error?.error || error);
} }
const { reasoningContent, content, finish_reason, usage } = getResponseData(); const { reasoningContent, content, finish_reason, usage, error } = getResponseData();
const { answer: llmAnswer, streamAnswer, toolCalls } = parsePromptToolCall(content); const { answer: llmAnswer, streamAnswer, toolCalls } = parsePromptToolCall(content);
if (streamAnswer) { if (streamAnswer) {
...@@ -365,6 +387,7 @@ export const createStreamResponse = async ({ ...@@ -365,6 +387,7 @@ export const createStreamResponse = async ({
}); });
return { return {
error,
answerText: llmAnswer, answerText: llmAnswer,
reasoningText: reasoningContent, reasoningText: reasoningContent,
finish_reason, finish_reason,
...@@ -374,30 +397,35 @@ export const createStreamResponse = async ({ ...@@ -374,30 +397,35 @@ export const createStreamResponse = async ({
} }
} else { } else {
// Not use tool // Not use tool
for await (const part of response) { try {
if (isAborted?.()) { for await (const part of response) {
response.controller?.abort(); if (isAborted?.()) {
updateFinishReason('close'); response.controller?.abort();
break; updateFinishReason('close');
} break;
}
const { reasoningContent, responseContent } = parsePart({ const { reasoningContent, responseContent } = parsePart({
part, part,
parseThinkTag: modelData.reasoning, parseThinkTag: modelData.reasoning,
retainDatasetCite retainDatasetCite
}); });
if (reasoningContent) { if (reasoningContent) {
onReasoning?.({ text: reasoningContent }); onReasoning?.({ text: reasoningContent });
} }
if (responseContent) { if (responseContent) {
onStreaming?.({ text: responseContent }); onStreaming?.({ text: responseContent });
}
} }
} catch (error: any) {
updateError(error?.error || error);
} }
const { reasoningContent, content, finish_reason, usage } = getResponseData(); const { reasoningContent, content, finish_reason, usage, error } = getResponseData();
return { return {
error,
answerText: content, answerText: content,
reasoningText: reasoningContent, reasoningText: reasoningContent,
finish_reason, finish_reason,
...@@ -479,6 +507,7 @@ export const createCompleteResponse = async ({ ...@@ -479,6 +507,7 @@ export const createCompleteResponse = async ({
} }
return { return {
error: response.error,
reasoningText: formatReasonContent, reasoningText: formatReasonContent,
answerText: formatContent, answerText: formatContent,
toolCalls, toolCalls,
...@@ -580,9 +609,9 @@ const llmCompletionsBodyFormat = async <T extends CompletionsBodyType>({ ...@@ -580,9 +609,9 @@ const llmCompletionsBodyFormat = async <T extends CompletionsBodyType>({
}) })
} as T; } as T;
// Filter null value // Filter undefined/null value
requestBody = Object.fromEntries( requestBody = Object.fromEntries(
Object.entries(requestBody).filter(([_, value]) => value !== null) Object.entries(requestBody).filter(([_, value]) => value !== null && value !== undefined)
) as T; ) as T;
// field map // field map
......
...@@ -364,6 +364,9 @@ export const loadRequestMessages = async ({ ...@@ -364,6 +364,9 @@ export const loadRequestMessages = async ({
const loadMessages = ( const loadMessages = (
await Promise.all( await Promise.all(
mergeMessages.map(async (item, i) => { mergeMessages.map(async (item, i) => {
delete item.dataId;
delete item.hideInUI;
if (item.role === ChatCompletionRequestMessageRoleEnum.System) { if (item.role === ChatCompletionRequestMessageRoleEnum.System) {
const content = parseSystemMessage(item.content); const content = parseSystemMessage(item.content);
if (!content) return; if (!content) return;
......
...@@ -73,6 +73,7 @@ export const parseLLMStreamResponse = () => { ...@@ -73,6 +73,7 @@ export const parseLLMStreamResponse = () => {
let buffer_usage: CompletionUsage = getLLMDefaultUsage(); let buffer_usage: CompletionUsage = getLLMDefaultUsage();
let buffer_reasoningContent = ''; let buffer_reasoningContent = '';
let buffer_content = ''; let buffer_content = '';
let error: any = undefined;
/* /*
parseThinkTag - 只控制是否主动解析 <think></think>,如果接口已经解析了,则不再解析。 parseThinkTag - 只控制是否主动解析 <think></think>,如果接口已经解析了,则不再解析。
...@@ -84,6 +85,7 @@ export const parseLLMStreamResponse = () => { ...@@ -84,6 +85,7 @@ export const parseLLMStreamResponse = () => {
retainDatasetCite = true retainDatasetCite = true
}: { }: {
part: { part: {
error?: any;
choices: { choices: {
delta: { delta: {
content?: string | null; content?: string | null;
...@@ -96,6 +98,7 @@ export const parseLLMStreamResponse = () => { ...@@ -96,6 +98,7 @@ export const parseLLMStreamResponse = () => {
parseThinkTag?: boolean; parseThinkTag?: boolean;
retainDatasetCite?: boolean; retainDatasetCite?: boolean;
}): { }): {
error?: any;
reasoningContent: string; reasoningContent: string;
content: string; // 原始内容,不去掉 cite content: string; // 原始内容,不去掉 cite
responseContent: string; // 响应的内容,会去掉 cite responseContent: string; // 响应的内容,会去掉 cite
...@@ -297,11 +300,14 @@ export const parseLLMStreamResponse = () => { ...@@ -297,11 +300,14 @@ export const parseLLMStreamResponse = () => {
buffer_reasoningContent += data.reasoningContent; buffer_reasoningContent += data.reasoningContent;
buffer_content += data.content; buffer_content += data.content;
error = part.error || error;
return data; return data;
}; };
const getResponseData = () => { const getResponseData = () => {
return { return {
error,
finish_reason: buffer_finishReason, finish_reason: buffer_finishReason,
usage: buffer_usage, usage: buffer_usage,
reasoningContent: buffer_reasoningContent, reasoningContent: buffer_reasoningContent,
...@@ -312,11 +318,15 @@ export const parseLLMStreamResponse = () => { ...@@ -312,11 +318,15 @@ export const parseLLMStreamResponse = () => {
const updateFinishReason = (finishReason: CompletionFinishReason) => { const updateFinishReason = (finishReason: CompletionFinishReason) => {
buffer_finishReason = finishReason; buffer_finishReason = finishReason;
}; };
const updateError = (err: any) => {
error = err;
};
return { return {
parsePart, parsePart,
getResponseData, getResponseData,
updateFinishReason updateFinishReason,
updateError
}; };
}; };
......
...@@ -177,47 +177,55 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp ...@@ -177,47 +177,55 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
const write = res ? responseWriteController({ res, readStream: stream }) : undefined; const write = res ? responseWriteController({ res, readStream: stream }) : undefined;
const { completeMessages, reasoningText, answerText, finish_reason, responseEmptyTip, usage } = const {
await createLLMResponse({ completeMessages,
body: { reasoningText,
model: modelConstantsData.model, answerText,
stream, finish_reason,
messages: filterMessages, responseEmptyTip,
temperature, usage,
max_tokens, error
top_p: aiChatTopP, } = await createLLMResponse({
stop: aiChatStopSign, throwError: false,
response_format: { body: {
type: aiChatResponseFormat, model: modelConstantsData.model,
json_schema: aiChatJsonSchema stream,
}, messages: filterMessages,
retainDatasetCite, temperature,
useVision: aiChatVision, max_tokens,
requestOrigin top_p: aiChatTopP,
stop: aiChatStopSign,
response_format: {
type: aiChatResponseFormat,
json_schema: aiChatJsonSchema
}, },
userKey: externalProvider.openaiAccount, retainDatasetCite,
isAborted: checkIsStopping, useVision: aiChatVision,
onReasoning({ text }) { requestOrigin
if (!aiChatReasoning) return; },
workflowStreamResponse?.({ userKey: externalProvider.openaiAccount,
write, isAborted: checkIsStopping,
event: SseResponseEventEnum.answer, onReasoning({ text }) {
data: textAdaptGptResponse({ if (!aiChatReasoning) return;
reasoning_content: text workflowStreamResponse?.({
}) write,
}); event: SseResponseEventEnum.answer,
}, data: textAdaptGptResponse({
onStreaming({ text }) { reasoning_content: text
if (!isResponseAnswerText) return; })
workflowStreamResponse?.({ });
write, },
event: SseResponseEventEnum.answer, onStreaming({ text }) {
data: textAdaptGptResponse({ if (!isResponseAnswerText) return;
text workflowStreamResponse?.({
}) write,
}); event: SseResponseEventEnum.answer,
} data: textAdaptGptResponse({
}); text
})
});
}
});
if (responseEmptyTip) { if (responseEmptyTip) {
return getNodeErrResponse({ error: responseEmptyTip }); return getNodeErrResponse({ error: responseEmptyTip });
...@@ -232,6 +240,35 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp ...@@ -232,6 +240,35 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
const chatCompleteMessages = GPTMessages2Chats({ messages: completeMessages }); const chatCompleteMessages = GPTMessages2Chats({ messages: completeMessages });
if (error) {
return getNodeErrResponse({
error,
responseData: {
totalPoints: points,
model: modelName,
inputTokens: usage.inputTokens,
outputTokens: usage.outputTokens,
query: `${userChatInput}`,
maxToken: max_tokens,
reasoningText,
historyPreview: getHistoryPreview(chatCompleteMessages, 10000, aiChatVision),
contextTotalLen: completeMessages.length,
finishReason: finish_reason
},
...(points && {
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
{
moduleName: name,
totalPoints: points,
model: modelName,
inputTokens: usage.inputTokens,
outputTokens: usage.outputTokens
}
]
})
});
}
return { return {
data: { data: {
answerText: answerText, answerText: answerText,
......
...@@ -14,7 +14,6 @@ import { formatModelChars2Points } from '../../../../support/wallet/usage/utils' ...@@ -14,7 +14,6 @@ import { formatModelChars2Points } from '../../../../support/wallet/usage/utils'
import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type'; import { type DispatchNodeResultType } from '@fastgpt/global/core/workflow/runtime/type';
import { getHandleId } from '@fastgpt/global/core/workflow/utils'; import { getHandleId } from '@fastgpt/global/core/workflow/utils';
import { addLog } from '../../../../common/system/log'; import { addLog } from '../../../../common/system/log';
import { ModelTypeEnum } from '../../../../../global/core/ai/model';
import { createLLMResponse } from '../../../ai/llm/request'; import { createLLMResponse } from '../../../ai/llm/request';
type Props = ModuleDispatchProps<{ type Props = ModuleDispatchProps<{
......
...@@ -187,7 +187,8 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise< ...@@ -187,7 +187,8 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
toolCallOutputTokens, toolCallOutputTokens,
completeMessages = [], // The actual message sent to AI(just save text) completeMessages = [], // The actual message sent to AI(just save text)
assistantResponses = [], // FastGPT system store assistant.value response assistantResponses = [], // FastGPT system store assistant.value response
finish_reason finish_reason,
error
} = await (async () => { } = await (async () => {
const adaptMessages = chats2GPTMessages({ const adaptMessages = chats2GPTMessages({
messages, messages,
...@@ -224,6 +225,46 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise< ...@@ -224,6 +225,46 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
// Preview assistant responses // Preview assistant responses
const previewAssistantResponses = filterToolResponseToPreview(assistantResponses); const previewAssistantResponses = filterToolResponseToPreview(assistantResponses);
if (error) {
return getNodeErrResponse({
error,
[DispatchNodeResponseKeyEnum.nodeResponse]: {
totalPoints: totalPointsUsage,
toolCallInputTokens: toolCallInputTokens,
toolCallOutputTokens: toolCallOutputTokens,
childTotalPoints: toolTotalPoints,
model: modelName,
query: userChatInput,
historyPreview: getHistoryPreview(
GPTMessages2Chats({ messages: completeMessages, reserveTool: false }),
10000,
useVision
),
toolDetail: toolDispatchFlowResponses.map((item) => item.flowResponses).flat(),
mergeSignId: nodeId,
finishReason: finish_reason
},
[DispatchNodeResponseKeyEnum.runTimes]: toolDispatchFlowResponses.reduce(
(sum, item) => sum + item.runTimes,
0
),
...(totalPointsUsage && {
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
// 模型本身的积分消耗
{
moduleName: name,
model: modelName,
totalPoints: modelUsage,
inputTokens: toolCallInputTokens,
outputTokens: toolCallOutputTokens
},
// 工具的消耗
...toolUsages
]
})
});
}
return { return {
data: { data: {
[NodeOutputKeyEnum.answerText]: previewAssistantResponses [NodeOutputKeyEnum.answerText]: previewAssistantResponses
......
...@@ -110,7 +110,8 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo ...@@ -110,7 +110,8 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
completeMessages, completeMessages,
assistantMessages, assistantMessages,
interactiveResponse, interactiveResponse,
finish_reason finish_reason,
error
} = await runAgentCall({ } = await runAgentCall({
maxRunAgentTimes: 50, maxRunAgentTimes: 50,
body: { body: {
...@@ -310,6 +311,7 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo ...@@ -310,6 +311,7 @@ export const runToolCall = async (props: DispatchToolModuleProps): Promise<RunTo
.flat(); .flat();
return { return {
error,
toolDispatchFlowResponses: toolRunResponses, toolDispatchFlowResponses: toolRunResponses,
toolCallInputTokens: inputTokens, toolCallInputTokens: inputTokens,
toolCallOutputTokens: outputTokens, toolCallOutputTokens: outputTokens,
......
...@@ -46,6 +46,7 @@ export type DispatchToolModuleProps = ModuleDispatchProps<{ ...@@ -46,6 +46,7 @@ export type DispatchToolModuleProps = ModuleDispatchProps<{
}; };
export type RunToolResponse = { export type RunToolResponse = {
error?: any;
toolDispatchFlowResponses: DispatchFlowResponse[]; toolDispatchFlowResponses: DispatchFlowResponse[];
toolCallInputTokens: number; toolCallInputTokens: number;
toolCallOutputTokens: number; toolCallOutputTokens: number;
......
...@@ -329,7 +329,7 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo ...@@ -329,7 +329,7 @@ export const dispatchRunTool = async (props: RunToolProps): Promise<RunToolRespo
return getNodeErrResponse({ return getNodeErrResponse({
error, error,
customNodeResponse: { [DispatchNodeResponseKeyEnum.nodeResponse]: {
toolInput, toolInput,
moduleLogo: avatar moduleLogo: avatar
} }
......
...@@ -203,6 +203,9 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi ...@@ -203,6 +203,9 @@ export const dispatchRunPlugin = async (props: RunPluginProps): Promise<RunPlugi
: null : null
}; };
} catch (error) { } catch (error) {
return getNodeErrResponse({ error, customNodeResponse: { moduleLogo: plugin?.avatar } }); return getNodeErrResponse({
error,
[DispatchNodeResponseKeyEnum.nodeResponse]: { moduleLogo: plugin?.avatar }
});
} }
}; };
...@@ -25,6 +25,7 @@ import { getMCPChildren } from '../../../core/app/mcp'; ...@@ -25,6 +25,7 @@ import { getMCPChildren } from '../../../core/app/mcp';
import { getSystemToolRunTimeNodeFromSystemToolset } from '../utils'; import { getSystemToolRunTimeNodeFromSystemToolset } from '../utils';
import type { localeType } from '@fastgpt/global/common/i18n/type'; import type { localeType } from '@fastgpt/global/common/i18n/type';
import type { HttpToolConfigType } from '@fastgpt/global/core/app/type'; import type { HttpToolConfigType } from '@fastgpt/global/core/app/type';
import type { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
export const getWorkflowResponseWrite = ({ export const getWorkflowResponseWrite = ({
res, res,
...@@ -293,22 +294,34 @@ export const rewriteRuntimeWorkFlow = async ({ ...@@ -293,22 +294,34 @@ export const rewriteRuntimeWorkFlow = async ({
export const getNodeErrResponse = ({ export const getNodeErrResponse = ({
error, error,
customErr, customErr,
customNodeResponse responseData,
nodeDispatchUsages,
runTimes,
newVariables,
system_memories
}: { }: {
error: any; error: any;
customErr?: Record<string, any>; customErr?: Record<string, any>;
customNodeResponse?: Record<string, any>; [DispatchNodeResponseKeyEnum.nodeResponse]?: Record<string, any>;
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]?: ChatNodeUsageType[]; // Node total usage
[DispatchNodeResponseKeyEnum.runTimes]?: number;
[DispatchNodeResponseKeyEnum.newVariables]?: Record<string, any>;
[DispatchNodeResponseKeyEnum.memories]?: Record<string, any>;
}) => { }) => {
const errorText = getErrText(error); const errorText = getErrText(error);
return { return {
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: nodeDispatchUsages,
[DispatchNodeResponseKeyEnum.runTimes]: runTimes,
[DispatchNodeResponseKeyEnum.newVariables]: newVariables,
[DispatchNodeResponseKeyEnum.memories]: system_memories,
error: { error: {
[NodeOutputKeyEnum.errorText]: errorText, [NodeOutputKeyEnum.errorText]: errorText,
...(typeof customErr === 'object' ? customErr : {}) ...(typeof customErr === 'object' ? customErr : {})
}, },
[DispatchNodeResponseKeyEnum.nodeResponse]: { [DispatchNodeResponseKeyEnum.nodeResponse]: {
errorText, errorText,
...(typeof customNodeResponse === 'object' ? customNodeResponse : {}) ...(typeof responseData === 'object' ? responseData : {})
}, },
[DispatchNodeResponseKeyEnum.toolResponses]: { [DispatchNodeResponseKeyEnum.toolResponses]: {
error: errorText, error: errorText,
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"click_to_add_url": "Enter file link", "click_to_add_url": "Enter file link",
"completion_finish_close": "Disconnection", "completion_finish_close": "Disconnection",
"completion_finish_content_filter": "Trigger safe wind control", "completion_finish_content_filter": "Trigger safe wind control",
"completion_finish_error": "Request error",
"completion_finish_function_call": "Function Calls", "completion_finish_function_call": "Function Calls",
"completion_finish_length": "Reply limit exceeded", "completion_finish_length": "Reply limit exceeded",
"completion_finish_null": "unknown", "completion_finish_null": "unknown",
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"click_to_add_url": "输入文件链接", "click_to_add_url": "输入文件链接",
"completion_finish_close": "请求关闭", "completion_finish_close": "请求关闭",
"completion_finish_content_filter": "触发安全风控", "completion_finish_content_filter": "触发安全风控",
"completion_finish_error": "请求错误",
"completion_finish_function_call": "函数调用", "completion_finish_function_call": "函数调用",
"completion_finish_length": "超出回复限制", "completion_finish_length": "超出回复限制",
"completion_finish_null": "未知", "completion_finish_null": "未知",
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
"click_to_add_url": "輸入文件鏈接", "click_to_add_url": "輸入文件鏈接",
"completion_finish_close": "連接斷開", "completion_finish_close": "連接斷開",
"completion_finish_content_filter": "觸發安全風控", "completion_finish_content_filter": "觸發安全風控",
"completion_finish_error": "請求錯誤",
"completion_finish_function_call": "函式呼叫", "completion_finish_function_call": "函式呼叫",
"completion_finish_length": "超出回覆限制", "completion_finish_length": "超出回覆限制",
"completion_finish_null": "未知", "completion_finish_null": "未知",
......
...@@ -149,6 +149,18 @@ export const WholeResponseContent = ({ ...@@ -149,6 +149,18 @@ export const WholeResponseContent = ({
value={formatNumber(activeModule.childTotalPoints)} value={formatNumber(activeModule.childTotalPoints)}
/> />
)} )}
<Row label={t('workflow:response.Error')} value={activeModule?.error} />
<Row label={t('workflow:response.Error')} value={activeModule?.errorText} />
<Row label={t('chat:response.node_inputs')} value={activeModule?.nodeInputs} />
</>
{/* ai chat */}
<>
{activeModule?.finishReason && (
<Row
label={t('chat:completion_finish_reason')}
value={t(completionFinishReasonMap[activeModule?.finishReason])}
/>
)}
<Row label={t('common:core.chat.response.module model')} value={activeModule?.model} /> <Row label={t('common:core.chat.response.module model')} value={activeModule?.model} />
{activeModule?.tokens && ( {activeModule?.tokens && (
<Row label={t('chat:llm_tokens')} value={`${activeModule?.tokens}`} /> <Row label={t('chat:llm_tokens')} value={`${activeModule?.tokens}`} />
...@@ -171,12 +183,6 @@ export const WholeResponseContent = ({ ...@@ -171,12 +183,6 @@ export const WholeResponseContent = ({
label={t('common:core.chat.response.context total length')} label={t('common:core.chat.response.context total length')}
value={activeModule?.contextTotalLen} value={activeModule?.contextTotalLen}
/> />
<Row label={t('workflow:response.Error')} value={activeModule?.error} />
<Row label={t('workflow:response.Error')} value={activeModule?.errorText} />
<Row label={t('chat:response.node_inputs')} value={activeModule?.nodeInputs} />
</>
{/* ai chat */}
<>
<Row <Row
label={t('common:core.chat.response.module temperature')} label={t('common:core.chat.response.module temperature')}
value={activeModule?.temperature} value={activeModule?.temperature}
...@@ -185,12 +191,6 @@ export const WholeResponseContent = ({ ...@@ -185,12 +191,6 @@ export const WholeResponseContent = ({
label={t('common:core.chat.response.module maxToken')} label={t('common:core.chat.response.module maxToken')}
value={activeModule?.maxToken} value={activeModule?.maxToken}
/> />
{activeModule?.finishReason && (
<Row
label={t('chat:completion_finish_reason')}
value={t(completionFinishReasonMap[activeModule?.finishReason])}
/>
)}
<Row label={t('chat:reasoning_text')} value={activeModule?.reasoningText} /> <Row label={t('chat:reasoning_text')} value={activeModule?.reasoningText} />
<Row <Row
......
...@@ -15,11 +15,6 @@ export type GetChatSpeechProps = OutLinkChatAuthProps & { ...@@ -15,11 +15,6 @@ export type GetChatSpeechProps = OutLinkChatAuthProps & {
}; };
/* ---------- chat ----------- */ /* ---------- chat ----------- */
export type InitChatProps = {
appId?: string;
chatId?: string;
loadCustomFeedbacks?: boolean;
};
export type GetChatRecordsProps = OutLinkChatAuthProps & { export type GetChatRecordsProps = OutLinkChatAuthProps & {
appId: string; appId: string;
......
import type { NextApiRequest, NextApiResponse } from 'next'; import type { NextApiRequest, NextApiResponse } from 'next';
import { jsonRes } from '@fastgpt/service/common/response';
import { authApp } from '@fastgpt/service/support/permission/app/auth'; import { authApp } from '@fastgpt/service/support/permission/app/auth';
import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils'; import { getGuideModule, getAppChatConfig } from '@fastgpt/global/core/workflow/utils';
import { getChatModelNameListByModules } from '@/service/core/app/workflow'; import { getChatModelNameListByModules } from '@/service/core/app/workflow';
import type { InitChatProps, InitChatResponse } from '@/global/core/chat/api.d'; import type { InitChatResponse } from '@/global/core/chat/api.d';
import { MongoChat } from '@fastgpt/service/core/chat/chatSchema'; import { MongoChat } from '@fastgpt/service/core/chat/chatSchema';
import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat'; import { ChatErrEnum } from '@fastgpt/global/common/error/code/chat';
import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller'; import { getAppLatestVersion } from '@fastgpt/service/core/app/version/controller';
...@@ -14,19 +13,10 @@ import { presignVariablesFileUrls } from '@fastgpt/service/core/chat/utils'; ...@@ -14,19 +13,10 @@ import { presignVariablesFileUrls } from '@fastgpt/service/core/chat/utils';
import { MongoAppRecord } from '@fastgpt/service/core/app/record/schema'; import { MongoAppRecord } from '@fastgpt/service/core/app/record/schema';
import { AppErrEnum } from '@fastgpt/global/common/error/code/app'; import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
import { authCert } from '@fastgpt/service/support/permission/auth/common'; import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { InitChatQuerySchema } from '@fastgpt/global/openapi/core/chat/controler/api';
async function handler( async function handler(req: NextApiRequest, res: NextApiResponse): Promise<InitChatResponse> {
req: NextApiRequest, const { appId, chatId } = InitChatQuerySchema.parse(req.query);
res: NextApiResponse
): Promise<InitChatResponse | void> {
let { appId, chatId } = req.query as InitChatProps;
if (!appId) {
return jsonRes(res, {
code: 501,
message: "You don't have an app yet"
});
}
try { try {
// auth app permission // auth app permission
...@@ -99,9 +89,3 @@ async function handler( ...@@ -99,9 +89,3 @@ async function handler(
} }
export default NextAPI(handler); export default NextAPI(handler);
export const config = {
api: {
responseLimit: '10mb'
}
};
...@@ -2,7 +2,6 @@ import { GET, POST, DELETE, PUT } from '@/web/common/api/request'; ...@@ -2,7 +2,6 @@ import { GET, POST, DELETE, PUT } from '@/web/common/api/request';
import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d'; import type { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type.d';
import type { getResDataQuery } from '@/pages/api/core/chat/getResData'; import type { getResDataQuery } from '@/pages/api/core/chat/getResData';
import type { import type {
InitChatProps,
InitChatResponse, InitChatResponse,
InitOutLinkChatProps, InitOutLinkChatProps,
InitTeamChatProps InitTeamChatProps
...@@ -24,7 +23,10 @@ import type { ...@@ -24,7 +23,10 @@ import type {
UpdateFavouriteAppParamsType UpdateFavouriteAppParamsType
} from '@fastgpt/global/openapi/core/chat/favourite/api'; } from '@fastgpt/global/openapi/core/chat/favourite/api';
import type { ChatFavouriteAppType } from '@fastgpt/global/core/chat/favouriteApp/type'; import type { ChatFavouriteAppType } from '@fastgpt/global/core/chat/favouriteApp/type';
import type { StopV2ChatParams } from '@fastgpt/global/openapi/core/chat/controler/api'; import type {
InitChatQueryType,
StopV2ChatParams
} from '@fastgpt/global/openapi/core/chat/controler/api';
import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/global/openapi/core/chat/api'; import type { GetRecentlyUsedAppsResponseType } from '@fastgpt/global/openapi/core/chat/api';
export const getRecentlyUsedApps = () => export const getRecentlyUsedApps = () =>
...@@ -33,7 +35,7 @@ export const getRecentlyUsedApps = () => ...@@ -33,7 +35,7 @@ export const getRecentlyUsedApps = () =>
/** /**
* 获取初始化聊天内容 * 获取初始化聊天内容
*/ */
export const getInitChatInfo = (data: InitChatProps) => export const getInitChatInfo = (data: InitChatQueryType) =>
GET<InitChatResponse>(`/core/chat/init`, data); GET<InitChatResponse>(`/core/chat/init`, data);
export const getInitOutLinkChatInfo = (data: InitOutLinkChatProps) => export const getInitOutLinkChatInfo = (data: InitOutLinkChatProps) =>
GET<InitChatResponse>(`/core/chat/outLink/init`, data); GET<InitChatResponse>(`/core/chat/outLink/init`, data);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment