@actiondock/core 2.6.0 → 2.8.0
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/README.md +61 -68
- package/dist/catalog/action-catalog.d.ts +56 -0
- package/dist/catalog/action-catalog.js +202 -0
- package/dist/catalog/discovery.d.ts +60 -0
- package/dist/catalog/discovery.js +119 -0
- package/dist/catalog/graph.d.ts +190 -0
- package/dist/catalog/graph.js +589 -0
- package/dist/catalog/index.d.ts +5 -5
- package/dist/catalog/index.js +5 -5
- package/dist/catalog/resolve-action.d.ts +43 -0
- package/dist/catalog/resolve-action.js +119 -0
- package/dist/catalog/resolve-playbook.d.ts +26 -0
- package/dist/catalog/resolve-playbook.js +114 -0
- package/dist/doctor/checks/project.js +27 -8
- package/dist/doctor/checks/registry.js +2 -2
- package/dist/doctor/checks/runtime.js +34 -1
- package/dist/errors.d.ts +122 -10
- package/dist/errors.js +123 -10
- package/dist/execution/service.d.ts +18 -16
- package/dist/execution/service.js +183 -252
- package/dist/execution/types.d.ts +25 -69
- package/dist/execution/types.js +2 -1
- package/dist/filter/intent.d.ts +8 -9
- package/dist/filter/intent.js +49 -10
- package/dist/graph/index.d.ts +4 -0
- package/dist/graph/index.js +4 -0
- package/dist/host/host.d.ts +74 -32
- package/dist/host/host.js +585 -336
- package/dist/host/routing.d.ts +15 -48
- package/dist/host/routing.js +90 -153
- package/dist/host/types.d.ts +50 -17
- package/dist/index.d.ts +21 -22
- package/dist/index.js +19 -21
- package/dist/input/advice.d.ts +104 -0
- package/dist/input/advice.js +716 -0
- package/dist/input/describe.d.ts +106 -0
- package/dist/input/describe.js +176 -0
- package/dist/input/file-input.d.ts +54 -0
- package/dist/input/file-input.js +124 -0
- package/dist/input/flat-decode.d.ts +11 -0
- package/dist/input/flat-decode.js +13 -0
- package/dist/input/flat-errors.d.ts +71 -0
- package/dist/input/flat-errors.js +87 -0
- package/dist/input/flat-materializer.d.ts +29 -0
- package/dist/input/flat-materializer.js +177 -0
- package/dist/input/flat-parser.d.ts +50 -0
- package/dist/input/flat-parser.js +169 -0
- package/dist/input/flat-predicates.d.ts +34 -0
- package/dist/input/flat-predicates.js +50 -0
- package/dist/input/index.d.ts +14 -0
- package/dist/input/index.js +14 -0
- package/dist/input/input-resolver.d.ts +63 -0
- package/dist/input/input-resolver.js +254 -0
- package/dist/input/json-depth-scanner.d.ts +17 -0
- package/dist/input/json-depth-scanner.js +49 -0
- package/dist/input/metadata.d.ts +99 -0
- package/dist/input/metadata.js +99 -0
- package/dist/input/stdin-input.d.ts +26 -0
- package/dist/input/stdin-input.js +125 -0
- package/dist/input/utf8.d.ts +19 -0
- package/dist/input/utf8.js +36 -0
- package/dist/input/validation-mapper.d.ts +27 -0
- package/dist/input/validation-mapper.js +144 -0
- package/dist/invocation/index.d.ts +2 -0
- package/dist/invocation/index.js +2 -0
- package/dist/invocation/policy.d.ts +157 -0
- package/dist/invocation/policy.js +231 -0
- package/dist/invocation/types.d.ts +172 -0
- package/dist/invocation/types.js +97 -0
- package/dist/ipc/diagnostic.d.ts +0 -12
- package/dist/ipc/diagnostic.js +0 -21
- package/dist/ipc/host.d.ts +4 -4
- package/dist/ipc/host.js +44 -47
- package/dist/ipc/index.d.ts +1 -1
- package/dist/ipc/index.js +1 -1
- package/dist/ipc/service.d.ts +40 -0
- package/dist/ipc/service.js +349 -0
- package/dist/ipc/types.d.ts +21 -15
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +1 -0
- package/dist/json/value-validator.d.ts +88 -0
- package/dist/json/value-validator.js +330 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.js +1 -0
- package/dist/node/module-loader.d.ts +63 -0
- package/dist/node/module-loader.js +112 -0
- package/dist/package/index.d.ts +23 -0
- package/dist/package/index.js +18 -0
- package/dist/{app/app.d.ts → package/runtime.d.ts} +41 -20
- package/dist/{app/app.js → package/runtime.js} +140 -95
- package/dist/{app → package}/static-index.js +58 -41
- package/dist/package/storage-view.d.ts +13 -0
- package/dist/package/storage-view.js +22 -0
- package/dist/{app → package}/types.d.ts +76 -57
- package/dist/package/types.js +22 -0
- package/dist/platform/index.d.ts +1 -1
- package/dist/platform/index.js +1 -1
- package/dist/platform/node.d.ts +48 -0
- package/dist/platform/node.js +96 -0
- package/dist/platform/types.d.ts +0 -9
- package/dist/process/control-arbiter.d.ts +2 -1
- package/dist/process/control-arbiter.js +1 -2
- package/dist/process/driver.d.ts +9 -8
- package/dist/process/driver.js +11 -22
- package/dist/process/index.d.ts +2 -0
- package/dist/process/index.js +2 -0
- package/dist/process/managed-record.d.ts +2 -2
- package/dist/process/process-driver.d.ts +109 -0
- package/dist/process/process-driver.js +650 -0
- package/dist/process/process-executor.d.ts +47 -0
- package/dist/process/process-executor.js +296 -0
- package/dist/process/process-manager.js +48 -26
- package/dist/process/run-executor.js +12 -12
- package/dist/profile/client-actions.js +2 -2
- package/dist/profile/client-health.js +3 -2
- package/dist/profile/client-query.js +5 -6
- package/dist/profile/client-transport.d.ts +19 -17
- package/dist/profile/client-transport.js +48 -80
- package/dist/profile/client.d.ts +2 -2
- package/dist/profile/client.js +1 -1
- package/dist/profile/index.d.ts +1 -0
- package/dist/profile/index.js +1 -0
- package/dist/profile/manager.d.ts +5 -0
- package/dist/profile/manager.js +41 -6
- package/dist/project/closure.js +2 -2
- package/dist/project/index.d.ts +8 -1
- package/dist/project/index.js +10 -1
- package/dist/project/init.js +2 -2
- package/dist/project/loader.d.ts +1 -1
- package/dist/project/loader.js +26 -29
- package/dist/project/transactions.js +5 -10
- package/dist/registry/index.d.ts +3 -1
- package/dist/registry/index.js +2 -1
- package/dist/registry/lock.d.ts +28 -7
- package/dist/registry/lock.js +136 -16
- package/dist/registry/registry.d.ts +1 -5
- package/dist/registry/registry.js +1 -53
- package/dist/registry/scan.d.ts +0 -15
- package/dist/registry/scan.js +0 -59
- package/dist/registry/store.d.ts +42 -0
- package/dist/registry/store.js +43 -0
- package/dist/registry/types.d.ts +0 -24
- package/dist/runtime/action-collection.d.ts +1 -1
- package/dist/runtime/action-registry.d.ts +0 -4
- package/dist/runtime/action-registry.js +0 -7
- package/dist/runtime/context.js +5 -11
- package/dist/runtime/events.js +3 -6
- package/dist/runtime/identity.d.ts +22 -0
- package/dist/runtime/identity.js +10 -0
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +1 -2
- package/dist/runtime/module-loader.d.ts +2 -34
- package/dist/runtime/module-loader.js +1 -16
- package/dist/runtime/process.d.ts +6 -24
- package/dist/runtime/process.js +1 -118
- package/dist/runtime/run-persistence.js +2 -5
- package/dist/runtime/runner.d.ts +33 -103
- package/dist/runtime/runner.js +142 -404
- package/dist/runtime/standalone.d.ts +37 -9
- package/dist/runtime/standalone.js +195 -136
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/validator.d.ts +10 -0
- package/dist/schema/validator.js +48 -54
- package/dist/server/body.d.ts +16 -8
- package/dist/server/body.js +33 -16
- package/dist/server/dispatcher.d.ts +6 -10
- package/dist/server/dispatcher.js +24 -32
- package/dist/server/http-server.d.ts +87 -0
- package/dist/server/http-server.js +304 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.js +10 -0
- package/dist/server/mcp-endpoint.d.ts +61 -0
- package/dist/server/mcp-endpoint.js +118 -0
- package/dist/server/routes/actions.js +34 -28
- package/dist/server/routes/common.d.ts +10 -14
- package/dist/server/routes/common.js +32 -56
- package/dist/server/routes/config.js +54 -64
- package/dist/server/routes/doctor.d.ts +1 -1
- package/dist/server/routes/doctor.js +10 -18
- package/dist/server/routes/health.d.ts +1 -1
- package/dist/server/routes/health.js +2 -3
- package/dist/server/routes/info.d.ts +2 -2
- package/dist/server/routes/info.js +12 -13
- package/dist/server/routes/playbooks.js +16 -29
- package/dist/server/routes/runs.js +95 -117
- package/dist/server/routes/state.js +63 -62
- package/dist/server/server.d.ts +2 -2
- package/dist/server/server.js +43 -227
- package/dist/server/types.d.ts +8 -19
- package/dist/service/factory.d.ts +12 -0
- package/dist/service/factory.js +85 -0
- package/dist/{target → service}/index.d.ts +1 -1
- package/dist/{target → service}/index.js +1 -1
- package/dist/service/local.d.ts +27 -0
- package/dist/service/local.js +138 -0
- package/dist/{target → service}/remote-errors.d.ts +3 -6
- package/dist/service/remote-errors.js +38 -0
- package/dist/{target → service}/remote-polling.d.ts +2 -2
- package/dist/{target → service}/remote-polling.js +8 -8
- package/dist/service/remote.d.ts +34 -0
- package/dist/service/remote.js +634 -0
- package/dist/service/sse-stream.d.ts +24 -0
- package/dist/service/sse-stream.js +139 -0
- package/dist/service/types.d.ts +272 -0
- package/dist/service/types.js +32 -0
- package/dist/storage/data-dir-lock.js +10 -5
- package/dist/storage/driver.d.ts +2 -1
- package/dist/storage/driver.js +3 -52
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.js +1 -0
- package/dist/storage/lock-core.d.ts +2 -6
- package/dist/storage/lock-core.js +4 -17
- package/dist/storage/params.d.ts +2 -8
- package/dist/storage/params.js +2 -8
- package/dist/storage/sqlite-driver.d.ts +40 -0
- package/dist/storage/sqlite-driver.js +116 -0
- package/dist/storage/sqlite.js +21 -6
- package/dist/storage/types.d.ts +4 -4
- package/dist/storage/types.js +2 -2
- package/dist/utils/index.d.ts +53 -0
- package/dist/utils/index.js +99 -4
- package/dist/utils/process.d.ts +10 -0
- package/dist/utils/process.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +41 -3
- package/dist/app/index.d.ts +0 -2
- package/dist/app/index.js +0 -2
- package/dist/app/types.js +0 -1
- package/dist/catalog/action-index.d.ts +0 -9
- package/dist/catalog/action-index.js +0 -95
- package/dist/catalog/action-resolver.d.ts +0 -20
- package/dist/catalog/action-resolver.js +0 -95
- package/dist/catalog/location-registry.d.ts +0 -15
- package/dist/catalog/location-registry.js +0 -138
- package/dist/catalog/package-catalog.d.ts +0 -7
- package/dist/catalog/package-catalog.js +0 -77
- package/dist/catalog/types.d.ts +0 -68
- package/dist/catalog/types.js +0 -1
- package/dist/export/index.d.ts +0 -1
- package/dist/export/index.js +0 -1
- package/dist/export/templates.d.ts +0 -71
- package/dist/export/templates.js +0 -623
- package/dist/ipc/target.d.ts +0 -74
- package/dist/ipc/target.js +0 -365
- package/dist/platform/default.d.ts +0 -38
- package/dist/platform/default.js +0 -78
- package/dist/project/resolver.d.ts +0 -116
- package/dist/project/resolver.js +0 -376
- package/dist/registry/resolve.d.ts +0 -62
- package/dist/registry/resolve.js +0 -195
- package/dist/runtime/execution-manager.d.ts +0 -48
- package/dist/runtime/execution-manager.js +0 -66
- package/dist/runtime/package-runner-factory.d.ts +0 -82
- package/dist/runtime/package-runner-factory.js +0 -186
- package/dist/target/local.d.ts +0 -53
- package/dist/target/local.js +0 -349
- package/dist/target/remote-errors.js +0 -51
- package/dist/target/remote.d.ts +0 -86
- package/dist/target/remote.js +0 -818
- package/dist/target/target.d.ts +0 -6
- package/dist/target/target.js +0 -37
- package/dist/target/types.d.ts +0 -261
- package/dist/target/types.js +0 -35
- /package/dist/{app → package}/static-index.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.d.ts +0 -0
- /package/dist/{target → service}/sse-parser.js +0 -0
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { DefaultExecutionService } from "../execution/service.js";
|
|
4
|
-
import {
|
|
4
|
+
import { createNodePlatform } from "../platform/index.js";
|
|
5
5
|
import { findProjectRoot, loadProjectConfig } from "../project/loader.js";
|
|
6
6
|
import { RuntimeConfig } from "../runtime/context.js";
|
|
7
7
|
import { normalizeActionCollection } from "../runtime/action-collection.js";
|
|
8
|
-
import {
|
|
8
|
+
import { createLazyStorage } from "../storage/index.js";
|
|
9
9
|
import { isSecretConfigKey, sanitizeConfigDefinitions } from "../storage/mask.js";
|
|
10
10
|
import { decodeStateKey, SqliteRuntimeStorage } from "../storage/sqlite.js";
|
|
11
|
+
import { createPackageIdentity } from "../runtime/identity.js";
|
|
12
|
+
import { ACTION_NOT_FOUND, ActionDockError, CAPABILITY_UNAVAILABLE, INVALID_ARGUMENT, INVOCATION_UNSUPPORTED, NOT_FOUND, } from "../errors.js";
|
|
13
|
+
import { createRootInvocationContext } from "../invocation/types.js";
|
|
11
14
|
import { buildStaticActionMap, buildStaticPlaybookMap } from "./static-index.js";
|
|
15
|
+
import { applyActionSummaryFilters } from "./types.js";
|
|
12
16
|
/**
|
|
13
|
-
* ActionDock
|
|
17
|
+
* ActionDock 统一包运行时默认实现。
|
|
14
18
|
* 封装并管理单个 Action Package 的执行引擎、静态元数据索引、配置与状态存储生命周期。
|
|
15
19
|
*/
|
|
16
|
-
export class
|
|
20
|
+
export class DefaultPackageRuntime {
|
|
21
|
+
identity;
|
|
17
22
|
packageId;
|
|
18
23
|
packageInstanceId;
|
|
19
24
|
generationId;
|
|
@@ -27,6 +32,7 @@ export class DefaultActionDockApp {
|
|
|
27
32
|
options;
|
|
28
33
|
runtimeConfig;
|
|
29
34
|
isClosed = false;
|
|
35
|
+
injectedGlobalStorage = false;
|
|
30
36
|
/** 静态清单索引缓存:包静态事实(根目录、配置、内存注入集合)在实例生命周期内不变,解析结果同实例内复用 */
|
|
31
37
|
staticActionIndex;
|
|
32
38
|
staticPlaybookIndex;
|
|
@@ -58,13 +64,18 @@ export class DefaultActionDockApp {
|
|
|
58
64
|
}
|
|
59
65
|
this.packageRoot = packageRoot;
|
|
60
66
|
this.projectConfig = projectConfig;
|
|
61
|
-
this.
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
this.identity = options.identity || createPackageIdentity({
|
|
68
|
+
id: projectConfig.id,
|
|
69
|
+
instanceId: options?.packageInstanceId || projectConfig.packageInstanceId,
|
|
70
|
+
generation: options?.generationId || projectConfig.generationId,
|
|
71
|
+
});
|
|
72
|
+
this.packageId = this.identity.id;
|
|
73
|
+
this.packageInstanceId = this.identity.instanceId;
|
|
74
|
+
this.generationId = this.identity.generation;
|
|
64
75
|
// 2. 转换 Action 集合:委托归一化单一入口
|
|
65
76
|
this.actionsMap = normalizeActionCollection(options.actions).actionsMap;
|
|
66
77
|
// 3. 确定平台适配层
|
|
67
|
-
this.platform = options.platform ??
|
|
78
|
+
this.platform = options.platform ?? createNodePlatform();
|
|
68
79
|
// 4. 确定并初始化存储实例
|
|
69
80
|
if (options.storage) {
|
|
70
81
|
this.storage = options.storage;
|
|
@@ -79,20 +90,8 @@ export class DefaultActionDockApp {
|
|
|
79
90
|
// CLI 查询旁观视图显式置 recoverOrphans: false 跳过收割
|
|
80
91
|
recoverOrphans: options.recoverOrphans !== false,
|
|
81
92
|
};
|
|
82
|
-
const storageFactory = this.platform.storage;
|
|
83
93
|
const initStorage = () => {
|
|
84
|
-
|
|
85
|
-
return storageFactory(this.packageId, storageOpts);
|
|
86
|
-
}
|
|
87
|
-
else if (storageFactory && typeof storageFactory.createStorage === "function") {
|
|
88
|
-
return storageFactory.createStorage(this.packageId, storageOpts);
|
|
89
|
-
}
|
|
90
|
-
else if (storageFactory && typeof storageFactory.create === "function") {
|
|
91
|
-
return storageFactory.create(this.packageId, storageOpts);
|
|
92
|
-
}
|
|
93
|
-
else {
|
|
94
|
-
return createStorage(this.packageId, storageOpts);
|
|
95
|
-
}
|
|
94
|
+
return this.platform.storage.createStorage(this.packageId, storageOpts);
|
|
96
95
|
};
|
|
97
96
|
if (options.inMemory) {
|
|
98
97
|
this.storage = initStorage();
|
|
@@ -104,12 +103,14 @@ export class DefaultActionDockApp {
|
|
|
104
103
|
// 5. 确定全局存储实例
|
|
105
104
|
if (options.globalStorage) {
|
|
106
105
|
this.globalStorage = options.globalStorage;
|
|
106
|
+
this.injectedGlobalStorage = true;
|
|
107
107
|
}
|
|
108
108
|
else if (options.inMemory) {
|
|
109
109
|
this.globalStorage = new SqliteRuntimeStorage({
|
|
110
110
|
dbPath: ":memory:",
|
|
111
111
|
packageId: "__global__",
|
|
112
112
|
});
|
|
113
|
+
this.injectedGlobalStorage = false;
|
|
113
114
|
}
|
|
114
115
|
else {
|
|
115
116
|
const globalOpts = {
|
|
@@ -119,20 +120,15 @@ export class DefaultActionDockApp {
|
|
|
119
120
|
// 与主存储保持同侧收割语义(全局库 runs 表为空集,收割无实际副作用)
|
|
120
121
|
recoverOrphans: options.recoverOrphans !== false,
|
|
121
122
|
};
|
|
122
|
-
const storageFactory = this.platform.storage;
|
|
123
123
|
const initGlobalStorage = () => {
|
|
124
|
-
|
|
125
|
-
return storageFactory.createGlobalStorage(globalOpts);
|
|
126
|
-
}
|
|
127
|
-
return createGlobalStorage(globalOpts);
|
|
124
|
+
return this.platform.storage.createGlobalStorage(globalOpts);
|
|
128
125
|
};
|
|
129
126
|
this.globalStorage = createLazyStorage(initGlobalStorage);
|
|
127
|
+
this.injectedGlobalStorage = false;
|
|
130
128
|
}
|
|
131
129
|
// 6. 初始化唯一执行协调服务
|
|
132
130
|
this.executionService = new DefaultExecutionService({
|
|
133
|
-
|
|
134
|
-
packageInstanceId: this.packageInstanceId,
|
|
135
|
-
generationId: this.generationId,
|
|
131
|
+
identity: this.identity,
|
|
136
132
|
hostSessionId: options.hostSessionId,
|
|
137
133
|
storage: this.storage,
|
|
138
134
|
globalStorage: this.globalStorage,
|
|
@@ -145,14 +141,18 @@ export class DefaultActionDockApp {
|
|
|
145
141
|
logger: options.logger,
|
|
146
142
|
eventSink: options.eventSink ?? this.platform?.eventSink,
|
|
147
143
|
maxActiveRuns: options.maxActiveRuns,
|
|
148
|
-
maxCallDepth: options.maxCallDepth,
|
|
149
|
-
maxSubRuns: options.maxSubRuns,
|
|
150
144
|
ownerId: options.ownerId,
|
|
151
145
|
actionResolver: options.actionResolver,
|
|
152
|
-
packageContextResolver: options.packageContextResolver,
|
|
153
146
|
customHome: options.customHome,
|
|
154
|
-
|
|
147
|
+
moduleLoader: this.platform.modules,
|
|
148
|
+
actionInvoker: options.actionInvoker,
|
|
155
149
|
});
|
|
150
|
+
if (!options.actionInvoker) {
|
|
151
|
+
const unsupportedInvoker = async () => {
|
|
152
|
+
throw new ActionDockError(INVOCATION_UNSUPPORTED, "Cascaded action invocation (ctx.actions.invoke) is not supported in standalone PackageRuntime. Actions must be executed within an ActionDock Host.");
|
|
153
|
+
};
|
|
154
|
+
this.executionService.setActionInvoker?.(unsupportedInvoker);
|
|
155
|
+
}
|
|
156
156
|
// 7. 初始化配置解析器
|
|
157
157
|
this.runtimeConfig = new RuntimeConfig(this.storage, options.configOverrides, this.projectConfig, this.globalStorage);
|
|
158
158
|
}
|
|
@@ -209,7 +209,7 @@ export class DefaultActionDockApp {
|
|
|
209
209
|
}
|
|
210
210
|
async listActions(options) {
|
|
211
211
|
const map = this.getStaticActionMap();
|
|
212
|
-
|
|
212
|
+
const summaries = Array.from(map.values()).map((spec) => ({
|
|
213
213
|
id: spec.id,
|
|
214
214
|
packageId: this.packageId,
|
|
215
215
|
description: spec.description,
|
|
@@ -220,18 +220,7 @@ export class DefaultActionDockApp {
|
|
|
220
220
|
inputSchema: spec.inputSchema,
|
|
221
221
|
outputSchema: spec.outputSchema,
|
|
222
222
|
}));
|
|
223
|
-
|
|
224
|
-
summaries = summaries.filter((s) => options.tags.every((t) => s.tags?.includes(t)));
|
|
225
|
-
}
|
|
226
|
-
if (options?.query) {
|
|
227
|
-
const q = options.query.toLowerCase();
|
|
228
|
-
summaries = summaries.filter((s) => s.id.toLowerCase().includes(q) ||
|
|
229
|
-
(s.description && s.description.toLowerCase().includes(q)));
|
|
230
|
-
}
|
|
231
|
-
if (options?.prefix) {
|
|
232
|
-
summaries = summaries.filter((s) => s.id.startsWith(options.prefix));
|
|
233
|
-
}
|
|
234
|
-
return summaries;
|
|
223
|
+
return applyActionSummaryFilters(summaries, options);
|
|
235
224
|
}
|
|
236
225
|
async describeAction(id) {
|
|
237
226
|
const map = this.getStaticActionMap();
|
|
@@ -253,14 +242,14 @@ export class DefaultActionDockApp {
|
|
|
253
242
|
this.executionService.getAction(id) ||
|
|
254
243
|
(spec ? this.executionService.getAction(spec.id) : undefined);
|
|
255
244
|
}
|
|
256
|
-
if (!liveAction && this.executionService.
|
|
245
|
+
if (!liveAction && this.executionService.resolveAction) {
|
|
257
246
|
try {
|
|
258
247
|
// 仅在本包范围内解析动态动作:限定 packageId 前缀,避免全局兜底搜索把
|
|
259
248
|
// 其他包的动作误计为本包提供者(host 层据此统计候选导致 AMBIGUOUS_ACTION_REF 误报)。
|
|
260
249
|
const qualifiedId = id.includes("/") ? id : `${this.packageId}/${id}`;
|
|
261
|
-
const resolution = await this.executionService.
|
|
262
|
-
if (resolution
|
|
263
|
-
liveAction = resolution
|
|
250
|
+
const resolution = await this.executionService.resolveAction(qualifiedId);
|
|
251
|
+
if (resolution) {
|
|
252
|
+
liveAction = resolution;
|
|
264
253
|
}
|
|
265
254
|
}
|
|
266
255
|
catch {
|
|
@@ -283,7 +272,7 @@ export class DefaultActionDockApp {
|
|
|
283
272
|
};
|
|
284
273
|
}
|
|
285
274
|
if (!spec) {
|
|
286
|
-
throw new
|
|
275
|
+
throw new ActionDockError(ACTION_NOT_FOUND, `Action '${id}' not found in package '${this.packageId}'`);
|
|
287
276
|
}
|
|
288
277
|
return {
|
|
289
278
|
...spec,
|
|
@@ -305,13 +294,28 @@ export class DefaultActionDockApp {
|
|
|
305
294
|
const cleanId = id.replace(/\.md$/, "");
|
|
306
295
|
const spec = map.get(cleanId) || map.get(id);
|
|
307
296
|
if (!spec) {
|
|
308
|
-
throw new
|
|
297
|
+
throw new ActionDockError(NOT_FOUND, `Playbook '${id}' not found in package '${this.packageId}'`);
|
|
309
298
|
}
|
|
310
299
|
return {
|
|
311
300
|
...spec,
|
|
312
301
|
packageId: this.packageId,
|
|
313
302
|
};
|
|
314
303
|
}
|
|
304
|
+
buildRootInvocationContext(actionId, options) {
|
|
305
|
+
const rootKey = `${this.packageId}/${actionId}`;
|
|
306
|
+
return createRootInvocationContext({
|
|
307
|
+
targetPackage: this.identity,
|
|
308
|
+
callStack: [rootKey],
|
|
309
|
+
signal: options?.signal,
|
|
310
|
+
timeoutMs: options?.timeoutMs,
|
|
311
|
+
config: options?.config,
|
|
312
|
+
requestId: options?.requestId,
|
|
313
|
+
hostSessionId: this.options.hostSessionId,
|
|
314
|
+
maxCallDepth: this.options.maxCallDepth,
|
|
315
|
+
logger: this.options.logger,
|
|
316
|
+
process: this.options.process ?? this.platform.process,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
315
319
|
async runAction(id, input, options) {
|
|
316
320
|
let actionId = id;
|
|
317
321
|
if (actionId.includes("/")) {
|
|
@@ -319,10 +323,11 @@ export class DefaultActionDockApp {
|
|
|
319
323
|
actionId = actionId.slice(this.packageId.length + 1);
|
|
320
324
|
}
|
|
321
325
|
else {
|
|
322
|
-
throw new
|
|
326
|
+
throw new ActionDockError(INVOCATION_UNSUPPORTED, `PackageRuntime only accepts local action short ID '${id}'. Cross-package invocations must be dispatched via Host invoker.`);
|
|
323
327
|
}
|
|
324
328
|
}
|
|
325
|
-
|
|
329
|
+
const context = this.buildRootInvocationContext(actionId, options);
|
|
330
|
+
return this.executionService.execute(actionId, input, context);
|
|
326
331
|
}
|
|
327
332
|
async startAction(id, input, options) {
|
|
328
333
|
let actionId = id;
|
|
@@ -331,10 +336,18 @@ export class DefaultActionDockApp {
|
|
|
331
336
|
actionId = actionId.slice(this.packageId.length + 1);
|
|
332
337
|
}
|
|
333
338
|
else {
|
|
334
|
-
throw new
|
|
339
|
+
throw new ActionDockError(INVOCATION_UNSUPPORTED, `PackageRuntime only accepts local action short ID '${id}'. Cross-package invocations must be dispatched via Host invoker.`);
|
|
335
340
|
}
|
|
336
341
|
}
|
|
337
|
-
|
|
342
|
+
const context = this.buildRootInvocationContext(actionId, options);
|
|
343
|
+
return this.executionService.start(actionId, input, context);
|
|
344
|
+
}
|
|
345
|
+
async startInvocation(actionId, input, context) {
|
|
346
|
+
let targetId = actionId;
|
|
347
|
+
if (targetId.startsWith(`${this.packageId}/`)) {
|
|
348
|
+
targetId = targetId.slice(this.packageId.length + 1);
|
|
349
|
+
}
|
|
350
|
+
return this.executionService.start(targetId, input, context);
|
|
338
351
|
}
|
|
339
352
|
async getRun(runId) {
|
|
340
353
|
return this.executionService.get(runId);
|
|
@@ -345,6 +358,16 @@ export class DefaultActionDockApp {
|
|
|
345
358
|
events(runId, options) {
|
|
346
359
|
return this.executionService.events(runId, options);
|
|
347
360
|
}
|
|
361
|
+
setActionInvoker(invoker) {
|
|
362
|
+
if (this.executionService && typeof this.executionService.setActionInvoker === "function") {
|
|
363
|
+
this.executionService.setActionInvoker(invoker);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
recoverDeadSessionRuns(sessionId) {
|
|
367
|
+
if (typeof this.storage.recoverDeadSessionRuns === "function") {
|
|
368
|
+
this.storage.recoverDeadSessionRuns(sessionId);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
348
371
|
async listConfig() {
|
|
349
372
|
const declared = this.projectConfig.config || {};
|
|
350
373
|
const stored = this.storage.listConfig();
|
|
@@ -383,36 +406,41 @@ export class DefaultActionDockApp {
|
|
|
383
406
|
/**
|
|
384
407
|
* 状态作用域统一解析辅助函数(单一事实源)。
|
|
385
408
|
*
|
|
386
|
-
*
|
|
387
|
-
* - actionId
|
|
388
|
-
* -
|
|
409
|
+
* 完成重载消歧后委托 mergeStateScope 计算最终生效的命名空间:
|
|
410
|
+
* - (actionId, key, options) 形态:位置 actionId 参与冲突校验;
|
|
411
|
+
* - (key, options) 扁平形态:首参是状态键,options.actionId 属合法显式指定。
|
|
389
412
|
*/
|
|
390
413
|
resolveStateScope(actionIdOrKey, keyOrOptions, options) {
|
|
391
|
-
let actionId;
|
|
392
|
-
let resolvedOpts;
|
|
393
414
|
// 消歧规则(与原始重载语义严格一致):仅当第二参为字符串时认定为
|
|
394
415
|
// (actionId, key, options) 形态;否则(undefined 或选项对象)认定为
|
|
395
416
|
// (key, options) 扁平调用形态,首参是状态键而非 actionId
|
|
396
417
|
if (typeof keyOrOptions === "string") {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
418
|
+
return { ns: this.mergeStateScope(actionIdOrKey, options), opts: options };
|
|
419
|
+
}
|
|
420
|
+
return { ns: this.mergeStateScope(undefined, keyOrOptions), opts: keyOrOptions };
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* 合并位置 actionId 与 options.actionId 并计算最终命名空间(单一事实源)。
|
|
424
|
+
*
|
|
425
|
+
* - positionalActionId 非 undefined:调用形态携带位置 actionId,
|
|
426
|
+
* options.actionId 与其冲突时抛出异常(空串同样参与冲突校验);
|
|
427
|
+
* - positionalActionId 为 undefined:无位置 actionId 的扁平调用形态,
|
|
428
|
+
* options.actionId 属合法显式指定,直接采纳。
|
|
429
|
+
*/
|
|
430
|
+
mergeStateScope(positionalActionId, opts) {
|
|
431
|
+
let actionId;
|
|
432
|
+
if (positionalActionId !== undefined) {
|
|
433
|
+
actionId = positionalActionId;
|
|
434
|
+
if (opts?.actionId && opts.actionId !== actionId) {
|
|
435
|
+
throw new ActionDockError(INVALID_ARGUMENT, `Conflicting actionId specified: positional '${actionId}' vs options.actionId '${opts.actionId}'`);
|
|
401
436
|
}
|
|
402
437
|
}
|
|
403
438
|
else {
|
|
404
|
-
|
|
405
|
-
// options.actionId 属于合法的显式指定,直接采纳而非判为冲突
|
|
406
|
-
actionId = "";
|
|
407
|
-
resolvedOpts = keyOrOptions;
|
|
408
|
-
}
|
|
409
|
-
if (!actionId && resolvedOpts?.actionId) {
|
|
410
|
-
actionId = resolvedOpts.actionId;
|
|
439
|
+
actionId = opts?.actionId ?? "";
|
|
411
440
|
}
|
|
412
|
-
|
|
413
|
-
? (
|
|
414
|
-
: (
|
|
415
|
-
return { ns, opts: resolvedOpts };
|
|
441
|
+
return actionId
|
|
442
|
+
? (opts?.namespace ? `${actionId}:${opts.namespace}` : actionId)
|
|
443
|
+
: (opts?.namespace ?? "");
|
|
416
444
|
}
|
|
417
445
|
async getState(actionIdOrKey, keyOrOptions, options) {
|
|
418
446
|
const { ns, opts } = this.resolveStateScope(actionIdOrKey, keyOrOptions, options);
|
|
@@ -431,18 +459,16 @@ export class DefaultActionDockApp {
|
|
|
431
459
|
let key;
|
|
432
460
|
let value;
|
|
433
461
|
let opts;
|
|
434
|
-
|
|
462
|
+
// 携带位置 actionId 的调用形态标记:undefined 表示扁平 (key, value[, options]) 形态
|
|
463
|
+
let positionalActionId;
|
|
464
|
+
// 消歧规则(与原始重载语义严格一致):按实参个数区分三形态
|
|
435
465
|
if (arguments.length >= 4) {
|
|
436
|
-
|
|
437
|
-
throw new Error(`Conflicting actionId specified: positional '${actionIdOrKey}' vs options.actionId '${options.actionId}'`);
|
|
438
|
-
}
|
|
439
|
-
actionId = actionIdOrKey;
|
|
466
|
+
positionalActionId = actionIdOrKey;
|
|
440
467
|
key = keyOrValue;
|
|
441
468
|
value = valueOrOptions;
|
|
442
469
|
opts = options;
|
|
443
470
|
}
|
|
444
471
|
else if (arguments.length === 2) {
|
|
445
|
-
actionId = "";
|
|
446
472
|
key = actionIdOrKey;
|
|
447
473
|
value = keyOrValue;
|
|
448
474
|
opts = undefined;
|
|
@@ -450,16 +476,14 @@ export class DefaultActionDockApp {
|
|
|
450
476
|
else {
|
|
451
477
|
if (valueOrOptions !== undefined &&
|
|
452
478
|
(typeof valueOrOptions !== "object" || valueOrOptions === null || Array.isArray(valueOrOptions))) {
|
|
453
|
-
throw new
|
|
479
|
+
throw new ActionDockError(INVALID_ARGUMENT, "Invalid options provided to setState. Use setActionState(actionId, key, value, options) or 4-argument setState for action state.");
|
|
454
480
|
}
|
|
455
481
|
key = actionIdOrKey;
|
|
456
482
|
value = keyOrValue;
|
|
457
483
|
opts = valueOrOptions;
|
|
458
|
-
actionId = opts?.actionId ?? "";
|
|
459
484
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
: (opts?.namespace ?? "");
|
|
485
|
+
// 作用域解析与命名空间计算统一委托 mergeStateScope 单一事实源
|
|
486
|
+
const ns = this.mergeStateScope(positionalActionId, opts);
|
|
463
487
|
if (ns) {
|
|
464
488
|
await this.storage.setState(ns, key, value, opts?.ttl);
|
|
465
489
|
return;
|
|
@@ -546,6 +570,25 @@ export class DefaultActionDockApp {
|
|
|
546
570
|
all: opts?.all,
|
|
547
571
|
});
|
|
548
572
|
}
|
|
573
|
+
async listRuns(options) {
|
|
574
|
+
return this.storage.listRuns({
|
|
575
|
+
actionId: options?.actionId,
|
|
576
|
+
status: options?.status,
|
|
577
|
+
limit: options?.limit,
|
|
578
|
+
});
|
|
579
|
+
}
|
|
580
|
+
async clearRuns(options) {
|
|
581
|
+
return this.storage.clearRuns({
|
|
582
|
+
actionId: options?.actionId,
|
|
583
|
+
status: options?.status,
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
async listStateEntries(options) {
|
|
587
|
+
if (typeof this.storage.listStateEntries === "function") {
|
|
588
|
+
return this.storage.listStateEntries(options);
|
|
589
|
+
}
|
|
590
|
+
throw new ActionDockError(CAPABILITY_UNAVAILABLE, `CAPABILITY_UNAVAILABLE: listStateEntries is not supported by package '${this.packageId}' storage`);
|
|
591
|
+
}
|
|
549
592
|
async close(options) {
|
|
550
593
|
if (this.isClosed)
|
|
551
594
|
return;
|
|
@@ -561,19 +604,21 @@ export class DefaultActionDockApp {
|
|
|
561
604
|
// 忽略存储重复关闭异常
|
|
562
605
|
}
|
|
563
606
|
finally {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
607
|
+
if (!this.injectedGlobalStorage) {
|
|
608
|
+
try {
|
|
609
|
+
this.globalStorage?.close();
|
|
610
|
+
}
|
|
611
|
+
catch {
|
|
612
|
+
// 忽略全局存储关闭异常
|
|
613
|
+
}
|
|
569
614
|
}
|
|
570
615
|
}
|
|
571
616
|
}
|
|
572
617
|
}
|
|
573
618
|
}
|
|
574
619
|
/**
|
|
575
|
-
* 工厂函数:创建并初始化
|
|
620
|
+
* 工厂函数:创建并初始化 PackageRuntime 实例。
|
|
576
621
|
*/
|
|
577
|
-
export async function
|
|
578
|
-
return new
|
|
622
|
+
export async function createPackageRuntime(options = {}) {
|
|
623
|
+
return new DefaultPackageRuntime(options);
|
|
579
624
|
}
|
|
@@ -2,6 +2,44 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { loadPlaybooks } from "../project/loader.js";
|
|
4
4
|
import { loadManifest, MANIFEST_FILE_NAME } from "../project/manifest.js";
|
|
5
|
+
/**
|
|
6
|
+
* 将增量声明合并到既有 Action 规范之上(纯函数,单一事实源)。
|
|
7
|
+
*
|
|
8
|
+
* 优先级语义由调用顺序表达:后层调用时以先层结果作为 base,
|
|
9
|
+
* 声明值(patch)存在时覆盖,缺省字段回退 base 既有值。
|
|
10
|
+
*/
|
|
11
|
+
function mergeSpec(base, id, packageId, patch, packageRoot, policy = {}) {
|
|
12
|
+
const { arrayCopy = true, arrayFields = [], deriveFilePath = false, preserveEntry = false } = policy;
|
|
13
|
+
const merged = {
|
|
14
|
+
id,
|
|
15
|
+
packageId,
|
|
16
|
+
description: patch.description ?? base?.description,
|
|
17
|
+
inputSchema: patch.inputSchema ?? base?.inputSchema,
|
|
18
|
+
outputSchema: patch.outputSchema ?? base?.outputSchema,
|
|
19
|
+
annotations: patch.annotations ?? base?.annotations,
|
|
20
|
+
};
|
|
21
|
+
for (const field of arrayFields) {
|
|
22
|
+
merged[field] = patch[field]
|
|
23
|
+
? (arrayCopy ? [...patch[field]] : patch[field])
|
|
24
|
+
: base?.[field];
|
|
25
|
+
}
|
|
26
|
+
if (deriveFilePath) {
|
|
27
|
+
merged.entry = patch.entry ?? base?.entry;
|
|
28
|
+
merged.filePath =
|
|
29
|
+
patch.entry && packageRoot
|
|
30
|
+
? resolve(packageRoot, patch.entry)
|
|
31
|
+
: base?.filePath;
|
|
32
|
+
}
|
|
33
|
+
else if (preserveEntry) {
|
|
34
|
+
merged.entry = base?.entry;
|
|
35
|
+
merged.filePath = base?.filePath;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
merged.entry = patch.entry ?? base?.entry;
|
|
39
|
+
merged.filePath = base?.filePath;
|
|
40
|
+
}
|
|
41
|
+
return merged;
|
|
42
|
+
}
|
|
5
43
|
/**
|
|
6
44
|
* 静态读取并聚合指定包的 Action 规范索引。
|
|
7
45
|
* 不产生全量模块导入与执行副作用。
|
|
@@ -28,18 +66,15 @@ export function buildStaticActionMap(input) {
|
|
|
28
66
|
const manifest = loadManifest(packageRoot);
|
|
29
67
|
if (manifest?.actions) {
|
|
30
68
|
for (const [id, item] of Object.entries(manifest.actions)) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
entry: item.entry,
|
|
41
|
-
filePath: item.entry ? resolve(packageRoot, item.entry) : undefined,
|
|
42
|
-
});
|
|
69
|
+
// 磁盘清单为最底层来源:无更低层可回退,tags 与 uses 缺省时归一为空数组
|
|
70
|
+
map.set(id, mergeSpec(undefined, id, packageId, {
|
|
71
|
+
...item,
|
|
72
|
+
tags: item.tags ?? [],
|
|
73
|
+
uses: item.uses ?? [],
|
|
74
|
+
}, packageRoot, {
|
|
75
|
+
arrayFields: ["tags", "uses"],
|
|
76
|
+
deriveFilePath: true,
|
|
77
|
+
}));
|
|
43
78
|
}
|
|
44
79
|
}
|
|
45
80
|
}
|
|
@@ -53,21 +88,12 @@ export function buildStaticActionMap(input) {
|
|
|
53
88
|
const rawActions = projectConfig.actions;
|
|
54
89
|
if (typeof rawActions === "object" && rawActions !== null) {
|
|
55
90
|
for (const [id, item] of Object.entries(rawActions)) {
|
|
56
|
-
|
|
57
|
-
map.set(id, {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
outputSchema: item.outputSchema ?? existing?.outputSchema,
|
|
63
|
-
tags: item.tags ?? existing?.tags,
|
|
64
|
-
annotations: item.annotations ?? existing?.annotations,
|
|
65
|
-
uses: item.uses ?? existing?.uses,
|
|
66
|
-
entry: item.entry ?? existing?.entry,
|
|
67
|
-
filePath: item.entry && packageRoot
|
|
68
|
-
? resolve(packageRoot, item.entry)
|
|
69
|
-
: existing?.filePath,
|
|
70
|
-
});
|
|
91
|
+
// 配置声明层:覆盖磁盘清单层,entry 变化时重算物理路径;数组字段直传引用
|
|
92
|
+
map.set(id, mergeSpec(map.get(id), id, packageId, item, packageRoot, {
|
|
93
|
+
arrayFields: ["tags", "uses"],
|
|
94
|
+
arrayCopy: false,
|
|
95
|
+
deriveFilePath: true,
|
|
96
|
+
}));
|
|
71
97
|
}
|
|
72
98
|
}
|
|
73
99
|
}
|
|
@@ -80,20 +106,11 @@ export function buildStaticActionMap(input) {
|
|
|
80
106
|
continue;
|
|
81
107
|
}
|
|
82
108
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
description: actObj.description ?? existing?.description,
|
|
89
|
-
inputSchema: actObj.inputSchema ?? existing?.inputSchema,
|
|
90
|
-
outputSchema: actObj.outputSchema ?? existing?.outputSchema,
|
|
91
|
-
tags: actObj.tags ? [...actObj.tags] : existing?.tags,
|
|
92
|
-
annotations: actObj.annotations ?? existing?.annotations,
|
|
93
|
-
uses: actObj.uses ? [...actObj.uses] : existing?.uses,
|
|
94
|
-
entry: existing?.entry,
|
|
95
|
-
filePath: existing?.filePath,
|
|
96
|
-
});
|
|
109
|
+
// 内存注入层:保留磁盘层解析出的 entry 与 filePath,仅覆盖动态定义相关字段
|
|
110
|
+
map.set(id, mergeSpec(map.get(id), id, packageId, act, packageRoot, {
|
|
111
|
+
arrayFields: ["tags", "uses"],
|
|
112
|
+
preserveEntry: true,
|
|
113
|
+
}));
|
|
97
114
|
}
|
|
98
115
|
return map;
|
|
99
116
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RuntimeStorage } from "../storage/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* 构造外部注入 storage 的非接管视图。
|
|
4
|
+
*
|
|
5
|
+
* 外部注入的 storage 生命周期由注入方管理,本视图仅委托读写而不接管关闭:
|
|
6
|
+
* 所有成员函数与属性原样转发到原始实例并绑定原 this,仅 close 收敛为
|
|
7
|
+
* 显式声明的无操作边界,确保 service.close() 级联关闭时不会误伤外部实例。
|
|
8
|
+
*
|
|
9
|
+
* 单一事实源:mcp 适配层与 testing 运行时共同引用,严禁再各自复制 Proxy 包装实现。
|
|
10
|
+
*
|
|
11
|
+
* @param storage 外部注入的存储实例
|
|
12
|
+
*/
|
|
13
|
+
export declare function createNonClosingStorageView<T extends RuntimeStorage>(storage: T): T;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 构造外部注入 storage 的非接管视图。
|
|
3
|
+
*
|
|
4
|
+
* 外部注入的 storage 生命周期由注入方管理,本视图仅委托读写而不接管关闭:
|
|
5
|
+
* 所有成员函数与属性原样转发到原始实例并绑定原 this,仅 close 收敛为
|
|
6
|
+
* 显式声明的无操作边界,确保 service.close() 级联关闭时不会误伤外部实例。
|
|
7
|
+
*
|
|
8
|
+
* 单一事实源:mcp 适配层与 testing 运行时共同引用,严禁再各自复制 Proxy 包装实现。
|
|
9
|
+
*
|
|
10
|
+
* @param storage 外部注入的存储实例
|
|
11
|
+
*/
|
|
12
|
+
export function createNonClosingStorageView(storage) {
|
|
13
|
+
return new Proxy(storage, {
|
|
14
|
+
get(target, prop) {
|
|
15
|
+
if (prop === "close") {
|
|
16
|
+
return () => undefined;
|
|
17
|
+
}
|
|
18
|
+
const value = Reflect.get(target, prop, target);
|
|
19
|
+
return typeof value === "function" ? value.bind(target) : value;
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
}
|