@actiondock/core 2.2.2 → 2.3.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 +8 -3
- package/dist/app/app.d.ts +2 -0
- package/dist/app/app.js +6 -0
- package/dist/app/types.d.ts +12 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.js +44 -0
- package/dist/execution/service.d.ts +2 -0
- package/dist/execution/service.js +13 -2
- package/dist/execution/types.d.ts +17 -0
- package/dist/host/host.js +46 -5
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/ipc/host.d.ts +5 -0
- package/dist/ipc/host.js +43 -1
- package/dist/ipc/target.d.ts +18 -0
- package/dist/ipc/target.js +74 -6
- package/dist/ipc/types.d.ts +10 -1
- package/dist/platform/default.d.ts +7 -1
- package/dist/platform/default.js +40 -2
- package/dist/process/context-process.d.ts +83 -0
- package/dist/process/context-process.js +168 -0
- package/dist/process/cursor.d.ts +52 -0
- package/dist/process/cursor.js +144 -0
- package/dist/process/driver.d.ts +214 -0
- package/dist/process/driver.js +197 -0
- package/dist/process/index.d.ts +6 -0
- package/dist/process/index.js +6 -0
- package/dist/process/metadata-store.d.ts +205 -0
- package/dist/process/metadata-store.js +462 -0
- package/dist/process/output-log.d.ts +136 -0
- package/dist/process/output-log.js +331 -0
- package/dist/process/process-manager.d.ts +279 -0
- package/dist/process/process-manager.js +1879 -0
- package/dist/profile/client.js +63 -21
- package/dist/project/init.js +2 -2
- package/dist/registry/registry.js +12 -3
- package/dist/runtime/context.d.ts +9 -6
- package/dist/runtime/context.js +31 -8
- package/dist/runtime/process.d.ts +19 -2
- package/dist/runtime/process.js +103 -131
- package/dist/runtime/runner.d.ts +45 -24
- package/dist/runtime/runner.js +106 -25
- package/dist/target/remote.js +7 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/runtime/runner.d.ts
CHANGED
|
@@ -3,22 +3,45 @@ import type { ProjectConfig } from "../project/types.js";
|
|
|
3
3
|
import type { RuntimeStorage } from "../storage/types.js";
|
|
4
4
|
import type { Clock } from "./clock.js";
|
|
5
5
|
import type { RuntimePlatform } from "../platform/types.js";
|
|
6
|
+
import type { ProcessOwner } from "../process/index.js";
|
|
6
7
|
export { RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, MAX_SUBRUNS_REACHED, ACTION_CALL_CYCLE, ACTION_CYCLE_DETECTED, ACTION_MAX_DEPTH_EXCEEDED, } from "../errors.js";
|
|
7
8
|
/**
|
|
8
9
|
* 校验值是否为合法的 JSON 兼容结构,严禁 NaN、Infinity、循环引用及不可序列化类型。
|
|
10
|
+
*
|
|
11
|
+
* 环路检测采用「当前递归路径栈」语义:对象仅在自身子树遍历期间保持标记,
|
|
12
|
+
* 子树遍历完成后立即移除,从而正确放行共享子对象的有向无环结构(如 {a: shared, b: shared})。
|
|
9
13
|
*/
|
|
10
|
-
export declare function validateJsonValue(val: unknown,
|
|
14
|
+
export declare function validateJsonValue(val: unknown, stack?: WeakSet<object>): {
|
|
11
15
|
valid: true;
|
|
12
16
|
} | {
|
|
13
17
|
valid: false;
|
|
14
18
|
reason: string;
|
|
15
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* 跨包运行上下文解析结果契约。
|
|
22
|
+
*/
|
|
23
|
+
export interface PackageContextResolution {
|
|
24
|
+
projectRoot?: string;
|
|
25
|
+
projectConfig?: ProjectConfig;
|
|
26
|
+
storage: RuntimeStorage;
|
|
27
|
+
actions?: Map<string, ActionDefinition>;
|
|
28
|
+
packageInstanceId?: string;
|
|
29
|
+
generationId?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 跨包运行上下文解析委托函数契约。
|
|
33
|
+
*/
|
|
34
|
+
export type PackageContextResolver = (packageId: string) => Promise<PackageContextResolution | undefined> | PackageContextResolution | undefined;
|
|
16
35
|
/**
|
|
17
36
|
* ActionRunner 初始化配置选项。
|
|
18
37
|
*/
|
|
19
38
|
export interface RunnerOptions {
|
|
20
39
|
/** 运行所属的 Package ID */
|
|
21
40
|
packageId: string;
|
|
41
|
+
/** 包物理实例标识 */
|
|
42
|
+
packageInstanceId?: string;
|
|
43
|
+
/** 快照代次标识 */
|
|
44
|
+
generationId?: string;
|
|
22
45
|
/** 持久化运行时存储实例(SQLite) */
|
|
23
46
|
storage?: RuntimeStorage;
|
|
24
47
|
/** 全局共享持久化存储实例(SQLite,用于单例池化避免泄漏) */
|
|
@@ -46,17 +69,7 @@ export interface RunnerOptions {
|
|
|
46
69
|
/** 跨包存储工厂 */
|
|
47
70
|
getStorageForPackage?: (packageId: string, projectRoot?: string) => RuntimeStorage;
|
|
48
71
|
/** 跨包运行上下文解析委托函数 */
|
|
49
|
-
packageContextResolver?:
|
|
50
|
-
projectRoot?: string;
|
|
51
|
-
projectConfig?: ProjectConfig;
|
|
52
|
-
storage: RuntimeStorage;
|
|
53
|
-
actions?: Map<string, ActionDefinition>;
|
|
54
|
-
} | undefined> | {
|
|
55
|
-
projectRoot?: string;
|
|
56
|
-
projectConfig?: ProjectConfig;
|
|
57
|
-
storage: RuntimeStorage;
|
|
58
|
-
actions?: Map<string, ActionDefinition>;
|
|
59
|
-
} | undefined;
|
|
72
|
+
packageContextResolver?: PackageContextResolver;
|
|
60
73
|
/** 自定义 ActionDock 用户家目录(用于测试隔离与多租户环境) */
|
|
61
74
|
customHome?: string;
|
|
62
75
|
/** 执行宿主会话标识 */
|
|
@@ -80,6 +93,12 @@ export interface ExecutionStartOptions {
|
|
|
80
93
|
generationId?: string;
|
|
81
94
|
/** 执行所有者标识 */
|
|
82
95
|
ownerId?: string;
|
|
96
|
+
/** 租户标识 */
|
|
97
|
+
tenantId?: string;
|
|
98
|
+
/** 主体标识 */
|
|
99
|
+
principalId?: string;
|
|
100
|
+
/** 显式执行归属所有者契约 */
|
|
101
|
+
owner?: ProcessOwner;
|
|
83
102
|
/** 执行宿主会话标识 */
|
|
84
103
|
hostSessionId?: string;
|
|
85
104
|
/** 调用栈数组(用于检测 A -> B -> A 环路死锁) */
|
|
@@ -142,7 +161,9 @@ export type ActionResolution = {
|
|
|
142
161
|
* - 自动记录并持久化 RunRecord 运行记录至 SQLite 存储。
|
|
143
162
|
*/
|
|
144
163
|
export declare class ActionRunner {
|
|
145
|
-
|
|
164
|
+
readonly packageId: string;
|
|
165
|
+
readonly packageInstanceId: string;
|
|
166
|
+
readonly generationId: string;
|
|
146
167
|
private storage;
|
|
147
168
|
private globalStorage?;
|
|
148
169
|
private projectRoot?;
|
|
@@ -156,6 +177,8 @@ export declare class ActionRunner {
|
|
|
156
177
|
private maxSubRuns;
|
|
157
178
|
private activeSubRuns;
|
|
158
179
|
private packageRunners;
|
|
180
|
+
/** 跨包 Runner 构建中的 in-flight Promise:并发调用 await 同一构建任务,消除 check-then-act 竞态 */
|
|
181
|
+
private pendingPackageRunners;
|
|
159
182
|
private actionResolver?;
|
|
160
183
|
private getStorageForPackage?;
|
|
161
184
|
private packageContextResolver?;
|
|
@@ -190,21 +213,19 @@ export declare class ActionRunner {
|
|
|
190
213
|
/**
|
|
191
214
|
* 注入或更新跨包运行上下文解析委托。
|
|
192
215
|
*/
|
|
193
|
-
setPackageContextResolver(resolver:
|
|
194
|
-
projectRoot?: string;
|
|
195
|
-
projectConfig?: ProjectConfig;
|
|
196
|
-
storage: RuntimeStorage;
|
|
197
|
-
actions?: Map<string, ActionDefinition>;
|
|
198
|
-
} | undefined> | {
|
|
199
|
-
projectRoot?: string;
|
|
200
|
-
projectConfig?: ProjectConfig;
|
|
201
|
-
storage: RuntimeStorage;
|
|
202
|
-
actions?: Map<string, ActionDefinition>;
|
|
203
|
-
} | undefined): void;
|
|
216
|
+
setPackageContextResolver(resolver: PackageContextResolver): void;
|
|
204
217
|
/**
|
|
205
218
|
* 跨包运行时解析与获取(确保跨包执行具备独立的配置、存储、状态与 Action 注册表)。
|
|
219
|
+
*
|
|
220
|
+
* 缓存 miss 后存在长异步窗口(加载配置、扫描 Action、打开存储),并发调用会重复构建
|
|
221
|
+
* Runner、重复打开 SQLite 连接且子任务限流计数分裂;故以 in-flight Promise 去重,
|
|
222
|
+
* 并发方 await 同一构建任务,构建失败时移除该 Promise 以便后续重试。
|
|
206
223
|
*/
|
|
207
224
|
resolveTargetPackageRunner(targetPackageId: string): Promise<ActionRunner | undefined>;
|
|
225
|
+
/**
|
|
226
|
+
* 实际构建跨包 Runner(仅由 resolveTargetPackageRunner 串行调度)。
|
|
227
|
+
*/
|
|
228
|
+
private buildTargetPackageRunner;
|
|
208
229
|
/**
|
|
209
230
|
* 异步启动 Action 的执行并立即返回 ExecutionHandle 句柄。
|
|
210
231
|
*
|
package/dist/runtime/runner.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
2
|
import { randomUUID } from "node:crypto";
|
|
4
3
|
import { ActionResolver } from "../catalog/action-resolver.js";
|
|
5
4
|
import { loadActions, loadProjectConfig } from "../project/loader.js";
|
|
@@ -11,8 +10,11 @@ import { createActionContext, StderrLogger } from "./context.js";
|
|
|
11
10
|
export { RUN_REPOSITORY_UNAVAILABLE, RUN_PERSISTENCE_FAILED, INPUT_NOT_JSON, OUTPUT_NOT_JSON, ACTION_SUBRUN_LIMIT, MAX_SUBRUNS_REACHED, ACTION_CALL_CYCLE, ACTION_CYCLE_DETECTED, ACTION_MAX_DEPTH_EXCEEDED, } from "../errors.js";
|
|
12
11
|
/**
|
|
13
12
|
* 校验值是否为合法的 JSON 兼容结构,严禁 NaN、Infinity、循环引用及不可序列化类型。
|
|
13
|
+
*
|
|
14
|
+
* 环路检测采用「当前递归路径栈」语义:对象仅在自身子树遍历期间保持标记,
|
|
15
|
+
* 子树遍历完成后立即移除,从而正确放行共享子对象的有向无环结构(如 {a: shared, b: shared})。
|
|
14
16
|
*/
|
|
15
|
-
export function validateJsonValue(val,
|
|
17
|
+
export function validateJsonValue(val, stack = new WeakSet()) {
|
|
16
18
|
if (val === null || typeof val === "boolean" || typeof val === "string") {
|
|
17
19
|
return { valid: true };
|
|
18
20
|
}
|
|
@@ -26,26 +28,32 @@ export function validateJsonValue(val, seen = new WeakSet()) {
|
|
|
26
28
|
return { valid: false, reason: `Unsupported JSON type '${typeof val}'` };
|
|
27
29
|
}
|
|
28
30
|
if (typeof val === "object") {
|
|
29
|
-
if (
|
|
31
|
+
if (stack.has(val)) {
|
|
30
32
|
return { valid: false, reason: "Circular reference detected in object structure" };
|
|
31
33
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
stack.add(val);
|
|
35
|
+
try {
|
|
36
|
+
if (Array.isArray(val)) {
|
|
37
|
+
for (const item of val) {
|
|
38
|
+
const res = validateJsonValue(item, stack);
|
|
39
|
+
if (!res.valid)
|
|
40
|
+
return res;
|
|
41
|
+
}
|
|
42
|
+
return { valid: true };
|
|
43
|
+
}
|
|
44
|
+
for (const v of Object.values(val)) {
|
|
45
|
+
if (v !== undefined) {
|
|
46
|
+
const res = validateJsonValue(v, stack);
|
|
47
|
+
if (!res.valid)
|
|
48
|
+
return res;
|
|
49
|
+
}
|
|
38
50
|
}
|
|
39
51
|
return { valid: true };
|
|
40
52
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!res.valid)
|
|
45
|
-
return res;
|
|
46
|
-
}
|
|
53
|
+
finally {
|
|
54
|
+
// 无论正常返回还是提前返回,均须将当前对象移出路径栈,避免祖先对象被误判为环路
|
|
55
|
+
stack.delete(val);
|
|
47
56
|
}
|
|
48
|
-
return { valid: true };
|
|
49
57
|
}
|
|
50
58
|
return { valid: true };
|
|
51
59
|
}
|
|
@@ -63,6 +71,8 @@ let anonymousRunnerActionCounter = 0;
|
|
|
63
71
|
*/
|
|
64
72
|
export class ActionRunner {
|
|
65
73
|
packageId;
|
|
74
|
+
packageInstanceId;
|
|
75
|
+
generationId;
|
|
66
76
|
storage;
|
|
67
77
|
globalStorage;
|
|
68
78
|
projectRoot;
|
|
@@ -76,6 +86,8 @@ export class ActionRunner {
|
|
|
76
86
|
maxSubRuns;
|
|
77
87
|
activeSubRuns = 0;
|
|
78
88
|
packageRunners = new Map();
|
|
89
|
+
/** 跨包 Runner 构建中的 in-flight Promise:并发调用 await 同一构建任务,消除 check-then-act 竞态 */
|
|
90
|
+
pendingPackageRunners = new Map();
|
|
79
91
|
actionResolver;
|
|
80
92
|
getStorageForPackage;
|
|
81
93
|
packageContextResolver;
|
|
@@ -83,6 +95,8 @@ export class ActionRunner {
|
|
|
83
95
|
hostSessionId;
|
|
84
96
|
constructor(options) {
|
|
85
97
|
this.packageId = options.packageId;
|
|
98
|
+
this.packageInstanceId = options.packageInstanceId || options.packageId;
|
|
99
|
+
this.generationId = options.generationId || "1";
|
|
86
100
|
this.hostSessionId = options.hostSessionId;
|
|
87
101
|
this.projectRoot = options.projectRoot;
|
|
88
102
|
this.projectConfig = options.projectConfig;
|
|
@@ -272,16 +286,38 @@ export class ActionRunner {
|
|
|
272
286
|
}
|
|
273
287
|
/**
|
|
274
288
|
* 跨包运行时解析与获取(确保跨包执行具备独立的配置、存储、状态与 Action 注册表)。
|
|
289
|
+
*
|
|
290
|
+
* 缓存 miss 后存在长异步窗口(加载配置、扫描 Action、打开存储),并发调用会重复构建
|
|
291
|
+
* Runner、重复打开 SQLite 连接且子任务限流计数分裂;故以 in-flight Promise 去重,
|
|
292
|
+
* 并发方 await 同一构建任务,构建失败时移除该 Promise 以便后续重试。
|
|
275
293
|
*/
|
|
276
294
|
async resolveTargetPackageRunner(targetPackageId) {
|
|
277
|
-
|
|
278
|
-
|
|
295
|
+
const cached = this.packageRunners.get(targetPackageId);
|
|
296
|
+
if (cached) {
|
|
297
|
+
return cached;
|
|
298
|
+
}
|
|
299
|
+
const inFlight = this.pendingPackageRunners.get(targetPackageId);
|
|
300
|
+
if (inFlight) {
|
|
301
|
+
return inFlight;
|
|
279
302
|
}
|
|
303
|
+
const building = this.buildTargetPackageRunner(targetPackageId).finally(() => {
|
|
304
|
+
// 无论成败均移除 in-flight 记录:成功者已写入正式缓存,失败者允许重试
|
|
305
|
+
this.pendingPackageRunners.delete(targetPackageId);
|
|
306
|
+
});
|
|
307
|
+
this.pendingPackageRunners.set(targetPackageId, building);
|
|
308
|
+
return building;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* 实际构建跨包 Runner(仅由 resolveTargetPackageRunner 串行调度)。
|
|
312
|
+
*/
|
|
313
|
+
async buildTargetPackageRunner(targetPackageId) {
|
|
280
314
|
if (this.packageContextResolver) {
|
|
281
315
|
const resolved = await this.packageContextResolver(targetPackageId);
|
|
282
316
|
if (resolved) {
|
|
283
317
|
const runner = new ActionRunner({
|
|
284
318
|
packageId: targetPackageId,
|
|
319
|
+
packageInstanceId: resolved.packageInstanceId || resolved.projectConfig?.packageInstanceId || targetPackageId,
|
|
320
|
+
generationId: resolved.generationId || resolved.projectConfig?.generationId || "1",
|
|
285
321
|
storage: resolved.storage,
|
|
286
322
|
globalStorage: this.globalStorage,
|
|
287
323
|
projectRoot: resolved.projectRoot,
|
|
@@ -314,10 +350,9 @@ export class ActionRunner {
|
|
|
314
350
|
});
|
|
315
351
|
}
|
|
316
352
|
else {
|
|
317
|
-
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
storage = new SqliteRuntimeStorage({ dbPath, packageId: targetPackageId, clock: this.clock });
|
|
353
|
+
// 回退分支与主路径共用 createStorage 单一事实源,确保 run 记录落在统一解析的库文件
|
|
354
|
+
const { createStorage } = await import("../storage/index.js");
|
|
355
|
+
storage = createStorage(targetPackageId, { projectRoot: root, customHome: this.customHome });
|
|
321
356
|
}
|
|
322
357
|
const actionsMap = await loadActions(root, config.actionsDir, {
|
|
323
358
|
autoInstall: false,
|
|
@@ -325,6 +360,8 @@ export class ActionRunner {
|
|
|
325
360
|
});
|
|
326
361
|
const runner = new ActionRunner({
|
|
327
362
|
packageId: targetPackageId,
|
|
363
|
+
packageInstanceId: config.packageInstanceId || targetPackageId,
|
|
364
|
+
generationId: config.generationId || "1",
|
|
328
365
|
storage,
|
|
329
366
|
globalStorage: this.globalStorage,
|
|
330
367
|
projectRoot: root,
|
|
@@ -578,9 +615,9 @@ export class ActionRunner {
|
|
|
578
615
|
rootRunId: this.computeRootRunId(runCtx),
|
|
579
616
|
parentRunId: options.parentRunId,
|
|
580
617
|
packageId: targetPackageId,
|
|
581
|
-
packageInstanceId: options.packageInstanceId || targetPackageId,
|
|
618
|
+
packageInstanceId: options.packageInstanceId || (this.packageId === targetPackageId ? this.packageInstanceId : targetPackageId),
|
|
582
619
|
actionId: targetActionId,
|
|
583
|
-
generationId: options.generationId || "1",
|
|
620
|
+
generationId: options.generationId || (this.packageId === targetPackageId ? this.generationId : "1"),
|
|
584
621
|
ownerId: options.ownerId || "local",
|
|
585
622
|
hostSessionId: options.hostSessionId || this.hostSessionId,
|
|
586
623
|
status,
|
|
@@ -700,7 +737,13 @@ export class ActionRunner {
|
|
|
700
737
|
*/
|
|
701
738
|
buildActionContext(args) {
|
|
702
739
|
const { runCtx, controller, rootRunId } = args;
|
|
703
|
-
const { options, targetActionId, effectiveProcess } = runCtx;
|
|
740
|
+
const { options, targetPackageId, targetActionId, effectiveProcess } = runCtx;
|
|
741
|
+
const effectiveOwner = options.owner || {
|
|
742
|
+
tenantId: options.tenantId || "default",
|
|
743
|
+
principalId: options.principalId || options.ownerId || "default",
|
|
744
|
+
packageInstanceId: options.packageInstanceId || (this.packageId === targetPackageId ? this.packageInstanceId : targetPackageId),
|
|
745
|
+
generationId: options.generationId || (this.packageId === targetPackageId ? this.generationId : "1"),
|
|
746
|
+
};
|
|
704
747
|
return createActionContext({
|
|
705
748
|
actionId: targetActionId,
|
|
706
749
|
storage: this.storage,
|
|
@@ -712,6 +755,7 @@ export class ActionRunner {
|
|
|
712
755
|
parentRunId: options.parentRunId,
|
|
713
756
|
signal: controller.signal,
|
|
714
757
|
process: effectiveProcess,
|
|
758
|
+
owner: effectiveOwner,
|
|
715
759
|
progress: options.progress,
|
|
716
760
|
logger: options.logger || new StderrLogger(targetActionId),
|
|
717
761
|
onActionInvoke: (childAction, childInput, parentRunId) => this.invokeChildAction({
|
|
@@ -742,12 +786,31 @@ export class ActionRunner {
|
|
|
742
786
|
childPackageId = parsed.packageId;
|
|
743
787
|
}
|
|
744
788
|
const childActionId = parsed.actionId;
|
|
789
|
+
const effectiveParentOwner = options.owner || {
|
|
790
|
+
tenantId: options.tenantId || "default",
|
|
791
|
+
principalId: options.principalId || options.ownerId || "default",
|
|
792
|
+
packageInstanceId: options.packageInstanceId || this.packageInstanceId || this.packageId,
|
|
793
|
+
generationId: options.generationId || this.generationId || "1",
|
|
794
|
+
};
|
|
795
|
+
const isSamePackage = !childPackageId || childPackageId === this.packageId;
|
|
745
796
|
this.activeSubRuns++;
|
|
746
797
|
try {
|
|
747
798
|
const runnerToUse = await this.resolveChildRunner(childPackageId, childActionId);
|
|
748
799
|
if (runnerToUse !== this) {
|
|
749
800
|
this.assertDeclaredUses(runCtx.action, targetActionId, childPackageId, childActionId);
|
|
750
801
|
}
|
|
802
|
+
const childPackageInstanceId = isSamePackage
|
|
803
|
+
? effectiveParentOwner.packageInstanceId
|
|
804
|
+
: (runnerToUse !== this ? runnerToUse.packageInstanceId : childPackageId);
|
|
805
|
+
const childGenerationId = isSamePackage
|
|
806
|
+
? effectiveParentOwner.generationId
|
|
807
|
+
: (runnerToUse !== this ? runnerToUse.generationId : "1");
|
|
808
|
+
const childOwner = {
|
|
809
|
+
tenantId: effectiveParentOwner.tenantId,
|
|
810
|
+
principalId: effectiveParentOwner.principalId,
|
|
811
|
+
packageInstanceId: childPackageInstanceId,
|
|
812
|
+
generationId: childGenerationId,
|
|
813
|
+
};
|
|
751
814
|
const childResult = await runnerToUse.execute(childAction, childInput, {
|
|
752
815
|
rootRunId,
|
|
753
816
|
parentRunId,
|
|
@@ -759,6 +822,13 @@ export class ActionRunner {
|
|
|
759
822
|
logger: options.logger,
|
|
760
823
|
configOverrides: options.configOverrides,
|
|
761
824
|
maxCallDepth: options.maxCallDepth ?? this.maxCallDepth,
|
|
825
|
+
tenantId: childOwner.tenantId,
|
|
826
|
+
principalId: childOwner.principalId,
|
|
827
|
+
ownerId: childOwner.principalId,
|
|
828
|
+
packageInstanceId: childOwner.packageInstanceId,
|
|
829
|
+
generationId: childOwner.generationId,
|
|
830
|
+
owner: childOwner,
|
|
831
|
+
hostSessionId: options.hostSessionId ?? this.hostSessionId,
|
|
762
832
|
});
|
|
763
833
|
if (!childResult.ok) {
|
|
764
834
|
const err = new Error(childResult.error.message);
|
|
@@ -912,6 +982,17 @@ export class ActionRunner {
|
|
|
912
982
|
catch (err) {
|
|
913
983
|
return this.classifyExecutionError(err, runCtx, controller, finalizer);
|
|
914
984
|
}
|
|
985
|
+
finally {
|
|
986
|
+
// 仅释放 run 级隔离实例;平台级共享 ContextProcessAPI 生命周期归平台所有,严禁在此误 dispose
|
|
987
|
+
if (ctx &&
|
|
988
|
+
ctx.process?.runScoped === true &&
|
|
989
|
+
typeof ctx.process.dispose === "function") {
|
|
990
|
+
try {
|
|
991
|
+
await ctx.process.dispose();
|
|
992
|
+
}
|
|
993
|
+
catch { }
|
|
994
|
+
}
|
|
995
|
+
}
|
|
915
996
|
})();
|
|
916
997
|
}
|
|
917
998
|
/**
|
package/dist/target/remote.js
CHANGED
|
@@ -215,6 +215,13 @@ export async function* streamRemoteEvents(serverUrl, runId, token, options) {
|
|
|
215
215
|
throw err;
|
|
216
216
|
}
|
|
217
217
|
finally {
|
|
218
|
+
// 防御性取消底层流:仅 releaseLock 会让连接保持挂起,造成连接泄漏
|
|
219
|
+
try {
|
|
220
|
+
await reader.cancel();
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
// 流已自然结束或已被取消时忽略次级异常
|
|
224
|
+
}
|
|
218
225
|
try {
|
|
219
226
|
reader.releaseLock();
|
|
220
227
|
}
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@actiondock/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "ActionDock Core Engine - Project loader, runtime execution, SQLite storage, standalone builder, and skill exporter",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"test": "node ../../scripts/run-tests.ts"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@actiondock/sdk": "^2.
|
|
32
|
+
"@actiondock/sdk": "^2.3.0",
|
|
33
33
|
"ajv": "^8.17.1",
|
|
34
34
|
"ajv-formats": "^3.0.1"
|
|
35
35
|
},
|