@huyooo/ai-chat-core 0.2.44 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/dist/adapter/index.d.ts +11 -0
  2. package/dist/adapter/index.d.ts.map +1 -0
  3. package/dist/adapter/model-adapter.d.ts +25 -0
  4. package/dist/adapter/model-adapter.d.ts.map +1 -0
  5. package/dist/adapter/model-options.d.ts +53 -0
  6. package/dist/adapter/model-options.d.ts.map +1 -0
  7. package/dist/adapter/types.d.ts +28 -0
  8. package/dist/adapter/types.d.ts.map +1 -0
  9. package/dist/chat-runtime.d.ts +96 -0
  10. package/dist/chat-runtime.d.ts.map +1 -0
  11. package/dist/constants.d.ts +12 -0
  12. package/dist/constants.d.ts.map +1 -0
  13. package/dist/events.d.ts +605 -1
  14. package/dist/events.d.ts.map +1 -0
  15. package/dist/events.js +1 -1
  16. package/dist/extension/index.d.ts +9 -0
  17. package/dist/extension/index.d.ts.map +1 -0
  18. package/dist/extension/types.d.ts +46 -0
  19. package/dist/extension/types.d.ts.map +1 -0
  20. package/dist/families/index.d.ts +11 -0
  21. package/dist/families/index.d.ts.map +1 -0
  22. package/dist/families/presets.d.ts +31 -0
  23. package/dist/families/presets.d.ts.map +1 -0
  24. package/dist/families/resolver.d.ts +11 -0
  25. package/dist/families/resolver.d.ts.map +1 -0
  26. package/dist/families/types.d.ts +29 -0
  27. package/dist/families/types.d.ts.map +1 -0
  28. package/dist/governance/command-safety.d.ts +34 -0
  29. package/dist/governance/command-safety.d.ts.map +1 -0
  30. package/dist/governance/governance.d.ts +19 -0
  31. package/dist/governance/governance.d.ts.map +1 -0
  32. package/dist/governance/index.d.ts +12 -0
  33. package/dist/governance/index.d.ts.map +1 -0
  34. package/dist/governance/types.d.ts +29 -0
  35. package/dist/governance/types.d.ts.map +1 -0
  36. package/dist/index.d.ts +72 -804
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +51 -1
  39. package/dist/internal/management-args.d.ts +13 -0
  40. package/dist/internal/management-args.d.ts.map +1 -0
  41. package/dist/internal/management-results.d.ts +21 -0
  42. package/dist/internal/management-results.d.ts.map +1 -0
  43. package/dist/llm-config.d.ts +108 -0
  44. package/dist/llm-config.d.ts.map +1 -0
  45. package/dist/logger/core.d.ts +31 -0
  46. package/dist/logger/core.d.ts.map +1 -0
  47. package/dist/logger/index.d.ts +9 -0
  48. package/dist/logger/index.d.ts.map +1 -0
  49. package/dist/orchestrator/compression-handler.d.ts +29 -0
  50. package/dist/orchestrator/compression-handler.d.ts.map +1 -0
  51. package/dist/orchestrator/context-compressor.d.ts +51 -0
  52. package/dist/orchestrator/context-compressor.d.ts.map +1 -0
  53. package/dist/orchestrator/context-summarizer.d.ts +41 -0
  54. package/dist/orchestrator/context-summarizer.d.ts.map +1 -0
  55. package/dist/orchestrator/index.d.ts +12 -0
  56. package/dist/orchestrator/index.d.ts.map +1 -0
  57. package/dist/orchestrator/orchestrator.d.ts +46 -0
  58. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  59. package/dist/orchestrator/types.d.ts +58 -0
  60. package/dist/orchestrator/types.d.ts.map +1 -0
  61. package/dist/parts/index.d.ts +13 -0
  62. package/dist/parts/index.d.ts.map +1 -0
  63. package/dist/parts/registry.d.ts +11 -0
  64. package/dist/parts/registry.d.ts.map +1 -0
  65. package/dist/parts/summaries.d.ts +9 -0
  66. package/dist/parts/summaries.d.ts.map +1 -0
  67. package/dist/parts/types.d.ts +61 -0
  68. package/dist/parts/types.d.ts.map +1 -0
  69. package/dist/platform.d.ts +17 -0
  70. package/dist/platform.d.ts.map +1 -0
  71. package/dist/platform.js +1 -0
  72. package/dist/protocols/anthropic.d.ts +20 -0
  73. package/dist/protocols/anthropic.d.ts.map +1 -0
  74. package/dist/protocols/ark.d.ts +36 -0
  75. package/dist/protocols/ark.d.ts.map +1 -0
  76. package/dist/protocols/deepseek.d.ts +24 -0
  77. package/dist/protocols/deepseek.d.ts.map +1 -0
  78. package/dist/protocols/error-utils.d.ts +14 -0
  79. package/dist/protocols/error-utils.d.ts.map +1 -0
  80. package/dist/protocols/gemini.d.ts +24 -0
  81. package/dist/protocols/gemini.d.ts.map +1 -0
  82. package/dist/protocols/glm.d.ts +20 -0
  83. package/dist/protocols/glm.d.ts.map +1 -0
  84. package/dist/protocols/grok.d.ts +20 -0
  85. package/dist/protocols/grok.d.ts.map +1 -0
  86. package/dist/protocols/index.d.ts +31 -0
  87. package/dist/protocols/index.d.ts.map +1 -0
  88. package/dist/protocols/minimax.d.ts +38 -0
  89. package/dist/protocols/minimax.d.ts.map +1 -0
  90. package/dist/protocols/moonshot.d.ts +20 -0
  91. package/dist/protocols/moonshot.d.ts.map +1 -0
  92. package/dist/protocols/openai-sse.d.ts +33 -0
  93. package/dist/protocols/openai-sse.d.ts.map +1 -0
  94. package/dist/protocols/openai.d.ts +19 -0
  95. package/dist/protocols/openai.d.ts.map +1 -0
  96. package/dist/protocols/qwen.d.ts +26 -0
  97. package/dist/protocols/qwen.d.ts.map +1 -0
  98. package/dist/protocols/responses-sse.d.ts +30 -0
  99. package/dist/protocols/responses-sse.d.ts.map +1 -0
  100. package/dist/protocols/sse-reader.d.ts +23 -0
  101. package/dist/protocols/sse-reader.d.ts.map +1 -0
  102. package/dist/protocols/tool-arguments.d.ts +8 -0
  103. package/dist/protocols/tool-arguments.d.ts.map +1 -0
  104. package/dist/protocols/types.d.ts +148 -0
  105. package/dist/protocols/types.d.ts.map +1 -0
  106. package/dist/protocols/vercel-gateway.d.ts +15 -0
  107. package/dist/protocols/vercel-gateway.d.ts.map +1 -0
  108. package/dist/runtime.d.ts +151 -0
  109. package/dist/runtime.d.ts.map +1 -0
  110. package/dist/runtime.js +1 -0
  111. package/dist/skills/index.d.ts +14 -0
  112. package/dist/skills/index.d.ts.map +1 -0
  113. package/dist/skills/management/admin.d.ts +10 -0
  114. package/dist/skills/management/admin.d.ts.map +1 -0
  115. package/dist/skills/management/index.d.ts +11 -0
  116. package/dist/skills/management/index.d.ts.map +1 -0
  117. package/dist/skills/management/inputs.d.ts +44 -0
  118. package/dist/skills/management/inputs.d.ts.map +1 -0
  119. package/dist/skills/management/operations.d.ts +78 -0
  120. package/dist/skills/management/operations.d.ts.map +1 -0
  121. package/dist/skills/management/types.d.ts +70 -0
  122. package/dist/skills/management/types.d.ts.map +1 -0
  123. package/dist/skills/registry.d.ts +37 -0
  124. package/dist/skills/registry.d.ts.map +1 -0
  125. package/dist/skills/summaries.d.ts +9 -0
  126. package/dist/skills/summaries.d.ts.map +1 -0
  127. package/dist/skills/types.d.ts +61 -0
  128. package/dist/skills/types.d.ts.map +1 -0
  129. package/dist/test-utils/mock-sse.d.ts +13 -0
  130. package/dist/test-utils/mock-sse.d.ts.map +1 -0
  131. package/dist/tool-manager/define-tool.d.ts +35 -0
  132. package/dist/tool-manager/define-tool.d.ts.map +1 -0
  133. package/dist/tool-manager/formats.d.ts +46 -0
  134. package/dist/tool-manager/formats.d.ts.map +1 -0
  135. package/dist/tool-manager/identity.d.ts +18 -0
  136. package/dist/tool-manager/identity.d.ts.map +1 -0
  137. package/dist/tool-manager/in-process-provider.d.ts +15 -0
  138. package/dist/tool-manager/in-process-provider.d.ts.map +1 -0
  139. package/dist/tool-manager/index.d.ts +18 -0
  140. package/dist/tool-manager/index.d.ts.map +1 -0
  141. package/dist/tool-manager/manager.d.ts +18 -0
  142. package/dist/tool-manager/manager.d.ts.map +1 -0
  143. package/dist/tool-manager/mcp-provider.d.ts +21 -0
  144. package/dist/tool-manager/mcp-provider.d.ts.map +1 -0
  145. package/dist/tool-manager/summaries.d.ts +39 -0
  146. package/dist/tool-manager/summaries.d.ts.map +1 -0
  147. package/dist/tool-manager/types.d.ts +314 -0
  148. package/dist/tool-manager/types.d.ts.map +1 -0
  149. package/dist/types.d.ts +663 -0
  150. package/dist/types.d.ts.map +1 -0
  151. package/package.json +26 -15
  152. package/src/adapter/index.ts +25 -0
  153. package/src/adapter/model-adapter.ts +196 -0
  154. package/src/adapter/model-options.ts +143 -0
  155. package/src/adapter/types.ts +41 -0
  156. package/src/chat-runtime.ts +515 -0
  157. package/src/constants.ts +9 -102
  158. package/src/events.ts +364 -150
  159. package/src/extension/index.ts +24 -0
  160. package/src/extension/types.ts +49 -0
  161. package/src/families/index.ts +28 -0
  162. package/src/families/presets.ts +124 -0
  163. package/src/families/resolver.ts +22 -0
  164. package/src/families/types.ts +55 -0
  165. package/src/governance/command-safety.ts +224 -0
  166. package/src/governance/governance.ts +125 -0
  167. package/src/governance/index.ts +38 -0
  168. package/src/governance/types.ts +44 -0
  169. package/src/index.ts +250 -145
  170. package/src/internal/management-args.ts +39 -0
  171. package/src/internal/management-results.ts +60 -0
  172. package/src/llm-config.ts +137 -0
  173. package/src/logger/core.ts +96 -0
  174. package/src/logger/index.ts +8 -0
  175. package/src/orchestrator/compression-handler.ts +137 -0
  176. package/src/{providers → orchestrator}/context-compressor.ts +79 -47
  177. package/src/orchestrator/context-summarizer.ts +123 -0
  178. package/src/orchestrator/index.ts +20 -0
  179. package/src/orchestrator/orchestrator.ts +1002 -0
  180. package/src/orchestrator/types.ts +70 -0
  181. package/src/parts/index.ts +20 -0
  182. package/src/parts/registry.ts +95 -0
  183. package/src/parts/summaries.ts +40 -0
  184. package/src/parts/types.ts +63 -0
  185. package/src/platform.ts +73 -0
  186. package/src/protocols/anthropic.ts +377 -0
  187. package/src/protocols/ark.ts +300 -0
  188. package/src/protocols/deepseek.ts +192 -0
  189. package/src/{providers/protocols → protocols}/error-utils.ts +17 -20
  190. package/src/protocols/gemini.ts +352 -0
  191. package/src/protocols/glm.ts +212 -0
  192. package/src/protocols/grok.ts +98 -0
  193. package/src/protocols/index.ts +48 -0
  194. package/src/protocols/minimax.ts +308 -0
  195. package/src/protocols/moonshot.ts +186 -0
  196. package/src/protocols/openai-sse.ts +156 -0
  197. package/src/protocols/openai.ts +97 -0
  198. package/src/protocols/qwen.ts +358 -0
  199. package/src/protocols/responses-sse.ts +224 -0
  200. package/src/protocols/sse-reader.ts +54 -0
  201. package/src/protocols/tool-arguments.ts +32 -0
  202. package/src/{providers/protocols → protocols}/types.ts +46 -37
  203. package/src/protocols/vercel-gateway.ts +391 -0
  204. package/src/runtime.ts +167 -0
  205. package/src/skills/index.ts +29 -0
  206. package/src/skills/management/admin.ts +170 -0
  207. package/src/skills/management/index.ts +27 -0
  208. package/src/skills/management/inputs.ts +79 -0
  209. package/src/skills/management/operations.ts +256 -0
  210. package/src/skills/management/types.ts +57 -0
  211. package/src/skills/registry.ts +120 -0
  212. package/src/skills/summaries.ts +48 -0
  213. package/src/skills/types.ts +65 -0
  214. package/src/test-utils/mock-sse.ts +3 -3
  215. package/src/tool-manager/define-tool.ts +201 -0
  216. package/src/tool-manager/formats.ts +146 -0
  217. package/src/tool-manager/identity.ts +80 -0
  218. package/src/tool-manager/in-process-provider.ts +164 -0
  219. package/src/tool-manager/index.ts +63 -0
  220. package/src/tool-manager/manager.ts +562 -0
  221. package/src/tool-manager/mcp-provider.ts +509 -0
  222. package/src/tool-manager/summaries.ts +136 -0
  223. package/src/tool-manager/types.ts +389 -0
  224. package/src/types.ts +750 -191
  225. package/dist/events-CU5D5ray.d.ts +0 -1128
  226. package/src/agent.ts +0 -409
  227. package/src/internal/update-plan.ts +0 -2
  228. package/src/internal/web-search.ts +0 -77
  229. package/src/mcp/client-manager.ts +0 -302
  230. package/src/mcp/index.ts +0 -2
  231. package/src/mcp/types.ts +0 -43
  232. package/src/providers/context-summarizer.ts +0 -70
  233. package/src/providers/index.ts +0 -125
  234. package/src/providers/model-registry.ts +0 -466
  235. package/src/providers/orchestrator.ts +0 -839
  236. package/src/providers/protocols/anthropic.ts +0 -406
  237. package/src/providers/protocols/ark.ts +0 -362
  238. package/src/providers/protocols/deepseek.ts +0 -344
  239. package/src/providers/protocols/gemini.ts +0 -350
  240. package/src/providers/protocols/index.ts +0 -36
  241. package/src/providers/protocols/openai.ts +0 -420
  242. package/src/providers/protocols/qwen.ts +0 -315
  243. package/src/providers/types.ts +0 -264
  244. package/src/providers/unified-adapter.ts +0 -367
  245. package/src/router.ts +0 -72
  246. package/src/tools.ts +0 -162
  247. package/src/utils.ts +0 -86
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Skill 管理核心业务逻辑
3
+ *
4
+ * - create / list / inspect / enable / delete 等与 registry、宿主回调协作
5
+ * - 统一返回 management-results 形状
6
+ */
7
+
8
+ import type { SkillMeta } from '../types';
9
+ import type { AssetSource } from '../../governance/types';
10
+ import { splitCommaSeparatedStrings } from '../../internal/management-args';
11
+ import {
12
+ createActionResult,
13
+ createCollectionResult,
14
+ createInspectResult,
15
+ createToggleResult,
16
+ } from '../../internal/management-results';
17
+ import { createManagedSkillDetail, createManagedSkillSummary } from '../summaries';
18
+ import type { ManagedSkillSummary } from '../types';
19
+ import type { SkillOperationContext } from './types';
20
+
21
+ interface CreateSkillInput {
22
+ id: string;
23
+ name: string;
24
+ description: string;
25
+ instructions: string;
26
+ category: string;
27
+ tags: string[];
28
+ icon: string;
29
+ }
30
+
31
+ interface UpdateSkillInput extends CreateSkillInput {}
32
+
33
+ interface SkillEnableItem {
34
+ id: string;
35
+ enabled: boolean;
36
+ }
37
+
38
+ function createUserSkillMeta(input: CreateSkillInput): SkillMeta {
39
+ return {
40
+ id: input.id,
41
+ name: input.name,
42
+ description: input.description,
43
+ category: input.category,
44
+ tags: input.tags,
45
+ icon: input.icon,
46
+ source: 'user',
47
+ enabled: true,
48
+ references: [],
49
+ scripts: [],
50
+ };
51
+ }
52
+
53
+ function ensureMutableUserSkill(
54
+ ctx: SkillOperationContext,
55
+ id: string,
56
+ action: '更新' | '删除',
57
+ ): { meta?: SkillMeta; error?: string } {
58
+ const meta = ctx.registry.get(id);
59
+ if (!meta) {
60
+ return {
61
+ error: `技能 "${id}" 不存在${action === '更新' ? '。如需新建,请使用 skill_create。' : ''}`,
62
+ };
63
+ }
64
+
65
+ if (meta.source !== 'user') {
66
+ return { error: `技能 "${id}" 是 ${meta.source} 技能,仅可${action} user 来源的技能` };
67
+ }
68
+
69
+ return { meta };
70
+ }
71
+
72
+ export function searchManagedSkills(
73
+ ctx: SkillOperationContext,
74
+ input: {
75
+ keyword?: string;
76
+ category?: string;
77
+ tags?: string;
78
+ source?: AssetSource;
79
+ },
80
+ ) {
81
+ const results = ctx.registry.search({
82
+ keyword: input.keyword,
83
+ category: input.category,
84
+ tags: splitCommaSeparatedStrings(input.tags),
85
+ source: input.source,
86
+ });
87
+
88
+ if (results.length === 0) {
89
+ return createCollectionResult('skills', [], {
90
+ found: 0,
91
+ hint: '没有匹配的技能。尝试更宽泛的关键词,或省略过滤条件。',
92
+ categories: ctx.registry.categories(),
93
+ });
94
+ }
95
+
96
+ return createCollectionResult('skills', results.map(skill => createManagedSkillSummary(skill)), {
97
+ found: results.length,
98
+ });
99
+ }
100
+
101
+ export function listManagedSkills(ctx: SkillOperationContext) {
102
+ const enabled = ctx.registry.listEnabled();
103
+ return createCollectionResult('skills', enabled.map(skill => createManagedSkillSummary(skill)));
104
+ }
105
+
106
+ export async function createManagedSkill(
107
+ ctx: SkillOperationContext,
108
+ input: CreateSkillInput,
109
+ ) {
110
+ if (!ctx.onSkillCreate) {
111
+ return { error: '当前环境未配置技能持久化,无法创建技能' };
112
+ }
113
+
114
+ if (ctx.registry.has(input.id)) {
115
+ return { error: `技能 "${input.id}" 已存在。如需更新,请使用 skill_update。` };
116
+ }
117
+
118
+ const result = await ctx.onSkillCreate(input);
119
+ if ('error' in result) {
120
+ return { error: result.error };
121
+ }
122
+
123
+ const createdMeta = ctx.registry.get(input.id) ?? createUserSkillMeta(input);
124
+ ctx.registry.add(createdMeta);
125
+ await ctx.onSkillSetEnabled(input.id, true);
126
+ const enabledMeta = ctx.registry.get(input.id) ?? { ...createdMeta, enabled: true };
127
+
128
+ return createActionResult('created', 'skill', createManagedSkillSummary(enabledMeta), {
129
+ message: `技能 "${input.name}" 已创建并启用,将在下次对话中生效`,
130
+ });
131
+ }
132
+
133
+ export async function updateManagedSkill(
134
+ ctx: SkillOperationContext,
135
+ input: UpdateSkillInput,
136
+ ) {
137
+ if (!ctx.onSkillUpdate) {
138
+ return { error: '当前环境未配置技能持久化,无法更新技能' };
139
+ }
140
+
141
+ const validation = ensureMutableUserSkill(ctx, input.id, '更新');
142
+ if (validation.error) return { error: validation.error };
143
+
144
+ const meta = validation.meta!;
145
+ const nextMeta: SkillMeta = {
146
+ ...meta,
147
+ name: input.name,
148
+ description: input.description,
149
+ category: input.category || meta.category,
150
+ tags: input.tags,
151
+ icon: input.icon,
152
+ };
153
+
154
+ const result = await ctx.onSkillUpdate({
155
+ id: input.id,
156
+ name: nextMeta.name,
157
+ description: nextMeta.description,
158
+ instructions: input.instructions,
159
+ category: nextMeta.category,
160
+ tags: nextMeta.tags,
161
+ icon: nextMeta.icon,
162
+ });
163
+ if ('error' in result) {
164
+ return { error: result.error };
165
+ }
166
+
167
+ ctx.registry.add(nextMeta);
168
+
169
+ return createActionResult('updated', 'skill', createManagedSkillSummary(nextMeta), {
170
+ enabled: meta.enabled,
171
+ message: `技能 "${nextMeta.name}" 已更新${meta.enabled ? ',将在下次对话中生效' : ''}`,
172
+ });
173
+ }
174
+
175
+ export async function setManagedSkillsEnabled(
176
+ ctx: SkillOperationContext,
177
+ items: SkillEnableItem[],
178
+ ) {
179
+ if (items.length === 0) {
180
+ return { error: '请传入至少一个技能' };
181
+ }
182
+
183
+ const results: Array<{ id: string; enabled: boolean; error?: string; skill?: ManagedSkillSummary }> = [];
184
+ for (const item of items) {
185
+ if (!ctx.registry.has(item.id)) {
186
+ results.push({ id: item.id, enabled: false, error: `技能不存在: ${item.id}` });
187
+ continue;
188
+ }
189
+
190
+ ctx.registry.setEnabled(item.id, item.enabled);
191
+ await ctx.onSkillSetEnabled(item.id, item.enabled);
192
+ const meta = ctx.registry.get(item.id);
193
+ results.push({
194
+ id: item.id,
195
+ enabled: item.enabled,
196
+ skill: meta ? createManagedSkillSummary(meta) : undefined,
197
+ });
198
+ }
199
+
200
+ const updatedCount = results.filter(result => !result.error).length;
201
+ return createToggleResult(results, {
202
+ message: `已更新 ${updatedCount} 个技能的状态`,
203
+ });
204
+ }
205
+
206
+ export async function deleteManagedSkill(
207
+ ctx: SkillOperationContext,
208
+ id: string,
209
+ ) {
210
+ if (!ctx.onSkillDelete) {
211
+ return { error: '当前环境未配置技能持久化,无法删除技能' };
212
+ }
213
+
214
+ const validation = ensureMutableUserSkill(ctx, id, '删除');
215
+ if (validation.error) return { error: validation.error };
216
+
217
+ const meta = validation.meta!;
218
+ const result = await ctx.onSkillDelete(id);
219
+ if (!result.ok) {
220
+ return { error: result.error ?? '删除失败' };
221
+ }
222
+
223
+ ctx.registry.remove(id);
224
+
225
+ return createActionResult('deleted', 'skill', createManagedSkillSummary(meta), {
226
+ message: `技能 "${meta.name}" 已彻底删除`,
227
+ });
228
+ }
229
+
230
+ export async function inspectManagedSkill(
231
+ ctx: SkillOperationContext,
232
+ id: string,
233
+ ) {
234
+ const meta = ctx.registry.get(id);
235
+ if (!meta) {
236
+ return { error: `技能 "${id}" 不存在` };
237
+ }
238
+
239
+ const content = await ctx.onSkillLoadContent(id);
240
+ if ('error' in content) {
241
+ return createInspectResult('skill', createManagedSkillDetail(meta, {
242
+ instructionsError: content.error,
243
+ }));
244
+ }
245
+
246
+ return createInspectResult('skill', createManagedSkillDetail(meta, {
247
+ instructions: content.instructions,
248
+ }));
249
+ }
250
+
251
+ export async function loadManagedSkillReference(
252
+ ctx: SkillOperationContext,
253
+ input: { id: string; referenceName: string },
254
+ ) {
255
+ return ctx.onSkillLoadReference(input.id, input.referenceName);
256
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Skill 管理层类型
3
+ *
4
+ * - 宿主回调:创建/更新/删除/启用、加载 SKILL.md 正文与参考文档
5
+ * - Admin / operations 上下文接口
6
+ */
7
+
8
+ import type { SkillRegistry } from '../registry';
9
+
10
+ /** 技能创建回调 */
11
+ export type OnSkillCreate = (params: {
12
+ id: string;
13
+ name: string;
14
+ description: string;
15
+ instructions: string;
16
+ category: string;
17
+ tags: string[];
18
+ icon: string;
19
+ }) => Promise<{ ok: boolean } | { error: string }>;
20
+
21
+ /** 技能更新回调:宿主覆盖 SKILL.md 内容 */
22
+ export type OnSkillUpdate = (params: {
23
+ id: string;
24
+ name: string;
25
+ description: string;
26
+ instructions: string;
27
+ category: string;
28
+ tags: string[];
29
+ icon: string;
30
+ }) => Promise<{ ok: boolean } | { error: string }>;
31
+
32
+ /** 技能删除回调 */
33
+ export type OnSkillDelete = (id: string) => Promise<{ ok: boolean; error?: string }>;
34
+
35
+ /** 技能启用状态变更回调(宿主持久化) */
36
+ export type OnSkillSetEnabled = (id: string, enabled: boolean) => Promise<void>;
37
+
38
+ /** 加载技能内容(SKILL.md body) */
39
+ export type OnSkillLoadContent = (id: string) => Promise<{ name: string; instructions: string } | { error: string }>;
40
+
41
+ /** 加载技能参考文档 */
42
+ export type OnSkillLoadReference = (id: string, refName: string) => Promise<{ content: string } | { error: string }>;
43
+
44
+ /** skillManagementPlugin 配置 */
45
+ export interface SkillManagementOptions {
46
+ registry: SkillRegistry;
47
+ onSkillSetEnabled: OnSkillSetEnabled;
48
+ onSkillLoadContent: OnSkillLoadContent;
49
+ onSkillLoadReference: OnSkillLoadReference;
50
+ onSkillCreate?: OnSkillCreate;
51
+ onSkillUpdate?: OnSkillUpdate;
52
+ onSkillDelete?: OnSkillDelete;
53
+ }
54
+
55
+ export interface SkillOperationContext extends SkillManagementOptions {}
56
+
57
+ export interface SkillAdminContext extends SkillOperationContext {}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Skill Registry - 技能注册表
3
+ *
4
+ * 纯内存索引,存储 SkillMeta。
5
+ * 与 ToolRegistry 不同:
6
+ * - 没有 lazy loading(Skill 是文本,不需要实例化)
7
+ * - 有 enabled 状态(决定是否注入 system prompt)
8
+ * - 搜索支持 enabledOnly 过滤
9
+ */
10
+
11
+ import type { SkillMeta, SkillSearchQuery } from './types';
12
+
13
+ export interface SkillRegistry {
14
+ /** 注册 Skill(完整元数据) */
15
+ add(meta: SkillMeta): void;
16
+ /** 移除 Skill */
17
+ remove(id: string): void;
18
+ /** 搜索 Skill */
19
+ search(query?: SkillSearchQuery): SkillMeta[];
20
+ /** 按 ID 获取 */
21
+ get(id: string): SkillMeta | undefined;
22
+ /** 设置启用/禁用 */
23
+ setEnabled(id: string, enabled: boolean): void;
24
+ /** 获取所有已启用的 Skill */
25
+ listEnabled(): SkillMeta[];
26
+ /** 所有条目 */
27
+ entries(): SkillMeta[];
28
+ /** 是否已注册 */
29
+ has(id: string): boolean;
30
+ /** 条目总数 */
31
+ readonly size: number;
32
+ /** 所有分类 */
33
+ categories(): Array<{ category: string; count: number }>;
34
+ }
35
+
36
+ function matchesKeyword(meta: SkillMeta, keyword: string): boolean {
37
+ const lower = keyword.toLowerCase();
38
+ if (meta.id.toLowerCase().includes(lower)) return true;
39
+ if (meta.name.toLowerCase().includes(lower)) return true;
40
+ if (meta.description.toLowerCase().includes(lower)) return true;
41
+ if (meta.category.toLowerCase().includes(lower)) return true;
42
+ if (meta.tags.some(t => t.toLowerCase().includes(lower))) return true;
43
+ return false;
44
+ }
45
+
46
+ export function skillRegistry(): SkillRegistry {
47
+ const store = new Map<string, SkillMeta>();
48
+
49
+ return {
50
+ add(meta) {
51
+ store.set(meta.id, { ...meta });
52
+ },
53
+
54
+ remove(id) {
55
+ store.delete(id);
56
+ },
57
+
58
+ search(query) {
59
+ let results = Array.from(store.values());
60
+
61
+ if (query?.keyword) {
62
+ const kw = query.keyword;
63
+ results = results.filter(m => matchesKeyword(m, kw));
64
+ }
65
+ if (query?.category) {
66
+ const cat = query.category.toLowerCase();
67
+ results = results.filter(m => m.category.toLowerCase() === cat);
68
+ }
69
+ if (query?.tags?.length) {
70
+ const required = query.tags.map(t => t.toLowerCase());
71
+ results = results.filter(m => {
72
+ const entryTags = m.tags.map(t => t.toLowerCase());
73
+ return required.every(rt => entryTags.includes(rt));
74
+ });
75
+ }
76
+ if (query?.source) {
77
+ results = results.filter(m => m.source === query.source);
78
+ }
79
+ if (query?.enabledOnly) {
80
+ results = results.filter(m => m.enabled);
81
+ }
82
+
83
+ return results;
84
+ },
85
+
86
+ get(id) {
87
+ const meta = store.get(id);
88
+ return meta ? { ...meta } : undefined;
89
+ },
90
+
91
+ setEnabled(id, enabled) {
92
+ const meta = store.get(id);
93
+ if (meta) meta.enabled = enabled;
94
+ },
95
+
96
+ listEnabled() {
97
+ return Array.from(store.values()).filter(m => m.enabled);
98
+ },
99
+
100
+ entries() {
101
+ return Array.from(store.values());
102
+ },
103
+
104
+ has(id) {
105
+ return store.has(id);
106
+ },
107
+
108
+ get size() {
109
+ return store.size;
110
+ },
111
+
112
+ categories() {
113
+ const counts = new Map<string, number>();
114
+ for (const meta of store.values()) {
115
+ counts.set(meta.category, (counts.get(meta.category) ?? 0) + 1);
116
+ }
117
+ return Array.from(counts.entries()).map(([category, count]) => ({ category, count }));
118
+ },
119
+ };
120
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Skill 管理摘要 / 详情构造
3
+ *
4
+ * - 从 SkillMeta 派生 ManagedSkillSummary / Detail,带统一治理字段
5
+ */
6
+
7
+ import { createAssetSummaryBase, createSkillAssetGovernance } from '../governance';
8
+ import type { ManagedSkillDetail, ManagedSkillSummary, SkillMeta } from './types';
9
+
10
+ export function createManagedSkillSummary(
11
+ skill: SkillMeta,
12
+ extra: Partial<ManagedSkillSummary> = {},
13
+ ): ManagedSkillSummary {
14
+ return {
15
+ ...createAssetSummaryBase({
16
+ kind: 'skill',
17
+ scope: skill.source === 'system' || skill.source === 'bundled' ? 'core' : 'local',
18
+ runtime: 'prompt-injection',
19
+ governance: extra.governance ?? createSkillAssetGovernance(),
20
+ }),
21
+ ref: skill.id,
22
+ id: skill.id,
23
+ name: skill.name,
24
+ description: skill.description,
25
+ category: skill.category,
26
+ tags: skill.tags,
27
+ icon: skill.icon,
28
+ source: skill.source,
29
+ enabled: skill.enabled,
30
+ references: skill.references,
31
+ scripts: skill.scripts,
32
+ dirPath: skill.dirPath,
33
+ displayName: skill.displayName,
34
+ shortDescription: skill.shortDescription,
35
+ defaultPrompt: skill.defaultPrompt,
36
+ ...extra,
37
+ };
38
+ }
39
+
40
+ export function createManagedSkillDetail(
41
+ skill: SkillMeta,
42
+ extra: Partial<ManagedSkillDetail> = {},
43
+ ): ManagedSkillDetail {
44
+ return {
45
+ ...createManagedSkillSummary(skill),
46
+ ...extra,
47
+ };
48
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Skill 类型定义
3
+ *
4
+ * Skill = AI 指令集(Markdown 文件),启用后注入 system prompt。
5
+ * 与 Tool 的区别:Tool 是可执行代码,Skill 是文本指令。
6
+ */
7
+
8
+ import type { AssetSource, ManagedAssetSummaryBase } from '../governance/types';
9
+
10
+ /** Skill 元数据(注册表中存储的索引信息) */
11
+ export interface SkillMeta {
12
+ /** 唯一 ID(文件夹名) */
13
+ id: string;
14
+ name: string;
15
+ description: string;
16
+ category: string;
17
+ tags: string[];
18
+ icon: string;
19
+ source: AssetSource;
20
+ enabled: boolean;
21
+ /** 可用的 references 文件列表 */
22
+ references: string[];
23
+ /** 可用的 scripts 文件列表 */
24
+ scripts: string[];
25
+ /** 技能所在目录的绝对路径(宿主提供,用于文件操作) */
26
+ dirPath?: string;
27
+ /** UI 展示名称(区别于 ID) */
28
+ displayName?: string;
29
+ /** 简短描述(用于列表展示) */
30
+ shortDescription?: string;
31
+ /** 推荐触发语 */
32
+ defaultPrompt?: string;
33
+ }
34
+
35
+ export interface ManagedSkillSummary extends ManagedAssetSummaryBase {
36
+ ref: string;
37
+ id: string;
38
+ name: string;
39
+ description: string;
40
+ category: string;
41
+ tags: string[];
42
+ icon: string;
43
+ source: AssetSource;
44
+ enabled: boolean;
45
+ references: string[];
46
+ scripts: string[];
47
+ dirPath?: string;
48
+ displayName?: string;
49
+ shortDescription?: string;
50
+ defaultPrompt?: string;
51
+ }
52
+
53
+ export interface ManagedSkillDetail extends ManagedSkillSummary {
54
+ instructions?: string;
55
+ instructionsError?: string;
56
+ }
57
+
58
+ /** Skill 搜索条件 */
59
+ export interface SkillSearchQuery {
60
+ keyword?: string;
61
+ category?: string;
62
+ tags?: string[];
63
+ source?: AssetSource;
64
+ enabledOnly?: boolean;
65
+ }
@@ -1,8 +1,9 @@
1
1
  /**
2
2
  * 测试用:根据 SSE 数据行创建 Response,用于 mock fetch
3
+ *
4
+ * Response.ok 由 status 自动决定(200-299 为 true),无需手动传入。
3
5
  */
4
- export function createSSEResponse(sseDataLines: string[], options?: { ok?: boolean; status?: number }): Response {
5
- const ok = options?.ok ?? true
6
+ export function createSSEResponse(sseDataLines: string[], options?: { status?: number }): Response {
6
7
  const status = options?.status ?? 200
7
8
  const body = new ReadableStream<Uint8Array>({
8
9
  start(controller) {
@@ -15,7 +16,6 @@ export function createSSEResponse(sseDataLines: string[], options?: { ok?: boole
15
16
  })
16
17
  return new Response(body, {
17
18
  status,
18
- ok,
19
19
  headers: { 'Content-Type': 'text/event-stream' },
20
20
  })
21
21
  }