From 33e18e7e64f7c9db2e23cb63a1208f1675df421a Mon Sep 17 00:00:00 2001 From: Chrys <53332481+ChrAlpha@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:50:39 +0800 Subject: [PATCH] feat(skills): add effective skill resolution and actions (#377) * feat(skills): add effective skill resolution and actions * refactor(workspace): normalize skill-related env and prompt * chore(api): regenerate skills OpenAPI and SDK artifacts * feat(web): surface effective skill state in console * test(skills): cover API and runtime effective state * fix(web): show adopt action for discovered skills * fix(web): align skill header and show stateful visibility icon * refactor(web): compact skill metadata on narrow layouts * fix(web): constrain long skill text in cards * refactor(skills): narrow default discovery roots * fix(skills): harden managed skill path validation * feat: add path in the results of `use_skill` --------- Co-authored-by: Acbox --- apps/web/src/i18n/locales/en.json | 19 + apps/web/src/i18n/locales/zh.json | 19 + .../src/pages/bots/components/bot-skills.vue | 197 ++++- .../home/components/session-info-panel.vue | 34 +- cmd/agent/app.go | 5 + internal/agent/agent.go | 1 + internal/agent/prompt.go | 5 +- internal/agent/tools/skill.go | 1 + internal/agent/tools/skill_test.go | 42 + internal/agent/tools/types.go | 1 + internal/agent/types.go | 1 + internal/conversation/flow/resolver.go | 2 + internal/conversation/flow/skill_test.go | 18 + internal/handlers/containerd.go | 1 + internal/handlers/skills.go | 244 +++--- internal/handlers/skills_test.go | 728 +++++++++++++++++- internal/handlers/supermarket.go | 3 +- internal/skills/skills.go | 509 ++++++++++++ internal/skills/skills_test.go | 265 +++++++ internal/workspace/manager.go | 4 +- packages/sdk/src/@pinia/colada.gen.ts | 24 +- packages/sdk/src/index.ts | 4 +- packages/sdk/src/sdk.gen.ts | 20 +- packages/sdk/src/types.gen.ts | 52 ++ spec/docs.go | 87 ++- spec/swagger.json | 87 ++- spec/swagger.yaml | 59 +- 27 files changed, 2223 insertions(+), 209 deletions(-) create mode 100644 internal/agent/tools/skill_test.go create mode 100644 internal/conversation/flow/skill_test.go create mode 100644 internal/skills/skills.go create mode 100644 internal/skills/skills_test.go diff --git a/apps/web/src/i18n/locales/en.json b/apps/web/src/i18n/locales/en.json index 587fc97a..b5b211b4 100644 --- a/apps/web/src/i18n/locales/en.json +++ b/apps/web/src/i18n/locales/en.json @@ -1123,11 +1123,30 @@ "addSkill": "New Skill", "emptyTitle": "No Skills", "emptyDescription": "Click above to create a new skill", + "managedBadge": "Managed", + "discoveredBadge": "Discovered", + "effectiveBadge": "Effective", + "shadowedBadge": "Shadowed", + "disabledBadge": "Disabled", + "legacyBadge": "Legacy", + "compatBadge": "Compatible", "description": "Description", "descriptionPlaceholder": "Enter skill description", "content": "Content", "contentPlaceholder": "Enter skill content/prompt", "deleteConfirm": "Are you sure you want to delete this skill?", + "overrideTitle": "Edit to create a managed override", + "adoptAction": "Adopt into Memoh-managed skills", + "adoptBlocked": "A higher-priority skill already exists", + "disableAction": "Disable this skill source", + "enableAction": "Enable this skill source", + "adoptSuccess": "Skill adopted", + "adoptFailed": "Failed to adopt skill", + "disableSuccess": "Skill disabled", + "disableFailed": "Failed to disable skill", + "enableSuccess": "Skill enabled", + "enableFailed": "Failed to enable skill", + "shadowedBy": "Shadowed by:", "deleteSuccess": "Skill deleted", "deleteFailed": "Failed to delete skill", "saveSuccess": "Skill saved", diff --git a/apps/web/src/i18n/locales/zh.json b/apps/web/src/i18n/locales/zh.json index 2b99bce8..3840439b 100644 --- a/apps/web/src/i18n/locales/zh.json +++ b/apps/web/src/i18n/locales/zh.json @@ -1119,11 +1119,30 @@ "addSkill": "新建技能", "emptyTitle": "暂无技能", "emptyDescription": "点击上方按钮创建新技能", + "managedBadge": "托管", + "discoveredBadge": "发现", + "effectiveBadge": "生效中", + "shadowedBadge": "被覆盖", + "disabledBadge": "已禁用", + "legacyBadge": "旧版", + "compatBadge": "兼容", "description": "描述", "descriptionPlaceholder": "输入技能描述", "content": "内容", "contentPlaceholder": "输入技能内容/提示词", "deleteConfirm": "确定要删除这个技能吗?", + "overrideTitle": "编辑后将创建托管覆盖版本", + "adoptAction": "纳入 Memoh 托管", + "adoptBlocked": "已有更高优先级的技能副本", + "disableAction": "禁用这个技能来源", + "enableAction": "启用这个技能来源", + "adoptSuccess": "技能已纳入托管", + "adoptFailed": "纳入托管失败", + "disableSuccess": "技能已禁用", + "disableFailed": "禁用技能失败", + "enableSuccess": "技能已启用", + "enableFailed": "启用技能失败", + "shadowedBy": "被以下来源覆盖:", "deleteSuccess": "技能已删除", "deleteFailed": "删除技能失败", "saveSuccess": "技能已保存", diff --git a/apps/web/src/pages/bots/components/bot-skills.vue b/apps/web/src/pages/bots/components/bot-skills.vue index d1ee29ce..60ee6ed1 100644 --- a/apps/web/src/pages/bots/components/bot-skills.vue +++ b/apps/web/src/pages/bots/components/bot-skills.vue @@ -52,13 +52,13 @@ > - -
+ +
{{ skill.name }} @@ -68,14 +68,69 @@ variant="ghost" size="sm" class="size-8 p-0" - :title="$t('common.edit')" + :title="!skill.managed ? $t('bots.skills.overrideTitle') : $t('common.edit')" @click="handleEdit(skill)" > + + +
{{ skill.description || '-' }}
+ +
+ + {{ skill.managed ? $t('bots.skills.managedBadge') : $t('bots.skills.discoveredBadge') }} + + + {{ stateLabel(skill.state) }} + +
+

+ {{ $t('bots.skills.shadowedBy') }} {{ skill.shadowed_by }} +

+

+ {{ sourceSummary(skill) }} +

+
@@ -147,12 +234,12 @@