From 053a321ec1fd8fd23968ac9ca9cf81d82418a05a Mon Sep 17 00:00:00 2001 From: baiyanyun Date: Mon, 15 Jun 2026 10:51:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=B8=E6=94=B6=E6=95=B0=E5=AD=97=E5=91=98?= =?UTF-8?q?=E5=B7=A5=E7=AE=A1=E7=90=86=E7=AB=AF=E6=8A=80=E8=83=BD=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E6=9D=83=E9=99=90=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DigitalEmployeeAdminWorkbenchRowDto.java | 12 ++++++++++ ...talEmployeeSyncApplicationServiceImpl.java | 12 ++++++++++ ...mployeeSyncApplicationServiceImplTest.java | 16 ++++++++++++-- .../Content/DigitalEmployeeOps/index.tsx | 8 ++++++- qiming/src/types/interfaces/systemManage.ts | 6 +++++ .../scripts/check-digital-employee.js | 22 +++++++++++++++++++ ...ital-employee-frontend-integration-plan.md | 2 +- 7 files changed, 74 insertions(+), 4 deletions(-) diff --git a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/digital/DigitalEmployeeAdminWorkbenchRowDto.java b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/digital/DigitalEmployeeAdminWorkbenchRowDto.java index 0877e56c..5a82a5c8 100644 --- a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/digital/DigitalEmployeeAdminWorkbenchRowDto.java +++ b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-adapter/src/main/java/com/xspaceagi/agent/core/adapter/dto/digital/DigitalEmployeeAdminWorkbenchRowDto.java @@ -177,6 +177,18 @@ public class DigitalEmployeeAdminWorkbenchRowDto { private String policySource; @JsonProperty("policy_status") private String policyStatus; + @JsonProperty("skill_install_request_id") + private String skillInstallRequestId; + @JsonProperty("skill_upgrade_request_id") + private String skillUpgradeRequestId; + @JsonProperty("permission_policy_id") + private String permissionPolicyId; + @JsonProperty("install_action_disabled") + private Boolean installActionDisabled; + @JsonProperty("upgrade_action_disabled") + private Boolean upgradeActionDisabled; + @JsonProperty("permission_edit_disabled") + private Boolean permissionEditDisabled; @JsonProperty("tool_name") private String toolName; @JsonProperty("server_id") diff --git a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImpl.java b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImpl.java index 54630a99..83b678ff 100644 --- a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImpl.java +++ b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/main/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImpl.java @@ -1158,6 +1158,12 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye .permissionScope(firstString(businessView.get("permission_scope"), businessView.get("permissionScope"), payload.get("permission_scope"), payload.get("permissionScope"))) .policySource(firstString(businessView.get("policy_source"), businessView.get("policySource"), businessView.get("source"), payload.get("policy_source"), payload.get("policySource"), payload.get("source"))) .policyStatus(firstString(businessView.get("policy_status"), businessView.get("policyStatus"), payload.get("policy_status"), payload.get("policyStatus"))) + .skillInstallRequestId(firstString(businessView.get("skill_install_request_id"), businessView.get("skillInstallRequestId"), payload.get("skill_install_request_id"), payload.get("skillInstallRequestId"))) + .skillUpgradeRequestId(firstString(businessView.get("skill_upgrade_request_id"), businessView.get("skillUpgradeRequestId"), payload.get("skill_upgrade_request_id"), payload.get("skillUpgradeRequestId"))) + .permissionPolicyId(firstString(businessView.get("permission_policy_id"), businessView.get("permissionPolicyId"), payload.get("permission_policy_id"), payload.get("permissionPolicyId"))) + .installActionDisabled(nullableBooleanValue(firstPresent(businessView.get("install_action_disabled"), businessView.get("installActionDisabled"), payload.get("install_action_disabled"), payload.get("installActionDisabled")))) + .upgradeActionDisabled(nullableBooleanValue(firstPresent(businessView.get("upgrade_action_disabled"), businessView.get("upgradeActionDisabled"), payload.get("upgrade_action_disabled"), payload.get("upgradeActionDisabled")))) + .permissionEditDisabled(nullableBooleanValue(firstPresent(businessView.get("permission_edit_disabled"), businessView.get("permissionEditDisabled"), payload.get("permission_edit_disabled"), payload.get("permissionEditDisabled")))) .toolName(firstString(businessView.get("tool_name"), businessView.get("toolName"), payload.get("tool_name"), payload.get("toolName"))) .serverId(firstString(businessView.get("server_id"), businessView.get("serverId"), payload.get("server_id"), payload.get("serverId"))) .auditArchiveId(firstString(businessView.get("audit_archive_id"), businessView.get("auditArchiveId"), payload.get("audit_archive_id"), payload.get("auditArchiveId"))) @@ -1401,6 +1407,12 @@ public class DigitalEmployeeSyncApplicationServiceImpl implements DigitalEmploye || StringUtils.isNotBlank(row.getSkillVersion()) || StringUtils.isNotBlank(row.getInstallStatus()) || StringUtils.isNotBlank(row.getPermissionScope()) + || StringUtils.isNotBlank(row.getSkillInstallRequestId()) + || StringUtils.isNotBlank(row.getSkillUpgradeRequestId()) + || StringUtils.isNotBlank(row.getPermissionPolicyId()) + || row.getInstallActionDisabled() != null + || row.getUpgradeActionDisabled() != null + || row.getPermissionEditDisabled() != null || StringUtils.isNotBlank(row.getToolName()) || StringUtils.isNotBlank(row.getServerId()); } diff --git a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/test/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImplTest.java b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/test/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImplTest.java index 34573c28..4dcf6d26 100644 --- a/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/test/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImplTest.java +++ b/qiming-backend/app-platform-modules/app-platform-agent/app-platform-agent-core-application/src/test/java/com/xspaceagi/agent/core/application/service/DigitalEmployeeSyncApplicationServiceImplTest.java @@ -638,7 +638,9 @@ class DigitalEmployeeSyncApplicationServiceImplTest { "skill_version", "1.2.3", "install_status", "installed", "permission_scope", "browser.open,browser.screenshot", - "policy_source", "local" + "policy_source", "local", + "skill_install_request_id", "install-req-1", + "install_action_disabled", true ), Map.of("id", "event-skill-catalog-1", "kind", "skill_catalog_snapshot")), record("outbox-skill-policy", "event", "event-skill-policy-1", 101L, new Date(11_000), @@ -652,7 +654,11 @@ class DigitalEmployeeSyncApplicationServiceImplTest { "skill_version", "1.2.3", "policy_source", "remote", "policy_status", "disabled", - "permission_scope", "browser.open" + "permission_scope", "browser.open", + "skill_upgrade_request_id", "upgrade-req-1", + "permission_policy_id", "permission-policy-1", + "upgrade_action_disabled", true, + "permission_edit_disabled", true ), Map.of("id", "event-skill-policy-1", "kind", "skill_policy_snapshot")), record("outbox-notification", "notification", "notification-1", 101L, new Date(12_000), @@ -679,8 +685,14 @@ class DigitalEmployeeSyncApplicationServiceImplTest { assertThat(result.getRecords().get(0).getInstallStatus()).isEqualTo("installed"); assertThat(result.getRecords().get(0).getPermissionScope()).isEqualTo("browser.open,browser.screenshot"); assertThat(result.getRecords().get(0).getPolicySource()).isEqualTo("local"); + assertThat(result.getRecords().get(0).getSkillInstallRequestId()).isEqualTo("install-req-1"); + assertThat(result.getRecords().get(0).getInstallActionDisabled()).isTrue(); assertThat(result.getRecords().get(1).getPolicySource()).isEqualTo("remote"); assertThat(result.getRecords().get(1).getPolicyStatus()).isEqualTo("disabled"); + assertThat(result.getRecords().get(1).getSkillUpgradeRequestId()).isEqualTo("upgrade-req-1"); + assertThat(result.getRecords().get(1).getPermissionPolicyId()).isEqualTo("permission-policy-1"); + assertThat(result.getRecords().get(1).getUpgradeActionDisabled()).isTrue(); + assertThat(result.getRecords().get(1).getPermissionEditDisabled()).isTrue(); } @Test diff --git a/qiming/src/pages/SystemManagement/Content/DigitalEmployeeOps/index.tsx b/qiming/src/pages/SystemManagement/Content/DigitalEmployeeOps/index.tsx index c9da7310..d6e8feb7 100644 --- a/qiming/src/pages/SystemManagement/Content/DigitalEmployeeOps/index.tsx +++ b/qiming/src/pages/SystemManagement/Content/DigitalEmployeeOps/index.tsx @@ -1214,13 +1214,19 @@ const DigitalEmployeeOps: React.FC = () => { {detailRecord.skill_id || detailRecord.tool_name || detailRecord.category || '--'} {detailRecord.status && ` · ${detailRecord.status}`} {detailRecord.skill_version && ` · 版本 ${detailRecord.skill_version}`} + {detailRecord.skill_install_request_id && ` · 安装请求 ${detailRecord.skill_install_request_id}`} + {detailRecord.skill_upgrade_request_id && ` · 升级请求 ${detailRecord.skill_upgrade_request_id}`} {detailRecord.install_status && ` · 安装状态 ${detailRecord.install_status}`} {detailRecord.permission_scope && ` · 权限范围 ${detailRecord.permission_scope}`} + {detailRecord.permission_policy_id && ` · 权限策略 ${detailRecord.permission_policy_id}`} {detailRecord.policy_source && ` · 策略来源 ${detailRecord.policy_source}`} {detailRecord.policy_status && ` · 策略状态 ${detailRecord.policy_status}`} + {detailRecord.install_action_disabled && ' · 安装禁用'} + {detailRecord.upgrade_action_disabled && ' · 升级禁用'} + {detailRecord.permission_edit_disabled && ' · 权限编辑禁用'} {' '} - · 展示版本、安装状态、权限范围和策略来源,只消费调用审计和安全摘要,不安装技能、不变更权限范围。 + · 展示版本、安装/升级请求、安装状态、权限范围和策略来源,只消费调用审计和安全摘要,不安装技能、不变更权限范围。 )} diff --git a/qiming/src/types/interfaces/systemManage.ts b/qiming/src/types/interfaces/systemManage.ts index a1749a75..2f72d262 100644 --- a/qiming/src/types/interfaces/systemManage.ts +++ b/qiming/src/types/interfaces/systemManage.ts @@ -672,6 +672,12 @@ export interface DigitalEmployeeAdminWorkbenchRow { permission_scope?: string; policy_source?: string; policy_status?: string; + skill_install_request_id?: string; + skill_upgrade_request_id?: string; + permission_policy_id?: string; + install_action_disabled?: boolean; + upgrade_action_disabled?: boolean; + permission_edit_disabled?: boolean; tool_name?: string; server_id?: string; audit_archive_id?: string; diff --git a/qimingclaw/crates/agent-electron-client/scripts/check-digital-employee.js b/qimingclaw/crates/agent-electron-client/scripts/check-digital-employee.js index 27f7ae9b..77e4826c 100644 --- a/qimingclaw/crates/agent-electron-client/scripts/check-digital-employee.js +++ b/qimingclaw/crates/agent-electron-client/scripts/check-digital-employee.js @@ -1698,6 +1698,12 @@ function checkDigitalAdminMemorySkillWorkbench() { [dto, "install_status", "backend skill install status row field"], [dto, "permission_scope", "backend skill permission scope row field"], [dto, "policy_source", "backend skill policy source row field"], + [dto, "skill_install_request_id", "backend skill install request id row field"], + [dto, "skill_upgrade_request_id", "backend skill upgrade request id row field"], + [dto, "permission_policy_id", "backend skill permission policy id row field"], + [dto, "install_action_disabled", "backend skill install action disabled row field"], + [dto, "upgrade_action_disabled", "backend skill upgrade action disabled row field"], + [dto, "permission_edit_disabled", "backend skill permission edit disabled row field"], [dto, "tool_name", "backend tool name row field"], [dto, "server_id", "backend server id row field"], [test, "queryAdminWorkbenchMemoryGovernanceReturnsMemoryRowsOnly", "backend memory governance test"], @@ -1706,6 +1712,11 @@ function checkDigitalAdminMemorySkillWorkbench() { [test, "getMemoryPolicyId", "backend memory policy assertion"], [test, "queryAdminWorkbenchSkillAuditsReturnsSkillAndToolAuditRowsOnly", "backend skill audits test"], [test, "queryAdminWorkbenchSkillAuditsReturnsVersionPermissionAndPolicyRowsOnly", "backend skill version permission test"], + [test, "getSkillInstallRequestId", "backend skill install request assertion"], + [test, "getPermissionPolicyId", "backend skill permission policy assertion"], + [test, "getInstallActionDisabled", "backend skill install disabled assertion"], + [test, "getUpgradeActionDisabled", "backend skill upgrade disabled assertion"], + [test, "getPermissionEditDisabled", "backend skill permission edit disabled assertion"], [qimingTypes, "memory_governance", "qiming memory governance view type"], [qimingTypes, "merge_candidate_count", "qiming memory merge candidate count field"], [qimingTypes, "duplicate_memory_ids", "qiming duplicate memory ids field"], @@ -1715,9 +1726,19 @@ function checkDigitalAdminMemorySkillWorkbench() { [qimingTypes, "skill_audits", "qiming skill audits view type"], [qimingTypes, "skill_version", "qiming skill version field"], [qimingTypes, "permission_scope", "qiming skill permission scope field"], + [qimingTypes, "skill_install_request_id", "qiming skill install request field"], + [qimingTypes, "skill_upgrade_request_id", "qiming skill upgrade request field"], + [qimingTypes, "permission_policy_id", "qiming skill permission policy field"], + [qimingTypes, "install_action_disabled", "qiming skill install disabled field"], + [qimingTypes, "upgrade_action_disabled", "qiming skill upgrade disabled field"], + [qimingTypes, "permission_edit_disabled", "qiming skill permission edit disabled field"], [qimingOps, "记忆治理", "qiming memory governance tab"], [qimingOps, "记忆策略", "qiming memory policies tab"], [qimingOps, "技能审计", "qiming skill audits tab"], + [qimingOps, "安装请求", "qiming skill install request copy"], + [qimingOps, "升级请求", "qiming skill upgrade request copy"], + [qimingOps, "权限策略", "qiming skill permission policy copy"], + [qimingOps, "权限编辑禁用", "qiming skill permission edit safety copy"], [qimingOps, "权限范围", "qiming skill permission scope copy"], [qimingOps, "策略来源", "qiming skill policy source copy"], [qimingOps, "批量归档", "qiming memory archive action"], @@ -1731,6 +1752,7 @@ function checkDigitalAdminMemorySkillWorkbench() { [docs, "远端记忆策略预览", "docs memory policy absorption"], [docs, "正式管理端技能审计预览", "docs skill audit absorption"], [docs, "正式管理端技能版本权限预览", "docs skill version permission absorption"], + [docs, "正式管理端技能安装权限预览", "docs skill install permission absorption"], ]; const missing = requiredSnippets .filter(([content, snippet]) => !content.includes(snippet)) diff --git a/qimingclaw/docs/digital-employee-frontend-integration-plan.md b/qimingclaw/docs/digital-employee-frontend-integration-plan.md index 23e98a7b..d8fd4bb6 100644 --- a/qimingclaw/docs/digital-employee-frontend-integration-plan.md +++ b/qimingclaw/docs/digital-employee-frontend-integration-plan.md @@ -578,7 +578,7 @@ GET /api/digital-employee/approvals - 建议:先沉淀安全重启审计和人工确认体验,再评估更细粒度的服务恢复策略。 6. **技能生命周期与策略** - - 已吸收:ACP / MCP / GUI / file server 能力已投射到 Skill Catalog,技能库不再使用 demo fallback;Skill Library 启用/禁用已写入 qimingclaw 本地 `digital_employee_skill_policies_v1.local_skills`,管理端下发策略写入 `remote_skills`,远端禁用优先生效且不会被本地按钮覆盖;入口路由候选技能会按有效策略过滤;MCP 注入 Agent 前会应用有效技能策略,ACP permission / tool update 会写入 `skill_call_allowed` / `skill_call_rejected` / `skill_call_observed` 审计事件,`policy_snapshot` 会包含本地/远端策略命中字段;embedded 已提供 `/api/digital-employee/skill-call-audits` 只读投影、`POST /api/skill/policies/pull` 手动拉取入口,技能调用策略与审计已开始闭环。管理端调用审计视图已开始吸收,embedded 新增“技能审计”入口,将 skill call audit、tool_call_audit、sandbox_audit 和 token_cost 统一成可筛选列表,技能库可按 skill id 跳转聚焦。正式管理端技能审计预览已开始吸收,qiming-backend 新增 `skill_audits` 运营台视图聚合 skill call、tool、sandbox 和 token/cost 安全摘要,qiming“数字员工运营台”的“技能审计”tab 只开放标记复核和忽略意图,不安装技能、不变更权限范围。正式管理端技能版本权限预览已开始吸收,`skill_audits` 继续聚合 skill catalog / skill policy snapshot,qiming 详情可展示技能版本、安装状态、权限范围、策略来源和策略状态,用于解释权限命中但不开放安装或权限编辑。 + - 已吸收:ACP / MCP / GUI / file server 能力已投射到 Skill Catalog,技能库不再使用 demo fallback;Skill Library 启用/禁用已写入 qimingclaw 本地 `digital_employee_skill_policies_v1.local_skills`,管理端下发策略写入 `remote_skills`,远端禁用优先生效且不会被本地按钮覆盖;入口路由候选技能会按有效策略过滤;MCP 注入 Agent 前会应用有效技能策略,ACP permission / tool update 会写入 `skill_call_allowed` / `skill_call_rejected` / `skill_call_observed` 审计事件,`policy_snapshot` 会包含本地/远端策略命中字段;embedded 已提供 `/api/digital-employee/skill-call-audits` 只读投影、`POST /api/skill/policies/pull` 手动拉取入口,技能调用策略与审计已开始闭环。管理端调用审计视图已开始吸收,embedded 新增“技能审计”入口,将 skill call audit、tool_call_audit、sandbox_audit 和 token_cost 统一成可筛选列表,技能库可按 skill id 跳转聚焦。正式管理端技能审计预览已开始吸收,qiming-backend 新增 `skill_audits` 运营台视图聚合 skill call、tool、sandbox 和 token/cost 安全摘要,qiming“数字员工运营台”的“技能审计”tab 只开放标记复核和忽略意图,不安装技能、不变更权限范围。正式管理端技能版本权限预览已开始吸收,`skill_audits` 继续聚合 skill catalog / skill policy snapshot,qiming 详情可展示技能版本、安装状态、权限范围、策略来源和策略状态,用于解释权限命中但不开放安装或权限编辑。正式管理端技能安装权限预览已开始吸收,`skill_audits` 继续展示安装请求、升级请求、权限策略和安装/升级/权限编辑禁用状态,只做安全壳提示和审计解释,不执行技能安装、升级或远程权限编辑。 - 缺口:仍缺少真实技能安装、版本升级管理和细粒度权限范围编辑。 - 建议:下一轮围绕管理端审计消费、技能安装和权限范围,把本地调用审计推进到更完整的跨端治理闭环。