@xgjktech/xg_cwork_im 1.17.39 → 1.17.40
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 +489 -484
- package/dist/src/account-connection.d.ts.map +1 -1
- package/dist/src/account-connection.js +7 -0
- package/dist/src/account-connection.js.map +1 -1
- package/dist/src/build-project-prompt.test.js +18 -18
- package/dist/src/channel-config.d.ts +31 -0
- package/dist/src/channel-config.d.ts.map +1 -1
- package/dist/src/channel-config.js +27 -3
- package/dist/src/channel-config.js.map +1 -1
- package/dist/src/channel-config.test.js +58 -1
- package/dist/src/channel-config.test.js.map +1 -1
- package/dist/src/connection-workspace-event.test.d.ts +2 -0
- package/dist/src/connection-workspace-event.test.d.ts.map +1 -0
- package/dist/src/connection-workspace-event.test.js +74 -0
- package/dist/src/connection-workspace-event.test.js.map +1 -0
- package/dist/src/connection.d.ts +4 -0
- package/dist/src/connection.d.ts.map +1 -1
- package/dist/src/connection.js +32 -0
- package/dist/src/connection.js.map +1 -1
- package/dist/src/gateway-session-queue.d.ts +3 -0
- package/dist/src/gateway-session-queue.d.ts.map +1 -1
- package/dist/src/gateway-session-queue.js +1 -0
- package/dist/src/gateway-session-queue.js.map +1 -1
- package/dist/src/nas-site.d.ts +16 -0
- package/dist/src/nas-site.d.ts.map +1 -0
- package/dist/src/nas-site.js +17 -0
- package/dist/src/nas-site.js.map +1 -0
- package/dist/src/nas-volumes.d.ts +8 -0
- package/dist/src/nas-volumes.d.ts.map +1 -1
- package/dist/src/nas-volumes.js +66 -0
- package/dist/src/nas-volumes.js.map +1 -1
- package/dist/src/single-chat-no-reply-fallback.d.ts +14 -0
- package/dist/src/single-chat-no-reply-fallback.d.ts.map +1 -0
- package/dist/src/single-chat-no-reply-fallback.js +20 -0
- package/dist/src/single-chat-no-reply-fallback.js.map +1 -0
- package/dist/src/subagent-progress-hooks.d.ts +11 -0
- package/dist/src/subagent-progress-hooks.d.ts.map +1 -0
- package/dist/src/subagent-progress-hooks.js +41 -0
- package/dist/src/subagent-progress-hooks.js.map +1 -0
- package/dist/src/types.d.ts +15 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/workspace-event-protocol.d.ts +3 -0
- package/dist/src/workspace-event-protocol.d.ts.map +1 -0
- package/dist/src/workspace-event-protocol.js +3 -0
- package/dist/src/workspace-event-protocol.js.map +1 -0
- package/dist/src/workspace-event-scheduler.d.ts +54 -0
- package/dist/src/workspace-event-scheduler.d.ts.map +1 -0
- package/dist/src/workspace-event-scheduler.js +131 -0
- package/dist/src/workspace-event-scheduler.js.map +1 -0
- package/dist/src/workspace-event-scheduler.test.d.ts +2 -0
- package/dist/src/workspace-event-scheduler.test.d.ts.map +1 -0
- package/dist/src/workspace-event-scheduler.test.js +157 -0
- package/dist/src/workspace-event-scheduler.test.js.map +1 -0
- package/dist/src/workspace-event.d.ts +28 -0
- package/dist/src/workspace-event.d.ts.map +1 -0
- package/dist/src/workspace-event.js +674 -0
- package/dist/src/workspace-event.js.map +1 -0
- package/dist/src/workspace-event.test.d.ts +2 -0
- package/dist/src/workspace-event.test.d.ts.map +1 -0
- package/dist/src/workspace-event.test.js +265 -0
- package/dist/src/workspace-event.test.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { XgImConfig } from "./types.js";
|
|
2
|
+
/** 一台 OpenClaw 进程内共享的工作区并发默认值。 */
|
|
3
|
+
export declare const DEFAULT_WORKSPACE_EVENT_MAX_CONCURRENCY = 32;
|
|
4
|
+
export declare const DEFAULT_WORKSPACE_EVENT_MAX_FILE_CONCURRENCY = 8;
|
|
5
|
+
export declare const DEFAULT_WORKSPACE_EVENT_PER_AGENT_CONCURRENCY = 2;
|
|
6
|
+
export declare const DEFAULT_WORKSPACE_EVENT_QUEUE_LIMIT = 64;
|
|
7
|
+
/**
|
|
8
|
+
* ws-notify 的回程路由默认 60 秒失效。排队超过 45 秒就返回 BUSY,给回包发送和
|
|
9
|
+
* 网络转发留出余量,避免插件完成了工作但客户端因 relay 已过期而收不到结果。
|
|
10
|
+
*/
|
|
11
|
+
export declare const WORKSPACE_EVENT_QUEUE_WAIT_MS = 45000;
|
|
12
|
+
export type WorkspaceEventTaskKind = "TREE" | "FILE";
|
|
13
|
+
export type WorkspaceEventBusyReason = "QUEUE_FULL" | "QUEUE_TIMEOUT";
|
|
14
|
+
export interface WorkspaceEventConcurrencyLimits {
|
|
15
|
+
maxConcurrency: number;
|
|
16
|
+
maxFileConcurrency: number;
|
|
17
|
+
perAgentConcurrency: number;
|
|
18
|
+
queueLimit: number;
|
|
19
|
+
queueWaitMs: number;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 并发参数是机器级配置。即使某个旧配置绕过 schema,也在这里补默认值并保证
|
|
23
|
+
* 文件/单 Agent 上限不会大于全局上限。
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveWorkspaceEventConcurrencyLimits(config: Pick<XgImConfig, "workspaceEventMaxConcurrency" | "workspaceEventMaxFileConcurrency" | "workspaceEventPerAgentConcurrency" | "workspaceEventQueueLimit">): WorkspaceEventConcurrencyLimits;
|
|
26
|
+
/**
|
|
27
|
+
* 进程级工作区调度器。一个插件进程中的所有机器人账户共享同一实例,避免把
|
|
28
|
+
* “每 Agent 并发”错误地放大为 Agent 数量乘以并发数。
|
|
29
|
+
*/
|
|
30
|
+
export declare class WorkspaceEventScheduler {
|
|
31
|
+
private activeTotal;
|
|
32
|
+
private activeFiles;
|
|
33
|
+
private readonly activeByAgent;
|
|
34
|
+
private readonly queue;
|
|
35
|
+
run<T>(args: {
|
|
36
|
+
agentKey: string;
|
|
37
|
+
kind: WorkspaceEventTaskKind;
|
|
38
|
+
limits: WorkspaceEventConcurrencyLimits;
|
|
39
|
+
task: () => Promise<T>;
|
|
40
|
+
onBusy: (reason: WorkspaceEventBusyReason) => T;
|
|
41
|
+
}): Promise<T>;
|
|
42
|
+
/** 只用于测试和运行监控,不暴露队列中的业务参数。 */
|
|
43
|
+
snapshot(): {
|
|
44
|
+
activeTotal: number;
|
|
45
|
+
activeFiles: number;
|
|
46
|
+
queued: number;
|
|
47
|
+
};
|
|
48
|
+
private canStart;
|
|
49
|
+
private start;
|
|
50
|
+
private drain;
|
|
51
|
+
private expire;
|
|
52
|
+
}
|
|
53
|
+
export declare const workspaceEventScheduler: WorkspaceEventScheduler;
|
|
54
|
+
//# sourceMappingURL=workspace-event-scheduler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-event-scheduler.d.ts","sourceRoot":"","sources":["../../src/workspace-event-scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,kCAAkC;AAClC,eAAO,MAAM,uCAAuC,KAAK,CAAC;AAC1D,eAAO,MAAM,4CAA4C,IAAI,CAAC;AAC9D,eAAO,MAAM,6CAA6C,IAAI,CAAC;AAC/D,eAAO,MAAM,mCAAmC,KAAK,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,wBAAwB,GAAG,YAAY,GAAG,eAAe,CAAC;AAEtE,MAAM,WAAW,+BAA+B;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAqBD;;;GAGG;AACH,wBAAgB,sCAAsC,CAClD,MAAM,EAAE,IAAI,CACR,UAAU,EACR,8BAA8B,GAC9B,kCAAkC,GAClC,mCAAmC,GACnC,0BAA0B,CAC/B,GACF,+BAA+B,CAwBjC;AAED;;;GAGG;AACH,qBAAa,uBAAuB;IAChC,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA6B;IAC3D,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAE3C,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,sBAAsB,CAAC;QAC7B,MAAM,EAAE,+BAA+B,CAAC;QACxC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,CAAC,CAAC;KACnD,GAAG,OAAO,CAAC,CAAC,CAAC;IA+Bd,8BAA8B;IAC9B,QAAQ,IAAI;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAQxE,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,KAAK;IAmBb,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,MAAM;CAUjB;AAED,eAAO,MAAM,uBAAuB,yBAAgC,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/** 一台 OpenClaw 进程内共享的工作区并发默认值。 */
|
|
2
|
+
export const DEFAULT_WORKSPACE_EVENT_MAX_CONCURRENCY = 32;
|
|
3
|
+
export const DEFAULT_WORKSPACE_EVENT_MAX_FILE_CONCURRENCY = 8;
|
|
4
|
+
export const DEFAULT_WORKSPACE_EVENT_PER_AGENT_CONCURRENCY = 2;
|
|
5
|
+
export const DEFAULT_WORKSPACE_EVENT_QUEUE_LIMIT = 64;
|
|
6
|
+
/**
|
|
7
|
+
* ws-notify 的回程路由默认 60 秒失效。排队超过 45 秒就返回 BUSY,给回包发送和
|
|
8
|
+
* 网络转发留出余量,避免插件完成了工作但客户端因 relay 已过期而收不到结果。
|
|
9
|
+
*/
|
|
10
|
+
export const WORKSPACE_EVENT_QUEUE_WAIT_MS = 45_000;
|
|
11
|
+
function positiveInteger(value, fallback) {
|
|
12
|
+
return Number.isInteger(value) && (value ?? 0) > 0 ? value : fallback;
|
|
13
|
+
}
|
|
14
|
+
function nonNegativeInteger(value, fallback) {
|
|
15
|
+
return Number.isInteger(value) && (value ?? -1) >= 0 ? value : fallback;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 并发参数是机器级配置。即使某个旧配置绕过 schema,也在这里补默认值并保证
|
|
19
|
+
* 文件/单 Agent 上限不会大于全局上限。
|
|
20
|
+
*/
|
|
21
|
+
export function resolveWorkspaceEventConcurrencyLimits(config) {
|
|
22
|
+
const maxConcurrency = positiveInteger(config.workspaceEventMaxConcurrency, DEFAULT_WORKSPACE_EVENT_MAX_CONCURRENCY);
|
|
23
|
+
return {
|
|
24
|
+
maxConcurrency,
|
|
25
|
+
maxFileConcurrency: Math.min(positiveInteger(config.workspaceEventMaxFileConcurrency, DEFAULT_WORKSPACE_EVENT_MAX_FILE_CONCURRENCY), maxConcurrency),
|
|
26
|
+
perAgentConcurrency: Math.min(positiveInteger(config.workspaceEventPerAgentConcurrency, DEFAULT_WORKSPACE_EVENT_PER_AGENT_CONCURRENCY), maxConcurrency),
|
|
27
|
+
queueLimit: nonNegativeInteger(config.workspaceEventQueueLimit, DEFAULT_WORKSPACE_EVENT_QUEUE_LIMIT),
|
|
28
|
+
queueWaitMs: WORKSPACE_EVENT_QUEUE_WAIT_MS,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 进程级工作区调度器。一个插件进程中的所有机器人账户共享同一实例,避免把
|
|
33
|
+
* “每 Agent 并发”错误地放大为 Agent 数量乘以并发数。
|
|
34
|
+
*/
|
|
35
|
+
export class WorkspaceEventScheduler {
|
|
36
|
+
activeTotal = 0;
|
|
37
|
+
activeFiles = 0;
|
|
38
|
+
activeByAgent = new Map();
|
|
39
|
+
queue = [];
|
|
40
|
+
run(args) {
|
|
41
|
+
const pending = {
|
|
42
|
+
agentKey: args.agentKey,
|
|
43
|
+
kind: args.kind,
|
|
44
|
+
limits: args.limits,
|
|
45
|
+
task: args.task,
|
|
46
|
+
onBusy: args.onBusy,
|
|
47
|
+
};
|
|
48
|
+
if (this.queue.length === 0 && this.canStart(pending)) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
this.start({ ...pending, resolve: resolve, reject });
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (this.queue.length >= args.limits.queueLimit) {
|
|
54
|
+
return Promise.resolve(args.onBusy("QUEUE_FULL"));
|
|
55
|
+
}
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const queued = {
|
|
58
|
+
...pending,
|
|
59
|
+
resolve: resolve,
|
|
60
|
+
reject,
|
|
61
|
+
};
|
|
62
|
+
queued.timer = setTimeout(() => this.expire(queued), args.limits.queueWaitMs);
|
|
63
|
+
queued.timer.unref?.();
|
|
64
|
+
this.queue.push(queued);
|
|
65
|
+
this.drain();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** 只用于测试和运行监控,不暴露队列中的业务参数。 */
|
|
69
|
+
snapshot() {
|
|
70
|
+
return {
|
|
71
|
+
activeTotal: this.activeTotal,
|
|
72
|
+
activeFiles: this.activeFiles,
|
|
73
|
+
queued: this.queue.length,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
canStart(task) {
|
|
77
|
+
if (this.activeTotal >= task.limits.maxConcurrency)
|
|
78
|
+
return false;
|
|
79
|
+
if (task.kind === "FILE" && this.activeFiles >= task.limits.maxFileConcurrency)
|
|
80
|
+
return false;
|
|
81
|
+
return (this.activeByAgent.get(task.agentKey) ?? 0) < task.limits.perAgentConcurrency;
|
|
82
|
+
}
|
|
83
|
+
start(task) {
|
|
84
|
+
if (task.timer)
|
|
85
|
+
clearTimeout(task.timer);
|
|
86
|
+
this.activeTotal += 1;
|
|
87
|
+
if (task.kind === "FILE")
|
|
88
|
+
this.activeFiles += 1;
|
|
89
|
+
this.activeByAgent.set(task.agentKey, (this.activeByAgent.get(task.agentKey) ?? 0) + 1);
|
|
90
|
+
void Promise.resolve()
|
|
91
|
+
.then(task.task)
|
|
92
|
+
.then(task.resolve, task.reject)
|
|
93
|
+
.finally(() => {
|
|
94
|
+
this.activeTotal -= 1;
|
|
95
|
+
if (task.kind === "FILE")
|
|
96
|
+
this.activeFiles -= 1;
|
|
97
|
+
const agentActive = (this.activeByAgent.get(task.agentKey) ?? 1) - 1;
|
|
98
|
+
if (agentActive > 0)
|
|
99
|
+
this.activeByAgent.set(task.agentKey, agentActive);
|
|
100
|
+
else
|
|
101
|
+
this.activeByAgent.delete(task.agentKey);
|
|
102
|
+
this.drain();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
drain() {
|
|
106
|
+
let index = 0;
|
|
107
|
+
while (index < this.queue.length) {
|
|
108
|
+
const task = this.queue[index];
|
|
109
|
+
if (!this.canStart(task)) {
|
|
110
|
+
index += 1;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
this.queue.splice(index, 1);
|
|
114
|
+
this.start(task);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
expire(task) {
|
|
118
|
+
const index = this.queue.indexOf(task);
|
|
119
|
+
if (index < 0)
|
|
120
|
+
return;
|
|
121
|
+
this.queue.splice(index, 1);
|
|
122
|
+
try {
|
|
123
|
+
task.resolve(task.onBusy("QUEUE_TIMEOUT"));
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
task.reject(error);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
export const workspaceEventScheduler = new WorkspaceEventScheduler();
|
|
131
|
+
//# sourceMappingURL=workspace-event-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-event-scheduler.js","sourceRoot":"","sources":["../../src/workspace-event-scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-event-scheduler.test.d.ts","sourceRoot":"","sources":["../../src/workspace-event-scheduler.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { describe, it } from "node:test";
|
|
3
|
+
import { DEFAULT_WORKSPACE_EVENT_MAX_CONCURRENCY, DEFAULT_WORKSPACE_EVENT_MAX_FILE_CONCURRENCY, DEFAULT_WORKSPACE_EVENT_PER_AGENT_CONCURRENCY, DEFAULT_WORKSPACE_EVENT_QUEUE_LIMIT, WorkspaceEventScheduler, resolveWorkspaceEventConcurrencyLimits, } from "./workspace-event-scheduler.js";
|
|
4
|
+
function deferred() {
|
|
5
|
+
let resolve;
|
|
6
|
+
const promise = new Promise((done) => {
|
|
7
|
+
resolve = done;
|
|
8
|
+
});
|
|
9
|
+
return { promise, resolve };
|
|
10
|
+
}
|
|
11
|
+
const limits = (overrides = {}) => ({
|
|
12
|
+
maxConcurrency: 2,
|
|
13
|
+
maxFileConcurrency: 2,
|
|
14
|
+
perAgentConcurrency: 2,
|
|
15
|
+
queueLimit: 2,
|
|
16
|
+
queueWaitMs: 1_000,
|
|
17
|
+
...overrides,
|
|
18
|
+
});
|
|
19
|
+
const busy = (reason) => `BUSY:${reason}`;
|
|
20
|
+
describe("workspace event concurrency config", () => {
|
|
21
|
+
it("uses machine defaults and keeps sub-limits inside the global limit", () => {
|
|
22
|
+
assert.deepEqual(resolveWorkspaceEventConcurrencyLimits({}), {
|
|
23
|
+
maxConcurrency: DEFAULT_WORKSPACE_EVENT_MAX_CONCURRENCY,
|
|
24
|
+
maxFileConcurrency: DEFAULT_WORKSPACE_EVENT_MAX_FILE_CONCURRENCY,
|
|
25
|
+
perAgentConcurrency: DEFAULT_WORKSPACE_EVENT_PER_AGENT_CONCURRENCY,
|
|
26
|
+
queueLimit: DEFAULT_WORKSPACE_EVENT_QUEUE_LIMIT,
|
|
27
|
+
queueWaitMs: 45_000,
|
|
28
|
+
});
|
|
29
|
+
assert.deepEqual(resolveWorkspaceEventConcurrencyLimits({
|
|
30
|
+
workspaceEventMaxConcurrency: 3,
|
|
31
|
+
workspaceEventMaxFileConcurrency: 8,
|
|
32
|
+
workspaceEventPerAgentConcurrency: 5,
|
|
33
|
+
workspaceEventQueueLimit: 9,
|
|
34
|
+
}), {
|
|
35
|
+
maxConcurrency: 3,
|
|
36
|
+
maxFileConcurrency: 3,
|
|
37
|
+
perAgentConcurrency: 3,
|
|
38
|
+
queueLimit: 9,
|
|
39
|
+
queueWaitMs: 45_000,
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
describe("workspace event scheduler", () => {
|
|
44
|
+
it("bounds global activity and returns BUSY when the global queue is full", async () => {
|
|
45
|
+
const scheduler = new WorkspaceEventScheduler();
|
|
46
|
+
const first = deferred();
|
|
47
|
+
const second = deferred();
|
|
48
|
+
const third = deferred();
|
|
49
|
+
const fourth = deferred();
|
|
50
|
+
const started = [];
|
|
51
|
+
const run = (name, gate) => scheduler.run({
|
|
52
|
+
agentKey: name,
|
|
53
|
+
kind: "TREE",
|
|
54
|
+
limits: limits(),
|
|
55
|
+
task: async () => {
|
|
56
|
+
started.push(name);
|
|
57
|
+
return gate.promise;
|
|
58
|
+
},
|
|
59
|
+
onBusy: busy,
|
|
60
|
+
});
|
|
61
|
+
const p1 = run("agent-1", first);
|
|
62
|
+
const p2 = run("agent-2", second);
|
|
63
|
+
const p3 = run("agent-3", third);
|
|
64
|
+
const p4 = run("agent-4", fourth);
|
|
65
|
+
const rejected = await run("agent-5", deferred());
|
|
66
|
+
assert.equal(rejected, "BUSY:QUEUE_FULL");
|
|
67
|
+
assert.deepEqual(scheduler.snapshot(), { activeTotal: 2, activeFiles: 0, queued: 2 });
|
|
68
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
69
|
+
assert.deepEqual(started, ["agent-1", "agent-2"]);
|
|
70
|
+
first.resolve("one");
|
|
71
|
+
assert.equal(await p1, "one");
|
|
72
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
73
|
+
assert.ok(started.includes("agent-3"));
|
|
74
|
+
second.resolve("two");
|
|
75
|
+
third.resolve("three");
|
|
76
|
+
fourth.resolve("four");
|
|
77
|
+
assert.deepEqual(await Promise.all([p2, p3, p4]), ["two", "three", "four"]);
|
|
78
|
+
assert.deepEqual(scheduler.snapshot(), { activeTotal: 0, activeFiles: 0, queued: 0 });
|
|
79
|
+
});
|
|
80
|
+
it("enforces file and per-Agent limits without blocking other Agents' tree requests", async () => {
|
|
81
|
+
const scheduler = new WorkspaceEventScheduler();
|
|
82
|
+
const fileA = deferred();
|
|
83
|
+
const fileB = deferred();
|
|
84
|
+
const treeA = deferred();
|
|
85
|
+
const treeB = deferred();
|
|
86
|
+
const started = [];
|
|
87
|
+
const customLimits = limits({
|
|
88
|
+
maxConcurrency: 4,
|
|
89
|
+
maxFileConcurrency: 1,
|
|
90
|
+
perAgentConcurrency: 1,
|
|
91
|
+
queueLimit: 8,
|
|
92
|
+
});
|
|
93
|
+
const run = (agentKey, kind, name, gate) => scheduler.run({
|
|
94
|
+
agentKey,
|
|
95
|
+
kind,
|
|
96
|
+
limits: customLimits,
|
|
97
|
+
task: async () => {
|
|
98
|
+
started.push(name);
|
|
99
|
+
return gate.promise;
|
|
100
|
+
},
|
|
101
|
+
onBusy: busy,
|
|
102
|
+
});
|
|
103
|
+
const pFileA = run("agent-a", "FILE", "file-a", fileA);
|
|
104
|
+
const pFileB = run("agent-b", "FILE", "file-b", fileB);
|
|
105
|
+
const pTreeA = run("agent-a", "TREE", "tree-a", treeA);
|
|
106
|
+
const pTreeB = run("agent-b", "TREE", "tree-b", treeB);
|
|
107
|
+
const treeC = deferred();
|
|
108
|
+
const pTreeC = run("agent-c", "TREE", "tree-c", treeC);
|
|
109
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
110
|
+
assert.deepEqual(started, ["file-a", "tree-b", "tree-c"]);
|
|
111
|
+
assert.deepEqual(scheduler.snapshot(), { activeTotal: 3, activeFiles: 1, queued: 2 });
|
|
112
|
+
fileA.resolve("file-a");
|
|
113
|
+
assert.equal(await pFileA, "file-a");
|
|
114
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
115
|
+
assert.ok(started.includes("tree-a"));
|
|
116
|
+
assert.equal(started.includes("file-b"), false);
|
|
117
|
+
treeB.resolve("tree-b");
|
|
118
|
+
assert.equal(await pTreeB, "tree-b");
|
|
119
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
120
|
+
assert.ok(started.includes("file-b"));
|
|
121
|
+
fileB.resolve("file-b");
|
|
122
|
+
treeA.resolve("tree-a");
|
|
123
|
+
treeC.resolve("tree-c");
|
|
124
|
+
await Promise.all([pFileB, pTreeA, pTreeC]);
|
|
125
|
+
assert.deepEqual(scheduler.snapshot(), { activeTotal: 0, activeFiles: 0, queued: 0 });
|
|
126
|
+
});
|
|
127
|
+
it("returns BUSY when a queued request waits past its deadline", async () => {
|
|
128
|
+
const scheduler = new WorkspaceEventScheduler();
|
|
129
|
+
const gate = deferred();
|
|
130
|
+
const shortWait = limits({
|
|
131
|
+
maxConcurrency: 1,
|
|
132
|
+
maxFileConcurrency: 1,
|
|
133
|
+
perAgentConcurrency: 1,
|
|
134
|
+
queueLimit: 1,
|
|
135
|
+
queueWaitMs: 20,
|
|
136
|
+
});
|
|
137
|
+
const active = scheduler.run({
|
|
138
|
+
agentKey: "agent-a",
|
|
139
|
+
kind: "FILE",
|
|
140
|
+
limits: shortWait,
|
|
141
|
+
task: () => gate.promise,
|
|
142
|
+
onBusy: busy,
|
|
143
|
+
});
|
|
144
|
+
const queued = scheduler.run({
|
|
145
|
+
agentKey: "agent-b",
|
|
146
|
+
kind: "TREE",
|
|
147
|
+
limits: shortWait,
|
|
148
|
+
task: async () => "unexpected",
|
|
149
|
+
onBusy: busy,
|
|
150
|
+
});
|
|
151
|
+
assert.equal(await queued, "BUSY:QUEUE_TIMEOUT");
|
|
152
|
+
assert.deepEqual(scheduler.snapshot(), { activeTotal: 1, activeFiles: 1, queued: 0 });
|
|
153
|
+
gate.resolve("done");
|
|
154
|
+
assert.equal(await active, "done");
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=workspace-event-scheduler.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-event-scheduler.test.js","sourceRoot":"","sources":["../../src/workspace-event-scheduler.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 会话工作区目录浏览与文本文件读取。
|
|
3
|
+
*
|
|
4
|
+
* 该信令与 robotMention/groupMessage 完全分流,不创建 Agent 轮次、不写会话记录。
|
|
5
|
+
* LOCAL 工作区以 IM 计算的 localRoot 为授权根;NAS 工作区只访问 nasVolumes 明确授权的
|
|
6
|
+
* dockerDir,并通过当前机器 nasVolumeRootMappings 映射到宿主目录。
|
|
7
|
+
*/
|
|
8
|
+
import type { OpenClawConfig } from "openclaw/plugin-sdk";
|
|
9
|
+
import type { Log } from "./auth.js";
|
|
10
|
+
import type { XgImConfig } from "./types.js";
|
|
11
|
+
export { OPENCLAW_WORKSPACE_EVENT_CMD } from "./workspace-event-protocol.js";
|
|
12
|
+
export type WorkspaceRequestEvent = "TREE_REQUEST" | "FILE_REQUEST";
|
|
13
|
+
export type WorkspaceResultEvent = "TREE_RESULT" | "FILE_RESULT";
|
|
14
|
+
export type WorkspaceErrorCode = "INVALID_REQUEST" | "PATH_OUTSIDE_WORKSPACE" | "NOT_FOUND" | "NOT_A_DIRECTORY" | "NOT_A_FILE" | "UNSUPPORTED_FILE_TYPE" | "FILE_TOO_LARGE" | "BUSY" | "READ_FAILED";
|
|
15
|
+
export interface WorkspaceEventContext {
|
|
16
|
+
config: XgImConfig;
|
|
17
|
+
cfg: OpenClawConfig;
|
|
18
|
+
log: Log;
|
|
19
|
+
logPrefix: string;
|
|
20
|
+
/** 测试或已知运行环境可直接传入;正常运行时由 OpenClaw SDK 按 agentId 解析。 */
|
|
21
|
+
workspaceHostRoot?: string;
|
|
22
|
+
}
|
|
23
|
+
export type WorkspaceEventResponse = Record<string, unknown>;
|
|
24
|
+
/**
|
|
25
|
+
* 处理工作区请求。所有账户共享进程级调度器;无效 event 不进入队列,直接返回协议错误。
|
|
26
|
+
*/
|
|
27
|
+
export declare function handleWorkspaceEvent(ctx: WorkspaceEventContext, rawParams: unknown): Promise<WorkspaceEventResponse>;
|
|
28
|
+
//# sourceMappingURL=workspace-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-event.d.ts","sourceRoot":"","sources":["../../src/workspace-event.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAiBrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAU7E,MAAM,MAAM,qBAAqB,GAAG,cAAc,GAAG,cAAc,CAAC;AACpE,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,aAAa,CAAC;AACjE,MAAM,MAAM,kBAAkB,GACxB,iBAAiB,GACjB,wBAAwB,GACxB,WAAW,GACX,iBAAiB,GACjB,YAAY,GACZ,uBAAuB,GACvB,gBAAgB,GAChB,MAAM,GACN,aAAa,CAAC;AA8BpB,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,cAAc,CAAC;IACpB,GAAG,EAAE,GAAG,CAAC;IACT,SAAS,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAmtB7D;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,GAAG,EAAE,qBAAqB,EAC1B,SAAS,EAAE,OAAO,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAajC"}
|