@moxt-ai/mobius 0.0.3 → 0.0.5
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/dist/acp/session-manager.d.ts.map +1 -1
- package/dist/acp/session-manager.js +15 -29
- package/dist/acp/session-manager.js.map +1 -1
- package/dist/agent-catalog/agent-diagnostics.d.ts +3 -0
- package/dist/agent-catalog/agent-diagnostics.d.ts.map +1 -0
- package/dist/agent-catalog/agent-diagnostics.js +62 -0
- package/dist/agent-catalog/agent-diagnostics.js.map +1 -0
- package/dist/agent-catalog/discover-local-agents.d.ts +77 -0
- package/dist/agent-catalog/discover-local-agents.d.ts.map +1 -0
- package/dist/agent-catalog/discover-local-agents.js +478 -0
- package/dist/agent-catalog/discover-local-agents.js.map +1 -0
- package/dist/agent-catalog/local-agent.d.ts +38 -0
- package/dist/agent-catalog/local-agent.d.ts.map +1 -0
- package/dist/agent-catalog/local-agent.js +93 -0
- package/dist/agent-catalog/local-agent.js.map +1 -0
- package/dist/agent-catalog/publish-agent-catalog.d.ts +3 -0
- package/dist/agent-catalog/publish-agent-catalog.d.ts.map +1 -0
- package/dist/agent-catalog/publish-agent-catalog.js +58 -0
- package/dist/agent-catalog/publish-agent-catalog.js.map +1 -0
- package/dist/agent-installation/agent-installation-manager.d.ts +60 -0
- package/dist/agent-installation/agent-installation-manager.d.ts.map +1 -0
- package/dist/agent-installation/agent-installation-manager.js +242 -0
- package/dist/agent-installation/agent-installation-manager.js.map +1 -0
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts +18 -0
- package/dist/agent-installation/automatic-adapter-provisioner.d.ts.map +1 -0
- package/dist/agent-installation/automatic-adapter-provisioner.js +116 -0
- package/dist/agent-installation/automatic-adapter-provisioner.js.map +1 -0
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts +20 -0
- package/dist/agent-installation/fixed-agent-install-recipes.d.ts.map +1 -0
- package/dist/agent-installation/fixed-agent-install-recipes.js +163 -0
- package/dist/agent-installation/fixed-agent-install-recipes.js.map +1 -0
- package/dist/agent-installation/fixed-installation-executor.d.ts +20 -0
- package/dist/agent-installation/fixed-installation-executor.d.ts.map +1 -0
- package/dist/agent-installation/fixed-installation-executor.js +213 -0
- package/dist/agent-installation/fixed-installation-executor.js.map +1 -0
- package/dist/agent-installation/installation-grants.d.ts +2 -0
- package/dist/agent-installation/installation-grants.d.ts.map +1 -0
- package/dist/agent-installation/installation-grants.js +52 -0
- package/dist/agent-installation/installation-grants.js.map +1 -0
- package/dist/agent-installation/local-installation-authorizer.d.ts +7 -0
- package/dist/agent-installation/local-installation-authorizer.d.ts.map +1 -0
- package/dist/agent-installation/local-installation-authorizer.js +32 -0
- package/dist/agent-installation/local-installation-authorizer.js.map +1 -0
- package/dist/agent-installation/managed-adapter-installer.d.ts +21 -0
- package/dist/agent-installation/managed-adapter-installer.d.ts.map +1 -0
- package/dist/agent-installation/managed-adapter-installer.js +161 -0
- package/dist/agent-installation/managed-adapter-installer.js.map +1 -0
- package/dist/agent-installation/verified-download.d.ts +24 -0
- package/dist/agent-installation/verified-download.d.ts.map +1 -0
- package/dist/agent-installation/verified-download.js +158 -0
- package/dist/agent-installation/verified-download.js.map +1 -0
- package/dist/audit/audit-store.d.ts +1 -0
- package/dist/audit/audit-store.d.ts.map +1 -1
- package/dist/audit/audit-store.js +12 -4
- package/dist/audit/audit-store.js.map +1 -1
- package/dist/cli.js +4284 -1178
- package/dist/cli.js.map +4 -4
- package/dist/config.d.ts +6 -10
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +10 -53
- package/dist/config.js.map +1 -1
- package/dist/index.js +3476 -458
- package/dist/index.js.map +4 -4
- package/dist/pairing/pair-local-machine.d.ts +2 -2
- package/dist/pairing/pair-local-machine.d.ts.map +1 -1
- package/dist/pairing/pair-local-machine.js +41 -20
- package/dist/pairing/pair-local-machine.js.map +1 -1
- package/dist/process/executable.d.ts +40 -0
- package/dist/process/executable.d.ts.map +1 -0
- package/dist/process/executable.js +313 -0
- package/dist/process/executable.js.map +1 -0
- package/dist/relay-connection/liveness.d.ts +14 -0
- package/dist/relay-connection/liveness.d.ts.map +1 -0
- package/dist/relay-connection/liveness.js +102 -0
- package/dist/relay-connection/liveness.js.map +1 -0
- package/dist/relay-connection/timer.d.ts +8 -0
- package/dist/relay-connection/timer.d.ts.map +1 -0
- package/dist/relay-connection/timer.js +8 -0
- package/dist/relay-connection/timer.js.map +1 -0
- package/dist/run-daemon.d.ts +3 -2
- package/dist/run-daemon.d.ts.map +1 -1
- package/dist/run-daemon.js +272 -22
- package/dist/run-daemon.js.map +1 -1
- package/dist/storage/state-directory.d.ts +2 -0
- package/dist/storage/state-directory.d.ts.map +1 -0
- package/dist/storage/state-directory.js +10 -0
- package/dist/storage/state-directory.js.map +1 -0
- package/package.json +3 -5
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { encodeRuntimeHeartbeatEvent, MOBIUS_PROTOCOL_VERSION, RUNTIME_HEARTBEAT_KIND, } from "@moxt-ai/mobius-protocol";
|
|
3
|
+
const HEARTBEAT_ACK_TIMEOUT_MILLISECONDS = 10_000;
|
|
4
|
+
const HEARTBEAT_INTERVAL_MILLISECONDS = 20_000;
|
|
5
|
+
class RelayLivenessState {
|
|
6
|
+
}
|
|
7
|
+
class UnsupportedRelayLivenessState extends RelayLivenessState {
|
|
8
|
+
}
|
|
9
|
+
class AwaitingHeartbeatAckState extends RelayLivenessState {
|
|
10
|
+
heartbeatId;
|
|
11
|
+
timeout;
|
|
12
|
+
constructor(heartbeatId, timeout) {
|
|
13
|
+
super();
|
|
14
|
+
this.heartbeatId = heartbeatId;
|
|
15
|
+
this.timeout = timeout;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
class WaitingForHeartbeatState extends RelayLivenessState {
|
|
19
|
+
schedule;
|
|
20
|
+
constructor(schedule) {
|
|
21
|
+
super();
|
|
22
|
+
this.schedule = schedule;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
class FinishedRelayLivenessState extends RelayLivenessState {
|
|
26
|
+
}
|
|
27
|
+
export class RelayConnectionLiveness {
|
|
28
|
+
#timer;
|
|
29
|
+
#transport;
|
|
30
|
+
#state = new UnsupportedRelayLivenessState();
|
|
31
|
+
constructor(timer, transport) {
|
|
32
|
+
this.#timer = timer;
|
|
33
|
+
this.#transport = transport;
|
|
34
|
+
}
|
|
35
|
+
acknowledge = (event) => {
|
|
36
|
+
if (!(this.#state instanceof AwaitingHeartbeatAckState)) {
|
|
37
|
+
throw new Error("Unexpected relay heartbeat acknowledgement");
|
|
38
|
+
}
|
|
39
|
+
if (event.heartbeatId !== this.#state.heartbeatId) {
|
|
40
|
+
throw new Error("Relay acknowledged the wrong heartbeat");
|
|
41
|
+
}
|
|
42
|
+
this.#state.timeout.cancel();
|
|
43
|
+
this.#state = new WaitingForHeartbeatState(this.#timer.schedule(this.#sendHeartbeat, HEARTBEAT_INTERVAL_MILLISECONDS));
|
|
44
|
+
};
|
|
45
|
+
close = () => {
|
|
46
|
+
if (this.#state instanceof AwaitingHeartbeatAckState) {
|
|
47
|
+
this.#state.timeout.cancel();
|
|
48
|
+
}
|
|
49
|
+
else if (this.#state instanceof WaitingForHeartbeatState) {
|
|
50
|
+
this.#state.schedule.cancel();
|
|
51
|
+
}
|
|
52
|
+
else if (!(this.#state instanceof UnsupportedRelayLivenessState) &&
|
|
53
|
+
!(this.#state instanceof FinishedRelayLivenessState)) {
|
|
54
|
+
throw new Error("Unknown relay liveness state");
|
|
55
|
+
}
|
|
56
|
+
this.#state = new FinishedRelayLivenessState();
|
|
57
|
+
};
|
|
58
|
+
start = () => {
|
|
59
|
+
if (this.#state instanceof UnsupportedRelayLivenessState) {
|
|
60
|
+
this.#sendHeartbeat();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (this.#state instanceof AwaitingHeartbeatAckState ||
|
|
64
|
+
this.#state instanceof WaitingForHeartbeatState) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (this.#state instanceof FinishedRelayLivenessState) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
throw new Error("Unknown relay liveness state");
|
|
71
|
+
};
|
|
72
|
+
#handleTimeout = () => {
|
|
73
|
+
if (this.#state instanceof FinishedRelayLivenessState) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (!(this.#state instanceof AwaitingHeartbeatAckState)) {
|
|
77
|
+
throw new Error("Heartbeat timeout occurred in an invalid state");
|
|
78
|
+
}
|
|
79
|
+
this.#state.timeout.cancel();
|
|
80
|
+
this.#state = new FinishedRelayLivenessState();
|
|
81
|
+
this.#transport.unresponsive();
|
|
82
|
+
};
|
|
83
|
+
#sendHeartbeat = () => {
|
|
84
|
+
if (this.#state instanceof WaitingForHeartbeatState) {
|
|
85
|
+
this.#state.schedule.cancel();
|
|
86
|
+
}
|
|
87
|
+
else if (!(this.#state instanceof UnsupportedRelayLivenessState)) {
|
|
88
|
+
if (this.#state instanceof FinishedRelayLivenessState) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
throw new Error("Heartbeat was scheduled in an invalid state");
|
|
92
|
+
}
|
|
93
|
+
const heartbeatId = randomUUID();
|
|
94
|
+
this.#state = new AwaitingHeartbeatAckState(heartbeatId, this.#timer.schedule(this.#handleTimeout, HEARTBEAT_ACK_TIMEOUT_MILLISECONDS));
|
|
95
|
+
this.#transport.send(encodeRuntimeHeartbeatEvent({
|
|
96
|
+
heartbeatId,
|
|
97
|
+
kind: RUNTIME_HEARTBEAT_KIND,
|
|
98
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
99
|
+
}));
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=liveness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveness.js","sourceRoot":"","sources":["../../src/relay-connection/liveness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface DaemonScheduledTask {
|
|
2
|
+
readonly cancel: () => void;
|
|
3
|
+
}
|
|
4
|
+
export interface DaemonTimer {
|
|
5
|
+
readonly schedule: (callback: () => void, milliseconds: number) => DaemonScheduledTask;
|
|
6
|
+
}
|
|
7
|
+
export declare const systemDaemonTimer: DaemonTimer;
|
|
8
|
+
//# sourceMappingURL=timer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.d.ts","sourceRoot":"","sources":["../../src/relay-connection/timer.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,CACjB,QAAQ,EAAE,MAAM,IAAI,EACpB,YAAY,EAAE,MAAM,KACjB,mBAAmB,CAAC;CAC1B;AAYD,eAAO,MAAM,iBAAiB,EAAE,WAAqC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
class SystemDaemonTimer {
|
|
2
|
+
schedule = (callback, milliseconds) => {
|
|
3
|
+
const timeout = setTimeout(callback, milliseconds);
|
|
4
|
+
return { cancel: () => clearTimeout(timeout) };
|
|
5
|
+
};
|
|
6
|
+
}
|
|
7
|
+
export const systemDaemonTimer = new SystemDaemonTimer();
|
|
8
|
+
//# sourceMappingURL=timer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timer.js","sourceRoot":"","sources":["../../src/relay-connection/timer.ts"],"names":[],"mappings":"AAWA,MAAM,iBAAiB;IACZ,QAAQ,GAAG,CAClB,QAAoB,EACpB,YAAoB,EACC,EAAE;QACvB,MAAM,OAAO,GAAG,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACnD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;IACjD,CAAC,CAAC;CACH;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAgB,IAAI,iBAAiB,EAAE,CAAC"}
|
package/dist/run-daemon.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AuditStore } from "./audit/audit-store.ts";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import type { DaemonConfig } from "./config.ts";
|
|
3
|
+
import { type DaemonTimer } from "./relay-connection/timer.ts";
|
|
4
|
+
export declare function runDaemon(config: DaemonConfig, audit: AuditStore, signal: AbortSignal, timer?: DaemonTimer): Promise<void>;
|
|
4
5
|
//# sourceMappingURL=run-daemon.d.ts.map
|
package/dist/run-daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-daemon.d.ts","sourceRoot":"","sources":["../src/run-daemon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-daemon.d.ts","sourceRoot":"","sources":["../src/run-daemon.ts"],"names":[],"mappings":"AAyGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,6BAA6B,CAAC;AAu9BrC,wBAAsB,SAAS,CAC7B,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,UAAU,EACjB,MAAM,EAAE,WAAW,EACnB,KAAK,GAAE,WAA+B,GACrC,OAAO,CAAC,IAAI,CAAC,CAqFf"}
|
package/dist/run-daemon.js
CHANGED
|
@@ -1,14 +1,75 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { basename } from "node:path";
|
|
3
|
-
import { AGENT_ACTIVITY_KIND, AGENT_MESSAGE_DELTA_KIND, decodeMessageKind, decodeSessionCancelCommand, decodeSessionConfigureCommand, decodeSessionElicitationRespondCommand, decodeSessionPermissionRespondCommand, decodeSessionPrepareCommand, decodeSessionPromptCommand, decodeWorkspaceListCommand, encodeAgentActivityEvent, encodeAgentContentEvent, encodeAgentMessageDeltaEvent, encodeSessionCommandsUpdatedEvent, encodeSessionCompletedEvent, encodeSessionConfigUpdatedEvent, encodeSessionElicitationRequestedEvent, encodeSessionElicitationResolvedEvent, encodeSessionFailedEvent, encodeSessionInfoUpdatedEvent, encodeSessionOperationFailedEvent, encodeSessionPermissionRequestedEvent, encodeSessionPermissionResolvedEvent, encodeSessionReadyEvent, encodeSessionStartedEvent, encodeSessionUsageUpdatedEvent, encodeWorkspaceEntriesEvent, MOBIUS_PROTOCOL_VERSION, SESSION_CANCEL_KIND, SESSION_COMPLETED_KIND, SESSION_CONFIGURE_KIND, SESSION_ELICITATION_RESPOND_KIND, SESSION_FAILED_KIND, SESSION_PERMISSION_RESPOND_KIND, SESSION_PREPARE_KIND, SESSION_PROMPT_KIND, SESSION_STARTED_KIND, WORKSPACE_LIST_KIND, } from "@moxt-ai/mobius-protocol";
|
|
3
|
+
import { AGENT_ACTIVITY_KIND, AGENT_INSTALL_AWAITING_APPROVAL_KIND, AGENT_INSTALL_CANCEL_KIND, AGENT_INSTALL_CANCELLED_KIND, AGENT_INSTALL_COMPLETED_KIND, AGENT_INSTALL_FAILED_KIND, AGENT_INSTALL_PROGRESS_KIND, AGENT_INSTALL_REQUEST_KIND, AGENT_INSTALL_STARTED_KIND, AGENT_MESSAGE_DELTA_KIND, decodeAgentInstallCancelCommand, decodeAgentInstallRequestCommand, decodeMessageKind, decodeRuntimeHeartbeatAckEvent, decodeRuntimeLivenessReadyEvent, decodeSessionCancelCommand, decodeSessionConfigureCommand, decodeSessionElicitationRespondCommand, decodeSessionPermissionRespondCommand, decodeSessionPrepareCommand, decodeSessionPromptCommand, decodeWorkspaceListCommand, encodeAgentActivityEvent, encodeAgentContentEvent, encodeAgentInstallAwaitingApprovalEvent, encodeAgentInstallCancelledEvent, encodeAgentInstallCompletedEvent, encodeAgentInstallFailedEvent, encodeAgentInstallProgressEvent, encodeAgentInstallStartedEvent, encodeAgentMessageDeltaEvent, encodeSessionCommandsUpdatedEvent, encodeSessionCompletedEvent, encodeSessionConfigUpdatedEvent, encodeSessionElicitationRequestedEvent, encodeSessionElicitationResolvedEvent, encodeSessionFailedEvent, encodeSessionInfoUpdatedEvent, encodeSessionOperationFailedEvent, encodeSessionPermissionRequestedEvent, encodeSessionPermissionResolvedEvent, encodeSessionReadyEvent, encodeSessionStartedEvent, encodeSessionUsageUpdatedEvent, encodeWorkspaceEntriesEvent, MOBIUS_PROTOCOL_VERSION, RUNTIME_HEARTBEAT_ACK_KIND, RUNTIME_LIVENESS_READY_KIND, SESSION_CANCEL_KIND, SESSION_COMPLETED_KIND, SESSION_CONFIGURE_KIND, SESSION_ELICITATION_RESPOND_KIND, SESSION_FAILED_KIND, SESSION_PERMISSION_RESPOND_KIND, SESSION_PREPARE_KIND, SESSION_PROMPT_KIND, SESSION_STARTED_KIND, WORKSPACE_LIST_KIND, } from "@moxt-ai/mobius-protocol";
|
|
4
4
|
import { WebSocket } from "undici";
|
|
5
5
|
import { AcpExecutionError, AcpSessionManager, NullAcpSessionObserver, } from "./acp/session-manager.js";
|
|
6
6
|
import { SqliteAcpSessionStore } from "./acp/session-store.js";
|
|
7
|
+
import { supportedLocalAgentSpecifications } from "./agent-catalog/discover-local-agents.js";
|
|
8
|
+
import { LocalAgentCatalogError } from "./agent-catalog/local-agent.js";
|
|
9
|
+
import { publishAgentCatalog } from "./agent-catalog/publish-agent-catalog.js";
|
|
10
|
+
import { AgentInstallationManager, AwaitingLocalApproval, CancelledInstallation, FailedInstallation, RequestedInstallation, RunningInstallation, SucceededInstallation, } from "./agent-installation/agent-installation-manager.js";
|
|
11
|
+
import { AutomaticAdapterProvisioner } from "./agent-installation/automatic-adapter-provisioner.js";
|
|
12
|
+
import { FixedInstallationExecutor } from "./agent-installation/fixed-installation-executor.js";
|
|
13
|
+
import { ConsoleInstallationAuthorizer } from "./agent-installation/local-installation-authorizer.js";
|
|
14
|
+
import { ManagedAdapterInstaller } from "./agent-installation/managed-adapter-installer.js";
|
|
7
15
|
import { LocalAuthorizationError } from "./authorization/authorize-binding.js";
|
|
8
16
|
import { WorkspaceDirectoryService } from "./authorization/workspace-directory.js";
|
|
9
|
-
import { findLocalAgent } from "./config.js";
|
|
10
17
|
import { connectRelay } from "./relay-connection/connect.js";
|
|
18
|
+
import { RelayConnectionLiveness } from "./relay-connection/liveness.js";
|
|
19
|
+
import { systemDaemonTimer, } from "./relay-connection/timer.js";
|
|
20
|
+
import { readStateDirectory } from "./storage/state-directory.js";
|
|
11
21
|
const RELAY_RECONNECT_DELAY_MILLISECONDS = 500;
|
|
22
|
+
const RELAY_CONNECTION_REFRESH_MILLISECONDS = 20 * 60 * 1_000;
|
|
23
|
+
class RelayConnectionRefreshState {
|
|
24
|
+
}
|
|
25
|
+
class ScheduledRelayConnectionRefreshState extends RelayConnectionRefreshState {
|
|
26
|
+
}
|
|
27
|
+
class DueRelayConnectionRefreshState extends RelayConnectionRefreshState {
|
|
28
|
+
}
|
|
29
|
+
class FinishedRelayConnectionRefreshState extends RelayConnectionRefreshState {
|
|
30
|
+
}
|
|
31
|
+
class RelayConnectionRefresh {
|
|
32
|
+
#isSafe;
|
|
33
|
+
#refresh;
|
|
34
|
+
#scheduledTask;
|
|
35
|
+
#state = new ScheduledRelayConnectionRefreshState();
|
|
36
|
+
constructor(timer, isSafe, refresh) {
|
|
37
|
+
this.#isSafe = isSafe;
|
|
38
|
+
this.#refresh = refresh;
|
|
39
|
+
this.#scheduledTask = timer.schedule(this.#request, RELAY_CONNECTION_REFRESH_MILLISECONDS);
|
|
40
|
+
}
|
|
41
|
+
afterTurnFinished = () => {
|
|
42
|
+
if (this.#state instanceof DueRelayConnectionRefreshState) {
|
|
43
|
+
this.#request();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
if (this.#state instanceof ScheduledRelayConnectionRefreshState ||
|
|
47
|
+
this.#state instanceof FinishedRelayConnectionRefreshState) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
throw new Error("Unknown relay connection refresh state");
|
|
51
|
+
};
|
|
52
|
+
close = () => {
|
|
53
|
+
this.#scheduledTask.cancel();
|
|
54
|
+
this.#state = new FinishedRelayConnectionRefreshState();
|
|
55
|
+
};
|
|
56
|
+
#request = () => {
|
|
57
|
+
if (this.#state instanceof FinishedRelayConnectionRefreshState) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (!(this.#state instanceof ScheduledRelayConnectionRefreshState) &&
|
|
61
|
+
!(this.#state instanceof DueRelayConnectionRefreshState)) {
|
|
62
|
+
throw new Error("Unknown relay connection refresh state");
|
|
63
|
+
}
|
|
64
|
+
if (!this.#isSafe()) {
|
|
65
|
+
this.#state = new DueRelayConnectionRefreshState();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
this.#state = new FinishedRelayConnectionRefreshState();
|
|
69
|
+
this.#scheduledTask.cancel();
|
|
70
|
+
this.#refresh();
|
|
71
|
+
};
|
|
72
|
+
}
|
|
12
73
|
class DaemonAcpObserver {
|
|
13
74
|
#socket;
|
|
14
75
|
constructor(socket) {
|
|
@@ -51,6 +112,110 @@ class DaemonAcpObserver {
|
|
|
51
112
|
return Promise.resolve();
|
|
52
113
|
};
|
|
53
114
|
}
|
|
115
|
+
class AuditInstallationEvents {
|
|
116
|
+
#audit;
|
|
117
|
+
constructor(audit) {
|
|
118
|
+
this.#audit = audit;
|
|
119
|
+
}
|
|
120
|
+
record = (event, requestId, agentId, details = {}) => {
|
|
121
|
+
this.#audit.record({
|
|
122
|
+
commandId: requestId,
|
|
123
|
+
details,
|
|
124
|
+
event,
|
|
125
|
+
sessionId: `agent-installation:${agentId}`,
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
class DaemonInstallationObserver {
|
|
130
|
+
#started = new Set();
|
|
131
|
+
#socket = null;
|
|
132
|
+
connect = (socket) => {
|
|
133
|
+
this.#socket = socket;
|
|
134
|
+
};
|
|
135
|
+
disconnect = (socket) => {
|
|
136
|
+
if (this.#socket === socket) {
|
|
137
|
+
this.#socket = null;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
#send = (socket, message) => {
|
|
141
|
+
try {
|
|
142
|
+
send(socket, message);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
if (this.#socket === socket) {
|
|
146
|
+
this.#socket = null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
onState = (state) => {
|
|
151
|
+
const socket = this.#socket;
|
|
152
|
+
if (socket === null || socket.readyState !== WebSocket.OPEN) {
|
|
153
|
+
return Promise.resolve();
|
|
154
|
+
}
|
|
155
|
+
if (state instanceof RequestedInstallation) {
|
|
156
|
+
return Promise.resolve();
|
|
157
|
+
}
|
|
158
|
+
if (state instanceof AwaitingLocalApproval) {
|
|
159
|
+
this.#send(socket, encodeAgentInstallAwaitingApprovalEvent({
|
|
160
|
+
agentId: state.agentId,
|
|
161
|
+
kind: AGENT_INSTALL_AWAITING_APPROVAL_KIND,
|
|
162
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
163
|
+
requestId: state.requestId,
|
|
164
|
+
}));
|
|
165
|
+
return Promise.resolve();
|
|
166
|
+
}
|
|
167
|
+
if (state instanceof RunningInstallation) {
|
|
168
|
+
if (!this.#started.has(state.requestId)) {
|
|
169
|
+
this.#started.add(state.requestId);
|
|
170
|
+
this.#send(socket, encodeAgentInstallStartedEvent({
|
|
171
|
+
agentId: state.agentId,
|
|
172
|
+
kind: AGENT_INSTALL_STARTED_KIND,
|
|
173
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
174
|
+
requestId: state.requestId,
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
this.#send(socket, encodeAgentInstallProgressEvent({
|
|
178
|
+
agentId: state.agentId,
|
|
179
|
+
kind: AGENT_INSTALL_PROGRESS_KIND,
|
|
180
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
181
|
+
requestId: state.requestId,
|
|
182
|
+
stage: state.stage,
|
|
183
|
+
}));
|
|
184
|
+
return Promise.resolve();
|
|
185
|
+
}
|
|
186
|
+
if (state instanceof SucceededInstallation) {
|
|
187
|
+
this.#send(socket, encodeAgentInstallCompletedEvent({
|
|
188
|
+
agentId: state.agentId,
|
|
189
|
+
authenticationMayBeRequired: state.authenticationMayBeRequired,
|
|
190
|
+
kind: AGENT_INSTALL_COMPLETED_KIND,
|
|
191
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
192
|
+
requestId: state.requestId,
|
|
193
|
+
}));
|
|
194
|
+
return Promise.resolve();
|
|
195
|
+
}
|
|
196
|
+
if (state instanceof FailedInstallation) {
|
|
197
|
+
this.#send(socket, encodeAgentInstallFailedEvent({
|
|
198
|
+
agentId: state.agentId,
|
|
199
|
+
code: state.code,
|
|
200
|
+
kind: AGENT_INSTALL_FAILED_KIND,
|
|
201
|
+
message: state.message,
|
|
202
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
203
|
+
requestId: state.requestId,
|
|
204
|
+
}));
|
|
205
|
+
return Promise.resolve();
|
|
206
|
+
}
|
|
207
|
+
if (state instanceof CancelledInstallation) {
|
|
208
|
+
this.#send(socket, encodeAgentInstallCancelledEvent({
|
|
209
|
+
agentId: state.agentId,
|
|
210
|
+
kind: AGENT_INSTALL_CANCELLED_KIND,
|
|
211
|
+
protocolVersion: MOBIUS_PROTOCOL_VERSION,
|
|
212
|
+
requestId: state.requestId,
|
|
213
|
+
}));
|
|
214
|
+
return Promise.resolve();
|
|
215
|
+
}
|
|
216
|
+
throw new Error("Unsupported Agent installation state");
|
|
217
|
+
};
|
|
218
|
+
}
|
|
54
219
|
class ResolvedSessionDirectories {
|
|
55
220
|
additionalDirectories;
|
|
56
221
|
additionalDirectoryEntries;
|
|
@@ -106,14 +271,16 @@ function reportFailure(socket, command, code, message) {
|
|
|
106
271
|
}
|
|
107
272
|
function operationErrorCode(error) {
|
|
108
273
|
if (error instanceof AcpExecutionError ||
|
|
109
|
-
error instanceof LocalAuthorizationError
|
|
274
|
+
error instanceof LocalAuthorizationError ||
|
|
275
|
+
error instanceof LocalAgentCatalogError) {
|
|
110
276
|
return error.code;
|
|
111
277
|
}
|
|
112
278
|
return "session_operation_failed";
|
|
113
279
|
}
|
|
114
280
|
function operationErrorMessage(error) {
|
|
115
281
|
if (error instanceof AcpExecutionError ||
|
|
116
|
-
error instanceof LocalAuthorizationError
|
|
282
|
+
error instanceof LocalAuthorizationError ||
|
|
283
|
+
error instanceof LocalAgentCatalogError) {
|
|
117
284
|
return error.message;
|
|
118
285
|
}
|
|
119
286
|
return "The local agent operation could not be completed";
|
|
@@ -176,7 +343,7 @@ async function executeWorkspaceList(socket, command, directories, audit) {
|
|
|
176
343
|
async function executeSessionPrepare(socket, command, config, directories, audit, sessions, signal) {
|
|
177
344
|
try {
|
|
178
345
|
const resolved = await resolveSessionDirectories(directories, command.bindingId, command.directoryId, command.additionalDirectoryIds);
|
|
179
|
-
const agent =
|
|
346
|
+
const agent = config.catalog.find(command.agentId);
|
|
180
347
|
const prepared = await sessions.prepareSession({
|
|
181
348
|
additionalDirectories: resolved.additionalDirectories,
|
|
182
349
|
agent,
|
|
@@ -216,7 +383,7 @@ async function executeSessionConfigure(socket, command, config, directories, aud
|
|
|
216
383
|
const resolved = await resolveSessionDirectories(directories, command.bindingId, command.directoryId, command.additionalDirectoryIds);
|
|
217
384
|
const configOptions = await sessions.configureSession({
|
|
218
385
|
additionalDirectories: resolved.additionalDirectories,
|
|
219
|
-
agent:
|
|
386
|
+
agent: config.catalog.find(command.agentId),
|
|
220
387
|
booleanValue: command.booleanValue,
|
|
221
388
|
configId: command.configId,
|
|
222
389
|
cwd: resolved.cwd,
|
|
@@ -246,7 +413,7 @@ async function executeSessionConfigure(socket, command, config, directories, aud
|
|
|
246
413
|
async function executePrompt(socket, command, config, directories, audit, sessions, signal) {
|
|
247
414
|
try {
|
|
248
415
|
const resolved = await resolveSessionDirectories(directories, command.bindingId, command.directoryId, command.additionalDirectoryIds);
|
|
249
|
-
const agent =
|
|
416
|
+
const agent = config.catalog.find(command.agentId);
|
|
250
417
|
const processAttemptId = randomUUID();
|
|
251
418
|
audit.record({
|
|
252
419
|
commandId: command.commandId,
|
|
@@ -322,36 +489,45 @@ async function executePrompt(socket, command, config, directories, audit, sessio
|
|
|
322
489
|
event: "session_failed",
|
|
323
490
|
sessionId: command.sessionId,
|
|
324
491
|
});
|
|
325
|
-
|
|
492
|
+
const code = operationErrorCode(error);
|
|
493
|
+
reportFailure(socket, command, code === "session_operation_failed" ? "agent_execution_failed" : code, code === "session_operation_failed"
|
|
494
|
+
? "The local agent could not complete the request"
|
|
495
|
+
: operationErrorMessage(error));
|
|
326
496
|
console.error("Mobius daemon command failed", error);
|
|
327
497
|
}
|
|
328
498
|
}
|
|
329
|
-
function waitForRelayRetry(signal) {
|
|
499
|
+
function waitForRelayRetry(signal, timer) {
|
|
330
500
|
if (signal.aborted) {
|
|
331
501
|
return Promise.resolve();
|
|
332
502
|
}
|
|
333
503
|
return new Promise((resolve) => {
|
|
334
|
-
const
|
|
504
|
+
const retry = timer.schedule(finish, RELAY_RECONNECT_DELAY_MILLISECONDS);
|
|
335
505
|
function finish() {
|
|
336
|
-
|
|
506
|
+
retry.cancel();
|
|
337
507
|
signal.removeEventListener("abort", finish);
|
|
338
508
|
resolve();
|
|
339
509
|
}
|
|
340
510
|
signal.addEventListener("abort", finish, { once: true });
|
|
341
511
|
});
|
|
342
512
|
}
|
|
343
|
-
async function runRelayConnection(config, directories, audit, sessions, signal) {
|
|
344
|
-
const
|
|
513
|
+
async function runRelayConnection(config, directories, audit, sessions, installations, installationObserver, signal, timer) {
|
|
514
|
+
const relayUrl = new URL(config.relayUrl);
|
|
515
|
+
relayUrl.searchParams.set("liveness", "1");
|
|
516
|
+
const socket = await connectRelay(relayUrl, signal);
|
|
345
517
|
const activeTurns = new Map();
|
|
346
518
|
const connectionController = new AbortController();
|
|
347
519
|
sessions.setObserver(new DaemonAcpObserver(socket));
|
|
520
|
+
installationObserver.connect(socket);
|
|
348
521
|
await new Promise((resolve, reject) => {
|
|
349
522
|
let finished = false;
|
|
350
523
|
const cleanup = () => {
|
|
524
|
+
connectionRefresh.close();
|
|
525
|
+
connectionLiveness.close();
|
|
351
526
|
signal.removeEventListener("abort", stop);
|
|
352
527
|
socket.removeEventListener("close", handleClose);
|
|
353
528
|
socket.removeEventListener("error", handleError);
|
|
354
529
|
socket.removeEventListener("message", handleMessage);
|
|
530
|
+
installationObserver.disconnect(socket);
|
|
355
531
|
connectionController.abort();
|
|
356
532
|
for (const turn of activeTurns.values()) {
|
|
357
533
|
turn.abortConnection();
|
|
@@ -378,6 +554,18 @@ async function runRelayConnection(config, directories, audit, sessions, signal)
|
|
|
378
554
|
socket.close(1000, "Daemon stopped");
|
|
379
555
|
resolveConnection();
|
|
380
556
|
};
|
|
557
|
+
const refreshConnection = () => {
|
|
558
|
+
socket.close(1000, "Refreshing idle relay connection");
|
|
559
|
+
resolveConnection();
|
|
560
|
+
};
|
|
561
|
+
const connectionLiveness = new RelayConnectionLiveness(timer, {
|
|
562
|
+
send: (message) => send(socket, message),
|
|
563
|
+
unresponsive: () => {
|
|
564
|
+
socket.close(4001, "Relay liveness check timed out");
|
|
565
|
+
resolveConnection();
|
|
566
|
+
},
|
|
567
|
+
});
|
|
568
|
+
const connectionRefresh = new RelayConnectionRefresh(timer, () => activeTurns.size === 0, refreshConnection);
|
|
381
569
|
signal.addEventListener("abort", stop, { once: true });
|
|
382
570
|
const handleClose = () => {
|
|
383
571
|
resolveConnection();
|
|
@@ -392,11 +580,21 @@ async function runRelayConnection(config, directories, audit, sessions, signal)
|
|
|
392
580
|
const handleMessage = (event) => {
|
|
393
581
|
const encoded = event.data;
|
|
394
582
|
if (typeof encoded !== "string") {
|
|
395
|
-
socket.close(
|
|
583
|
+
socket.close(4003, "Text message required");
|
|
584
|
+
rejectConnection();
|
|
396
585
|
return;
|
|
397
586
|
}
|
|
398
587
|
try {
|
|
399
588
|
const kind = decodeMessageKind(encoded);
|
|
589
|
+
if (kind === RUNTIME_LIVENESS_READY_KIND) {
|
|
590
|
+
decodeRuntimeLivenessReadyEvent(encoded);
|
|
591
|
+
connectionLiveness.start();
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (kind === RUNTIME_HEARTBEAT_ACK_KIND) {
|
|
595
|
+
connectionLiveness.acknowledge(decodeRuntimeHeartbeatAckEvent(encoded));
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
400
598
|
if (kind === SESSION_CANCEL_KIND) {
|
|
401
599
|
const cancellation = decodeSessionCancelCommand(encoded);
|
|
402
600
|
const turn = activeTurns.get(cancellation.commandId);
|
|
@@ -464,10 +662,27 @@ async function runRelayConnection(config, directories, audit, sessions, signal)
|
|
|
464
662
|
});
|
|
465
663
|
return;
|
|
466
664
|
}
|
|
467
|
-
if (kind
|
|
468
|
-
|
|
665
|
+
if (kind === AGENT_INSTALL_REQUEST_KIND) {
|
|
666
|
+
const command = decodeAgentInstallRequestCommand(encoded);
|
|
667
|
+
void installations
|
|
668
|
+
.request(command, signal)
|
|
669
|
+
.catch((error) => {
|
|
670
|
+
console.error("Mobius Agent installation failed", error);
|
|
671
|
+
});
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
if (kind === AGENT_INSTALL_CANCEL_KIND) {
|
|
675
|
+
const command = decodeAgentInstallCancelCommand(encoded);
|
|
676
|
+
void installations
|
|
677
|
+
.cancel(command.requestId)
|
|
678
|
+
.catch((error) => {
|
|
679
|
+
reportOperationFailure(socket, command.requestId, "", error);
|
|
680
|
+
});
|
|
469
681
|
return;
|
|
470
682
|
}
|
|
683
|
+
if (kind !== SESSION_PROMPT_KIND) {
|
|
684
|
+
throw new Error("Unsupported protocol message");
|
|
685
|
+
}
|
|
471
686
|
const command = decodeSessionPromptCommand(encoded);
|
|
472
687
|
if (activeTurns.has(command.commandId)) {
|
|
473
688
|
reportFailure(socket, command, "duplicate_command", "The command is already running");
|
|
@@ -481,11 +696,13 @@ async function runRelayConnection(config, directories, audit, sessions, signal)
|
|
|
481
696
|
})
|
|
482
697
|
.finally(() => {
|
|
483
698
|
activeTurns.delete(command.commandId);
|
|
699
|
+
connectionRefresh.afterTurnFinished();
|
|
484
700
|
});
|
|
485
701
|
}
|
|
486
702
|
catch (error) {
|
|
487
703
|
console.error("Mobius daemon rejected a message", error);
|
|
488
|
-
socket.close(
|
|
704
|
+
socket.close(4008, "Invalid protocol message");
|
|
705
|
+
rejectConnection();
|
|
489
706
|
}
|
|
490
707
|
};
|
|
491
708
|
socket.addEventListener("close", handleClose);
|
|
@@ -496,15 +713,39 @@ async function runRelayConnection(config, directories, audit, sessions, signal)
|
|
|
496
713
|
}
|
|
497
714
|
});
|
|
498
715
|
}
|
|
499
|
-
export async function runDaemon(config, audit, signal) {
|
|
716
|
+
export async function runDaemon(config, audit, signal, timer = systemDaemonTimer) {
|
|
717
|
+
const installationAudit = new AuditInstallationEvents(audit);
|
|
718
|
+
const stateDirectory = readStateDirectory();
|
|
719
|
+
const specifications = supportedLocalAgentSpecifications();
|
|
720
|
+
const installationExecutor = new FixedInstallationExecutor({
|
|
721
|
+
approvedRoot: config.approvedRoot,
|
|
722
|
+
audit: installationAudit,
|
|
723
|
+
catalog: config.catalog,
|
|
724
|
+
environment: process.env,
|
|
725
|
+
publishCatalog: async (installationSignal) => await publishAgentCatalog(config, installationSignal),
|
|
726
|
+
stateDirectory,
|
|
727
|
+
});
|
|
728
|
+
await new AutomaticAdapterProvisioner({
|
|
729
|
+
approvedRoot: config.approvedRoot,
|
|
730
|
+
audit: installationAudit,
|
|
731
|
+
catalog: config.catalog,
|
|
732
|
+
environment: process.env,
|
|
733
|
+
}, new ManagedAdapterInstaller({
|
|
734
|
+
approvedRoot: config.approvedRoot,
|
|
735
|
+
environment: process.env,
|
|
736
|
+
stateDirectory,
|
|
737
|
+
}), specifications).prepare(signal);
|
|
500
738
|
const sessionStore = new SqliteAcpSessionStore(config.auditDatabasePath);
|
|
501
739
|
const sessions = new AcpSessionManager(new NullAcpSessionObserver(), sessionStore);
|
|
502
740
|
const directories = new WorkspaceDirectoryService(config.bindingId, config.approvedRoot);
|
|
741
|
+
const installationObserver = new DaemonInstallationObserver();
|
|
742
|
+
const installations = new AgentInstallationManager(specifications, new ConsoleInstallationAuthorizer(stateDirectory), installationExecutor, installationObserver, installationAudit);
|
|
503
743
|
let retryAnnounced = false;
|
|
504
744
|
try {
|
|
505
745
|
while (!signal.aborted) {
|
|
506
746
|
try {
|
|
507
|
-
await
|
|
747
|
+
await publishAgentCatalog(config, signal);
|
|
748
|
+
await runRelayConnection(config, directories, audit, sessions, installations, installationObserver, signal, timer);
|
|
508
749
|
retryAnnounced = false;
|
|
509
750
|
}
|
|
510
751
|
catch {
|
|
@@ -516,12 +757,21 @@ export async function runDaemon(config, audit, signal) {
|
|
|
516
757
|
retryAnnounced = true;
|
|
517
758
|
}
|
|
518
759
|
}
|
|
519
|
-
await waitForRelayRetry(signal);
|
|
760
|
+
await waitForRelayRetry(signal, timer);
|
|
520
761
|
}
|
|
521
762
|
}
|
|
522
763
|
finally {
|
|
523
|
-
|
|
524
|
-
|
|
764
|
+
try {
|
|
765
|
+
await installations.close();
|
|
766
|
+
}
|
|
767
|
+
finally {
|
|
768
|
+
try {
|
|
769
|
+
await sessions.close();
|
|
770
|
+
}
|
|
771
|
+
finally {
|
|
772
|
+
sessionStore.close();
|
|
773
|
+
}
|
|
774
|
+
}
|
|
525
775
|
}
|
|
526
776
|
}
|
|
527
777
|
//# sourceMappingURL=run-daemon.js.map
|