@downcity/agent 1.1.174 → 1.1.178
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/AgentPluginFactory.d.ts +4 -2
- package/bin/agent/local/AgentPluginFactory.d.ts.map +1 -1
- package/bin/agent/local/AgentPluginFactory.js +4 -6
- package/bin/agent/local/AgentPluginFactory.js.map +1 -1
- package/bin/agent/local/AgentRuntimeAssembly.d.ts.map +1 -1
- package/bin/agent/local/AgentRuntimeAssembly.js +3 -8
- package/bin/agent/local/AgentRuntimeAssembly.js.map +1 -1
- package/bin/agent/local/ProjectSetup.d.ts +1 -1
- package/bin/agent/local/ProjectSetup.d.ts.map +1 -1
- package/bin/agent/local/ProjectSetup.js +2 -6
- package/bin/agent/local/ProjectSetup.js.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.d.ts +2 -3
- package/bin/agent/local/services/AgentAssemblyService.d.ts.map +1 -1
- package/bin/agent/local/services/AgentAssemblyService.js +9 -14
- package/bin/agent/local/services/AgentAssemblyService.js.map +1 -1
- package/bin/agent/local/services/AgentBackgroundService.d.ts.map +1 -1
- package/bin/agent/local/services/AgentBackgroundService.js +5 -6
- package/bin/agent/local/services/AgentBackgroundService.js.map +1 -1
- package/bin/agent/local/services/AgentSessionManager.d.ts +2 -2
- package/bin/agent/local/services/AgentSessionManager.d.ts.map +1 -1
- package/bin/agent/local/services/AgentSessionManager.js +1 -28
- package/bin/agent/local/services/AgentSessionManager.js.map +1 -1
- package/bin/config/AgentInitializer.d.ts +4 -4
- package/bin/config/AgentInitializer.d.ts.map +1 -1
- package/bin/config/AgentInitializer.js +7 -49
- package/bin/config/AgentInitializer.js.map +1 -1
- package/bin/config/DowncitySchema.d.ts +3 -4
- package/bin/config/DowncitySchema.d.ts.map +1 -1
- package/bin/config/DowncitySchema.js +1 -2
- package/bin/config/DowncitySchema.js.map +1 -1
- package/bin/executor/Executor.d.ts.map +1 -1
- package/bin/executor/Executor.js +1 -1
- package/bin/executor/Executor.js.map +1 -1
- package/bin/executor/composer/system/default/SystemDomain.d.ts.map +1 -1
- package/bin/executor/composer/system/default/SystemDomain.js +1 -2
- package/bin/executor/composer/system/default/SystemDomain.js.map +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.d.ts +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.d.ts.map +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.js +1 -1
- package/bin/executor/composer/system/default/assets/core.prompt.js.map +1 -1
- package/bin/index.d.ts +0 -2
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +1 -4
- package/bin/index.js.map +1 -1
- package/bin/plugin/core/Activation.d.ts +6 -5
- package/bin/plugin/core/Activation.d.ts.map +1 -1
- package/bin/plugin/core/Activation.js +9 -9
- package/bin/plugin/core/Activation.js.map +1 -1
- package/bin/plugin/core/BasePlugin.d.ts +5 -4
- package/bin/plugin/core/BasePlugin.d.ts.map +1 -1
- package/bin/plugin/core/BasePlugin.js +7 -4
- package/bin/plugin/core/BasePlugin.js.map +1 -1
- package/bin/plugin/core/HookRegistry.d.ts +4 -0
- package/bin/plugin/core/HookRegistry.d.ts.map +1 -1
- package/bin/plugin/core/HookRegistry.js +40 -0
- package/bin/plugin/core/HookRegistry.js.map +1 -1
- package/bin/plugin/core/Manager.d.ts +1 -1
- package/bin/plugin/core/Manager.d.ts.map +1 -1
- package/bin/plugin/core/Manager.js +1 -1
- package/bin/plugin/core/Manager.js.map +1 -1
- package/bin/plugin/core/PluginActionRunner.d.ts +13 -7
- package/bin/plugin/core/PluginActionRunner.d.ts.map +1 -1
- package/bin/plugin/core/PluginActionRunner.js +46 -111
- package/bin/plugin/core/PluginActionRunner.js.map +1 -1
- package/bin/plugin/core/PluginCatalog.d.ts +1 -1
- package/bin/plugin/core/PluginCatalog.d.ts.map +1 -1
- package/bin/plugin/core/PluginCatalog.js +1 -21
- package/bin/plugin/core/PluginCatalog.js.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.d.ts +12 -2
- package/bin/plugin/core/PluginLocalExecution.d.ts.map +1 -1
- package/bin/plugin/core/PluginLocalExecution.js +18 -24
- package/bin/plugin/core/PluginLocalExecution.js.map +1 -1
- package/bin/plugin/core/PluginRegistry.d.ts +60 -7
- package/bin/plugin/core/PluginRegistry.d.ts.map +1 -1
- package/bin/plugin/core/PluginRegistry.js +269 -42
- package/bin/plugin/core/PluginRegistry.js.map +1 -1
- package/bin/plugin/core/PluginStateController.d.ts +11 -36
- package/bin/plugin/core/PluginStateController.d.ts.map +1 -1
- package/bin/plugin/core/PluginStateController.js +45 -190
- package/bin/plugin/core/PluginStateController.js.map +1 -1
- package/bin/plugin/types/Plugin.d.ts +1 -1
- package/bin/plugin/types/Plugin.d.ts.map +1 -1
- package/bin/plugin/types/PluginState.d.ts +1 -1
- package/bin/plugin/types/PluginState.d.ts.map +1 -1
- package/bin/plugin/types/Plugins.d.ts +12 -12
- package/bin/plugin/types/Plugins.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.d.ts.map +1 -1
- package/bin/session/services/SessionStateService.js +1 -1
- package/bin/session/services/SessionStateService.js.map +1 -1
- package/bin/types/agent/AgentOptions.d.ts +12 -3
- package/bin/types/agent/AgentOptions.d.ts.map +1 -1
- package/bin/types/agent/AgentRuntimeAssembly.d.ts +1 -1
- package/bin/types/config/AgentProject.d.ts +6 -14
- package/bin/types/config/AgentProject.d.ts.map +1 -1
- package/bin/types/plugin/PluginRuntime.d.ts +23 -2
- package/bin/types/plugin/PluginRuntime.d.ts.map +1 -1
- package/bin/types/plugin/PluginState.d.ts +47 -36
- package/bin/types/plugin/PluginState.d.ts.map +1 -1
- package/bin/types/plugin/PluginState.js +4 -3
- package/bin/types/plugin/PluginState.js.map +1 -1
- package/bin/types/runtime/agent/AgentContext.d.ts +3 -3
- package/bin/types/runtime/agent/AgentContext.d.ts.map +1 -1
- package/bin/types/runtime/agent/AgentContext.js.map +1 -1
- package/package.json +3 -3
- package/src/agent/local/AgentPluginFactory.ts +8 -8
- package/src/agent/local/AgentRuntimeAssembly.ts +3 -9
- package/src/agent/local/ProjectSetup.ts +1 -8
- package/src/agent/local/services/AgentAssemblyService.ts +13 -23
- package/src/agent/local/services/AgentBackgroundService.ts +5 -6
- package/src/agent/local/services/AgentSessionManager.ts +4 -26
- package/src/config/AgentInitializer.ts +7 -57
- package/src/config/DowncitySchema.ts +3 -4
- package/src/executor/Executor.ts +1 -3
- package/src/executor/composer/system/default/SystemDomain.ts +1 -2
- package/src/executor/composer/system/default/assets/core.prompt.ts +1 -1
- package/src/executor/composer/system/default/assets/core.prompt.ts.txt +1 -1
- package/src/index.ts +1 -8
- package/src/plugin/core/Activation.ts +10 -10
- package/src/plugin/core/BasePlugin.ts +9 -6
- package/src/plugin/core/HookRegistry.ts +41 -0
- package/src/plugin/core/Manager.ts +0 -2
- package/src/plugin/core/PluginActionRunner.ts +52 -133
- package/src/plugin/core/PluginCatalog.ts +1 -23
- package/src/plugin/core/PluginLocalExecution.ts +30 -25
- package/src/plugin/core/PluginRegistry.ts +298 -44
- package/src/plugin/core/PluginStateController.ts +45 -235
- package/src/plugin/types/Plugin.ts +2 -1
- package/src/plugin/types/PluginState.ts +2 -1
- package/src/plugin/types/Plugins.ts +12 -12
- package/src/session/services/SessionStateService.ts +1 -3
- package/src/types/agent/AgentOptions.ts +13 -3
- package/src/types/agent/AgentRuntimeAssembly.ts +1 -1
- package/src/types/config/AgentProject.ts +7 -15
- package/src/types/plugin/PluginRuntime.ts +23 -2
- package/src/types/plugin/PluginState.ts +50 -43
- package/src/types/runtime/agent/AgentContext.ts +3 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/bin/config/Defaults.d.ts +0 -21
- package/bin/config/Defaults.d.ts.map +0 -1
- package/bin/config/Defaults.js +0 -47
- package/bin/config/Defaults.js.map +0 -1
- package/bin/plugin/core/ProjectConfigStore.d.ts +0 -84
- package/bin/plugin/core/ProjectConfigStore.d.ts.map +0 -1
- package/bin/plugin/core/ProjectConfigStore.js +0 -89
- package/bin/plugin/core/ProjectConfigStore.js.map +0 -1
- package/src/config/Defaults.ts +0 -49
- package/src/plugin/core/ProjectConfigStore.ts +0 -155
|
@@ -4,21 +4,25 @@
|
|
|
4
4
|
* 关键点(中文)
|
|
5
5
|
* - 这里不创建或维护任何全局注册表,调用方必须显式传入 plugin 集合。
|
|
6
6
|
* - 用于 CLI / 控制面这类没有运行中 Agent 实例、但需要执行 setup action 的场景。
|
|
7
|
-
* - 真正运行中的 Agent 仍应优先使用 `
|
|
7
|
+
* - 真正运行中的 Agent 仍应优先使用 `Agent.plugins.runAction`。
|
|
8
8
|
*/
|
|
9
9
|
import path from "node:path";
|
|
10
10
|
import { logger as defaultLogger } from "../../utils/logger/Logger.js";
|
|
11
|
-
import {
|
|
12
|
-
import { isPluginEnabled } from "../../plugin/core/Activation.js";
|
|
11
|
+
import { resolveAgentEnv } from "../../config/Config.js";
|
|
13
12
|
import { findPluginByName } from "../../plugin/core/PluginCatalog.js";
|
|
14
13
|
import { createAgentPathRuntime, createAgentPluginConfigRuntime, } from "../../agent/local/AgentRuntimeAssembly.js";
|
|
14
|
+
import { createFallbackSdkConfig } from "../../agent/local/AgentInstructions.js";
|
|
15
15
|
/**
|
|
16
16
|
* 创建本地 plugin 命令上下文。
|
|
17
17
|
*/
|
|
18
|
-
export function createLocalPluginCommandContext(
|
|
18
|
+
export function createLocalPluginCommandContext(input) {
|
|
19
|
+
const projectRoot = typeof input === "string" ? input : input.projectRoot;
|
|
19
20
|
const rootPath = path.resolve(String(projectRoot || "").trim() || ".");
|
|
20
21
|
const env = resolveAgentEnv(rootPath);
|
|
21
|
-
const config =
|
|
22
|
+
const config = typeof input === "string" || !input.config
|
|
23
|
+
? createFallbackSdkConfig(path.basename(rootPath) || "agent")
|
|
24
|
+
: input.config;
|
|
25
|
+
const agent_id = String(config.id || "").trim() || path.basename(rootPath) || "agent";
|
|
22
26
|
defaultLogger.bindProjectRoot(rootPath);
|
|
23
27
|
return {
|
|
24
28
|
cwd: rootPath,
|
|
@@ -26,7 +30,7 @@ export function createLocalPluginCommandContext(projectRoot) {
|
|
|
26
30
|
logger: defaultLogger,
|
|
27
31
|
config,
|
|
28
32
|
env,
|
|
29
|
-
paths: createAgentPathRuntime(rootPath,
|
|
33
|
+
paths: createAgentPathRuntime(rootPath, agent_id),
|
|
30
34
|
pluginConfig: createAgentPluginConfigRuntime(rootPath),
|
|
31
35
|
};
|
|
32
36
|
}
|
|
@@ -42,18 +46,13 @@ export async function getLocalPluginAvailability(params) {
|
|
|
42
46
|
reasons: [`Unknown plugin: ${params.pluginName}`],
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
|
-
const context = createLocalPluginCommandContext(
|
|
49
|
+
const context = createLocalPluginCommandContext({
|
|
50
|
+
projectRoot: params.projectRoot,
|
|
51
|
+
config: params.config,
|
|
52
|
+
});
|
|
46
53
|
if (plugin.availability) {
|
|
47
54
|
return await plugin.availability(context);
|
|
48
55
|
}
|
|
49
|
-
const enabled = isPluginEnabled({ plugin, context });
|
|
50
|
-
if (!enabled) {
|
|
51
|
-
return {
|
|
52
|
-
enabled: false,
|
|
53
|
-
available: false,
|
|
54
|
-
reasons: [`Plugin "${plugin.name}" is disabled`],
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
56
|
return {
|
|
58
57
|
enabled: true,
|
|
59
58
|
available: true,
|
|
@@ -88,15 +87,10 @@ export async function runLocalPluginAction(params) {
|
|
|
88
87
|
message: `Plugin "${plugin.name}" does not implement action "${actionName}"`,
|
|
89
88
|
};
|
|
90
89
|
}
|
|
91
|
-
const context = createLocalPluginCommandContext(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
success: false,
|
|
96
|
-
error: `Plugin "${plugin.name}" is disabled`,
|
|
97
|
-
message: `Plugin "${plugin.name}" is disabled`,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
90
|
+
const context = createLocalPluginCommandContext({
|
|
91
|
+
projectRoot: params.projectRoot,
|
|
92
|
+
config: params.config,
|
|
93
|
+
});
|
|
100
94
|
try {
|
|
101
95
|
const payload = (params.payload ?? {});
|
|
102
96
|
const schema = action.input_schema?.zod;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginLocalExecution.js","sourceRoot":"","sources":["../../../src/plugin/core/PluginLocalExecution.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"PluginLocalExecution.js","sourceRoot":"","sources":["../../../src/plugin/core/PluginLocalExecution.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +1,75 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Agent plugin runtime。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
5
|
+
* - Plugin 只属于 Agent:注册即生效,卸载即不可见。
|
|
6
|
+
* - 注册时自动启动 plugin lifecycle;卸载时自动停止 plugin lifecycle。
|
|
7
|
+
* - action、system、hook、resolve 都统一以“已注册且 ready”为生效边界。
|
|
7
8
|
*/
|
|
8
9
|
import type { HookRegistry } from "../../plugin/core/HookRegistry.js";
|
|
9
10
|
import type { Plugin, PluginActionResult, AgentPlugins, PluginAvailability, PluginReadView, PluginView } from "../../plugin/types/Plugin.js";
|
|
11
|
+
import type { AgentSessionSystemBlock } from "../../types/agent/AgentTypes.js";
|
|
10
12
|
import type { AgentContext } from "../../types/runtime/agent/AgentContext.js";
|
|
11
13
|
import type { JsonValue } from "../../types/common/Json.js";
|
|
14
|
+
import type { PluginSnapshot } from "../../types/plugin/PluginState.js";
|
|
12
15
|
type ContextResolver = () => AgentContext;
|
|
13
16
|
/**
|
|
14
|
-
* PluginRegistry:plugin
|
|
17
|
+
* PluginRegistry:Agent plugin 注册、卸载与调用实现。
|
|
15
18
|
*/
|
|
16
19
|
export declare class PluginRegistry implements AgentPlugins {
|
|
17
20
|
private readonly contextResolver;
|
|
18
21
|
private readonly hookRegistry;
|
|
19
|
-
private readonly
|
|
22
|
+
private readonly pluginInstances;
|
|
23
|
+
private readonly records;
|
|
20
24
|
constructor(params: {
|
|
21
25
|
contextResolver: ContextResolver;
|
|
22
26
|
hookRegistry: HookRegistry;
|
|
27
|
+
pluginInstances: Map<string, Plugin>;
|
|
23
28
|
});
|
|
24
29
|
/**
|
|
25
|
-
* 注册单个
|
|
30
|
+
* 注册单个 plugin。
|
|
31
|
+
*
|
|
32
|
+
* 说明(中文)
|
|
33
|
+
* - 同名注册表示替换:先卸载旧实例,再注册并启动新实例。
|
|
34
|
+
* - 如果新实例启动失败,会自动回滚为未注册状态并抛错。
|
|
26
35
|
*/
|
|
27
|
-
register(plugin: Plugin):
|
|
36
|
+
register(plugin: Plugin): Promise<PluginSnapshot>;
|
|
37
|
+
/**
|
|
38
|
+
* 同步挂载 plugin 元信息。
|
|
39
|
+
*
|
|
40
|
+
* 说明(中文)
|
|
41
|
+
* - 仅供 Agent 构造期使用,避免构造函数里 await。
|
|
42
|
+
* - 后续 `startAll()` 会统一启动这些初始 plugin。
|
|
43
|
+
*/
|
|
44
|
+
mount(plugin: Plugin): PluginSnapshot;
|
|
45
|
+
/**
|
|
46
|
+
* 卸载指定 plugin。
|
|
47
|
+
*/
|
|
48
|
+
unregister(pluginName: string): Promise<boolean>;
|
|
49
|
+
/**
|
|
50
|
+
* 启动全部已挂载 plugin。
|
|
51
|
+
*/
|
|
52
|
+
startAll(): Promise<PluginSnapshot[]>;
|
|
53
|
+
/**
|
|
54
|
+
* 卸载全部 plugin。
|
|
55
|
+
*/
|
|
56
|
+
unregisterAll(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* 判断 plugin 是否已注册且 ready。
|
|
59
|
+
*/
|
|
60
|
+
isReady(pluginName: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* 读取单个 plugin 快照。
|
|
63
|
+
*/
|
|
64
|
+
status(pluginName: string): PluginSnapshot | null;
|
|
65
|
+
/**
|
|
66
|
+
* 判断 plugin 是否已注册。
|
|
67
|
+
*/
|
|
68
|
+
has(pluginName: string): boolean;
|
|
69
|
+
private register_hooks;
|
|
70
|
+
private unregister_hooks;
|
|
71
|
+
private start_record;
|
|
72
|
+
private stop_record;
|
|
28
73
|
/**
|
|
29
74
|
* 运行 pipeline 点。
|
|
30
75
|
*/
|
|
@@ -49,6 +94,10 @@ export declare class PluginRegistry implements AgentPlugins {
|
|
|
49
94
|
* 列出全部 plugin 概览视图。
|
|
50
95
|
*/
|
|
51
96
|
list(): PluginView[];
|
|
97
|
+
/**
|
|
98
|
+
* 列出全部 plugin 注册快照。
|
|
99
|
+
*/
|
|
100
|
+
snapshots(): PluginSnapshot[];
|
|
52
101
|
/**
|
|
53
102
|
* 读取 action metadata。
|
|
54
103
|
*/
|
|
@@ -78,6 +127,10 @@ export declare class PluginRegistry implements AgentPlugins {
|
|
|
78
127
|
action: string;
|
|
79
128
|
payload?: JsonValue;
|
|
80
129
|
}): Promise<PluginActionResult<JsonValue>>;
|
|
130
|
+
/**
|
|
131
|
+
* 读取当前生效的 plugin system blocks。
|
|
132
|
+
*/
|
|
133
|
+
systemBlocks(): Promise<AgentSessionSystemBlock[]>;
|
|
81
134
|
}
|
|
82
135
|
export {};
|
|
83
136
|
//# sourceMappingURL=PluginRegistry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/plugin/core/PluginRegistry.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"PluginRegistry.d.ts","sourceRoot":"","sources":["../../../src/plugin/core/PluginRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +1,181 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Agent plugin runtime。
|
|
3
3
|
*
|
|
4
4
|
* 关键点(中文)
|
|
5
|
-
* -
|
|
6
|
-
* -
|
|
5
|
+
* - Plugin 只属于 Agent:注册即生效,卸载即不可见。
|
|
6
|
+
* - 注册时自动启动 plugin lifecycle;卸载时自动停止 plugin lifecycle。
|
|
7
|
+
* - action、system、hook、resolve 都统一以“已注册且 ready”为生效边界。
|
|
7
8
|
*/
|
|
8
|
-
import { isPluginEnabled } from "../../plugin/core/Activation.js";
|
|
9
9
|
import { toPluginView } from "../../plugin/core/PluginCatalog.js";
|
|
10
|
+
function now_ms() {
|
|
11
|
+
return Date.now();
|
|
12
|
+
}
|
|
13
|
+
function normalize_plugin_name(plugin_name) {
|
|
14
|
+
return String(plugin_name || "").trim();
|
|
15
|
+
}
|
|
16
|
+
function create_record(plugin) {
|
|
17
|
+
const current_time = now_ms();
|
|
18
|
+
return {
|
|
19
|
+
plugin,
|
|
20
|
+
state: "ready",
|
|
21
|
+
registered_at: current_time,
|
|
22
|
+
updated_at: current_time,
|
|
23
|
+
chain: Promise.resolve(),
|
|
24
|
+
lifecycle_started: false,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function to_plugin_snapshot(record) {
|
|
28
|
+
const plugin = record.plugin;
|
|
29
|
+
const last_error = String(record.last_error || "").trim();
|
|
30
|
+
return {
|
|
31
|
+
name: plugin.name,
|
|
32
|
+
title: String(plugin.title || plugin.name || "").trim(),
|
|
33
|
+
description: String(plugin.description || "").trim(),
|
|
34
|
+
status: record.state,
|
|
35
|
+
state: record.state,
|
|
36
|
+
registered_at: record.registered_at,
|
|
37
|
+
updated_at: record.updated_at,
|
|
38
|
+
updatedAt: record.updated_at,
|
|
39
|
+
...(last_error ? { last_error, lastError: last_error } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function update_record_state(record, state, error) {
|
|
43
|
+
record.state = state;
|
|
44
|
+
record.updated_at = now_ms();
|
|
45
|
+
const normalized_error = String(error || "").trim();
|
|
46
|
+
if (normalized_error) {
|
|
47
|
+
record.last_error = normalized_error;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
delete record.last_error;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function run_serial(record, step) {
|
|
54
|
+
const next = record.chain.then(() => Promise.resolve(step()));
|
|
55
|
+
record.chain = next.then(() => undefined, () => undefined);
|
|
56
|
+
await next;
|
|
57
|
+
}
|
|
10
58
|
/**
|
|
11
|
-
* PluginRegistry:plugin
|
|
59
|
+
* PluginRegistry:Agent plugin 注册、卸载与调用实现。
|
|
12
60
|
*/
|
|
13
61
|
export class PluginRegistry {
|
|
14
62
|
contextResolver;
|
|
15
63
|
hookRegistry;
|
|
16
|
-
|
|
64
|
+
pluginInstances;
|
|
65
|
+
records = new Map();
|
|
17
66
|
constructor(params) {
|
|
18
67
|
this.contextResolver = params.contextResolver;
|
|
19
68
|
this.hookRegistry = params.hookRegistry;
|
|
69
|
+
this.pluginInstances = params.pluginInstances;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 注册单个 plugin。
|
|
73
|
+
*
|
|
74
|
+
* 说明(中文)
|
|
75
|
+
* - 同名注册表示替换:先卸载旧实例,再注册并启动新实例。
|
|
76
|
+
* - 如果新实例启动失败,会自动回滚为未注册状态并抛错。
|
|
77
|
+
*/
|
|
78
|
+
async register(plugin) {
|
|
79
|
+
const key = normalize_plugin_name(plugin.name);
|
|
80
|
+
if (!key) {
|
|
81
|
+
throw new Error("Plugin name is required");
|
|
82
|
+
}
|
|
83
|
+
if (this.records.has(key)) {
|
|
84
|
+
await this.unregister(key);
|
|
85
|
+
}
|
|
86
|
+
const record = create_record(plugin);
|
|
87
|
+
this.records.set(key, record);
|
|
88
|
+
this.register_hooks(plugin);
|
|
89
|
+
this.pluginInstances.set(key, plugin);
|
|
90
|
+
try {
|
|
91
|
+
await this.start_record(record);
|
|
92
|
+
return to_plugin_snapshot(record);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.unregister_hooks(key);
|
|
96
|
+
this.records.delete(key);
|
|
97
|
+
this.pluginInstances.delete(key);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
20
100
|
}
|
|
21
101
|
/**
|
|
22
|
-
*
|
|
102
|
+
* 同步挂载 plugin 元信息。
|
|
103
|
+
*
|
|
104
|
+
* 说明(中文)
|
|
105
|
+
* - 仅供 Agent 构造期使用,避免构造函数里 await。
|
|
106
|
+
* - 后续 `startAll()` 会统一启动这些初始 plugin。
|
|
23
107
|
*/
|
|
24
|
-
|
|
25
|
-
const key =
|
|
108
|
+
mount(plugin) {
|
|
109
|
+
const key = normalize_plugin_name(plugin.name);
|
|
26
110
|
if (!key) {
|
|
27
111
|
throw new Error("Plugin name is required");
|
|
28
112
|
}
|
|
29
|
-
if (this.
|
|
113
|
+
if (this.records.has(key)) {
|
|
30
114
|
throw new Error(`Plugin already registered: ${key}`);
|
|
31
115
|
}
|
|
32
|
-
|
|
116
|
+
const record = create_record(plugin);
|
|
117
|
+
this.records.set(key, record);
|
|
118
|
+
this.register_hooks(plugin);
|
|
119
|
+
this.pluginInstances.set(key, plugin);
|
|
120
|
+
return to_plugin_snapshot(record);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 卸载指定 plugin。
|
|
124
|
+
*/
|
|
125
|
+
async unregister(pluginName) {
|
|
126
|
+
const key = normalize_plugin_name(pluginName);
|
|
127
|
+
if (!key)
|
|
128
|
+
return false;
|
|
129
|
+
const record = this.records.get(key);
|
|
130
|
+
if (!record)
|
|
131
|
+
return false;
|
|
132
|
+
await this.stop_record(record);
|
|
133
|
+
this.unregister_hooks(key);
|
|
134
|
+
this.records.delete(key);
|
|
135
|
+
this.pluginInstances.delete(key);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* 启动全部已挂载 plugin。
|
|
140
|
+
*/
|
|
141
|
+
async startAll() {
|
|
142
|
+
const snapshots = [];
|
|
143
|
+
for (const record of this.records.values()) {
|
|
144
|
+
await this.start_record(record);
|
|
145
|
+
snapshots.push(to_plugin_snapshot(record));
|
|
146
|
+
}
|
|
147
|
+
return snapshots;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* 卸载全部 plugin。
|
|
151
|
+
*/
|
|
152
|
+
async unregisterAll() {
|
|
153
|
+
for (const name of Array.from(this.records.keys())) {
|
|
154
|
+
await this.unregister(name);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 判断 plugin 是否已注册且 ready。
|
|
159
|
+
*/
|
|
160
|
+
isReady(pluginName) {
|
|
161
|
+
const record = this.records.get(normalize_plugin_name(pluginName));
|
|
162
|
+
return Boolean(record && record.state === "ready");
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* 读取单个 plugin 快照。
|
|
166
|
+
*/
|
|
167
|
+
status(pluginName) {
|
|
168
|
+
const record = this.records.get(normalize_plugin_name(pluginName));
|
|
169
|
+
return record ? to_plugin_snapshot(record) : null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* 判断 plugin 是否已注册。
|
|
173
|
+
*/
|
|
174
|
+
has(pluginName) {
|
|
175
|
+
return this.records.has(normalize_plugin_name(pluginName));
|
|
176
|
+
}
|
|
177
|
+
register_hooks(plugin) {
|
|
178
|
+
const key = normalize_plugin_name(plugin.name);
|
|
33
179
|
for (const [hookName, handlers] of Object.entries(plugin.hooks?.pipeline || {})) {
|
|
34
180
|
for (const handler of handlers) {
|
|
35
181
|
this.hookRegistry.pipeline(hookName, key, handler);
|
|
@@ -49,6 +195,43 @@ export class PluginRegistry {
|
|
|
49
195
|
this.hookRegistry.resolve(pointName, key, handler);
|
|
50
196
|
}
|
|
51
197
|
}
|
|
198
|
+
unregister_hooks(pluginName) {
|
|
199
|
+
this.hookRegistry.unregisterPlugin(pluginName);
|
|
200
|
+
}
|
|
201
|
+
async start_record(record) {
|
|
202
|
+
if (record.lifecycle_started) {
|
|
203
|
+
update_record_state(record, "ready");
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
await run_serial(record, async () => {
|
|
207
|
+
if (record.lifecycle_started) {
|
|
208
|
+
update_record_state(record, "ready");
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
await record.plugin.lifecycle?.start?.(this.contextResolver());
|
|
213
|
+
record.lifecycle_started = true;
|
|
214
|
+
update_record_state(record, "ready");
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
update_record_state(record, "error", String(error));
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
async stop_record(record) {
|
|
223
|
+
await run_serial(record, async () => {
|
|
224
|
+
if (!record.lifecycle_started)
|
|
225
|
+
return;
|
|
226
|
+
try {
|
|
227
|
+
await record.plugin.lifecycle?.stop?.(this.contextResolver());
|
|
228
|
+
}
|
|
229
|
+
finally {
|
|
230
|
+
record.lifecycle_started = false;
|
|
231
|
+
record.updated_at = now_ms();
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
}
|
|
52
235
|
/**
|
|
53
236
|
* 运行 pipeline 点。
|
|
54
237
|
*/
|
|
@@ -77,14 +260,22 @@ export class PluginRegistry {
|
|
|
77
260
|
* 获取单个 plugin 定义。
|
|
78
261
|
*/
|
|
79
262
|
get(pluginName) {
|
|
80
|
-
return this.
|
|
263
|
+
return this.records.get(normalize_plugin_name(pluginName))?.plugin || null;
|
|
81
264
|
}
|
|
82
265
|
/**
|
|
83
266
|
* 列出全部 plugin 概览视图。
|
|
84
267
|
*/
|
|
85
268
|
list() {
|
|
86
|
-
return Array.from(this.
|
|
87
|
-
.map((
|
|
269
|
+
return Array.from(this.records.values())
|
|
270
|
+
.map((record) => toPluginView(record.plugin))
|
|
271
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* 列出全部 plugin 注册快照。
|
|
275
|
+
*/
|
|
276
|
+
snapshots() {
|
|
277
|
+
return Array.from(this.records.values())
|
|
278
|
+
.map((record) => to_plugin_snapshot(record))
|
|
88
279
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
89
280
|
}
|
|
90
281
|
/**
|
|
@@ -108,7 +299,7 @@ export class PluginRegistry {
|
|
|
108
299
|
* 读取 plugin / action metadata。
|
|
109
300
|
*/
|
|
110
301
|
read(params) {
|
|
111
|
-
const pluginName =
|
|
302
|
+
const pluginName = normalize_plugin_name(params.plugin || "");
|
|
112
303
|
if (!pluginName) {
|
|
113
304
|
return { plugins: this.list() };
|
|
114
305
|
}
|
|
@@ -121,7 +312,7 @@ export class PluginRegistry {
|
|
|
121
312
|
actions: [],
|
|
122
313
|
};
|
|
123
314
|
}
|
|
124
|
-
const actionName =
|
|
315
|
+
const actionName = normalize_plugin_name(params.action || "");
|
|
125
316
|
const actions = Object.entries(plugin.actions || {})
|
|
126
317
|
.filter(([name]) => !actionName || name === actionName)
|
|
127
318
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
@@ -137,26 +328,25 @@ export class PluginRegistry {
|
|
|
137
328
|
* 检查 plugin 可用性。
|
|
138
329
|
*/
|
|
139
330
|
async availability(pluginName) {
|
|
140
|
-
const
|
|
141
|
-
|
|
331
|
+
const key = normalize_plugin_name(pluginName);
|
|
332
|
+
const record = this.records.get(key);
|
|
333
|
+
if (!record) {
|
|
142
334
|
return {
|
|
143
335
|
enabled: false,
|
|
144
336
|
available: false,
|
|
145
337
|
reasons: [`Unknown plugin: ${pluginName}`],
|
|
146
338
|
};
|
|
147
339
|
}
|
|
148
|
-
if (
|
|
149
|
-
return await plugin.availability(this.contextResolver());
|
|
150
|
-
}
|
|
151
|
-
const context = this.contextResolver();
|
|
152
|
-
const enabled = isPluginEnabled({ plugin, context });
|
|
153
|
-
if (!enabled) {
|
|
340
|
+
if (record.state !== "ready") {
|
|
154
341
|
return {
|
|
155
|
-
enabled:
|
|
342
|
+
enabled: true,
|
|
156
343
|
available: false,
|
|
157
|
-
reasons: [`Plugin "${plugin.name}" is
|
|
344
|
+
reasons: [record.last_error || `Plugin "${record.plugin.name}" is not ready`],
|
|
158
345
|
};
|
|
159
346
|
}
|
|
347
|
+
if (record.plugin.availability) {
|
|
348
|
+
return await record.plugin.availability(this.contextResolver());
|
|
349
|
+
}
|
|
160
350
|
return {
|
|
161
351
|
enabled: true,
|
|
162
352
|
available: true,
|
|
@@ -184,15 +374,16 @@ export class PluginRegistry {
|
|
|
184
374
|
* 运行 plugin action。
|
|
185
375
|
*/
|
|
186
376
|
async runAction(params) {
|
|
187
|
-
const
|
|
188
|
-
|
|
377
|
+
const key = normalize_plugin_name(params.plugin);
|
|
378
|
+
const record = this.records.get(key);
|
|
379
|
+
if (!record) {
|
|
189
380
|
return {
|
|
190
381
|
success: false,
|
|
191
382
|
error: `Unknown plugin: ${params.plugin}`,
|
|
192
383
|
message: `Unknown plugin: ${params.plugin}`,
|
|
193
384
|
};
|
|
194
385
|
}
|
|
195
|
-
const actionName =
|
|
386
|
+
const actionName = normalize_plugin_name(params.action);
|
|
196
387
|
if (!actionName) {
|
|
197
388
|
return {
|
|
198
389
|
success: false,
|
|
@@ -200,26 +391,24 @@ export class PluginRegistry {
|
|
|
200
391
|
message: "action is required",
|
|
201
392
|
};
|
|
202
393
|
}
|
|
203
|
-
|
|
204
|
-
if (!action) {
|
|
394
|
+
if (record.state !== "ready") {
|
|
205
395
|
return {
|
|
206
396
|
success: false,
|
|
207
|
-
error: `Plugin "${plugin.name}"
|
|
208
|
-
message: `Plugin "${plugin.name}"
|
|
397
|
+
error: `Plugin "${record.plugin.name}" is not ready`,
|
|
398
|
+
message: `Plugin "${record.plugin.name}" is not ready`,
|
|
209
399
|
};
|
|
210
400
|
}
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
if (!enabled && action.allowWhenDisabled !== true) {
|
|
401
|
+
const action = record.plugin.actions?.[actionName];
|
|
402
|
+
if (!action) {
|
|
214
403
|
return {
|
|
215
404
|
success: false,
|
|
216
|
-
error: `Plugin "${plugin.name}"
|
|
217
|
-
message: `Plugin "${plugin.name}"
|
|
405
|
+
error: `Plugin "${record.plugin.name}" does not implement action "${actionName}"`,
|
|
406
|
+
message: `Plugin "${record.plugin.name}" does not implement action "${actionName}"`,
|
|
218
407
|
};
|
|
219
408
|
}
|
|
220
409
|
try {
|
|
221
410
|
const parsed_payload = this.parseActionPayload({
|
|
222
|
-
pluginName: plugin.name,
|
|
411
|
+
pluginName: record.plugin.name,
|
|
223
412
|
actionName,
|
|
224
413
|
payload: (params.payload ?? {}),
|
|
225
414
|
action,
|
|
@@ -227,15 +416,20 @@ export class PluginRegistry {
|
|
|
227
416
|
if (!("input" in parsed_payload)) {
|
|
228
417
|
return parsed_payload;
|
|
229
418
|
}
|
|
230
|
-
|
|
231
|
-
context,
|
|
419
|
+
const result = await action.execute({
|
|
420
|
+
context: this.contextResolver(),
|
|
232
421
|
payload: parsed_payload.input,
|
|
233
422
|
input: parsed_payload.input,
|
|
234
|
-
pluginName: plugin.name,
|
|
423
|
+
pluginName: record.plugin.name,
|
|
235
424
|
actionName,
|
|
236
425
|
});
|
|
426
|
+
if (!result.success) {
|
|
427
|
+
update_record_state(record, "error", result.error || result.message);
|
|
428
|
+
}
|
|
429
|
+
return result;
|
|
237
430
|
}
|
|
238
431
|
catch (error) {
|
|
432
|
+
update_record_state(record, "error", String(error));
|
|
239
433
|
return {
|
|
240
434
|
success: false,
|
|
241
435
|
error: String(error),
|
|
@@ -243,5 +437,38 @@ export class PluginRegistry {
|
|
|
243
437
|
};
|
|
244
438
|
}
|
|
245
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* 读取当前生效的 plugin system blocks。
|
|
442
|
+
*/
|
|
443
|
+
async systemBlocks() {
|
|
444
|
+
const context = this.contextResolver();
|
|
445
|
+
const out = [];
|
|
446
|
+
for (const record of this.records.values()) {
|
|
447
|
+
const plugin = record.plugin;
|
|
448
|
+
if (record.state !== "ready")
|
|
449
|
+
continue;
|
|
450
|
+
if (typeof plugin.system !== "function")
|
|
451
|
+
continue;
|
|
452
|
+
try {
|
|
453
|
+
if (typeof plugin.availability === "function") {
|
|
454
|
+
const availability = await plugin.availability(context);
|
|
455
|
+
if (!availability.available)
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
const text = String(await plugin.system(context)).trim();
|
|
459
|
+
if (!text)
|
|
460
|
+
continue;
|
|
461
|
+
out.push({
|
|
462
|
+
source: "plugin",
|
|
463
|
+
name: plugin.name,
|
|
464
|
+
content: text,
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
catch {
|
|
468
|
+
// 单个 plugin system 失败不应阻断 session 主链路。
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return out;
|
|
472
|
+
}
|
|
246
473
|
}
|
|
247
474
|
//# sourceMappingURL=PluginRegistry.js.map
|