@beeos-ai/device-agent 0.9.3 → 0.9.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/adapters/transport-bridge-ws.d.ts +12 -0
- package/dist/adapters/transport-bridge-ws.js +27 -3
- package/dist/adapters/transport-bridge-ws.js.map +1 -1
- package/dist/agent-runtime/core.d.ts +1 -1
- package/dist/agent-runtime/core.js +41 -0
- package/dist/agent-runtime/core.js.map +1 -1
- package/dist/app/session-manager.d.ts +14 -11
- package/dist/app/session-manager.js +8 -9
- package/dist/app/session-manager.js.map +1 -1
- package/dist/bootstrap.js +140 -11
- package/dist/bootstrap.js.map +1 -1
- package/dist/chat.js +11 -1
- package/dist/chat.js.map +1 -1
- package/dist/config/loader.js +3 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/schema.d.ts +3 -0
- package/dist/config/schema.js +51 -15
- package/dist/config/schema.js.map +1 -1
- package/dist/fleet/adapters/process/node-process-manager.d.ts +115 -13
- package/dist/fleet/adapters/process/node-process-manager.js +412 -64
- package/dist/fleet/adapters/process/node-process-manager.js.map +1 -1
- package/dist/fleet/adapters/state/port-allocator.d.ts +12 -0
- package/dist/fleet/adapters/state/port-allocator.js +39 -5
- package/dist/fleet/adapters/state/port-allocator.js.map +1 -1
- package/dist/fleet/domain/events.d.ts +23 -1
- package/dist/fleet/domain/fsm.d.ts +13 -1
- package/dist/fleet/domain/fsm.js +70 -0
- package/dist/fleet/domain/fsm.js.map +1 -1
- package/dist/fleet/supervisor.js +30 -0
- package/dist/fleet/supervisor.js.map +1 -1
- package/dist/health/adb-track-devices.d.ts +103 -0
- package/dist/health/adb-track-devices.js +171 -0
- package/dist/health/adb-track-devices.js.map +1 -0
- package/dist/health/health-reporter.d.ts +67 -0
- package/dist/health/health-reporter.js +123 -0
- package/dist/health/health-reporter.js.map +1 -0
- package/dist/health/index.d.ts +6 -0
- package/dist/health/index.js +4 -0
- package/dist/health/index.js.map +1 -0
- package/dist/health/mcp-health-monitor.d.ts +190 -0
- package/dist/health/mcp-health-monitor.js +267 -0
- package/dist/health/mcp-health-monitor.js.map +1 -0
- package/dist/inbound/cli/main.js +8 -1
- package/dist/inbound/cli/main.js.map +1 -1
- package/dist/inbound/cli/run-command.js +11 -1
- package/dist/inbound/cli/run-command.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp-client/action-mapping.d.ts +45 -0
- package/dist/mcp-client/action-mapping.js +224 -0
- package/dist/mcp-client/action-mapping.js.map +1 -0
- package/dist/mcp-client/autospawn.d.ts +15 -2
- package/dist/mcp-client/autospawn.js +82 -4
- package/dist/mcp-client/autospawn.js.map +1 -1
- package/dist/mcp-client/client.d.ts +134 -38
- package/dist/mcp-client/client.js +394 -87
- package/dist/mcp-client/client.js.map +1 -1
- package/dist/mcp-client/index.d.ts +5 -3
- package/dist/mcp-client/index.js +2 -1
- package/dist/mcp-client/index.js.map +1 -1
- package/dist/mcp-client/inproc.d.ts +2 -2
- package/dist/mcp-client/inproc.js.map +1 -1
- package/dist/mcp-client/runtime.d.ts +124 -21
- package/dist/mcp-client/runtime.js +18 -7
- package/dist/mcp-client/runtime.js.map +1 -1
- package/dist/model/adapters/autoglm.js +44 -45
- package/dist/model/adapters/autoglm.js.map +1 -1
- package/dist/plugins/acp/index.d.ts +35 -0
- package/dist/plugins/acp/index.js +121 -0
- package/dist/plugins/acp/index.js.map +1 -1
- package/dist/ports/transport.d.ts +11 -0
- package/package.json +3 -2
|
@@ -1,23 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Adapter — `IProcessManager` implementation backed by `child_process.spawn`.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 0.4.0 SINGLETON MCP TOPOLOGY:
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Pre-0.4 the manager spawned **one mcp + one daemon per device** (1:1) so
|
|
7
|
+
* the daemon could pin its `--mcp-url` to a per-device port. With the new
|
|
8
|
+
* SDK-backed device-mcp-server (which is itself a singleton multi-device
|
|
9
|
+
* BackendRegistry process), the manager keeps the per-device `IProcessManager`
|
|
10
|
+
* API the FSM/supervisor expect but internally collapses every `spawnMcp`
|
|
11
|
+
* call onto a **single shared MCP child**:
|
|
12
|
+
*
|
|
13
|
+
* - The first `spawnMcp` call actually starts `device-mcp-server` on the
|
|
14
|
+
* supplied port, runs the `initialize` JSON-RPC readiness handshake,
|
|
15
|
+
* and remembers that port as the global MCP port.
|
|
16
|
+
* - Subsequent `spawnMcp` calls (for additional devices) skip the spawn,
|
|
17
|
+
* immediately emit a synthetic per-device `mcp_started` for the
|
|
18
|
+
* existing global port, and add the serial to a refcount set.
|
|
19
|
+
* - `killMcp(serial)` removes the serial from the refcount; the actual
|
|
20
|
+
* `device-mcp-server` child is only killed when the last device drops
|
|
21
|
+
* out (or `stop()` is called).
|
|
22
|
+
* - When the global MCP exits unexpectedly, every refcounted serial
|
|
23
|
+
* receives a synthetic `mcp_exited` so each per-device FSM transitions
|
|
24
|
+
* coherently and triggers a respawn (whose first call rebuilds the
|
|
25
|
+
* singleton).
|
|
26
|
+
*
|
|
27
|
+
* The daemon's `--mcp-url` always points at the global port (recorded in
|
|
28
|
+
* `globalMcpPort`), so per-device daemons all share the same backend
|
|
29
|
+
* registry. Tool calls route by the `device` argument the daemon's
|
|
30
|
+
* `McpClient` injects from its `defaultDevice = serial`. The MCP server's
|
|
31
|
+
* own `--adb-serial` per-device pin flag is gone; the registry discovers
|
|
32
|
+
* every connected device on its own.
|
|
33
|
+
*
|
|
34
|
+
* Spawn surface:
|
|
35
|
+
*
|
|
36
|
+
* - **mcp** `device-mcp-server --backend <kind>
|
|
37
|
+
* --host 127.0.0.1 --port <globalMcpPort>` (singleton)
|
|
8
38
|
* - **daemon** `device-agent --key <keyFile> --agent-gateway-url <url>
|
|
9
|
-
* --mcp-url http://127.0.0.1:<
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
39
|
+
* --mcp-url http://127.0.0.1:<globalMcpPort>
|
|
40
|
+
* --device <serial> [--adb <serial> for ADB backends]
|
|
41
|
+
* [--http --http-port <httpPort>]` (per device)
|
|
42
|
+
* - **scrcpy** `scrcpy-bridge` (no args; per device, optional —
|
|
43
|
+
* only spawned when the binding's `videoMode === "scrcpy"`).
|
|
14
44
|
*
|
|
15
45
|
* Lifecycle responsibilities:
|
|
16
46
|
*
|
|
17
|
-
* - `spawnMcp` waits for
|
|
18
|
-
* before emitting `mcp_started`. If readiness times out
|
|
19
|
-
* killed and
|
|
20
|
-
* attempt as a crash
|
|
47
|
+
* - `spawnMcp` (first call) waits for the MCP `initialize` handshake to
|
|
48
|
+
* return 200/202 before emitting `mcp_started`. If readiness times out
|
|
49
|
+
* the global child is killed and a synthetic `mcp_exited` is reported
|
|
50
|
+
* so the FSM treats the attempt as a crash. Subsequent (refcount-bump)
|
|
51
|
+
* calls emit `mcp_started` synchronously without re-probing.
|
|
21
52
|
* - `spawnDaemon` emits `daemon_started` as soon as the child has a PID
|
|
22
53
|
* (the daemon's own readiness is observable through ACP traffic which is
|
|
23
54
|
* out of fleet scope; the daemon process itself dying is what we react to
|
|
@@ -83,7 +114,11 @@ export interface NodeProcessManagerOptions {
|
|
|
83
114
|
bridgeUrl?: string;
|
|
84
115
|
/** Optional region passed to daemon. */
|
|
85
116
|
region?: string;
|
|
86
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* Initial readiness probe timeout for the singleton mcp server. 0.4
|
|
119
|
+
* replaced the bespoke `GET /healthz` with a real MCP `initialize`
|
|
120
|
+
* JSON-RPC handshake on `POST /mcp` — see `defaultHttpProbeFn`.
|
|
121
|
+
*/
|
|
87
122
|
mcpHealthTimeoutMs?: number;
|
|
88
123
|
/**
|
|
89
124
|
* Window we wait for scrcpy-bridge to keep running before declaring it
|
|
@@ -130,6 +165,41 @@ export declare class NodeProcessManager implements IProcessManager {
|
|
|
130
165
|
private readonly slots;
|
|
131
166
|
private readonly listeners;
|
|
132
167
|
private started;
|
|
168
|
+
/**
|
|
169
|
+
* The lone `device-mcp-server` child shared across all devices, or
|
|
170
|
+
* `undefined` when no device currently needs the MCP. First `spawnMcp`
|
|
171
|
+
* call spawns it; the last `killMcp` (or `stop()`) tears it down.
|
|
172
|
+
*/
|
|
173
|
+
private globalMcpSlot?;
|
|
174
|
+
/** Port the singleton is bound to. 0 when not running. */
|
|
175
|
+
private globalMcpPort;
|
|
176
|
+
/**
|
|
177
|
+
* Port the most recent successfully-probed singleton was bound to.
|
|
178
|
+
* Survives `globalMcpPort` being reset to 0 on exit; consulted by
|
|
179
|
+
* the next `startGlobalMcp` to detect port drift across respawn.
|
|
180
|
+
* 0 means "no prior cycle has succeeded" (suppresses the false-
|
|
181
|
+
* positive `mcp_port_changed` on the very first spawn).
|
|
182
|
+
*/
|
|
183
|
+
private previousGlobalMcpPort;
|
|
184
|
+
/** Serials currently refcounting the global MCP. */
|
|
185
|
+
private readonly mcpRefs;
|
|
186
|
+
/**
|
|
187
|
+
* Single-flight readiness: when two devices land on `spawnMcp` at the
|
|
188
|
+
* same time we want only one of them to actually probe `initialize`;
|
|
189
|
+
* the other just awaits this promise.
|
|
190
|
+
*/
|
|
191
|
+
private mcpReadyPromise?;
|
|
192
|
+
/**
|
|
193
|
+
* Single-flight first-spawn: protects the
|
|
194
|
+
* (`globalMcpSlot === undefined` → `spawnFn` → `globalMcpSlot = …`)
|
|
195
|
+
* critical section. Without this, two concurrent first-time
|
|
196
|
+
* `spawnMcp(A)` / `spawnMcp(B)` calls could each call `spawnFn`
|
|
197
|
+
* (the `globalMcpSlot` write is post-spawn, so the second caller
|
|
198
|
+
* sees `undefined` and overwrites with its own child, leaking
|
|
199
|
+
* the first one). When non-undefined, every other caller waits
|
|
200
|
+
* here instead of starting a second mcp.
|
|
201
|
+
*/
|
|
202
|
+
private globalMcpStartPromise?;
|
|
133
203
|
constructor(opts?: NodeProcessManagerOptions);
|
|
134
204
|
start(): Promise<void>;
|
|
135
205
|
stop(): Promise<void>;
|
|
@@ -139,6 +209,38 @@ export declare class NodeProcessManager implements IProcessManager {
|
|
|
139
209
|
private slotFor;
|
|
140
210
|
private setSlot;
|
|
141
211
|
spawnMcp(opts: SpawnOptions): Promise<void>;
|
|
212
|
+
/**
|
|
213
|
+
* Spawn the singleton `device-mcp-server`. Driven by the FIRST device
|
|
214
|
+
* to enter the spawn pipeline — its `opts.mcpPort` becomes the global
|
|
215
|
+
* port, and its `opts.backend` (or the constructor default) selects
|
|
216
|
+
* the backend kind. On readiness failure, emits a synthetic per-device
|
|
217
|
+
* `mcp_exited` for `opts.serial` so the caller's FSM transitions
|
|
218
|
+
* cleanly; on success leaves `globalMcpSlot` populated for refcount
|
|
219
|
+
* attachment.
|
|
220
|
+
*/
|
|
221
|
+
private startGlobalMcp;
|
|
222
|
+
/**
|
|
223
|
+
* Wire `serial` into the running global MCP: store a ref-pointing
|
|
224
|
+
* `ChildSlot` on the device's slots, register the ref, and emit a
|
|
225
|
+
* per-device `mcp_started` event using the global port. Idempotent —
|
|
226
|
+
* a serial already in `mcpRefs` becomes a no-op.
|
|
227
|
+
*/
|
|
228
|
+
private attachToGlobalMcp;
|
|
229
|
+
/**
|
|
230
|
+
* Attach a single global exit listener to the singleton MCP child. When
|
|
231
|
+
* it dies, fan-out a synthetic `mcp_exited` to every refcounted serial
|
|
232
|
+
* (clearing their slots) so each per-device FSM transitions cleanly.
|
|
233
|
+
* The `expected` flag is taken from `globalMcpSlot.expectingKill`, which
|
|
234
|
+
* is set by `killGlobalMcp(expected=true)` during graceful shutdown.
|
|
235
|
+
*/
|
|
236
|
+
private attachGlobalExitListener;
|
|
237
|
+
/**
|
|
238
|
+
* Tear down the singleton MCP child unconditionally. `expected=true`
|
|
239
|
+
* marks the upcoming exit so FSMs don't penalise restartCount; the
|
|
240
|
+
* actual `*_exited` events are emitted by the global exit listener.
|
|
241
|
+
* A no-op when the singleton is already gone.
|
|
242
|
+
*/
|
|
243
|
+
private killGlobalMcp;
|
|
142
244
|
spawnDaemon(opts: SpawnOptions): Promise<void>;
|
|
143
245
|
spawnScrcpy(opts: SpawnScrcpyOptions): Promise<void>;
|
|
144
246
|
killMcp(serial: string, opts?: {
|