@downcity/plugins 1.0.96 → 1.0.108

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 (56) hide show
  1. package/bin/asr/Plugin.d.ts +1 -15
  2. package/bin/asr/Plugin.d.ts.map +1 -1
  3. package/bin/asr/Plugin.js +36 -5
  4. package/bin/asr/Plugin.js.map +1 -1
  5. package/bin/chat/runtime/ChatAuthorizationRuntime.d.ts.map +1 -1
  6. package/bin/chat/runtime/ChatAuthorizationRuntime.js +53 -12
  7. package/bin/chat/runtime/ChatAuthorizationRuntime.js.map +1 -1
  8. package/bin/chat/runtime/ChatPluginActionRegistry.d.ts.map +1 -1
  9. package/bin/chat/runtime/ChatPluginActionRegistry.js +114 -42
  10. package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
  11. package/bin/contact/Action.d.ts.map +1 -1
  12. package/bin/contact/Action.js +159 -37
  13. package/bin/contact/Action.js.map +1 -1
  14. package/bin/image/ImagePlugin.d.ts +14 -67
  15. package/bin/image/ImagePlugin.d.ts.map +1 -1
  16. package/bin/image/ImagePlugin.js +432 -151
  17. package/bin/image/ImagePlugin.js.map +1 -1
  18. package/bin/image/types/ImagePlugin.d.ts +87 -32
  19. package/bin/image/types/ImagePlugin.d.ts.map +1 -1
  20. package/bin/image/types/ImagePlugin.js +1 -1
  21. package/bin/index.d.ts +1 -1
  22. package/bin/index.d.ts.map +1 -1
  23. package/bin/memory/MemoryPlugin.d.ts.map +1 -1
  24. package/bin/memory/MemoryPlugin.js +130 -17
  25. package/bin/memory/MemoryPlugin.js.map +1 -1
  26. package/bin/skill/Plugin.d.ts.map +1 -1
  27. package/bin/skill/Plugin.js +90 -11
  28. package/bin/skill/Plugin.js.map +1 -1
  29. package/bin/task/runtime/TaskPluginActionRegistry.d.ts.map +1 -1
  30. package/bin/task/runtime/TaskPluginActionRegistry.js +202 -24
  31. package/bin/task/runtime/TaskPluginActionRegistry.js.map +1 -1
  32. package/bin/tts/Plugin.d.ts +1 -15
  33. package/bin/tts/Plugin.d.ts.map +1 -1
  34. package/bin/tts/Plugin.js +38 -5
  35. package/bin/tts/Plugin.js.map +1 -1
  36. package/bin/web/Plugin.d.ts +2 -19
  37. package/bin/web/Plugin.d.ts.map +1 -1
  38. package/bin/web/Plugin.js +39 -5
  39. package/bin/web/Plugin.js.map +1 -1
  40. package/bin/workboard/Plugin.d.ts.map +1 -1
  41. package/bin/workboard/Plugin.js +10 -2
  42. package/bin/workboard/Plugin.js.map +1 -1
  43. package/package.json +3 -3
  44. package/src/asr/Plugin.ts +37 -5
  45. package/src/chat/runtime/ChatAuthorizationRuntime.ts +53 -12
  46. package/src/chat/runtime/ChatPluginActionRegistry.ts +114 -42
  47. package/src/contact/Action.ts +159 -37
  48. package/src/image/ImagePlugin.ts +477 -222
  49. package/src/image/types/ImagePlugin.ts +91 -32
  50. package/src/index.ts +3 -1
  51. package/src/memory/MemoryPlugin.ts +130 -17
  52. package/src/skill/Plugin.ts +101 -21
  53. package/src/task/runtime/TaskPluginActionRegistry.ts +209 -24
  54. package/src/tts/Plugin.ts +39 -5
  55. package/src/web/Plugin.ts +39 -5
  56. package/src/workboard/Plugin.ts +10 -2
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * 关键点(中文)
5
5
  * - 这里仅定义图片 plugin 对图片能力的最低层协议,不绑定 city 或任意上游 provider。
