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
7 changes: 7 additions & 0 deletions ui/src/api/API_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,10 @@ API 对象和工作空间上下文,作为该抽屉的范围选择例外;用
当前 Workspace 关联资源 API 一致。`resource-trigger.ts` 使用
`/system/resource/<sourceType>/<sourceId>/trigger`,资源上下文与触发器载荷复用公共类型。
System 接口由资源管理服务提供;本地开源后端没有对应扩展时,需要连接提供这些接口的部署。

### System 共享工具工作流

`system/shared-resources/tool/tool-workflow.ts` 维护共享工具的工作流详情、保存、发布、调试、
版本和执行记录,前缀为 `/system/shared/tool`,调用只传资源 ID,不读取工作空间。
两种 System 工具 API 的 `getToolListWithShared` 查询各自 `/tool_list` 并合并 `tools`、`shared_tools`,
供画布的工具菜单及 MCP 选项使用。系统扩展接口需连接支持相应协议的部署进行联调。
5 changes: 5 additions & 0 deletions ui/src/api/admin/system/resource-management/tool/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import type { Dict, ToolDebugPayload, ToolItem, ToolPayload, ToolPylintIssue } f

const prefix = '/system/resource/tool'

/** 获取当前系统范围可用的工具选项。 */
const getToolListWithShared = (query?: Dict<unknown>) =>
get<{ tools: ToolItem[]; shared_tools: ToolItem[] }>(`${prefix}/tool_list`, query).then(({ tools, shared_tools }) => [...tools, ...shared_tools])

