Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion document/content/docs/upgrading/4-14/4145.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description: 'FastGPT V4.14.5 更新说明'

## 🚀 新增内容


1. 对话记录使用侧改成软删除,增加从日志管理里删除对话记录。

## ⚙️ 优化

Expand Down
3 changes: 2 additions & 1 deletion document/data/doc-last-modified.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"document/content/docs/protocol/terms.en.mdx": "2025-12-15T23:36:54+08:00",
"document/content/docs/protocol/terms.mdx": "2025-12-15T23:36:54+08:00",
"document/content/docs/toc.en.mdx": "2025-08-04T13:42:36+08:00",
"document/content/docs/toc.mdx": "2025-12-09T23:33:32+08:00",
"document/content/docs/toc.mdx": "2025-12-17T17:44:38+08:00",
"document/content/docs/upgrading/4-10/4100.mdx": "2025-08-02T19:38:37+08:00",
"document/content/docs/upgrading/4-10/4101.mdx": "2025-09-08T20:07:20+08:00",
"document/content/docs/upgrading/4-11/4110.mdx": "2025-08-05T23:20:39+08:00",
Expand All @@ -120,6 +120,7 @@
"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/4144.mdx": "2025-12-16T14:56:04+08:00",
"document/content/docs/upgrading/4-14/4145.mdx": "2025-12-17T17:44:38+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/42.mdx": "2025-08-02T19:38:37+08:00",
Expand Down
2 changes: 1 addition & 1 deletion packages/global/common/file/api.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OutLinkChatAuthProps } from '../../support/permission/chat.d';
import type { OutLinkChatAuthProps } from '../../support/permission/chat';

export type preUploadImgProps = OutLinkChatAuthProps & {
// expiredTime?: Date;
Expand Down
2 changes: 1 addition & 1 deletion packages/global/core/app/logs/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const AppLogKeysEnumMap = {
};

export const DefaultAppLogKeys = [
{ key: AppLogKeysEnum.SOURCE, enable: true },
{ key: AppLogKeysEnum.SOURCE, enable: false },
{ key: AppLogKeysEnum.USER, enable: true },
{ key: AppLogKeysEnum.TITLE, enable: true },
{ key: AppLogKeysEnum.SESSION_ID, enable: false },
Expand Down
4 changes: 3 additions & 1 deletion packages/global/core/chat/type.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export type ChatSchemaType = {
hasBadFeedback?: boolean;
hasUnreadGoodFeedback?: boolean;
hasUnreadBadFeedback?: boolean;

deleteTime?: Date | null;
};

export type ChatWithAppSchema = Omit<ChatSchemaType, 'appId'> & {
Expand Down Expand Up @@ -197,7 +199,7 @@ export type HistoryItemType = {
};
export type ChatHistoryItemType = HistoryItemType & {
appId: string;
top: boolean;
top?: boolean;
};

/* ------- response data ------------ */
Expand Down
12 changes: 11 additions & 1 deletion packages/global/openapi/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { z } from 'zod';

export const PaginationSchema = z.object({
pageSize: z.union([z.number(), z.string()]),
pageSize: z.union([z.number(), z.string()]).optional(),
offset: z.union([z.number(), z.string()]).optional(),
pageNum: z.union([z.number(), z.string()]).optional()
});
export type PaginationType = z.infer<typeof PaginationSchema>;

export const PaginationResponseSchema = <T extends z.ZodTypeAny>(itemSchema: T) =>
z.object({
total: z.number().optional().default(0),
list: z.array(itemSchema).optional().default([])
});
export type PaginationResponseType<T extends z.ZodTypeAny> = z.infer<
ReturnType<typeof PaginationResponseSchema<T>>
>;
4 changes: 2 additions & 2 deletions packages/global/openapi/core/app/log/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const ChatLogItemSchema = z.object({
title: z.string().optional().meta({ example: '用户对话', description: '对话标题' }),
customTitle: z.string().nullish().meta({ example: '自定义标题', description: '自定义对话标题' }),
source: z.enum(ChatSourceEnum).meta({ example: ChatSourceEnum.api, description: '对话来源' }),
sourceName: z.string().optional().meta({ example: 'API调用', description: '来源名称' }),
sourceName: z.string().nullish().meta({ example: 'API调用', description: '来源名称' }),
updateTime: z.date().meta({ example: '2024-01-01T00:30:00.000Z', description: '更新时间' }),
createTime: z.date().meta({ example: '2024-01-01T00:00:00.000Z', description: '创建时间' }),
messageCount: z.int().nullish().meta({ example: 10, description: '消息数量' }),
Expand All @@ -50,7 +50,7 @@ export const ChatLogItemSchema = z.object({
totalPoints: z.number().nullish().meta({ example: 150.5, description: '总积分消耗' }),
outLinkUid: z.string().nullish().meta({ example: 'outLink123', description: '外链用户 ID' }),
tmbId: z.string().nullish().meta({ example: 'tmb123', description: '团队成员 ID' }),
sourceMember: SourceMemberSchema.optional().meta({ description: '来源成员信息' }),
sourceMember: SourceMemberSchema.nullish().meta({ description: '来源成员信息' }),
versionName: z.string().nullish().meta({ example: 'v1.0.0', description: '版本名称' }),
region: z.string().nullish().meta({ example: '中国', description: '区域' })
});
Expand Down
4 changes: 2 additions & 2 deletions packages/global/openapi/core/chat/feedback/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,11 @@ export const UpdateUserFeedbackBodySchema = z.object({
example: 'data123',
description: '消息数据 ID'
}),
userGoodFeedback: z.string().optional().nullable().meta({
userGoodFeedback: z.string().nullish().meta({
example: '回答很好',
description: '用户好评反馈内容'
}),
userBadFeedback: z.string().optional().nullable().meta({
userBadFeedback: z.string().nullish().meta({
example: '回答不准确',
description: '用户差评反馈内容'
})
Expand Down
73 changes: 73 additions & 0 deletions packages/global/openapi/core/chat/history/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import z from 'zod';
import { ObjectIdSchema } from '../../../../common/type/mongo';
import { OutLinkChatAuthSchema } from '../../../../support/permission/chat';
import { ChatSourceEnum } from '../../../../core/chat/constants';
import { PaginationSchema, PaginationResponseSchema } from '../../../api';

// Get chat histories schema
export const GetHistoriesBodySchema = PaginationSchema.and(
OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.optional().describe('应用ID'),
source: z.enum(ChatSourceEnum).optional().describe('对话来源'),
startCreateTime: z.string().optional().describe('创建时间开始'),
endCreateTime: z.string().optional().describe('创建时间结束'),
startUpdateTime: z.string().optional().describe('更新时间开始'),
endUpdateTime: z.string().optional().describe('更新时间结束')
})
)
);
export type GetHistoriesBodyType = z.infer<typeof GetHistoriesBodySchema>;
export const GetHistoriesResponseSchema = PaginationResponseSchema(
z.object({
chatId: z.string(),
updateTime: z.date(),
appId: z.string(),
customTitle: z.string().optional(),
title: z.string(),
top: z.boolean().optional()
})
);
export type GetHistoriesResponseType = z.infer<typeof GetHistoriesResponseSchema>;

// Update chat history schema
export const UpdateHistoryBodySchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID'),
chatId: z.string().min(1).describe('对话ID'),
title: z.string().optional().describe('标题'),
customTitle: z.string().optional().describe('自定义标题'),
top: z.boolean().optional().describe('是否置顶')
})
);
export type UpdateHistoryBodyType = z.infer<typeof UpdateHistoryBodySchema>;

// Delete single chat history schema
export const DelChatHistorySchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID'),
chatId: z.string().min(1).describe('对话ID')
})
);
export type DelChatHistoryType = z.infer<typeof DelChatHistorySchema>;

