@downcity/plugins 1.0.96 → 1.0.103
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.
- package/bin/asr/Plugin.d.ts +1 -15
- package/bin/asr/Plugin.d.ts.map +1 -1
- package/bin/asr/Plugin.js +36 -5
- package/bin/asr/Plugin.js.map +1 -1
- package/bin/chat/runtime/ChatAuthorizationRuntime.d.ts.map +1 -1
- package/bin/chat/runtime/ChatAuthorizationRuntime.js +53 -12
- package/bin/chat/runtime/ChatAuthorizationRuntime.js.map +1 -1
- package/bin/chat/runtime/ChatPluginActionRegistry.d.ts.map +1 -1
- package/bin/chat/runtime/ChatPluginActionRegistry.js +114 -42
- package/bin/chat/runtime/ChatPluginActionRegistry.js.map +1 -1
- package/bin/contact/Action.d.ts.map +1 -1
- package/bin/contact/Action.js +159 -37
- package/bin/contact/Action.js.map +1 -1
- package/bin/image/ImagePlugin.d.ts +11 -68
- package/bin/image/ImagePlugin.d.ts.map +1 -1
- package/bin/image/ImagePlugin.js +288 -151
- package/bin/image/ImagePlugin.js.map +1 -1
- package/bin/image/types/ImagePlugin.d.ts +63 -32
- package/bin/image/types/ImagePlugin.d.ts.map +1 -1
- package/bin/image/types/ImagePlugin.js +1 -1
- package/bin/index.d.ts +1 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/memory/MemoryPlugin.d.ts.map +1 -1
- package/bin/memory/MemoryPlugin.js +130 -17
- package/bin/memory/MemoryPlugin.js.map +1 -1
- package/bin/skill/Plugin.d.ts.map +1 -1
- package/bin/skill/Plugin.js +90 -11
- package/bin/skill/Plugin.js.map +1 -1
- package/bin/task/runtime/TaskPluginActionRegistry.d.ts.map +1 -1
- package/bin/task/runtime/TaskPluginActionRegistry.js +202 -24
- package/bin/task/runtime/TaskPluginActionRegistry.js.map +1 -1
- package/bin/tts/Plugin.d.ts +1 -15
- package/bin/tts/Plugin.d.ts.map +1 -1
- package/bin/tts/Plugin.js +38 -5
- package/bin/tts/Plugin.js.map +1 -1
- package/bin/web/Plugin.d.ts +2 -19
- package/bin/web/Plugin.d.ts.map +1 -1
- package/bin/web/Plugin.js +39 -5
- package/bin/web/Plugin.js.map +1 -1
- package/bin/workboard/Plugin.d.ts.map +1 -1
- package/bin/workboard/Plugin.js +10 -2
- package/bin/workboard/Plugin.js.map +1 -1
- package/package.json +3 -3
- package/src/asr/Plugin.ts +37 -5
- package/src/chat/runtime/ChatAuthorizationRuntime.ts +53 -12
- package/src/chat/runtime/ChatPluginActionRegistry.ts +114 -42
- package/src/contact/Action.ts +159 -37
- package/src/image/ImagePlugin.ts +327 -226
- package/src/image/types/ImagePlugin.ts +67 -32
- package/src/index.ts +3 -1
- package/src/memory/MemoryPlugin.ts +130 -17
- package/src/skill/Plugin.ts +101 -21
- package/src/task/runtime/TaskPluginActionRegistry.ts +209 -24
- package/src/tts/Plugin.ts +39 -5
- package/src/web/Plugin.ts +39 -5
- package/src/workboard/Plugin.ts +10 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 这里仅定义图片 plugin 对图片能力的最低层协议,不绑定 city 或任意上游 provider。
|
|
6
|
-
* -
|
|
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
|
-
/**
|
|
33
|
-
url
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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 |
|
|
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,13 @@ 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;
|
|
147
188
|
}
|
|
148
189
|
|
|
149
190
|
/**
|
|
150
191
|
* ImagePlugin 可见模型信息。
|
|
151
192
|
*/
|
|
152
193
|
export interface ImagePluginModel {
|
|
153
|
-
/** 模型唯一 ID,用于 `image_create`
|
|
194
|
+
/** 模型唯一 ID,用于 `image_create` payload 的 `model` 字段。 */
|
|
154
195
|
id: string;
|
|
155
196
|
/** 模型展示名称。 */
|
|
156
197
|
name: string;
|
|
@@ -190,7 +231,7 @@ export interface ImagePluginOptions {
|
|
|
190
231
|
description?: string;
|
|
191
232
|
/** 创建图片生成任务,通常传入 `(input) => city.ai.image_create(input)`。 */
|
|
192
233
|
image_create?: (
|
|
193
|
-
input:
|
|
234
|
+
input: ImagePluginResolvedInput,
|
|
194
235
|
) => Promise<ImagePluginJobCreateResult> | ImagePluginJobCreateResult;
|
|
195
236
|
/** 查询图片生成任务,通常传入 `(input) => city.ai.image_result(input)`。 */
|
|
196
237
|
image_result?: (
|
|
@@ -198,10 +239,4 @@ export interface ImagePluginOptions {
|
|
|
198
239
|
) => Promise<ImagePluginJobResult> | ImagePluginJobResult;
|
|
199
240
|
/** 列出可用图片模型,通常传入 `async () => city.ai.listModels().then((catalog) => catalog.forModality("image"))`。 */
|
|
200
241
|
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
242
|
}
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
/**
|
package/src/skill/Plugin.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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
|
}
|