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
27 changes: 19 additions & 8 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -594,29 +594,40 @@ System 前缀中的额外 `knowledge` 段暂按 V2 保留,不能依据普通
调用方直接读取已解包数据并管理 loading;共享只读 API 不补写方法以凑齐接口集合。
公共类型维护在 `types/chat-user.ts`,经 `@/api/types` 导出;用户组已授权人数读取 `authorized_count`,不用分页用户数据推算全组人数。

智能体对话用户页继续直接调用普通 `workspace/chat-user.ts`。知识库对话用户页通过详情 context
智能体对话用户页通过 `application-detail/context.ts` 的 `resourceApi.chatUser` 选择 Workspace 或
System 资源管理 API,不包含 Workspace 共享和 System 共享。知识库对话用户页通过详情 context
的 `resourceApi.chatUser` 选择四套现有完整 API,传 `RESOURCE_TYPE.KNOWLEDGE` 和上下文知识库 ID。
共有查询方法为必填,部分范围缺失的保存方法按 ScheduledSync、Tags、Document 同样的规则标记为可选,
调用使用 `?.`;缺失方法不发请求、不提示保存成功,不回退普通 Workspace,不修改现有接口协议。

### 智能体对话日志

`workspace/application/chat-log.ts` 使用 Admin 请求客户端,日志分页请求
智能体详情 context 仅装配 Workspace 和 System 资源管理的完整 Application、Overview、Access、ChatLog、
Workflow 与 ChatUser API。System 智能体接口统一使用 `/system/resource/application` 前缀,
详情 GET、配置 PUT 使用 `/<applicationId>`,发布 PUT 使用 `/<applicationId>/publish`;
概览统计、Tokens 排行、提问排行分别为 GET `application_stats`、`application_token_usage`、`top_questions`。
发布历史使用 GET `/<applicationId>/application_version`,版本编辑使用 PUT 追加版本 ID。
DebugPanel 与日志正文仍使用现有 Workspace conversation/聊天记录实现,尚未按 System 范围适配。

`workspace/application/chat-log.ts` 和 `system/resource-management/application/chat-log.ts` 使用 Admin 请求客户端,
前缀分别为 `/workspace/<workspaceId>/application` 和 `/system/resource/application`。日志分页请求
`/<applicationId>/chat/<currentPage>/<pageSize>`,导出使用 `postExportExcel` 请求
`/<applicationId>/chat/export`,查询包含日期、摘要或用户及点赞、点踩下限;
导出请求体为 `{ select_ids }`,空数组表示导出当前筛选结果。
日志业务类型经 `@/api/types` 导出,来源枚举经 `@/api/enums` 导出,loading 由调用方维护。
清除策略通过 PUT `batch_clean_time` 提交当前智能体的单元素 `id_list`、`clean_time`、
`file_clean_time`,避免调用通用应用编辑流程;成功后页面刷新应用详情。
Workspace 清除策略通过 PUT `batch_clean_time` 提交当前智能体的单元素 `id_list`、`clean_time`、
`file_clean_time`;System 沿用 v2 的单个智能体 PUT `/<applicationId>` 保存两个清除天数字段。
成功后页面刷新应用详情。
添加知识库通过 POST `/<applicationId>/add_knowledge` 提交 `ChatLogAddKnowledgePayload`
(`knowledge_id`、`document_id`、`chat_ids`),将所选对话的问答写入目标文档。
目标文档选项通过 `workspace/knowledge/document.ts` 的 `getAllDocuments(knowledgeId)`
请求不分页的文档列表。聊天记录与标注接口保留在同一 API 文件,尚未接入日志详情正文。
知识库及目标文档选项通过当前范围 Knowledge/Document API 查询,文档使用 `getAllDocuments(knowledgeId)`。
聊天记录与标注接口保留在同一 API 文件;日志详情使用现有 `LogConversation`,其聊天记录查询仍使用 Workspace API。

### 智能体发布渠道