// Clear all chat histories schema
export const ClearChatHistoriesSchema = OutLinkChatAuthSchema.and(
z.object({
appId: ObjectIdSchema.describe('应用ID')
})
);
export type ClearChatHistoriesType = z.infer<typeof ClearChatHistoriesSchema>;

// Batch delete chat histories schema (for log manager)
export const ChatBatchDeleteBodySchema = z.object({
appId: ObjectIdSchema,
chatIds: z
.array(z.string().min(1))
.min(1)
.meta({
description: '对话ID列表',
example: ['chat_123456', 'chat_789012']
})
});
export type ChatBatchDeleteBodyType = z.infer<typeof ChatBatchDeleteBodySchema>;
109 changes: 109 additions & 0 deletions packages/global/openapi/core/chat/history/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type { OpenAPIPath } from '../../../type';
import { TagsMap } from '../../../tag';
import {
GetHistoriesBodySchema,
GetHistoriesResponseSchema,
UpdateHistoryBodySchema,
ChatBatchDeleteBodySchema,
DelChatHistorySchema,
ClearChatHistoriesSchema
} from './api';

export const ChatHistoryPath: OpenAPIPath = {
'/core/chat/history/getHistories': {
post: {
summary: '获取对话历史列表',
description: '分页获取指定应用的对话历史记录',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: GetHistoriesBodySchema
}
}
},
responses: {
200: {
description: '成功获取对话历史列表',
content: {
'application/json': {
schema: GetHistoriesResponseSchema
}
}
}
}
}
},
'/core/chat/history/updateHistory': {
put: {
summary: '修改对话历史',
description: '修改对话历史的标题、自定义标题或置顶状态',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: UpdateHistoryBodySchema
}
}
},
responses: {
200: {
description: '成功修改对话历史'
}
}
}
},
'/core/chat/history/delHistory': {
delete: {
summary: '删除单个对话历史',
description: '软删除指定的单个对话记录',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: DelChatHistorySchema
}
}
Comment thread
c121914yu marked this conversation as resolved.
},
responses: {
200: {
description: '成功删除对话'
}
}
}
},
'/core/chat/history/clearHistories': {
delete: {
summary: '清空应用对话历史',
description: '清空指定应用的所有对话记录(软删除)',
tags: [TagsMap.chatHistory],
requestParams: {
query: ClearChatHistoriesSchema
},
responses: {
200: {
description: '成功清空对话历史'
}
}
}
},
'/core/chat/history/batchDelete': {
post: {
summary: '批量删除对话历史',
description: '批量删除指定应用的多个对话记录(真实删除),需应用日志权限。',
tags: [TagsMap.chatHistory],
requestBody: {
content: {
'application/json': {
schema: ChatBatchDeleteBodySchema
}
}
},
responses: {
200: {
description: '成功删除对话'
}
}
}
}
};
2 changes: 2 additions & 0 deletions packages/global/openapi/core/chat/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { OpenAPIPath } from '../../type';
import { ChatSettingPath } from './setting';
import { ChatFavouriteAppPath } from './favourite/index';
import { ChatFeedbackPath } from './feedback/index';
import { ChatHistoryPath } from './history/index';
import { z } from 'zod';
import { CreatePostPresignedUrlResultSchema } from '../../../../service/common/s3/type';
import { PresignChatFileGetUrlSchema, PresignChatFilePostUrlSchema } from '../../../core/chat/api';
Expand All @@ -11,6 +12,7 @@ export const ChatPath: OpenAPIPath = {
...ChatSettingPath,
...ChatFavouriteAppPath,
...ChatFeedbackPath,
...ChatHistoryPath,

'/core/chat/presignChatFileGetUrl': {
post: {
Expand Down
2 changes: 1 addition & 1 deletion packages/global/openapi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const openAPIDocument = createDocument({
},
{
name: '对话管理',
tags: [TagsMap.chatSetting, TagsMap.chatPage, TagsMap.chatFeedback]
tags: [TagsMap.chatHistory, TagsMap.chatPage, TagsMap.chatFeedback, TagsMap.chatSetting]
},
{
name: '插件系统',
Expand Down
3 changes: 2 additions & 1 deletion packages/global/openapi/tag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export const TagsMap = {
appLog: 'Agent 日志',

// Chat - home
chatPage: '对话页',
chatPage: '对话页操作',
chatHistory: '对话历史管理',
chatSetting: '门户页配置',
chatFeedback: '对话反馈',

Expand Down
9 changes: 0 additions & 9 deletions packages/global/support/permission/chat.d.ts

This file was deleted.

16 changes: 16 additions & 0 deletions packages/global/support/permission/chat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import z from 'zod';

export const ShareChatAuthSchema = z.object({
shareId: z.string().optional().describe('分享链接ID'),
outLinkUid: z.string().optional().describe('外链用户ID')
});
export type ShareChatAuthProps = z.infer<typeof ShareChatAuthSchema>;

export const TeamChatAuthSchema = z.object({
teamId: z.string().optional().describe('团队ID'),
teamToken: z.string().optional().describe('团队Token')
});
export type TeamChatAuthProps = z.infer<typeof TeamChatAuthSchema>;

export const OutLinkChatAuthSchema = ShareChatAuthSchema.and(TeamChatAuthSchema);
export type OutLinkChatAuthProps = z.infer<typeof OutLinkChatAuthSchema>;
4 changes: 1 addition & 3 deletions packages/global/support/user/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ export type UserType = {

export const SourceMemberSchema = z.object({
name: z.string().meta({ example: '张三', description: '成员名称' }),
avatar: z
.string()
.meta({ example: 'https://cloud.fastgpt.cn/avatar.png', description: '成员头像' }),
avatar: z.string().nullish().meta({ description: '成员头像' }),
status: z
.enum(TeamMemberStatusEnum)
.meta({ example: TeamMemberStatusEnum.active, description: '成员状态' })
Expand Down
6 changes: 2 additions & 4 deletions packages/service/common/middle/entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ export const NextEntry = ({
if (error instanceof ZodError) {
return jsonRes(res, {
code: 400,
error: {
message: 'Validation error',
details: error.message
},
message: 'Data validation error',
error,
url: req.url
});
}
Expand Down
4 changes: 4 additions & 0 deletions packages/service/common/response/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { addLog } from '../system/log';
import { replaceSensitiveText } from '@fastgpt/global/common/string/tools';
import { UserError } from '@fastgpt/global/common/error/utils';
import { clearCookie } from '../../support/permission/auth/common';
import { ZodError } from 'zod';

export interface ResponseType<T = any> {
code: number;
Expand Down Expand Up @@ -65,6 +66,9 @@ export function processError(params: {
// 3. 根据错误类型记录不同级别的日志
if (error instanceof UserError) {
addLog.info(`Request error: ${url}, ${msg}`);
} else if (error instanceof ZodError) {
addLog.error(`[Zod] Error in ${url}`, error.message);
msg = error.message;
} else {
addLog.error(`System unexpected error: ${url}, ${msg}`, error);
}
Expand Down
Loading
Loading