/** 获取工具分页列表。 */
const getToolPage = (page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<ToolItem>>(`${prefix}/${page.currentPage}/${page.pageSize}`, query)
Expand Down Expand Up @@ -57,6 +61,7 @@ const postToolTestConnection = (payload: ToolPayload) => {
}

export default {
getToolListWithShared,
getToolPage,
exportTool,
deleteTool,
Expand Down
72 changes: 72 additions & 0 deletions ui/src/api/admin/system/shared-resources/tool/tool-workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type LogicFlow from '@logicflow/core'
import { get, put, postStream } from '../../../core/request'
import type { ParamsPage, ResponsePage } from '../../../core/types'
import type {
DefaultModelSettingPayload,
Dict,
ToolExecutionRecord,
ToolExecutionRecordDetail,
ToolWorkflowDetail,
ToolWorkflowRecord,
WorkflowStoreTemplate,
WorkflowVersion,
WorkflowVersionPayload,
} from '@/api/types'
import { ADMIN_API_BASE_PATH } from '@/api/constants'

type ToolWorkflowPayload =
| { default_model_setting?: DefaultModelSettingPayload; work_flow: LogicFlow.GraphConfigData; work_flow_template?: never }
| { work_flow_template: WorkflowStoreTemplate; work_flow?: never }

const prefix = '/system/shared/tool'

/** 获取工具工作流详情。 */
const getToolWorkflow = (toolId: string) => {
return get<ToolWorkflowDetail>(`${prefix}/${toolId}/workflow`)
}

/** 保存工具工作流,或使用商店模板覆盖当前工作流。 */
const putToolWorkflow = (toolId: string, payload: ToolWorkflowPayload) => {
return put<ToolWorkflowPayload, ToolWorkflowDetail>(`${prefix}/${toolId}/workflow`, payload)
}

/** 发布工具工作流。 */
const putToolWorkflowPublish = (toolId: string) => {
return put<undefined, boolean>(`${prefix}/${toolId}/publish`)
}

/** 调试已保存的工具工作流,返回 SSE 响应。 */
const postToolWorkflowDebug = (toolId: string, parameters: Record<string, unknown>) =>
postStream(ADMIN_API_BASE_PATH, `${prefix}/${toolId}/debug`, parameters)

/** 查询工具工作流调试的输出和节点执行记录。 */
const getToolWorkflowRecord = (toolId: string, recordId: string) => get<ToolWorkflowRecord>(`${prefix}/${toolId}/tool_record/${recordId}`)

/** 获取工具发布历史,按发布时间倒序返回完整版本快照。 */
const getWorkflowVersions = (toolId: string) => get<WorkflowVersion[]>(`${prefix}/${toolId}/tool_version`)

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

/** 获取工具执行记录分页,按执行时间倒序返回。 */
const getToolExecutionRecordPage = (toolId: string, page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<ToolExecutionRecord>>(`${prefix}/${toolId}/tool_record/${page.currentPage}/${page.pageSize}`, query)
}

/** 获取工具执行记录的输入输出及节点详情。 */
const getToolExecutionRecordDetail = (toolId: string, recordId: string) => {
return get<ToolExecutionRecordDetail>(`${prefix}/${toolId}/tool_record/${recordId}`)
}

export default {
getToolExecutionRecordPage,
getToolExecutionRecordDetail,
getWorkflowVersions,
putWorkflowVersion,
getToolWorkflow,
putToolWorkflow,
putToolWorkflowPublish,
postToolWorkflowDebug,
getToolWorkflowRecord,
}
5 changes: 5 additions & 0 deletions ui/src/api/admin/system/shared-resources/tool/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import type { Dict, ToolDebugPayload, ToolItem, ToolPayload, ToolPylintIssue } f

const prefix = '/system/shared/tool'

/** 获取当前系统范围可用的工具选项。 */
const getToolListWithShared = (query?: Dict<unknown>) =>
get<{ tools: ToolItem[]; shared_tools: ToolItem[] }>(`${prefix}/tool_list`, query).then(({ tools, shared_tools }) => [...tools, ...shared_tools])

/** 获取工具分页列表。 */
const getToolPage = (page: ParamsPage, query?: Dict<unknown>) => {
return get<ResponsePage<ToolItem>>(`${prefix}/${page.currentPage}/${page.pageSize}`, query)
Expand Down Expand Up @@ -70,6 +74,7 @@ const postToolTestConnection = (payload: ToolPayload) => {
}

export default {
getToolListWithShared,
getToolPage,
exportTool,
deleteTool,
Expand Down
4 changes: 2 additions & 2 deletions ui/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ declare module 'vue' {
MkTable: typeof import('./components/global/mk-table/index.vue')['default']
MkTableFilter: typeof import('./components/global/mk-table/MkTableFilter.vue')['default']
MkTableMoreDropdown: typeof import('./components/global/mk-table/MkTableMoreDropdown.vue')['default']
MkTableOperationGroup: typeof import('./components/global/mk-table/MkTableOperationGroup.vue')['default']
MkTableOperationGroup: typeof import('./components/global/mk-action/MkTableOperationGroup.vue')['default']
MkTagGroup: typeof import('./components/global/mk-tag-group/index.vue')['default']
MkTooltip: typeof import('./components/global/mk-tooltip/index.vue')['default']
MkViewLayout: typeof import('./components/global/mk-view-layout/index.vue')['default']
Expand Down Expand Up @@ -86,7 +86,7 @@ declare global {
const MkTable: typeof import('./components/global/mk-table/index.vue')['default']
const MkTableFilter: typeof import('./components/global/mk-table/MkTableFilter.vue')['default']
const MkTableMoreDropdown: typeof import('./components/global/mk-table/MkTableMoreDropdown.vue')['default']
const MkTableOperationGroup: typeof import('./components/global/mk-table/MkTableOperationGroup.vue')['default']
const MkTableOperationGroup: typeof import('./components/global/mk-action/MkTableOperationGroup.vue')['default']
const MkTagGroup: typeof import('./components/global/mk-tag-group/index.vue')['default']
const MkTooltip: typeof import('./components/global/mk-tooltip/index.vue')['default']
const MkViewLayout: typeof import('./components/global/mk-view-layout/index.vue')['default']
Expand Down
1 change: 1 addition & 0 deletions ui/src/components/COMPONENT_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ Dialog、Drawer、Popover、嵌套区域等其他大、小表格均禁止开启

### MkTableOperationGroup、MkAction

`MkTableOperationGroup` 与 `MkAction`、`context.ts` 统一维护在 `global/mk-action/`。
表格操作列使用 `MkTableOperationGroup` 默认插槽声明操作,按模板顺序将前 `maxVisible` 个操作
(默认 2)显示为图标按钮,其余自动进入 More;没有剩余操作时不显示 More。
每个直接子组件代表一个操作,业务 Action 内使用 `MkAction` 作为展示入口。
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { Comment, Fragment, Text, computed, defineComponent, h, isVNode, provide, type PropType, type VNode } from 'vue'
import MkTableMoreDropdown from './MkTableMoreDropdown.vue'
import { actionContextKey, type ActionContext } from '../mk-action/context'
import MkTableMoreDropdown from '../mk-table/MkTableMoreDropdown.vue'
import { actionContextKey, type ActionContext } from './context'

/* 每个操作只挂载一次,由所在位置提供展示模式。 */
const ActionPlacement = defineComponent({
Expand Down
10 changes: 7 additions & 3 deletions ui/src/router/ROUTE_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,11 @@ Workspace 父路由为 `workspace-application-detail-layout`;System 详情实
`/system/resource/models`、`/system/resource/tools` 分别渲染
`views/system/resource-management/ModelResourceView.vue` 和 `ToolResourceView.vue`,
继承 `resourceScope: 'system-resource'`,保留原导航名称、顺序与权限。
资源管理工具的全屏工作流使用 `system-resource-tool-workflow`,地址为
`/system/resource/workspace/:workspaceId/tool/:toolId/workflow`,在 `admin/workflow/index.ts`
注册,复用 `ToolWorkflowView`。`workspaceId` 来自工具数据,用于画布辅助资源选择;
资源管理工具的全屏工作流使用 `system-resource-workflow-tool`,地址为
`/system/resource/tool/:toolId/workflow`,在 `admin/workflow/index.ts`
注册,复用 `ToolWorkflowView`。系统工作流路由不携带 `workspaceId`,画布辅助查询使用对应 System API;
工具自身的查询、编辑、调试和发布使用 System API,返回 `system-resource-tools`。

共享工具工作流使用 `system-shared-tool-workflow`,地址为 `/system/shared/tool/:toolId/workflow`,
与资源管理共用 `ToolWorkflowView`,通过 `resourceScope` 选择接口。共享工具卡片点击及创建成功后
进入该路由,Ctrl / Command 点击支持新标签页;退出返回 `system-shared-tools`。
6 changes: 3 additions & 3 deletions ui/src/router/admin/workflow/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ export const workflowRoutes: RouteRecordRaw[] = [
},

{
path: '/system/resource//tool/:toolId/workflow',
name: 'system-resource-tool-workflow',
path: '/system/resource/tool/:toolId/workflow',
name: 'system-resource-workflow-tool',
component: () => import('@/views/workflow/tool/ToolWorkflowView.vue'),
meta: { title: '工具工作流', resourceScope: 'system-resource' },
},
{
path: '/system/shared/tool/:toolId/workflow',
name: 'system-resource-tool-workflow',
name: 'system-shared-workflow-tool',
component: () => import('@/views/workflow/tool/ToolWorkflowView.vue'),
meta: { title: '工具工作流', resourceScope: 'system-shared' },
},
Expand Down
15 changes: 11 additions & 4 deletions ui/src/views/VIEW_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,8 +332,8 @@ src/views/system/shared-resources/
导出、删除 Action。列表使用 `MkInfiniteScroll` 分页加载,支持类型、名称和创建者筛选;
创建与删除后重新查询,编辑和启停成功后替换对应卡片数据。
`ButtonCreateTool` 可接收完整 `api`,默认使用 Workspace Tool API;`showWorkflow` 默认开启,
共享页关闭该入口,因为共享工作流画布尚未接入。共享页支持普通工具、Skills、MCP、数据源及
导入创建,已有工作流工具只编辑基础信息。共享页不组合工作空间专用的移动、授权和触发器入口。
共享页开启工作流创建,创建后进入 `system-shared-tool-workflow`。共享页支持普通工具、Skills、MCP、数据源及
导入创建,工作流卡片点击进入画布(支持 Ctrl / Command 新标签页),编辑菜单仍修改基础信息。共享页不组合工作空间专用的移动、授权和触发器入口。

System 用户页面按业务流程归拢操作入口和专属 Dialog。入口组件管理弹窗 Ref、打开动作并转发
`refresh`;列表页负责查询、批量选择和刷新策略,创建与编辑共用的 `UserFromDrawer` 仍由页面管理。
Expand Down Expand Up @@ -809,7 +809,11 @@ application、tool、knowledge 的 WorkflowView 统一使用一个 `loading` 控
保存后发送 `refresh`。共享模型页继续组合相同业务 Action,在卡片菜单中自动显示为菜单项。
资源管理删除保留页面专属确认、引用数量提示、加载状态和分页回退,通过 `MkAction` 展示,
不强行复用卡片的 `DeleteModelAction`。
工具操作列继续使用 `MkTableMoreDropdown`。
工具操作列同样使用 `MkTableOperationGroup`,按现有模板顺序和显隐条件外露前两个操作;
启停开关位于操作组外,不计入两个操作。商店工具改名、System 工作流跳转和带引用提示、
分页回退的删除继续由资源管理页维护,通过 `MkAction` 展示。
工具 `action-dropdown` 内的各操作统一使用 `MkAction`,Workspace 和共享工具卡片仍通过
`MkDropdownMenu` 自动显示菜单项,保留原有 API、权限条件、事件和浮层生命周期。
名称、类型、创建者(工具另含来源)筛选和工作空间表头筛选变化后回到第一页;分页大小变化由
`MkTable` 重置页码。工作空间列及选项查询只在企业版开启,`workspace_ids` 沿用 JSON 数组字符串。
页面使用 v3 的 System 权限方法保留迁移前已有的操作权限,不增加创建、导入、批量或复制入口。
Expand All @@ -820,7 +824,10 @@ MCP 配置、授权、导出、触发器和执行记录。页面显式传入对
商店工具只修改名称,不开放模板代码编辑;编辑与启停合并返回数据,保留列表中的工作空间等展示字段。
工具维护表单的 API 联合包含 System 资源对象,该范围没有 `postTool`,不通过伪造创建接口满足类型。

资源管理中的工作流进入 `system-resource-tool-workflow`,由 `ToolWorkflowView` 选择 System
资源管理中的工作流进入 `system-resource-workflow-tool`,由 `ToolWorkflowView` 选择 System
工具、工作流和模型 API,并把工作流 API 传给发布历史与调试抽屉;返回资源管理工具列表。
`TriggerToolAction` 和 `ResourceTriggerDialog` 透传可选 `toolApi`、`toolWorkflowApi`,
由 `TriggerFormDrawer` 查询当前资源的完整输入定义;未传时保持 Workspace 默认接口。

工具工作流按三种 `resourceScope` 选择完整工具、工作流与模型 API,并透传到默认模型、历史、调试抽屉。
System 两种工作流入口只传 `toolId`,不传路由工作空间;共享范围默认模型选项使用共享模型列表。
31 changes: 16 additions & 15 deletions ui/src/views/system/resource-management/ToolResourceView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ function handleToolUpdate(tool: ToolItem) {
}

function handleOpenWorkflow(tool: ToolItem, event: MouseEvent) {
const target = { name: 'system-resource-tool-workflow', params: { workspaceId: tool.workspace_id, toolId: tool.id } }
const target = { name: 'system-resource-workflow-tool', params: { toolId: tool.id } }
if (event.ctrlKey || event.metaKey) {
window.open(router.resolve(target).href)
return
Expand Down Expand Up @@ -213,9 +213,9 @@ onMounted(() => {
<el-table-column label="创建时间" width="180"
><template #default="{ row }">{{ datetimeFormat(row.create_time) }}</template></el-table-column
>
<el-table-column label="操作" width="110" fixed="right">
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<div class="flex-align-center">
<div class="flex-align-center gap-3">
<!-- 启用或禁用工具 -->
<ToolStatusSwitch
v-if="perm.tool.system.switch()"
Expand All @@ -224,12 +224,10 @@ onMounted(() => {
:tool="row"
@update="handleToolUpdate"
/>
<!-- 更多工具操作 -->
<MkTableMoreDropdown persistent>
<!-- 工具操作,前两个外露,其余进入更多菜单 -->
<MkTableOperationGroup>
<!-- 编辑商店工具名称 -->
<MkDropdownItem v-if="row.template_id && perm.tool.system.edit()" @click="handleOpenRename(row)"
><template #icon><MkIcon name="icon_edit_outlined" /></template>编辑</MkDropdownItem
>
<MkAction v-if="row.template_id && perm.tool.system.edit()" label="编辑" icon="icon_edit_outlined" @click="handleOpenRename(row)" />
<!-- 编辑工具配置 -->
<EditToolAction
v-if="!row.template_id && perm.tool.system.edit()"
Expand All @@ -239,9 +237,7 @@ onMounted(() => {
@update="handleToolUpdate"
/>
<!-- 打开工具工作流 -->
<MkDropdownItem v-if="row.tool_type === TOOL_TYPE.WORKFLOW" @click="handleOpenWorkflow(row, $event)"
><template #icon><MkIcon name="icon_setting" /></template>工作流</MkDropdownItem
>
<MkAction v-if="row.tool_type === TOOL_TYPE.WORKFLOW" label="工作流" icon="icon_setting" @click="handleOpenWorkflow(row, $event)" />
<!-- 配置启动参数 -->
<InitParamAction
v-if="row.init_field_list?.length && perm.tool.system.edit()"
Expand Down Expand Up @@ -288,10 +284,15 @@ onMounted(() => {
:tool="row"
/>
<!-- 删除工具 -->
<MkDropdownItem v-if="perm.tool.system.delete()" divided :disabled="operationLoading" @click="handleDeleteTool(row)"
><template #icon><MkIcon name="icon_delete-trash_outlined" /></template>删除</MkDropdownItem
>
</MkTableMoreDropdown>
<MkAction
v-if="perm.tool.system.delete()"
label="删除"
icon="icon_delete-trash_outlined"
divided
:disabled="operationLoading"
@click="handleDeleteTool(row)"
/>
</MkTableOperationGroup>
</div>
</template>
</el-table-column>
Expand Down
17 changes: 14 additions & 3 deletions ui/src/views/system/shared-resources/ToolSharedView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
import { computed, ref, useTemplateRef } from 'vue'
import { useRouter } from 'vue-router'
import SystemSharedToolApi from '@/api/admin/system/shared-resources/tool/tool'
import CommonSystemApi from '@/api/admin/system/common'
import type { ParamsPage } from '@/api/admin/core/types'
Expand All @@ -10,6 +11,8 @@ import ToolCard from '@/views/tool/tool-card/ToolCard.vue'
import ButtonCreateTool from '@/views/tool/components/ButtonCreateTool.vue'
import { DeleteToolAction, EditToolAction, ExportToolAction, InitParamAction, McpConfigAction } from '@/views/tool/tool-card/action-dropdown'

const router = useRouter()

/* 共享工具查询 */
const toolsData = ref<ToolItem[]>([])
const toolQuery = ref<Dict<unknown>>()
Expand Down Expand Up @@ -44,7 +47,15 @@ function handleSearchChange(query?: Dict<unknown>) {
const toolOperationLoading = ref(false)
const editToolActionRefs: Record<string, InstanceType<typeof EditToolAction> | null> = {}

function handleOpenTool(tool: ToolItem) {
function handleOpenTool(tool: ToolItem, event: MouseEvent) {
if (tool.tool_type === TOOL_TYPE.WORKFLOW) {
const target = { name: 'system-shared-tool-workflow', params: { toolId: tool.id } }
if (event.ctrlKey || event.metaKey) {
window.open(router.resolve(target).href)
return
}
return router.push(target)
}
editToolActionRefs[tool.id]?.handleOpenToolForm()
}

Expand All @@ -68,7 +79,7 @@ function handleToolUpdate(tool: ToolItem) {
<div class="flex-align-center gap-3">
<MkComplexSearch :fields="searchFields" @change="handleSearchChange" />
<!-- 创建共享工具 -->
<ButtonCreateTool :api="SystemSharedToolApi" folder-id="" :show-workflow="false" @refresh="refreshTools" />
<ButtonCreateTool :api="SystemSharedToolApi" folder-id="" @refresh="refreshTools" />
</div>
</component>
<div v-loading="toolOperationLoading" class="min-h-0 flex-1">
Expand All @@ -81,7 +92,7 @@ function handleToolUpdate(tool: ToolItem) {
:tool="tool"
:shared="true"
:store-tools="[]"
@click="handleOpenTool(tool)"
@click="handleOpenTool(tool, $event)"
@update="handleToolUpdate"
>
<template #action-dropdown>
Expand Down
Loading
Loading