`admin/workspace/application/access.ts` 独立维护发布渠道接口,前缀为
`/workspace/<workspaceId>/application/<applicationId>/platform`,沿用 v2 协议。
`admin/workspace/application/access.ts` 和 `admin/system/resource-management/application/access.ts`
独立维护发布渠道接口,前缀分别为 `/workspace/<workspaceId>/application/<applicationId>/platform`
与 `/system/resource/application/<applicationId>/platform`,沿用 v2 协议。
GET `/status` 返回按平台标识索引的 `[是否已配置, 是否启用]`;POST `/status` 提交
`{ type, status }`。GET、POST `/<type>` 查询与保存对应平台配置,不由通用 application.ts 转发。
平台标识由 `APPLICATION_ACCESS_PLATFORM` 定义,业务类型在 `types/application.ts` 经公共入口导出。
Expand Down
21 changes: 21 additions & 0 deletions ui/src/api/admin/system/resource-management/application/access.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/** System 资源管理智能体发布渠道配置与启停接口。 */
import { get, post } from '@/api/admin/core/request'
import type { ApplicationAccessConfig, ApplicationAccessPlatform, ApplicationAccessStatus, ApplicationAccessStatusPayload } from '@/api/types'

const getPrefix = (applicationId: string) => `/system/resource/application/${applicationId}/platform`

/** 获取智能体各发布渠道的配置及启用状态。 */
const getPlatformStatus = (applicationId: string) => get<ApplicationAccessStatus>(`${getPrefix(applicationId)}/status`)

/** 启用或停用智能体发布渠道。 */
const postPlatformStatus = (applicationId: string, payload: ApplicationAccessStatusPayload) => post(`${getPrefix(applicationId)}/status`, payload)

/** 获取智能体指定发布渠道的配置。 */
const getPlatformConfig = (applicationId: string, platform: ApplicationAccessPlatform) =>
get<ApplicationAccessConfig | null>(`${getPrefix(applicationId)}/${platform}`)

/** 保存智能体指定发布渠道的配置。 */
const postPlatformConfig = (applicationId: string, platform: ApplicationAccessPlatform, payload: ApplicationAccessConfig) =>
post(`${getPrefix(applicationId)}/${platform}`, payload)

export default { getPlatformStatus, postPlatformStatus, getPlatformConfig, postPlatformConfig }
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { del, get, getExportFile } from '@/api/admin/core/request'
import { del, get, getExportFile, put } from '@/api/admin/core/request'
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
import type { ApplicationDetail, Dict } from '@/api/types'
import type { ApplicationDetail, ApplicationFormPayload, Dict } from '@/api/types'

const prefix = '/system/resource/application'

Expand All @@ -22,7 +22,24 @@ const exportApplication = (applicationId: string, applicationName: string) => {
return getExportFile(`${applicationName}.mk`, `${prefix}/${applicationId}/export`)
}

/** 获取 System 资源管理智能体详情。 */
const getApplicationDetail = (applicationId: string) => get<ApplicationDetail>(`${prefix}/${applicationId}`)

/** 保存 System 资源管理智能体配置。 */
const putApplication = (applicationId: string, data: ApplicationFormPayload) =>
put<ApplicationFormPayload, ApplicationDetail>(`${prefix}/${applicationId}`, data)

/** 发布 System 资源管理智能体。 */
const putApplicationPublish = (applicationId: string, publishName: string, publishDesc?: string) =>
put<Record<string, unknown>, ApplicationDetail>(`${prefix}/${applicationId}/publish`, {
publish_name: publishName,
publish_desc: publishDesc,
})