6
- * - 图片生成结果使用 AI SDK UIMessage,保证 session 落盘格式与现有消息系统一致。
6
+ * - 图片成功结果使用 AI SDK UIMessage,保证 session 落盘格式与现有消息系统一致。
7
7
  * - 字段保持 JSON 可序列化,便于通过 plugin action 与 tool bridge 传递。
8
8
  */
9
9
 
@@ -24,15 +24,13 @@ export interface ImagePluginTextContent {
24
24
  }
25
25
 
26
26
  /**
27
- * 图片生成参考图片内容片段。
27
+ * 图片生成图片内容片段。
28
28
  */
29
29
  export interface ImagePluginFileContent {
30
30
  /** 内容类型,固定为图片。 */
31
31
  type: "image";
32
- /** 远程图片 URL */
33
- url?: string;
34
- /** data URL 图片内容。 */
35
- data_url?: string;
32
+ /** 图片地址,支持 http(s) URL、本地绝对路径或相对项目根目录的路径。 */
33
+ url: string;
36
34
  /** 图片 MIME 类型,例如 `image/png`。 */
37
35
  media_type?: string;
38
36
  }
@@ -45,13 +43,27 @@ export type ImagePluginContent =
45
43
  | ImagePluginFileContent;
46
44
 
47
45
  /**
48
- * 图片生成上下文消息。
46
+ * ImagePlugin 内部解析后的图片内容片段。
49
47
  */
