@anusornneal/chat-relay 0.8.0 → 0.9.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 +339 -336
- package/agent/capability-scheduler.mjs +121 -121
- package/agent/connection-state.mjs +141 -126
- package/agent/desktop-manager.mjs +424 -440
- package/agent/file-manager.mjs +527 -527
- package/agent/lifecycle.mjs +101 -101
- package/agent/local-agent.mjs +494 -475
- package/agent/macos-desktop-helper.js +243 -0
- package/agent/macos-desktop-runner.mjs +292 -0
- package/agent/process-manager.mjs +110 -26
- package/agent/protocol.mjs +67 -67
- package/agent/terminal-manager.mjs +587 -550
- package/agent/windows-desktop-runner.mjs +109 -0
- package/agent/windows-desktop-worker.ps1 +582 -508
- package/cli/config.mjs +114 -114
- package/cli/device-login.mjs +170 -170
- package/cli/index.mjs +241 -241
- package/cli/remote.mjs +139 -139
- package/package.json +76 -75
- package/agent/windows-desktop.ps1 +0 -288
package/agent/lifecycle.mjs
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
const ALLOWED_WHILE_DRAINING = new Set([
|
|
2
|
-
"ping",
|
|
3
|
-
"agent.config",
|
|
4
|
-
"agent.recentCalls",
|
|
5
|
-
"agent.lifecycle.status",
|
|
6
|
-
"agent.lifecycle.drain",
|
|
7
|
-
"agent.lifecycle.resume",
|
|
8
|
-
"agent.lifecycle.restart",
|
|
9
|
-
"fs.stat",
|
|
10
|
-
"fs.list",
|
|
11
|
-
"fs.read",
|
|
12
|
-
"fs.readMany",
|
|
13
|
-
"fs.batch",
|
|
14
|
-
"fs.artifact",
|
|
15
|
-
"fs.search.start",
|
|
16
|
-
"fs.search.results",
|
|
17
|
-
"process.list",
|
|
18
|
-
"process.kill",
|
|
19
|
-
"desktop.screenshot",
|
|
20
|
-
"desktop.clipboard.read",
|
|
21
|
-
"desktop.window.list",
|
|
22
|
-
"terminal.batch.status",
|
|
23
|
-
"terminal.batch.read",
|
|
24
|
-
"terminal.batch.cancel",
|
|
25
|
-
"terminal.read",
|
|
26
|
-
"terminal.write",
|
|
27
|
-
"terminal.kill",
|
|
28
|
-
"terminal.list",
|
|
29
|
-
"terminal.observability",
|
|
30
|
-
]);
|
|
31
|
-
|
|
32
|
-
export const AGENT_RESTART_EXIT_CODE = 4;
|
|
33
|
-
|
|
34
|
-
function normalizeWork(value = {}) {
|
|
35
|
-
const count = (key) => Math.max(0, Number(value[key]) || 0);
|
|
36
|
-
const work = {
|
|
37
|
-
activeSessions: count("activeSessions"),
|
|
38
|
-
activeBatchJobs: count("activeBatchJobs"),
|
|
39
|
-
queuedBatchJobs: count("queuedBatchJobs"),
|
|
40
|
-
activeTerminalExecs: count("activeTerminalExecs"),
|
|
41
|
-
queuedTerminalExecs: count("queuedTerminalExecs"),
|
|
42
|
-
};
|
|
43
|
-
work.total = Object.values(work).reduce((sum, item) => sum + item, 0);
|
|
44
|
-
return work;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export class AgentLifecycle {
|
|
48
|
-
constructor(options = {}) {
|
|
49
|
-
this.state = "running";
|
|
50
|
-
this.drainStartedAt = null;
|
|
51
|
-
this.restartRequestedAt = null;
|
|
52
|
-
this.now = options.now ?? (() => Date.now());
|
|
53
|
-
this.workSummary = options.workSummary ?? (() => ({}));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
snapshot() {
|
|
57
|
-
const work = normalizeWork(this.workSummary());
|
|
58
|
-
return {
|
|
59
|
-
state: this.state,
|
|
60
|
-
drainStartedAt: this.drainStartedAt,
|
|
61
|
-
restartRequestedAt: this.restartRequestedAt,
|
|
62
|
-
readyToRestart: this.state === "draining" && work.total === 0,
|
|
63
|
-
work,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
drain() {
|
|
68
|
-
if (this.state !== "restart-pending") {
|
|
69
|
-
this.state = "draining";
|
|
70
|
-
this.drainStartedAt ??= new Date(this.now()).toISOString();
|
|
71
|
-
}
|
|
72
|
-
return { ok: true, lifecycle: this.snapshot() };
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
resume() {
|
|
76
|
-
if (this.state === "restart-pending") {
|
|
77
|
-
return { ok: false, error: "restart_pending", lifecycle: this.snapshot() };
|
|
78
|
-
}
|
|
79
|
-
this.state = "running";
|
|
80
|
-
this.drainStartedAt = null;
|
|
81
|
-
return { ok: true, lifecycle: this.snapshot() };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
guard(action) {
|
|
85
|
-
if (this.state === "running" || ALLOWED_WHILE_DRAINING.has(String(action))) return null;
|
|
86
|
-
return { ok: false, error: "agent_draining", lifecycle: this.snapshot() };
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
requestRestart() {
|
|
90
|
-
if (this.state !== "draining") {
|
|
91
|
-
return { ok: false, error: "drain_required", lifecycle: this.snapshot() };
|
|
92
|
-
}
|
|
93
|
-
const snapshot = this.snapshot();
|
|
94
|
-
if (snapshot.work.total > 0) {
|
|
95
|
-
return { ok: false, error: "active_work_remaining", lifecycle: snapshot };
|
|
96
|
-
}
|
|
97
|
-
this.state = "restart-pending";
|
|
98
|
-
this.restartRequestedAt = new Date(this.now()).toISOString();
|
|
99
|
-
return { ok: true, restart: true, lifecycle: this.snapshot() };
|
|
100
|
-
}
|
|
101
|
-
}
|
|
1
|
+
const ALLOWED_WHILE_DRAINING = new Set([
|
|
2
|
+
"ping",
|
|
3
|
+
"agent.config",
|
|
4
|
+
"agent.recentCalls",
|
|
5
|
+
"agent.lifecycle.status",
|
|
6
|
+
"agent.lifecycle.drain",
|
|
7
|
+
"agent.lifecycle.resume",
|
|
8
|
+
"agent.lifecycle.restart",
|
|
9
|
+
"fs.stat",
|
|
10
|
+
"fs.list",
|
|
11
|
+
"fs.read",
|
|
12
|
+
"fs.readMany",
|
|
13
|
+
"fs.batch",
|
|
14
|
+
"fs.artifact",
|
|
15
|
+
"fs.search.start",
|
|
16
|
+
"fs.search.results",
|
|
17
|
+
"process.list",
|
|
18
|
+
"process.kill",
|
|
19
|
+
"desktop.screenshot",
|
|
20
|
+
"desktop.clipboard.read",
|
|
21
|
+
"desktop.window.list",
|
|
22
|
+
"terminal.batch.status",
|
|
23
|
+
"terminal.batch.read",
|
|
24
|
+
"terminal.batch.cancel",
|
|
25
|
+
"terminal.read",
|
|
26
|
+
"terminal.write",
|
|
27
|
+
"terminal.kill",
|
|
28
|
+
"terminal.list",
|
|
29
|
+
"terminal.observability",
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
export const AGENT_RESTART_EXIT_CODE = 4;
|
|
33
|
+
|
|
34
|
+
function normalizeWork(value = {}) {
|
|
35
|
+
const count = (key) => Math.max(0, Number(value[key]) || 0);
|
|
36
|
+
const work = {
|
|
37
|
+
activeSessions: count("activeSessions"),
|
|
38
|
+
activeBatchJobs: count("activeBatchJobs"),
|
|
39
|
+
queuedBatchJobs: count("queuedBatchJobs"),
|
|
40
|
+
activeTerminalExecs: count("activeTerminalExecs"),
|
|
41
|
+
queuedTerminalExecs: count("queuedTerminalExecs"),
|
|
42
|
+
};
|
|
43
|
+
work.total = Object.values(work).reduce((sum, item) => sum + item, 0);
|
|
44
|
+
return work;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class AgentLifecycle {
|
|
48
|
+
constructor(options = {}) {
|
|
49
|
+
this.state = "running";
|
|
50
|
+
this.drainStartedAt = null;
|
|
51
|
+
this.restartRequestedAt = null;
|
|
52
|
+
this.now = options.now ?? (() => Date.now());
|
|
53
|
+
this.workSummary = options.workSummary ?? (() => ({}));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
snapshot() {
|
|
57
|
+
const work = normalizeWork(this.workSummary());
|
|
58
|
+
return {
|
|
59
|
+
state: this.state,
|
|
60
|
+
drainStartedAt: this.drainStartedAt,
|
|
61
|
+
restartRequestedAt: this.restartRequestedAt,
|
|
62
|
+
readyToRestart: this.state === "draining" && work.total === 0,
|
|
63
|
+
work,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
drain() {
|
|
68
|
+
if (this.state !== "restart-pending") {
|
|
69
|
+
this.state = "draining";
|
|
70
|
+
this.drainStartedAt ??= new Date(this.now()).toISOString();
|
|
71
|
+
}
|
|
72
|
+
return { ok: true, lifecycle: this.snapshot() };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
resume() {
|
|
76
|
+
if (this.state === "restart-pending") {
|
|
77
|
+
return { ok: false, error: "restart_pending", lifecycle: this.snapshot() };
|
|
78
|
+
}
|
|
79
|
+
this.state = "running";
|
|
80
|
+
this.drainStartedAt = null;
|
|
81
|
+
return { ok: true, lifecycle: this.snapshot() };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
guard(action) {
|
|
85
|
+
if (this.state === "running" || ALLOWED_WHILE_DRAINING.has(String(action))) return null;
|
|
86
|
+
return { ok: false, error: "agent_draining", lifecycle: this.snapshot() };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
requestRestart() {
|
|
90
|
+
if (this.state !== "draining") {
|
|
91
|
+
return { ok: false, error: "drain_required", lifecycle: this.snapshot() };
|
|
92
|
+
}
|
|
93
|
+
const snapshot = this.snapshot();
|
|
94
|
+
if (snapshot.work.total > 0) {
|
|
95
|
+
return { ok: false, error: "active_work_remaining", lifecycle: snapshot };
|
|
96
|
+
}
|
|
97
|
+
this.state = "restart-pending";
|
|
98
|
+
this.restartRequestedAt = new Date(this.now()).toISOString();
|
|
99
|
+
return { ok: true, restart: true, lifecycle: this.snapshot() };
|
|
100
|
+
}
|
|
101
|
+
}
|