export default {
getApplicationDetail,
putApplication,
putApplicationPublish,
getAllApplication,
getApplicationPage,
deleteApplication,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { del, get, post, postExportExcel, put } from '@/api/admin/core/request'
import type { ParamsPage, ResponsePage } from '@/api/admin/core/types'
import type { ChatLog, ChatLogAddKnowledgePayload, ChatLogRecord, ApplicationDetail, Dict } from '@/api/types'

const getPrefix = () => `/system/resource/application`

/** 分页获取智能体对话日志。 */
const getChatLog = (applicationId: string, page: ParamsPage, query: Dict<unknown>) =>
get<ResponsePage<ChatLog>>(`${getPrefix()}/${applicationId}/chat/${page.currentPage}/${page.pageSize}`, query)

/** 导出筛选结果或选中的对话日志。 */
const postExportChatLog = (applicationId: string, applicationName: string, query: Dict<unknown>, data: { select_ids: string[] }) =>
postExportExcel(`${applicationName}.xlsx`, `${getPrefix()}/${applicationId}/chat/export`, query, data)

/** 保存 System 智能体的日志与文件清除策略,沿用单个智能体更新协议。 */
const putChatLogCleanTime = (applicationId: string, cleanTime: number, fileCleanTime: number) =>
put<{ clean_time: number; file_clean_time: number }, ApplicationDetail>(`${getPrefix()}/${applicationId}`, {
clean_time: cleanTime,
file_clean_time: fileCleanTime,
})

/** 将对话记录添加至知识库。 */
const postChatLogAddKnowledge = (applicationId: string, data: ChatLogAddKnowledgePayload) =>
post<ChatLogAddKnowledgePayload, void>(`${getPrefix()}/${applicationId}/add_knowledge`, data)

/** 分页获取对话中的聊天记录。 */
const getChatRecordLog = (applicationId: string, chatId: string, page: ParamsPage, orderAsc = true) =>
get<ResponsePage<ChatLogRecord>>(`${getPrefix()}/${applicationId}/chat/${chatId}/chat_record/${page.currentPage}/${page.pageSize}`, {
order_asc: orderAsc,
})

/** 获取聊天记录的标注段落。 */
const getMarkChatRecord = (applicationId: string, chatId: string, chatRecordId: string) =>
get<Dict<unknown>[]>(`${getPrefix()}/${applicationId}/chat/${chatId}/chat_record/${chatRecordId}/improve`)

/** 保存聊天记录的知识库标注内容。 */
const putChatRecordLog = (
applicationId: string,
chatId: string,
chatRecordId: string,
knowledgeId: string,
documentId: string,
data: Dict<unknown>,
) => put(`${getPrefix()}/${applicationId}/chat/${chatId}/chat_record/${chatRecordId}/knowledge/${knowledgeId}/document/${documentId}/improve`, data)

/** 删除聊天记录的知识库标注。 */
const deleteMarkChatRecord = (
applicationId: string,
chatId: string,
chatRecordId: string,
knowledgeId: string,
documentId: string,
paragraphId: string,
) =>
del(
`${getPrefix()}/${applicationId}/chat/${chatId}/chat_record/${chatRecordId}/knowledge/${knowledgeId}/document/${documentId}/paragraph/${paragraphId}/improve`,
)

export default {
getChatLog,
postExportChatLog,
putChatLogCleanTime,
postChatLogAddKnowledge,
getChatRecordLog,
getMarkChatRecord,
putChatRecordLog,
deleteMarkChatRecord,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/** System 资源管理智能体概览的使用统计与用户排行接口。 */
import { get } from '@/api/admin/core/request'
import type { ApplicationTokenUsage, ApplicationTopQuestion, HomeDateRange, HomeMonitoringDay } from '@/api/types'

const getPrefix = () => '/system/resource/application'

/** 获取智能体每日对话、用户、Tokens 与满意度统计。 */
const getMonitoring = (_workspaceId: string, range: HomeDateRange, applicationId: string) =>
get<HomeMonitoringDay[]>(`${getPrefix()}/${applicationId}/application_stats`, { ...range })

/** 获取智能体按用户排序的 Tokens 消耗。 */
const getTokenUsage = (applicationId: string, range: HomeDateRange) =>
get<ApplicationTokenUsage[]>(`${getPrefix()}/${applicationId}/application_token_usage`, { ...range })

/** 获取智能体按用户排序的提问次数。 */
const getTopQuestions = (applicationId: string, range: HomeDateRange) =>
get<ApplicationTopQuestion[]>(`${getPrefix()}/${applicationId}/top_questions`, { ...range })

export default {
getMonitoring,
getTokenUsage,
getTopQuestions,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { get, put } from '@/api/admin/core/request'
import type { WorkflowVersion, WorkflowVersionPayload } from '@/api/types'

const getPrefix = (applicationId: string) => `/system/resource/application/${applicationId}/application_version`

/** 获取智能体发布历史,按发布时间倒序返回完整版本快照。 */
const getWorkflowVersions = (applicationId: string) => get<WorkflowVersion[]>(getPrefix(applicationId))

/** 修改智能体历史版本标题和更新说明,更新说明需要服务端支持 description 字段。 */
const putWorkflowVersion = (applicationId: string, versionId: string, data: WorkflowVersionPayload) =>
put<WorkflowVersionPayload, WorkflowVersion>(`${getPrefix(applicationId)}/${versionId}`, data)

export default { getWorkflowVersions, putWorkflowVersion }
10 changes: 8 additions & 2 deletions ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ Workspace 共享覆盖 resourceScope,保留 Workspace scope 及知识库 activ
| 授权与集成 | integration/chat-user、integration/external-retrieval |
| 设置 | BASE 单独 setting;WEB 分组含 setting/base、document-strategy、scheduled-sync;LARK/WORKFLOW 含 base、scheduled-sync |

召回测试子路由通过 `props` 传入资源范围与知识库 ID 组成的 Vue `key`,切换资源时重建该页。
分组不挂 View,直接访问重定向首个子页,保留参数、query、hash。
设置只用 detailMenuVisible 控制菜单类型,不添加类型访问守卫。资料库 View 的目录是 library/tags,URL 仍为 tag。

Expand All @@ -257,15 +256,22 @@ Workspace 共享覆盖 resourceScope,保留 Workspace scope 及知识库 activ
### 智能体

Workspace 详情父路由为 workspace-application-detail-layout,详情参数包含 applicationId 与 ApplicationDetail.type。
System 资源管理详情为 `/system/resource/application/:applicationId/:type`,父路由名为
`system-resource-application-detail-layout`,默认进入 `system-resource-application-overview`。
配置集中在 `admin/system/modules/application-system-resource.ts`,由 System 路由汇总接入。
两种范围独立维护 children,复用 `application-detail` 页面;System 隐藏系统侧栏,不携带 workspaceId,
不提供 Workspace 共享或 System 共享的智能体详情。System 列表点击名称进入详情。
菜单为概览、设置、发布渠道、对话用户、对话日志;SIMPLE 的 setting 与高级 workflow-entry 互斥显示。
发布渠道使用 access 路径、workspace-application-access 路由名,对应 application-detail/access 页面。
高级设置重定向 workflow-application,保留 workspaceId、applicationId 和 query。
System 高级设置重定向 `system-resource-workflow-application`,地址为
`/system/resource/application/:applicationId/workflow`,保留 applicationId 和 query。
对话日志保留 operation-log 路径和 workspace-application-operation-log 名称。

workflow/application/navigation.ts 按详情子路由 order 查找首个有名称、标题、未隐藏且 canAccess 允许的页面。
未配置 canAccess 默认允许;它仅用于返回导航,不替代守卫或后端鉴权。
概览使用 overviewRead,简易设置要求 SIMPLE 与编辑权限,高级设置 canAccess 为 false,避免返回画布。
无可访问详情或 System 详情父路由未实现时返回对应列表,不在导航函数硬编码子页分支。
无可访问详情时返回对应列表,不在导航函数硬编码子页分支。

### 工具

Expand Down
4 changes: 2 additions & 2 deletions ui/src/router/admin/system/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { RouteRecordRaw } from 'vue-router'
import { RESOURCE_TYPE } from '@/api/enums'
import { systemApplicationRoutes } from './modules/application'
import { systemResourceApplicationRoutes } from './modules/application-system-resource'
import { systemResourceKnowledgeRoutes } from './modules/knowledge-system-resource'
import { systemSharedKnowledgeRoutes } from './modules/knowledge-system-shared'
import perm from '@/permission/index'
Expand Down Expand Up @@ -181,7 +181,7 @@ export const systemRoutes: RouteRecordRaw = {
},
],
},
...systemApplicationRoutes,
...systemResourceApplicationRoutes,
{
path: 'shared',
name: 'system-shared',
Expand Down
74 changes: 74 additions & 0 deletions ui/src/router/admin/system/modules/application-system-resource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { RouteRecordRaw } from 'vue-router'
import { APPLICATION_TYPE } from '@/api/enums'

/** System 资源管理智能体详情,与 Workspace 复用页面,不提供共享详情。 */
export const systemResourceApplicationRoutes: RouteRecordRaw[] = [
{
path: '/system/resource/application/:applicationId/:type',
name: 'system-resource-application-detail',
component: () => import('@/views/application-detail/index.vue'),
redirect: { name: 'system-resource-application-overview' },
meta: { title: '智能体详情', hidden: true, hideSidebar: true, resourceDetailRoot: true, scope: 'system', resourceScope: 'system-resource' },
children: [
{
path: 'overview',
name: 'system-resource-application-overview',
component: () => import('@/views/application-detail/overview/index.vue'),
meta: {
title: '概览',
icon: 'icon_screen_outlined',
activeIcon: 'icon_screen_filled',
order: 10,
},
},
{
path: 'setting',
name: 'system-resource-application-simple-setting',
component: () => import('@/views/application-detail/setting/index.vue'),
meta: {
title: '设置',
icon: 'icon_setting',
activeIcon: 'icon_setting_filled',
order: 20,
detailMenuVisible: (params) => params.type === APPLICATION_TYPE.SIMPLE,
},
},
{
path: 'workflow-entry',
name: 'system-resource-application-workflow-setting',
redirect: (to) => ({
name: 'system-resource-workflow-application',
params: { applicationId: to.params.applicationId },
query: to.query,
}),
meta: {
title: '设置',
icon: 'icon_setting',
activeIcon: 'icon_setting_filled',
order: 20,
detailMenuVisible: (params) => params.type === APPLICATION_TYPE.WORK_FLOW,
// 工作流跳转入口不能作为画布返回的落脚页。
canAccess: () => false,
},
},
{
path: 'access',
name: 'system-resource-application-access',
component: () => import('@/views/application-detail/access/index.vue'),
meta: { title: '发布渠道', icon: 'icon_application_outlined', activeIcon: 'icon_application_filled', order: 30 },
},
{
path: 'chat-user',
name: 'system-resource-application-chat-user',
component: () => import('@/views/application-detail/chat-user/index.vue'),
meta: { title: '对话用户', icon: 'icon_contacts_outlined', activeIcon: 'icon_contacts_filled', order: 40 },
},
{
path: 'operation-log',
name: 'system-resource-application-operation-log',
component: () => import('@/views/application-detail/chat-log/index.vue'),
meta: { title: '对话日志', icon: 'icon_logs_outlined', activeIcon: 'icon_logs_filled', order: 50 },
},
],
},
]
6 changes: 0 additions & 6 deletions ui/src/router/admin/system/modules/application.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export const systemResourceKnowledgeRoutes: RouteRecordRaw[] = [
path: 'hit-test',
name: 'system-resource-knowledge-hit-test',
component: () => import('@/views/knowledge-detail/hit-test/index.vue'),
props: (route) => ({ key: `${route.meta.resourceScope}:${route.params.knowledgeId}` }),
meta: { title: '召回测试', order: 10 },
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export const systemSharedKnowledgeRoutes: RouteRecordRaw[] = [
path: 'hit-test',
name: 'system-shared-knowledge-hit-test',
component: () => import('@/views/knowledge-detail/hit-test/index.vue'),
props: (route) => ({ key: `${route.meta.resourceScope}:${route.params.knowledgeId}` }),
meta: { title: '召回测试', order: 10 },
},
{
Expand Down
Loading
Loading