skill-catalog.ts 1.9 KB

12345678910111213141516171819202122232425262728293031
  1. // 某个引擎可选的技能:Claude = 本地技能 + 已启用插件 + 第三方技能 + 自定义技能;Codex = Codex 实际可见的技能。
  2. // 后台的 Profile 编辑与工作组的能力卡片共用
  3. import { COMMUNITY_SKILL_PLUGIN, CUSTOM_SKILL_PLUGIN, type AppSettings, type ProviderId, type SkillInfo } from '@agent-server/shared'
  4. import type { CustomSkillService } from '../custom-skills/service'
  5. import { CodexProvider } from '../providers/codex/adapter'
  6. import type { AgentProvider } from '../providers/types'
  7. import type { CommunitySkillService } from './community-skills'
  8. import type { PluginService } from './plugins'
  9. export function createSkillCatalog(deps: {
  10. settings: () => AppSettings
  11. plugins: PluginService
  12. communitySkills: CommunitySkillService
  13. customSkills: CustomSkillService
  14. providers: Partial<Record<ProviderId, AgentProvider>>
  15. }) {
  16. return async (engine: ProviderId): Promise<SkillInfo[]> => {
  17. if (engine !== 'codex') return [...await deps.plugins.skills(), ...deps.communitySkills.skillInfos().map(s => ({ ...s, optIn: true })), ...deps.customSkills.skillInfos()]
  18. const codex = deps.providers.codex
  19. if (!(codex instanceof CodexProvider)) return []
  20. const infos = await codex.skillInfos(deps.settings()).catch(() => [])
  21. const excluded = new Set(deps.customSkills.excludedFromAll())
  22. return infos.map(s => {
  23. const [prefix] = s.id.split(':')
  24. const source = s.scope === 'system' ? 'system' : prefix === 'openai-skills' ? 'official' : prefix === 'codex-user' ? 'plugin'
  25. : prefix === COMMUNITY_SKILL_PLUGIN ? 'community' : prefix === CUSTOM_SKILL_PLUGIN ? 'custom' : 'local'
  26. const optIn = source === 'community' || (source === 'custom' && excluded.has(s.id))
  27. return { id: s.id, name: s.id.split(':').pop()!, description: s.description, plugin: prefix!, source, license: source === 'plugin' || source === 'system' ? 'unknown' : 'open', optIn }
  28. })
  29. }
  30. }