50
- export interface ImagePluginMessage {
51
- /** 消息角色。 */
52
- role: "system" | "user" | "assistant";
53
- /** 该消息内的文本与图片内容。 */
54
- content: ImagePluginContent[];
48
+ export type ImagePluginResolvedContent =
49
+ | ImagePluginContent
50
+ | {
51
+ /** 内容类型,固定为图片。 */
52
+ type: "image";
53
+ /** 本地图片由 ImagePlugin 读取后转换得到的 data URL。 */
54
+ data_url: string;
55
+ /** 图片 MIME 类型,例如 `image/png`。 */
56
+ media_type: string;
57
+ };
58
+
59
+ /**
60
+ * ImagePlugin 内部解析后的图片消息。
61
+ */
62
+ export interface ImagePluginResolvedMessage {
63
+ /** 消息角色。ImagePlugin 目前只会生成单条 user 消息。 */
64
+ role: "user";
65
+ /** 已解析的文本与图片内容。 */
66
+ content: ImagePluginResolvedContent[];
55
67
  }
56
68
 
57
69
  /**
@@ -62,8 +74,45 @@ export interface ImagePluginInput {
62
74
  model?: string;
63
75
  /** 单句快捷提示词。 */
64
76
  prompt?: string;
65
- /** 多轮或多模态图片生成上下文。 */
66
- messages?: ImagePluginMessage[];
77
+ /** 简单多模态内容。带参考图或改图时使用。 */
78
+ content?: ImagePluginContent[];
79
+ /** 生成图片数量。 */
80
+ n?: number;
81
+ /** 生成图片数量,兼容部分上游使用的 count 命名。 */
82
+ count?: number;
83
+ /** 图片尺寸,例如 `1024x1024`。 */
84
+ size?: string;
85
+ /** 图片宽高比,例如 `1:1`。 */
86
+ aspect_ratio?: string;
87
+ /** 图片宽高比,兼容部分上游使用的 ratio 命名。 */
88
+ ratio?: string;
89
+ /** 图片质量,例如 `standard`、`hd`、`ultra`、`4k`。 */
90
+ quality?: string;
91
+ /** 随机种子。 */
92
+ seed?: number;
93
+ /** 业务侧任务 ID,用于 provider 侧幂等、追踪和恢复。 */
94
+ client_job_id?: string;
95
+ /** Provider 私有参数,例如 `{ openai: {...}, gemini: {...}, luchi: {...} }`。 */
96
+ provider_options?: JsonObject;
97
+ /** 允许外部 image 函数接收其他 JSON 可序列化参数。 */
98
+ [key: string]: JsonValue | ImagePluginContent[] | undefined;
99
+ }
100
+
101
+ /**
102
+ * ImagePlugin 传给 image_create 回调的已解析输入。
103
+ *
104
+ * 关键点(中文)
105
+ * - Agent 公开 payload 只使用 `prompt` 或 `content`。
106
+ * - 当公开 payload 使用 `content` 时,ImagePlugin 会把本地图片读取为 data URL,并把内容转成 `messages`。
107
+ * - 这个类型只描述 ImagePlugin 到 City / provider adapter 的内部边界,不是 Agent 调用 payload。
108
+ */
109
+ export interface ImagePluginResolvedInput {
110
+ /** 图片模型引用。 */
111
+ model?: string;
112
+ /** 单句快捷提示词。纯文本生成时保留。 */
113
+ prompt?: string;
114
+ /** 已解析后的多模态消息。带参考图或改图时由 `content` 转换得到。 */
115
+ messages?: ImagePluginResolvedMessage[];
67
116
  /** 生成图片数量。 */
68
117
  n?: number;
69
118
  /** 生成图片数量,兼容部分上游使用的 count 命名。 */
@@ -83,11 +132,11 @@ export interface ImagePluginInput {
83
132
  /** Provider 私有参数,例如 `{ openai: {...}, gemini: {...}, luchi: {...} }`。 */
84
133
  provider_options?: JsonObject;
85
134
  /** 允许外部 image 函数接收其他 JSON 可序列化参数。 */
86
- [key: string]: JsonValue | ImagePluginMessage[] | undefined;
135
+ [key: string]: JsonValue | ImagePluginResolvedMessage[] | undefined;
87
136
  }
88
137
 
89
138
  /**
90
- * ImagePlugin 生成结果。
139
+ * ImagePlugin 图片成功结果。
91
140
  */
92
141
  export type ImagePluginResult = UIMessage;
93
142
 
@@ -136,21 +185,37 @@ export interface ImagePluginJobResult {
136
185
  export interface ImagePluginJobResultInput {
137
186
  /** 图片任务 ID,由 `image_create` 返回。 */
138
187
  job_id: string;
139
- /** 是否持续轮询直到任务进入成功或失败终态,默认由 action 决定。 */
140
- until_finish?: boolean;
141
- /** 单次查询最大等待时间,单位毫秒。 */
142
- timeout_ms?: number;
143
- /** 轮询间隔下限,单位毫秒。 */
144
- min_poll_interval_ms?: number;
145
- /** 轮询间隔上限,单位毫秒。 */
146
- max_poll_interval_ms?: number;
188
+ /**
189
+ * 是否阻塞等待任务到达终态(`succeeded` / `failed`)。
190
+ *
191
+ * 关键点(中文)
192
+ * - 默认 false:行为与历史一致,调用一次 provider 即返回。
193
+ * - true:plugin 内部按 `poll_interval_ms` 节奏轮询,直到任务终止或 `max_wait_ms` 到期。
194
+ */
195
+ until_done?: boolean;
196
+ /**
197
+ * 轮询的总等待上限(毫秒)。
198
+ *
199
+ * 关键点(中文)
200
+ * - 仅当 `until_done` 为 true 时生效。
201
+ * - 默认 60_000;命中上限后返回当前最后一次状态,不抛错。
202
+ */
203
+ max_wait_ms?: number;
204
+ /**
205
+ * 单次轮询之间的等待间隔(毫秒)。
206
+ *
207
+ * 关键点(中文)
208
+ * - 仅当 `until_done` 为 true 时生效。
209
+ * - 默认 1500;若 provider 返回 `poll_after_ms`,则取两者较大值。
210
+ */
211
+ poll_interval_ms?: number;
147
212
  }
148
213
 
149
214
  /**
150
215
  * ImagePlugin 可见模型信息。
151
216
  */
152
217
  export interface ImagePluginModel {
153
- /** 模型唯一 ID,用于 `image_create` / `generate` payload 的 `model` 字段。 */
218
+ /** 模型唯一 ID,用于 `image_create` payload 的 `model` 字段。 */
154
219
  id: string;
155
220
  /** 模型展示名称。 */
156
221
  name: string;
@@ -190,7 +255,7 @@ export interface ImagePluginOptions {
190
255
  description?: string;
191
256
  /** 创建图片生成任务,通常传入 `(input) => city.ai.image_create(input)`。 */
192
257
  image_create?: (
193
- input: ImagePluginInput,
258
+ input: ImagePluginResolvedInput,
194
259
  ) => Promise<ImagePluginJobCreateResult> | ImagePluginJobCreateResult;
195
260
  /** 查询图片生成任务,通常传入 `(input) => city.ai.image_result(input)`。 */
196
261
  image_result?: (
@@ -198,10 +263,4 @@ export interface ImagePluginOptions {
198
263
  ) => Promise<ImagePluginJobResult> | ImagePluginJobResult;
199
264
  /** 列出可用图片模型,通常传入 `async () => city.ai.listModels().then((catalog) => catalog.forModality("image"))`。 */
200
265
  list_models?: () => Promise<ImagePluginModel[]> | ImagePluginModel[];
201
- /** 图片任务最大等待时间,默认 300000ms。 */
202
- timeout_ms?: number;
203
- /** 轮询间隔下限,默认 100ms。 */
204
- min_poll_interval_ms?: number;
205
- /** 轮询间隔上限,默认 10000ms。 */
206
- max_poll_interval_ms?: number;
207
266
  }
package/src/index.ts CHANGED
@@ -109,10 +109,12 @@ export type {
109
109
  ImagePluginJobResult,
110
110
  ImagePluginJobResultInput,
111
111
  ImagePluginJobStatus,
112
- ImagePluginMessage,
113
112
  ImagePluginModel,
114
113
  ImagePluginModelsResult,
115
114
  ImagePluginOptions,
115
+ ImagePluginResolvedContent,
116
+ ImagePluginResolvedInput,
117
+ ImagePluginResolvedMessage,
116
118
  ImagePluginResult,
117
119
  ImagePluginTextContent,
118
120
  } from "./image/types/ImagePlugin.js";
@@ -12,6 +12,8 @@ import type { JsonObject, JsonValue } from "@downcity/agent/internal/types/commo
12
12
  import type { AgentContext } from "@downcity/agent/internal/types/runtime/agent/AgentContext.js";
13
13
  import type { PluginActions } from "@downcity/agent/internal/plugin/types/Plugin.js";
14
14
  import { BasePlugin } from "@downcity/agent/internal/plugin/core/BasePlugin.js";
15
+ import { createAction } from "@downcity/agent/internal/plugin/core/PluginActionFactory.js";
16
+ import { z } from "zod";
15
17
  import {
16
18
  digestMemoryAction,
17
19
  readMemoryAction,
@@ -124,7 +126,13 @@ export class MemoryPlugin extends BasePlugin {
124
126
  * 当前 plugin action 定义表。
125
127
  */
126
128
  readonly actions: PluginActions = {
127
- status: {
129
+ status: createAction({
130
+ description: "查看 memory wiki 状态(wiki/source/working)。",
131
+ input_schema: {
132
+ zod: z.object({}).passthrough(),
133
+ json_schema: { type: "object", properties: {} },
134
+ },
135
+ examples: [{ title: "查看状态", payload: {} }],
128
136
  command: {
129
137
  description: "查看 memory wiki 状态(wiki/source/working)",
130
138
  mapInput() {
@@ -135,8 +143,30 @@ export class MemoryPlugin extends BasePlugin {
135
143
  const state = this.getOrCreateRuntimeState(params.context);
136
144
  return await statusMemoryAction(params.context, state);
137
145
  },
138
- },
139
- search: {
146
+ }),
147
+ search: createAction({
148
+ description: "检索 memory wiki,可选择是否扩展到 source 层。",
149
+ input_schema: {
150
+ zod: z.object({
151
+ query: z.string(),
152
+ maxResults: z.number().optional(),
153
+ minScore: z.number().optional(),
154
+ includeSources: z.boolean().optional(),
155
+ }),
156
+ json_schema: {
157
+ type: "object",
158
+ required: ["query"],
159
+ properties: {
160
+ query: { type: "string", description: "检索关键词" },
161
+ maxResults: { type: "number", description: "返回条数上限" },
162
+ minScore: { type: "number", description: "最小相关分数" },
163
+ includeSources: { type: "boolean", description: "是否包含 source 层" },
164
+ },
165
+ },
166
+ },
167
+ examples: [
168
+ { title: "搜索记忆", payload: { query: "用户偏好" } },
169
+ ],
140
170
  command: {
141
171
  description: "检索 memory wiki",
142
172
  configure(command: Command) {
@@ -163,7 +193,7 @@ export class MemoryPlugin extends BasePlugin {
163
193
  },
164
194
  },
165
195
  execute: async (params) => {
166
- const body = readBodyObject(params.payload);
196
+ const body = readBodyObject(params.input);
167
197
  const state = this.getOrCreateRuntimeState(params.context);
168
198
  return await searchMemoryAction(params.context, state, {
169
199
  query: readString(body, "query"),
@@ -172,8 +202,28 @@ export class MemoryPlugin extends BasePlugin {
172
202
  includeSources: readOptionalBoolean(body, "includeSources"),
173
203
  });
174
204
  },
175
- },
176
- read: {
205
+ }),
206
+ read: createAction({
207
+ description: "读取 memory wiki/source 文件片段。",
208
+ input_schema: {
209
+ zod: z.object({
210
+ path: z.string(),
211
+ from: z.number().optional(),
212
+ lines: z.number().optional(),
213
+ }),
214
+ json_schema: {
215
+ type: "object",
216
+ required: ["path"],
217
+ properties: {
218
+ path: { type: "string", description: "记忆文件路径(相对项目根目录)" },
219
+ from: { type: "number", description: "起始行(1-based)" },
220
+ lines: { type: "number", description: "读取行数" },
221
+ },
222
+ },
223
+ },
224
+ examples: [
225
+ { title: "读取整页", payload: { path: ".downcity/memory/wiki/index.md" } },
226
+ ],
177
227
  command: {
178
228
  description: "读取 memory wiki/source 文件片段",
179
229
  configure(command: Command) {
@@ -196,15 +246,37 @@ export class MemoryPlugin extends BasePlugin {
196
246
  },
197
247
  },
198
248
  execute: async (params) => {
199
- const body = readBodyObject(params.payload);
249
+ const body = readBodyObject(params.input);
200
250
  return await readMemoryAction(params.context, {
201
251
  path: readString(body, "path"),
202
252
  from: readOptionalNumber(body, "from"),
203
253
  lines: readOptionalNumber(body, "lines"),
204
254
  });
205
255
  },
206
- },
207
- remember: {
256
+ }),
257
+ remember: createAction({
258
+ description: "把事实/偏好/决策记入 memory wiki。",
259
+ input_schema: {
260
+ zod: z.object({
261
+ content: z.string(),
262
+ topic: z.string().optional(),
263
+ path: z.string().optional(),
264
+ source: z.string().optional(),
265
+ }),
266
+ json_schema: {
267
+ type: "object",
268
+ required: ["content"],
269
+ properties: {
270
+ content: { type: "string", description: "需要记住的内容" },
271
+ topic: { type: "string", description: "记忆主题" },
272
+ path: { type: "string", description: "目标 wiki page 路径" },
273
+ source: { type: "string", description: "来源说明" },
274
+ },
275
+ },
276
+ },
277
+ examples: [
278
+ { title: "记住偏好", payload: { content: "用户偏好简短回答", topic: "user-prefs" } },
279
+ ],
208
280
  command: {
209
281
  description: "把事实/偏好/决策记入 memory wiki",
210
282
  configure(command: Command) {
@@ -231,7 +303,7 @@ export class MemoryPlugin extends BasePlugin {
231
303
  },
232
304
  },
233
305
  execute: async (params) => {
234
- const body = readBodyObject(params.payload);
306
+ const body = readBodyObject(params.input);
235
307
  return await rememberMemoryAction(params.context, this.options, {
236
308
  content: readString(body, "content"),
237
309
  topic: readOptionalString(body, "topic"),
@@ -239,8 +311,26 @@ export class MemoryPlugin extends BasePlugin {
239
311
  source: readOptionalString(body, "source"),
240
312
  });
241
313
  },
242
- },
243
- digest: {
314
+ }),
315
+ digest: createAction({
316
+ description: "把 session 提炼进 memory wiki。",
317
+ input_schema: {
318
+ zod: z.object({
319
+ sessionId: z.string(),
320
+ maxMessages: z.number().optional(),
321
+ }),
322
+ json_schema: {
323
+ type: "object",
324
+ required: ["sessionId"],
325
+ properties: {
326
+ sessionId: { type: "string", description: "会话 ID" },
327
+ maxMessages: { type: "number", description: "提取消息窗口" },
328
+ },
329
+ },
330
+ },
331
+ examples: [
332
+ { title: "提炼会话", payload: { sessionId: "sess-1" } },
333
+ ],
244
334
  command: {
245
335
  description: "把 session 提炼进 memory wiki",
246
336
  configure(command: Command) {
@@ -259,14 +349,37 @@ export class MemoryPlugin extends BasePlugin {
259
349
  },
260
350
  },
261
351
  execute: async (params) => {
262
- const body = readBodyObject(params.payload);
352
+ const body = readBodyObject(params.input);
263
353
  return await digestMemoryAction(params.context, this.options, {
264
354
  sessionId: readString(body, "sessionId"),
265
355
  maxMessages: readOptionalNumber(body, "maxMessages"),
266
356
  });
267
357
  },
268
- },
269
- revise: {
358
+ }),
359
+ revise: createAction({
360
+ description: "基于新证据修订 memory wiki page。",
361
+ input_schema: {
362
+ zod: z.object({
363
+ path: z.string(),
364
+ instruction: z.string(),
365
+ evidence: z.string().optional(),
366
+ }),
367
+ json_schema: {
368
+ type: "object",
369
+ required: ["path", "instruction"],
370
+ properties: {
371
+ path: { type: "string", description: "目标 wiki page 路径" },
372
+ instruction: { type: "string", description: "修订指令" },
373
+ evidence: { type: "string", description: "新证据" },
374
+ },
375
+ },
376
+ },
377
+ examples: [
378
+ {
379
+ title: "修订条目",
380
+ payload: { path: "wiki/preferences.md", instruction: "替换最新偏好" },
381
+ },
382
+ ],
270
383
  command: {
271
384
  description: "基于新证据修订 memory wiki page",
272
385
  configure(command: Command) {
@@ -287,14 +400,14 @@ export class MemoryPlugin extends BasePlugin {
287
400
  },
288
401
  },
289
402
  execute: async (params) => {
290
- const body = readBodyObject(params.payload);
403
+ const body = readBodyObject(params.input);
291
404
  return await reviseMemoryAction(params.context, this.options, {
292
405
  path: readString(body, "path"),
293
406
  instruction: readString(body, "instruction"),
294
407
  evidence: readOptionalString(body, "evidence"),
295
408
  });
296
409
  },
297
- },
410
+ }),
298
411
  };
299
412
 
300
413
  /**
@@ -8,8 +8,11 @@
8
8
  */
9
9
 
10
10
  import { BasePlugin } from "@downcity/agent/internal/plugin/core/BasePlugin.js";
11
+ import { createAction } from "@downcity/agent/internal/plugin/core/PluginActionFactory.js";
12
+ import { z } from "zod";
11
13
  import type { Plugin } from "@downcity/agent/internal/plugin/types/Plugin.js";
12
14
  import type { JsonObject, JsonValue } from "@downcity/agent/internal/types/common/Json.js";
15
+ import type { PluginActionResult } from "@downcity/agent/internal/types/plugin/PluginAction.js";
13
16
  import type {
14
17
  SkillPluginFindPayload,
15
18
  SkillPluginInstallPayload,
@@ -104,7 +107,26 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
104
107
  return [SKILL_PLUGIN_PROMPT, dynamicText].filter(Boolean).join("\n\n");
105
108
  },
106
109
  actions: {
107
- [SKILL_PLUGIN_ACTIONS.find]: {
110
+ [SKILL_PLUGIN_ACTIONS.find]: createAction({
111
+ description: "查找 `list` 中不存在的未学会 skills(缺失时再 install)",
112
+ input_schema: {
113
+ zod: z.object({
114
+ query: z.string(),
115
+ }),
116
+ json_schema: {
117
+ type: "object",
118
+ required: ["query"],
119
+ properties: {
120
+ query: { type: "string", description: "Skill 查询词" },
121
+ },
122
+ },
123
+ },
124
+ examples: [
125
+ {
126
+ title: "查找 skill",
127
+ payload: { query: "web-search" },
128
+ },
129
+ ],
108
130
  command: {
109
131
  description: "查找 `list` 中不存在的未学会 skills(缺失时再 install)",
110
132
  configure(command) {
@@ -116,8 +138,8 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
116
138
  return { query };
117
139
  },
118
140
  },
119
- async execute(params) {
120
- const payload = params.payload as SkillPluginFindPayload;
141
+ async execute(params): Promise<PluginActionResult<JsonObject>> {
142
+ const payload = params.input as SkillPluginFindPayload;
121
143
  const rootPath = params.context.rootPath;
122
144
  const exactLearned = findLearnedSkillExact(
123
145
  rootPath,
@@ -134,7 +156,7 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
134
156
  nextAction: "lookup",
135
157
  learnedSkill: exactLearned,
136
158
  learnedHints: [],
137
- },
159
+ } as JsonObject,
138
160
  };
139
161
  }
140
162
 
@@ -154,11 +176,36 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
154
176
  nextAction: "install",
155
177
  learnedSkill: null,
156
178
  learnedHints,
157
- },
179
+ } as JsonObject,
158
180
  };
159
181
  },
160
- },
161
- [SKILL_PLUGIN_ACTIONS.install]: {
182
+ }),
183
+ [SKILL_PLUGIN_ACTIONS.install]: createAction({
184
+ description: "安装 `list` 中不存在的 skill(完成后请先 lookup)",
185
+ input_schema: {
186
+ zod: z.object({
187
+ spec: z.string(),
188
+ global: z.boolean().optional(),
189
+ yes: z.boolean().optional(),
190
+ agent: z.string().optional(),
191
+ }),
192
+ json_schema: {
193
+ type: "object",
194
+ required: ["spec"],
195
+ properties: {
196
+ spec: { type: "string", description: "Skill 安装 spec" },
197
+ global: { type: "boolean", description: "是否全局安装" },
198
+ yes: { type: "boolean", description: "跳过确认" },
199
+ agent: { type: "string", description: "指定 agent" },
200
+ },
201
+ },
202
+ },
203
+ examples: [
204
+ {
205
+ title: "安装 skill",
206
+ payload: { spec: "web-search", global: true, yes: true },
207
+ },
208
+ ],
162
209
  command: {
163
210
  description: "安装 `list` 中不存在的 skill(完成后请先 lookup)",
164
211
  configure(command) {
@@ -179,8 +226,8 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
179
226
  };
180
227
  },
181
228
  },
182
- async execute(params) {
183
- const payload = params.payload as SkillPluginInstallPayload;
229
+ async execute(params): Promise<PluginActionResult<JsonObject>> {
230
+ const payload = params.input as SkillPluginInstallPayload;
184
231
  const rootPath = params.context.rootPath;
185
232
  const queryFromSpec = inferSkillQueryFromSpec(payload.spec);
186
233
  const beforeList = listSkills(rootPath, options).skills;
@@ -201,7 +248,7 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
201
248
  queryFromSpec,
202
249
  addedSkills: [],
203
250
  learnedSkill: learnedBefore,
204
- },
251
+ } as JsonObject,
205
252
  };
206
253
  }
207
254
 
@@ -228,11 +275,25 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
228
275
  queryFromSpec,
229
276
  addedSkills,
230
277
  learnedSkill: learnedAfter || null,
231
- },
278
+ } as JsonObject,
232
279
  };
233
280
  },
234
- },
235
- [SKILL_PLUGIN_ACTIONS.list]: {
281
+ }),
282
+ [SKILL_PLUGIN_ACTIONS.list]: createAction({
283
+ description: "列出当前已学会(本地可发现)的 skills",
284
+ input_schema: {
285
+ zod: z.object({}).passthrough(),
286
+ json_schema: {
287
+ type: "object",
288
+ properties: {},
289
+ },
290
+ },
291
+ examples: [
292
+ {
293
+ title: "列出 skills",
294
+ payload: {},
295
+ },
296
+ ],
236
297
  command: {
237
298
  description: "列出当前已学会(本地可发现)的 skills",
238
299
  mapInput() {
@@ -242,14 +303,33 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
242
303
  api: {
243
304
  method: "GET",
244
305
  },
245
- execute(params) {
306
+ execute(params): PluginActionResult<JsonObject> {
246
307
  return {
247
308
  success: true,
248
- data: listSkills(params.context.rootPath, options),
309
+ data: listSkills(params.context.rootPath, options) as unknown as JsonObject,
249
310
  };
250
311
  },
251
- },
252
- [SKILL_PLUGIN_ACTIONS.lookup]: {
312
+ }),
313
+ [SKILL_PLUGIN_ACTIONS.lookup]: createAction({
314
+ description: "读取已学会 skill 内容(SKILL.md)",
315
+ input_schema: {
316
+ zod: z.object({
317
+ name: z.string(),
318
+ }),
319
+ json_schema: {
320
+ type: "object",
321
+ required: ["name"],
322
+ properties: {
323
+ name: { type: "string", description: "Skill 名称" },
324
+ },
325
+ },
326
+ },
327
+ examples: [
328
+ {
329
+ title: "读取 skill",
330
+ payload: { name: "web-search" },
331
+ },
332
+ ],
253
333
  command: {
254
334
  description: "读取已学会 skill 内容(SKILL.md)",
255
335
  configure(command) {
@@ -270,8 +350,8 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
270
350
  return { name };
271
351
  },
272
352
  },
273
- async execute(params) {
274
- const payload = params.payload as SkillPluginLookupPayload;
353
+ async execute(params): Promise<PluginActionResult<JsonObject>> {
354
+ const payload = params.input as SkillPluginLookupPayload;
275
355
  const result = await lookupSkill({
276
356
  projectRoot: params.context.rootPath,
277
357
  request: {
@@ -316,10 +396,10 @@ function createSkillPluginDefinition(options: SkillPluginOptions): Plugin {
316
396
  toolOutputMessage:
317
397
  "skill lookup success; content injected as <skill> user message.",
318
398
  },
319
- },
399
+ } as JsonObject,
320
400
  };
321
401
  },
322
- },
402
+ }),
323
403
  },
324
404
  };
325
405
  }