4.14.4 features (#6090)

* perf: zod with app log (#6083)

* perf: safe decode

* perf: zod with app log

* fix: text

* remove log

* rename field

* refactor: improve like/dislike interaction (#6080)

* refactor: improve like/dislike interaction

* button style & merge status

* perf

* fix

* i18n

* feedback ui

* format

* api optimize

* openapi

* read status

---------

Co-authored-by: archer <545436317@qq.com>

* perf: remove empty chat

* perf: delete resource tip

* fix: confirm

* feedback filter

* fix: ts

* perf: linker scroll

* perf: feedback ui

* fix: plugin file input store

* fix: max tokens

* update comment

* fix: condition value type

* fix feedback (#6095)

* fix feedback

* text

* list

* fix: versionid

---------

Co-authored-by: archer <545436317@qq.com>

* fix: chat setting render;export logs filter

* add test

* perf: log list api

* perf: redirect check

* perf: log list

* create ui

* create ui

---------

Co-authored-by: heheer <heheer@sealos.io>
This commit is contained in:
Archer
2025-12-15 23:36:54 +08:00
committed by GitHub
parent 13681c9246
commit af669a1cfc
135 changed files with 6363 additions and 2021 deletions

View File

@@ -1,29 +0,0 @@
import type { AppLogTimespanEnum } from './constants';
import type { AppChatLogAppData, AppChatLogChatData, AppChatLogUserData } from './type';
export type getChartDataBody = {
appId: string;
dateStart: Date;
dateEnd: Date;
source?: ChatSourceEnum[];
offset: number;
userTimespan: AppLogTimespanEnum;
chatTimespan: AppLogTimespanEnum;
appTimespan: AppLogTimespanEnum;
};
export type getChartDataResponse = {
userData: AppChatLogUserData;
chatData: AppChatLogChatData;
appData: AppChatLogAppData;
};
export type getTotalDataQuery = {
appId: string;
};
export type getTotalDataResponse = {
totalUsers: number;
totalChats: number;
totalPoints: number;
};

View File

@@ -14,7 +14,8 @@ export enum AppLogKeysEnum {
POINTS = 'points',
RESPONSE_TIME = 'responseTime',
ERROR_COUNT = 'errorCount',
REGION = 'region'
REGION = 'region',
VERSION_NAME = 'versionName'
}
export const AppLogKeysEnumMap = {
@@ -31,7 +32,8 @@ export const AppLogKeysEnumMap = {
[AppLogKeysEnum.POINTS]: i18nT('app:logs_keys_points'),
[AppLogKeysEnum.RESPONSE_TIME]: i18nT('app:logs_keys_responseTime'),
[AppLogKeysEnum.ERROR_COUNT]: i18nT('app:logs_keys_errorCount'),
[AppLogKeysEnum.REGION]: i18nT('app:logs_keys_region')
[AppLogKeysEnum.REGION]: i18nT('app:logs_keys_region'),
[AppLogKeysEnum.VERSION_NAME]: i18nT('app:logs_keys_versionName')
};
export const DefaultAppLogKeys = [
@@ -48,7 +50,8 @@ export const DefaultAppLogKeys = [
{ key: AppLogKeysEnum.POINTS, enable: false },
{ key: AppLogKeysEnum.RESPONSE_TIME, enable: false },
{ key: AppLogKeysEnum.ERROR_COUNT, enable: false },
{ key: AppLogKeysEnum.REGION, enable: true }
{ key: AppLogKeysEnum.REGION, enable: true },
{ key: AppLogKeysEnum.VERSION_NAME, enable: false }
];
export enum AppLogTimespanEnum {

View File

@@ -1,65 +0,0 @@
import type { ChatSourceEnum } from '../../core/chat/constants';
import type { AppLogKeysEnum } from './constants';
export type AppLogKeysType = {
key: AppLogKeysEnum;
enable: boolean;
};
export type AppLogKeysSchemaType = {
teamId: string;
appId: string;
logKeys: AppLogKeysType[];
};
export type AppChatLogSchema = {
_id: string;
appId: string;
teamId: string;
chatId: string;
userId: string;
source: string;
sourceName?: string;
createTime: Date;
updateTime: Date;
chatItemCount: number;
errorCount: number;
totalPoints: number;
goodFeedbackCount: number;
badFeedbackCount: number;
totalResponseTime: number;
isFirstChat: boolean; // whether this is the user's first session in the app
};
export type AppChatLogUserData = {
timestamp: number;
summary: {
userCount: number;
newUserCount: number;
retentionUserCount: number;
points: number;
sourceCountMap: Record<ChatSourceEnum, number>;
};
}[];
export type AppChatLogChatData = {
timestamp: number;
summary: {
chatItemCount: number;
chatCount: number;
errorCount: number;
points: number;
};
}[];
export type AppChatLogAppData = {
timestamp: number;
summary: {
goodFeedBackCount: number;
badFeedBackCount: number;
chatCount: number;
totalResponseTime: number;
};
}[];

View File

@@ -0,0 +1,39 @@
import { ObjectIdSchema } from '../../../common/type/mongo';
import { ChatSourceEnum } from '../../chat/constants';
import { AppLogKeysEnum } from './constants';
import { z } from 'zod';
export const AppLogKeysSchema = z.object({
key: z.enum(AppLogKeysEnum),
enable: z.boolean()
});
export type AppLogKeysType = z.infer<typeof AppLogKeysSchema>;
export const AppLogKeysSchemaType = z.object({
teamId: z.string(),
appId: z.string(),
logKeys: z.array(AppLogKeysSchema)
});
export type AppLogKeysSchemaType = z.infer<typeof AppLogKeysSchemaType>;
export const AppChatLogSchema = z.object({
_id: ObjectIdSchema,
appId: ObjectIdSchema,
teamId: ObjectIdSchema,
chatId: z.string(),
userId: z.string(),
source: z.enum(ChatSourceEnum),
sourceName: z.string().optional(),
createTime: z.date(),
updateTime: z.date(),
chatItemCount: z.number(),
errorCount: z.number(),
totalPoints: z.number(),
goodFeedbackCount: z.number(),
badFeedbackCount: z.number(),
totalResponseTime: z.number(),
isFirstChat: z.boolean() // whether this is the user's first session in the app
});
export type AppChatLogSchema = z.infer<typeof AppChatLogSchema>;

View File

@@ -28,6 +28,7 @@ export type ChatSchemaType = {
teamId: string;
tmbId: string;
appId: string;
appVersionId?: string;
createTime: Date;
updateTime: Date;
title: string;
@@ -44,6 +45,12 @@ export type ChatSchemaType = {
variables: Record<string, any>;
pluginInputs?: FlowNodeInputItemType[];
metadata?: Record<string, any>;
// Boolean flags for efficient filtering
hasGoodFeedback?: boolean;
hasBadFeedback?: boolean;
hasUnreadGoodFeedback?: boolean;
hasUnreadBadFeedback?: boolean;
};
export type ChatWithAppSchema = Omit<ChatSchemaType, 'appId'> & {
@@ -105,6 +112,7 @@ export type AIChatItemType = {
userBadFeedback?: string;
customFeedbacks?: string[];
adminFeedback?: AdminFbkType;
isFeedbackRead?: boolean;
durationSeconds?: number;
errorMsg?: string;
@@ -152,6 +160,7 @@ export type ChatItemType = ChatItemMergeType & {
// Frontend type
export type ChatSiteItemType = ChatItemMergeType & {
_id?: string;
id: string;
dataId: string;
status: `${ChatStatusEnum}`;
moduleName?: string;