@downcity/agent 1.1.153 → 1.1.157
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/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.js +1 -0
- package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.d.ts.map +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.js +1 -1
- package/bin/executor/composer/system/default/assets/plugin.prompt.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts +5 -1
- package/bin/executor/tools/plugin/PluginToolBridge.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolBridge.js +26 -0
- package/bin/executor/tools/plugin/PluginToolBridge.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts +11 -0
- package/bin/executor/tools/plugin/PluginToolDefinition.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolDefinition.js +12 -3
- package/bin/executor/tools/plugin/PluginToolDefinition.js.map +1 -1
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts +4 -0
- package/bin/executor/tools/plugin/PluginToolSchemas.d.ts.map +1 -1
- package/bin/executor/tools/plugin/PluginToolSchemas.js +11 -1
- package/bin/executor/tools/plugin/PluginToolSchemas.js.map +1 -1
- package/bin/executor/tools/plugin/types/PluginTool.d.ts +20 -0
- package/bin/executor/tools/plugin/types/PluginTool.d.ts.map +1 -1
- package/bin/index.d.ts +3 -1
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +1 -0
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/PluginActionFactory.d.ts +99 -0
- package/bin/plugin/core/PluginActionFactory.d.ts.map +1 -0
- package/bin/plugin/core/PluginActionFactory.js +59 -0
- package/bin/plugin/core/PluginActionFactory.js.map +1 -0
- package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionRunner.js +14 -1
- package/bin/plugin/core/PluginActionRunner.js.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +15 -1
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +18 -1
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +74 -1
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/plugin/types/Plugin.d.ts +2 -2
- package/bin/plugin/types/Plugin.d.ts.map +1 -1
- package/bin/types/plugin/PluginAction.d.ts +40 -2
- package/bin/types/plugin/PluginAction.d.ts.map +1 -1
- package/bin/types/plugin/PluginRuntime.d.ts +44 -0
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/package.json +3 -3
- package/scripts/image-plugin-job.test.mjs +209 -68
- package/scripts/plugin-tool-bridge.test.mjs +113 -2
- package/src/agent/local/services/AgentAssemblyService.ts +1 -0
- package/src/executor/composer/system/default/assets/plugin.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/plugin.prompt.ts.txt +3 -2
- package/src/executor/tools/plugin/PluginToolBridge.ts +30 -0
- package/src/executor/tools/plugin/PluginToolDefinition.ts +25 -4
- package/src/executor/tools/plugin/PluginToolSchemas.ts +12 -1
- package/src/executor/tools/plugin/types/PluginTool.ts +22 -0
- package/src/index.ts +11 -0
- package/src/plugin/core/PluginActionFactory.ts +185 -0
- package/src/plugin/core/PluginActionRunner.ts +14 -1
- package/src/plugin/core/PluginLocalExecution.ts +15 -1
- package/src/plugin/core/PluginRegistry.ts +89 -1
- package/src/plugin/types/Plugin.ts +5 -0
- package/src/types/plugin/PluginAction.ts +43 -2
- package/src/types/plugin/PluginRuntime.ts +44 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -20,6 +20,16 @@ export interface PluginCallInput {
|
|
|
20
20
|
payload?: JsonObject;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* plugin_read 输入。
|
|
25
|
+
*/
|
|
26
|
+
export interface PluginReadInput {
|
|
27
|
+
/** 要读取的 plugin 名称;不传则列出 plugin 概览。 */
|
|
28
|
+
plugin?: string;
|
|
29
|
+
/** 要读取的 action 名称;仅在 plugin 存在时生效。 */
|
|
30
|
+
action?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* plugin_call 产生的 assistant 文件摘要。
|
|
25
35
|
*/
|
|
@@ -57,3 +67,15 @@ export interface PluginCallToolResult {
|
|
|
57
67
|
/** 返回给模型读取的短摘要数据。 */
|
|
58
68
|
data?: JsonObject;
|
|
59
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* plugin_read 返回给模型的 metadata。
|
|
73
|
+
*/
|
|
74
|
+
export interface PluginReadToolResult {
|
|
75
|
+
/** 调用是否成功。 */
|
|
76
|
+
success: boolean;
|
|
77
|
+
/** 人类可读消息。 */
|
|
78
|
+
message: string;
|
|
79
|
+
/** 读取到的 metadata。 */
|
|
80
|
+
data: JsonObject;
|
|
81
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -72,6 +72,14 @@ export type {
|
|
|
72
72
|
|
|
73
73
|
// Plugin 作者 API
|
|
74
74
|
export { BasePlugin } from "./plugin/core/BasePlugin.js";
|
|
75
|
+
export {
|
|
76
|
+
createAction,
|
|
77
|
+
createPlugin,
|
|
78
|
+
} from "./plugin/core/PluginActionFactory.js";
|
|
79
|
+
export type {
|
|
80
|
+
CreatePluginActionOptions,
|
|
81
|
+
CreatePluginOptions,
|
|
82
|
+
} from "./plugin/core/PluginActionFactory.js";
|
|
75
83
|
|
|
76
84
|
// Session 与即时执行集成
|
|
77
85
|
export { Executor } from "./executor/Executor.js";
|
|
@@ -229,6 +237,9 @@ export type {
|
|
|
229
237
|
PluginActionApi,
|
|
230
238
|
PluginActionCommand,
|
|
231
239
|
PluginActionCommandInput,
|
|
240
|
+
PluginActionExample,
|
|
241
|
+
PluginActionInputSchema,
|
|
242
|
+
PluginActionMetadata,
|
|
232
243
|
PluginActionResult,
|
|
233
244
|
PluginActions,
|
|
234
245
|
PluginAvailability,
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PluginActionFactory:创建带 metadata 和 schema 的 plugin/action。
|
|
3
|
+
*
|
|
4
|
+
* 关键点(中文)
|
|
5
|
+
* - `createAction` 让 action 的运行时 schema 与 TypeScript 输入类型保持一致。
|
|
6
|
+
* - `createPlugin` 只做轻量对象装配,不强制继承 BasePlugin。
|
|
7
|
+
* - 旧的 class extends BasePlugin 写法仍可继续使用。
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { z } from "zod";
|
|
11
|
+
import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
12
|
+
import type { JsonValue } from "@/types/common/Json.js";
|
|
13
|
+
import type {
|
|
14
|
+
PluginAction,
|
|
15
|
+
PluginActionApi,
|
|
16
|
+
PluginActionCommand,
|
|
17
|
+
PluginActionExample,
|
|
18
|
+
PluginActionInputSchema,
|
|
19
|
+
PluginActionResult,
|
|
20
|
+
PluginActions,
|
|
21
|
+
} from "@/types/plugin/PluginAction.js";
|
|
22
|
+
import type { Plugin } from "@/types/plugin/PluginDefinition.js";
|
|
23
|
+
import type {
|
|
24
|
+
PluginAvailability,
|
|
25
|
+
PluginConfigDefinition,
|
|
26
|
+
PluginHooks,
|
|
27
|
+
PluginResolves,
|
|
28
|
+
} from "@/types/plugin/PluginRuntime.js";
|
|
29
|
+
import type {
|
|
30
|
+
PluginCommandContext,
|
|
31
|
+
PluginLifecycle,
|
|
32
|
+
} from "@/types/plugin/PluginCommand.js";
|
|
33
|
+
import type {
|
|
34
|
+
PluginSetupDefinition,
|
|
35
|
+
PluginUsageDefinition,
|
|
36
|
+
} from "@/types/plugin/PluginSetup.js";
|
|
37
|
+
import type { PluginHttpDefinition } from "@/types/plugin/PluginHttp.js";
|
|
38
|
+
import type { StructuredConfig } from "@/types/runtime/agent/AgentContext.js";
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 从 Zod schema 推导 JSON 输入类型。
|
|
42
|
+
*/
|
|
43
|
+
type InferZodJson<TSchema extends z.ZodTypeAny> =
|
|
44
|
+
z.infer<TSchema> extends JsonValue ? z.infer<TSchema> : JsonValue;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* createAction 参数。
|
|
48
|
+
*/
|
|
49
|
+
export interface CreatePluginActionOptions<
|
|
50
|
+
P extends JsonValue,
|
|
51
|
+
R extends JsonValue,
|
|
52
|
+
> {
|
|
53
|
+
/** Action 用途说明。 */
|
|
54
|
+
description?: string;
|
|
55
|
+
/** Zod 输入 schema。 */
|
|
56
|
+
input_schema?: z.ZodTypeAny | PluginActionInputSchema<P>;
|
|
57
|
+
/** Action 调用示例。 */
|
|
58
|
+
examples?: PluginActionExample<P>[];
|
|
59
|
+
/** disabled 状态下是否仍允许执行。 */
|
|
60
|
+
allowWhenDisabled?: boolean;
|
|
61
|
+
/** CLI 定义。 */
|
|
62
|
+
command?: PluginActionCommand<P>;
|
|
63
|
+
/** HTTP 定义。 */
|
|
64
|
+
api?: PluginActionApi<P>;
|
|
65
|
+
/** Action 执行器。 */
|
|
66
|
+
execute: (params: {
|
|
67
|
+
/** 当前执行上下文。 */
|
|
68
|
+
context: AgentContext;
|
|
69
|
+
/** 已通过 schema 校验后的输入。 */
|
|
70
|
+
input: P;
|
|
71
|
+
/** 兼容旧命名的 payload。 */
|
|
72
|
+
payload: P;
|
|
73
|
+
/** 当前插件名称。 */
|
|
74
|
+
pluginName: string;
|
|
75
|
+
/** 当前 Action 名称。 */
|
|
76
|
+
actionName: string;
|
|
77
|
+
}) => Promise<PluginActionResult<R>> | PluginActionResult<R>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* createPlugin 参数。
|
|
82
|
+
*/
|
|
83
|
+
export interface CreatePluginOptions<TActions extends PluginActions> {
|
|
84
|
+
/** Plugin 稳定名称。 */
|
|
85
|
+
name: string;
|
|
86
|
+
/** Plugin 展示标题。 */
|
|
87
|
+
title?: string;
|
|
88
|
+
/** Plugin 用途说明。 */
|
|
89
|
+
description?: string;
|
|
90
|
+
/** Plugin 显式 action 集合。 */
|
|
91
|
+
actions?: TActions;
|
|
92
|
+
/** Plugin 配置定义。 */
|
|
93
|
+
config?: PluginConfigDefinition<StructuredConfig>;
|
|
94
|
+
/** Plugin setup 定义。 */
|
|
95
|
+
setup?: PluginSetupDefinition;
|
|
96
|
+
/** Plugin usage 定义。 */
|
|
97
|
+
usage?: PluginUsageDefinition;
|
|
98
|
+
/** Plugin hook 集合。 */
|
|
99
|
+
hooks?: PluginHooks;
|
|
100
|
+
/** Plugin resolve 集合。 */
|
|
101
|
+
resolves?: PluginResolves;
|
|
102
|
+
/** Plugin system 文本构建器。 */
|
|
103
|
+
system?: (context: AgentContext) => string | Promise<string>;
|
|
104
|
+
/** 旧生命周期兼容定义。 */
|
|
105
|
+
lifecycle?: PluginLifecycle;
|
|
106
|
+
/** Plugin 可用性检查。 */
|
|
107
|
+
availability?: (
|
|
108
|
+
context: PluginCommandContext | AgentContext,
|
|
109
|
+
) => Promise<PluginAvailability> | PluginAvailability;
|
|
110
|
+
/** Plugin HTTP 注入定义。 */
|
|
111
|
+
http?: PluginHttpDefinition;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 归一化输入 schema。
|
|
116
|
+
*/
|
|
117
|
+
function normalize_input_schema<P extends JsonValue>(
|
|
118
|
+
input_schema: z.ZodTypeAny | PluginActionInputSchema<P> | undefined,
|
|
119
|
+
): PluginActionInputSchema<P> | undefined {
|
|
120
|
+
if (!input_schema) return undefined;
|
|
121
|
+
if (typeof (input_schema as z.ZodTypeAny).safeParse === "function") {
|
|
122
|
+
return { zod: input_schema as z.ZodTypeAny };
|
|
123
|
+
}
|
|
124
|
+
return input_schema as PluginActionInputSchema<P>;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 创建带 metadata 的 action。
|
|
129
|
+
*/
|
|
130
|
+
export function createAction<
|
|
131
|
+
TSchema extends z.ZodTypeAny,
|
|
132
|
+
R extends JsonValue = JsonValue,
|
|
133
|
+
>(
|
|
134
|
+
options: CreatePluginActionOptions<InferZodJson<TSchema>, R> & {
|
|
135
|
+
/** Zod 输入 schema。 */
|
|
136
|
+
input_schema?: TSchema | PluginActionInputSchema<InferZodJson<TSchema>>;
|
|
137
|
+
},
|
|
138
|
+
): PluginAction<InferZodJson<TSchema>, R>;
|
|
139
|
+
export function createAction<R extends JsonValue = JsonValue>(
|
|
140
|
+
options: CreatePluginActionOptions<JsonValue, R>,
|
|
141
|
+
): PluginAction<JsonValue, R>;
|
|
142
|
+
export function createAction(
|
|
143
|
+
options: CreatePluginActionOptions<JsonValue, JsonValue>,
|
|
144
|
+
): PluginAction<JsonValue, JsonValue> {
|
|
145
|
+
return {
|
|
146
|
+
...(options.description ? { description: options.description } : {}),
|
|
147
|
+
...(options.input_schema
|
|
148
|
+
? { input_schema: normalize_input_schema(options.input_schema) }
|
|
149
|
+
: {}),
|
|
150
|
+
...(options.examples ? { examples: options.examples } : {}),
|
|
151
|
+
...(typeof options.allowWhenDisabled === "boolean"
|
|
152
|
+
? { allowWhenDisabled: options.allowWhenDisabled }
|
|
153
|
+
: {}),
|
|
154
|
+
...(options.command ? { command: options.command } : {}),
|
|
155
|
+
...(options.api ? { api: options.api } : {}),
|
|
156
|
+
execute: options.execute,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* 创建 plugin 对象。
|
|
162
|
+
*/
|
|
163
|
+
export function createPlugin<TActions extends PluginActions>(
|
|
164
|
+
options: CreatePluginOptions<TActions>,
|
|
165
|
+
): Plugin & { actions: TActions } {
|
|
166
|
+
const name = String(options.name || "").trim();
|
|
167
|
+
if (!name) {
|
|
168
|
+
throw new Error("createPlugin requires a non-empty name");
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
name,
|
|
172
|
+
title: String(options.title || name).trim(),
|
|
173
|
+
description: String(options.description || "").trim(),
|
|
174
|
+
actions: options.actions || ({} as TActions),
|
|
175
|
+
...(options.config ? { config: options.config } : {}),
|
|
176
|
+
...(options.setup ? { setup: options.setup } : {}),
|
|
177
|
+
...(options.usage ? { usage: options.usage } : {}),
|
|
178
|
+
...(options.hooks ? { hooks: options.hooks } : {}),
|
|
179
|
+
...(options.resolves ? { resolves: options.resolves } : {}),
|
|
180
|
+
...(options.system ? { system: options.system } : {}),
|
|
181
|
+
...(options.lifecycle ? { lifecycle: options.lifecycle } : {}),
|
|
182
|
+
...(options.availability ? { availability: options.availability } : {}),
|
|
183
|
+
...(options.http ? { http: options.http } : {}),
|
|
184
|
+
};
|
|
185
|
+
}
|
|
@@ -58,9 +58,22 @@ export async function invokePluginAction(params: {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
try {
|
|
61
|
+
const payload = (params.payload ?? {}) as JsonValue;
|
|
62
|
+
const schema = action.input_schema?.zod;
|
|
63
|
+
const parsed_payload = schema ? schema.safeParse(payload) : null;
|
|
64
|
+
if (parsed_payload && !parsed_payload.success) {
|
|
65
|
+
return {
|
|
66
|
+
success: false,
|
|
67
|
+
error: `Invalid payload for ${params.plugin.name}.${params.actionName}: ${parsed_payload.error.message}`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const input_payload = parsed_payload?.success
|
|
71
|
+
? parsed_payload.data as JsonValue
|
|
72
|
+
: payload;
|
|
61
73
|
return await action.execute({
|
|
62
74
|
context: params.context,
|
|
63
|
-
payload:
|
|
75
|
+
payload: input_payload,
|
|
76
|
+
input: input_payload,
|
|
64
77
|
pluginName: params.plugin.name,
|
|
65
78
|
actionName: params.actionName,
|
|
66
79
|
});
|
|
@@ -135,9 +135,23 @@ export async function runLocalPluginAction(params: {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
try {
|
|
138
|
+
const payload = (params.payload ?? {}) as JsonValue;
|
|
139
|
+
const schema = action.input_schema?.zod;
|
|
140
|
+
const parsed_payload = schema ? schema.safeParse(payload) : null;
|
|
141
|
+
if (parsed_payload && !parsed_payload.success) {
|
|
142
|
+
return {
|
|
143
|
+
success: false,
|
|
144
|
+
error: `Invalid payload for ${plugin.name}.${actionName}: ${parsed_payload.error.message}`,
|
|
145
|
+
message: `Invalid payload for ${plugin.name}.${actionName}`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
const input_payload = parsed_payload?.success
|
|
149
|
+
? parsed_payload.data as JsonValue
|
|
150
|
+
: payload;
|
|
138
151
|
return await action.execute({
|
|
139
152
|
context: context as unknown as AgentContext,
|
|
140
|
-
payload:
|
|
153
|
+
payload: input_payload,
|
|
154
|
+
input: input_payload,
|
|
141
155
|
pluginName: plugin.name,
|
|
142
156
|
actionName,
|
|
143
157
|
});
|
|
@@ -14,6 +14,8 @@ import type {
|
|
|
14
14
|
PluginActionResult,
|
|
15
15
|
AgentPlugins,
|
|
16
16
|
PluginAvailability,
|
|
17
|
+
PluginActionReadView,
|
|
18
|
+
PluginReadView,
|
|
17
19
|
PluginView,
|
|
18
20
|
} from "@/plugin/types/Plugin.js";
|
|
19
21
|
import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
@@ -128,6 +130,60 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
128
130
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
129
131
|
}
|
|
130
132
|
|
|
133
|
+
/**
|
|
134
|
+
* 读取 action metadata。
|
|
135
|
+
*/
|
|
136
|
+
private readAction(
|
|
137
|
+
actionName: string,
|
|
138
|
+
action: NonNullable<Plugin["actions"]>[string],
|
|
139
|
+
): PluginActionReadView {
|
|
140
|
+
return {
|
|
141
|
+
name: actionName,
|
|
142
|
+
description: String(action.description || "").trim(),
|
|
143
|
+
has_input_schema: Boolean(action.input_schema),
|
|
144
|
+
...(action.input_schema?.json_schema
|
|
145
|
+
? { input_schema: action.input_schema.json_schema }
|
|
146
|
+
: {}),
|
|
147
|
+
...(action.examples ? { examples: action.examples } : {}),
|
|
148
|
+
allow_when_disabled: action.allowWhenDisabled === true,
|
|
149
|
+
has_command: Boolean(action.command),
|
|
150
|
+
has_api: Boolean(action.api),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* 读取 plugin / action metadata。
|
|
156
|
+
*/
|
|
157
|
+
read(params: {
|
|
158
|
+
plugin?: string;
|
|
159
|
+
action?: string;
|
|
160
|
+
}): PluginReadView | { plugins: PluginView[] } {
|
|
161
|
+
const pluginName = String(params.plugin || "").trim();
|
|
162
|
+
if (!pluginName) {
|
|
163
|
+
return { plugins: this.list() };
|
|
164
|
+
}
|
|
165
|
+
const plugin = this.get(pluginName);
|
|
166
|
+
if (!plugin) {
|
|
167
|
+
return {
|
|
168
|
+
name: pluginName,
|
|
169
|
+
title: pluginName,
|
|
170
|
+
description: "",
|
|
171
|
+
actions: [],
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
const actionName = String(params.action || "").trim();
|
|
175
|
+
const actions = Object.entries(plugin.actions || {})
|
|
176
|
+
.filter(([name]) => !actionName || name === actionName)
|
|
177
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
178
|
+
.map(([name, action]) => this.readAction(name, action));
|
|
179
|
+
return {
|
|
180
|
+
name: plugin.name,
|
|
181
|
+
title: String(plugin.title || plugin.name || "").trim(),
|
|
182
|
+
description: String(plugin.description || "").trim(),
|
|
183
|
+
actions,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
131
187
|
/**
|
|
132
188
|
* 检查 plugin 可用性。
|
|
133
189
|
*/
|
|
@@ -162,6 +218,28 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
162
218
|
};
|
|
163
219
|
}
|
|
164
220
|
|
|
221
|
+
/**
|
|
222
|
+
* 按 action schema 校验 payload。
|
|
223
|
+
*/
|
|
224
|
+
private parseActionPayload(params: {
|
|
225
|
+
pluginName: string;
|
|
226
|
+
actionName: string;
|
|
227
|
+
payload: JsonValue;
|
|
228
|
+
action: NonNullable<Plugin["actions"]>[string];
|
|
229
|
+
}): PluginActionResult<JsonValue> | { input: JsonValue } {
|
|
230
|
+
const schema = params.action.input_schema?.zod;
|
|
231
|
+
if (!schema) return { input: params.payload };
|
|
232
|
+
const parsed = schema.safeParse(params.payload);
|
|
233
|
+
if (parsed.success) {
|
|
234
|
+
return { input: parsed.data as JsonValue };
|
|
235
|
+
}
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
error: `Invalid payload for ${params.pluginName}.${params.actionName}: ${parsed.error.message}`,
|
|
239
|
+
message: `Invalid payload for ${params.pluginName}.${params.actionName}`,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
165
243
|
/**
|
|
166
244
|
* 运行 plugin action。
|
|
167
245
|
*/
|
|
@@ -208,9 +286,19 @@ export class PluginRegistry implements AgentPlugins {
|
|
|
208
286
|
}
|
|
209
287
|
|
|
210
288
|
try {
|
|
289
|
+
const parsed_payload = this.parseActionPayload({
|
|
290
|
+
pluginName: plugin.name,
|
|
291
|
+
actionName,
|
|
292
|
+
payload: (params.payload ?? {}) as JsonValue,
|
|
293
|
+
action,
|
|
294
|
+
});
|
|
295
|
+
if (!("input" in parsed_payload)) {
|
|
296
|
+
return parsed_payload;
|
|
297
|
+
}
|
|
211
298
|
return await action.execute({
|
|
212
299
|
context,
|
|
213
|
-
payload:
|
|
300
|
+
payload: parsed_payload.input,
|
|
301
|
+
input: parsed_payload.input,
|
|
214
302
|
pluginName: plugin.name,
|
|
215
303
|
actionName,
|
|
216
304
|
});
|
|
@@ -24,9 +24,12 @@ export type {
|
|
|
24
24
|
PluginActionApi,
|
|
25
25
|
PluginActionCommand,
|
|
26
26
|
PluginActionCommandInput,
|
|
27
|
+
PluginActionExample,
|
|
27
28
|
PluginActionInvokeParams,
|
|
28
29
|
PluginActionInvokePort,
|
|
29
30
|
PluginActionInvokeResult,
|
|
31
|
+
PluginActionInputSchema,
|
|
32
|
+
PluginActionMetadata,
|
|
30
33
|
PluginActionResult,
|
|
31
34
|
PluginActions,
|
|
32
35
|
} from "@/types/plugin/PluginAction.js";
|
|
@@ -38,8 +41,10 @@ export type {
|
|
|
38
41
|
PluginHooks,
|
|
39
42
|
PluginPipelineHook,
|
|
40
43
|
AgentPlugins,
|
|
44
|
+
PluginActionReadView,
|
|
41
45
|
PluginResolveHook,
|
|
42
46
|
PluginResolves,
|
|
47
|
+
PluginReadView,
|
|
43
48
|
PluginView,
|
|
44
49
|
} from "@/types/plugin/PluginRuntime.js";
|
|
45
50
|
export type {
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
|
|
9
9
|
import type { Command } from "commander";
|
|
10
10
|
import type { Context as HonoContext } from "hono";
|
|
11
|
+
import type { z } from "zod";
|
|
11
12
|
import type { AgentContext } from "@/types/runtime/agent/AgentContext.js";
|
|
12
|
-
import type { JsonValue } from "@/types/common/Json.js";
|
|
13
|
+
import type { JsonObject, JsonValue } from "@/types/common/Json.js";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Plugin action 调用参数。
|
|
@@ -93,13 +94,51 @@ export interface PluginActionApi<P extends JsonValue = JsonValue> {
|
|
|
93
94
|
mapInput?: (ctx: HonoContext) => P | Promise<P>;
|
|
94
95
|
}
|
|
95
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Plugin Action 示例。
|
|
99
|
+
*/
|
|
100
|
+
export interface PluginActionExample<P extends JsonValue = JsonValue> {
|
|
101
|
+
/** 示例标题。 */
|
|
102
|
+
title: string;
|
|
103
|
+
/** 示例说明。 */
|
|
104
|
+
description?: string;
|
|
105
|
+
/** 示例 payload。 */
|
|
106
|
+
payload: P;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Plugin Action 输入 schema。
|
|
111
|
+
*
|
|
112
|
+
* 关键点(中文)
|
|
113
|
+
* - 优先支持 Zod,运行时用 safeParse 做校验。
|
|
114
|
+
* - `json_schema` 用于给模型或 UI 读取;没有时仍可依赖 description/examples。
|
|
115
|
+
*/
|
|
116
|
+
export interface PluginActionInputSchema<P extends JsonValue = JsonValue> {
|
|
117
|
+
/** Zod schema,负责运行时校验与 TypeScript 推导。 */
|
|
118
|
+
zod?: z.ZodTypeAny;
|
|
119
|
+
/** 面向模型和 UI 的 JSON Schema 描述。 */
|
|
120
|
+
json_schema?: JsonObject;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Plugin Action 元数据。
|
|
125
|
+
*/
|
|
126
|
+
export interface PluginActionMetadata<P extends JsonValue = JsonValue> {
|
|
127
|
+
/** Action 用途说明。 */
|
|
128
|
+
description?: string;
|
|
129
|
+
/** Action 输入 schema。 */
|
|
130
|
+
input_schema?: PluginActionInputSchema<P>;
|
|
131
|
+
/** Action 调用示例。 */
|
|
132
|
+
examples?: PluginActionExample<P>[];
|
|
133
|
+
}
|
|
134
|
+
|
|
96
135
|
/**
|
|
97
136
|
* Plugin Action 定义。
|
|
98
137
|
*/
|
|
99
138
|
export interface PluginAction<
|
|
100
139
|
P extends JsonValue = JsonValue,
|
|
101
140
|
R extends JsonValue = JsonValue,
|
|
102
|
-
> {
|
|
141
|
+
> extends PluginActionMetadata<P> {
|
|
103
142
|
/**
|
|
104
143
|
* disabled 状态下是否仍允许执行。
|
|
105
144
|
*
|
|
@@ -118,6 +157,8 @@ export interface PluginAction<
|
|
|
118
157
|
context: AgentContext;
|
|
119
158
|
/** 输入 payload。 */
|
|
120
159
|
payload: P;
|
|
160
|
+
/** 已通过 schema 校验后的输入。 */
|
|
161
|
+
input: P;
|
|
121
162
|
/** 当前插件名称。 */
|
|
122
163
|
pluginName: string;
|
|
123
164
|
/** 当前 Action 名称。 */
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
} from "@/types/runtime/agent/AgentContext.js";
|
|
13
13
|
import type { JsonValue } from "@/types/common/Json.js";
|
|
14
14
|
import type { PluginActionResult } from "@/types/plugin/PluginAction.js";
|
|
15
|
+
import type { PluginActionExample } from "@/types/plugin/PluginAction.js";
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Plugin 概览视图。
|
|
@@ -39,6 +40,42 @@ export interface PluginView {
|
|
|
39
40
|
hasAvailability: boolean;
|
|
40
41
|
}
|
|
41
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Plugin Action 读取视图。
|
|
45
|
+
*/
|
|
46
|
+
export interface PluginActionReadView {
|
|
47
|
+
/** Action 名称。 */
|
|
48
|
+
name: string;
|
|
49
|
+
/** Action 用途说明。 */
|
|
50
|
+
description: string;
|
|
51
|
+
/** 是否声明输入 schema。 */
|
|
52
|
+
has_input_schema: boolean;
|
|
53
|
+
/** JSON Schema 形式的输入说明。 */
|
|
54
|
+
input_schema?: JsonValue;
|
|
55
|
+
/** Action 调用示例。 */
|
|
56
|
+
examples?: PluginActionExample[];
|
|
57
|
+
/** disabled 状态下是否仍允许执行。 */
|
|
58
|
+
allow_when_disabled: boolean;
|
|
59
|
+
/** 是否声明 CLI command。 */
|
|
60
|
+
has_command: boolean;
|
|
61
|
+
/** 是否声明 HTTP API。 */
|
|
62
|
+
has_api: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Plugin 读取视图。
|
|
67
|
+
*/
|
|
68
|
+
export interface PluginReadView {
|
|
69
|
+
/** Plugin 稳定名称。 */
|
|
70
|
+
name: string;
|
|
71
|
+
/** Plugin 展示标题。 */
|
|
72
|
+
title: string;
|
|
73
|
+
/** Plugin 用途说明。 */
|
|
74
|
+
description: string;
|
|
75
|
+
/** Action 列表或指定 action。 */
|
|
76
|
+
actions: PluginActionReadView[];
|
|
77
|
+
}
|
|
78
|
+
|
|
42
79
|
/**
|
|
43
80
|
* Plugin 可用性结果。
|
|
44
81
|
*/
|
|
@@ -57,6 +94,13 @@ export interface PluginAvailability {
|
|
|
57
94
|
export interface AgentPlugins {
|
|
58
95
|
/** 列出全部已注册 plugin。 */
|
|
59
96
|
list(): PluginView[];
|
|
97
|
+
/** 读取 plugin / action metadata。 */
|
|
98
|
+
read(params: {
|
|
99
|
+
/** Plugin 名称。 */
|
|
100
|
+
plugin?: string;
|
|
101
|
+
/** Action 名称。 */
|
|
102
|
+
action?: string;
|
|
103
|
+
}): PluginReadView | { plugins: PluginView[] };
|
|
60
104
|
/** 检查指定 plugin 可用性。 */
|
|
61
105
|
availability(pluginName: string): Promise<PluginAvailability>;
|
|
62
106
|
/** 运行指定 plugin action。 */
|