@beeos-ai/device-agent 0.9.3 → 0.9.7

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.
Files changed (102) hide show
  1. package/dist/adapters/transport-bridge-ws.d.ts +12 -0
  2. package/dist/adapters/transport-bridge-ws.js +27 -3
  3. package/dist/adapters/transport-bridge-ws.js.map +1 -1
  4. package/dist/agent-runtime/core.d.ts +1 -1
  5. package/dist/agent-runtime/core.js +41 -0
  6. package/dist/agent-runtime/core.js.map +1 -1
  7. package/dist/app/session-manager.d.ts +14 -11
  8. package/dist/app/session-manager.js +8 -9
  9. package/dist/app/session-manager.js.map +1 -1
  10. package/dist/bootstrap.js +140 -11
  11. package/dist/bootstrap.js.map +1 -1
  12. package/dist/chat.js +11 -1
  13. package/dist/chat.js.map +1 -1
  14. package/dist/config/loader.js +3 -0
  15. package/dist/config/loader.js.map +1 -1
  16. package/dist/config/schema.d.ts +3 -0
  17. package/dist/config/schema.js +65 -21
  18. package/dist/config/schema.js.map +1 -1
  19. package/dist/fleet/adapters/process/node-process-manager.d.ts +115 -13
  20. package/dist/fleet/adapters/process/node-process-manager.js +412 -64
  21. package/dist/fleet/adapters/process/node-process-manager.js.map +1 -1
  22. package/dist/fleet/adapters/state/port-allocator.d.ts +12 -0
  23. package/dist/fleet/adapters/state/port-allocator.js +39 -5
  24. package/dist/fleet/adapters/state/port-allocator.js.map +1 -1
  25. package/dist/fleet/domain/events.d.ts +23 -1
  26. package/dist/fleet/domain/fsm.d.ts +13 -1
  27. package/dist/fleet/domain/fsm.js +70 -0
  28. package/dist/fleet/domain/fsm.js.map +1 -1
  29. package/dist/fleet/supervisor.js +30 -0
  30. package/dist/fleet/supervisor.js.map +1 -1
  31. package/dist/health/adb-track-devices.d.ts +103 -0
  32. package/dist/health/adb-track-devices.js +171 -0
  33. package/dist/health/adb-track-devices.js.map +1 -0
  34. package/dist/health/health-reporter.d.ts +67 -0
  35. package/dist/health/health-reporter.js +123 -0
  36. package/dist/health/health-reporter.js.map +1 -0
  37. package/dist/health/index.d.ts +6 -0
  38. package/dist/health/index.js +4 -0
  39. package/dist/health/index.js.map +1 -0
  40. package/dist/health/mcp-health-monitor.d.ts +190 -0
  41. package/dist/health/mcp-health-monitor.js +267 -0
  42. package/dist/health/mcp-health-monitor.js.map +1 -0
  43. package/dist/inbound/cli/main.js +10 -3
  44. package/dist/inbound/cli/main.js.map +1 -1
  45. package/dist/inbound/cli/run-command.js +24 -2
  46. package/dist/inbound/cli/run-command.js.map +1 -1
  47. package/dist/index.d.ts +1 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/mcp-client/action-mapping.d.ts +45 -0
  50. package/dist/mcp-client/action-mapping.js +224 -0
  51. package/dist/mcp-client/action-mapping.js.map +1 -0
  52. package/dist/mcp-client/autospawn.d.ts +15 -2
  53. package/dist/mcp-client/autospawn.js +82 -4
  54. package/dist/mcp-client/autospawn.js.map +1 -1
  55. package/dist/mcp-client/client.d.ts +134 -38
  56. package/dist/mcp-client/client.js +394 -87
  57. package/dist/mcp-client/client.js.map +1 -1
  58. package/dist/mcp-client/index.d.ts +5 -3
  59. package/dist/mcp-client/index.js +2 -1
  60. package/dist/mcp-client/index.js.map +1 -1
  61. package/dist/mcp-client/inproc.d.ts +2 -2
  62. package/dist/mcp-client/inproc.js.map +1 -1
  63. package/dist/mcp-client/runtime.d.ts +124 -21
  64. package/dist/mcp-client/runtime.js +18 -7
  65. package/dist/mcp-client/runtime.js.map +1 -1
  66. package/dist/messaging/token-provider.d.ts +15 -14
  67. package/dist/messaging/token-provider.js +16 -16
  68. package/dist/messaging/token-provider.js.map +1 -1
  69. package/dist/model/adapters/autoglm.js +44 -45
  70. package/dist/model/adapters/autoglm.js.map +1 -1
  71. package/dist/model/adapters/guiowl.js +3 -2
  72. package/dist/model/adapters/guiowl.js.map +1 -1
  73. package/dist/model/adapters/maiui.js +80 -53
  74. package/dist/model/adapters/maiui.js.map +1 -1
  75. package/dist/model/adapters/qwenvl.js +147 -51
  76. package/dist/model/adapters/qwenvl.js.map +1 -1
  77. package/dist/model/adapters/tool-call.js +13 -3
  78. package/dist/model/adapters/tool-call.js.map +1 -1
  79. package/dist/model/adapters/uitars.js +80 -84
  80. package/dist/model/adapters/uitars.js.map +1 -1
  81. package/dist/plugins/acp/index.d.ts +35 -0
  82. package/dist/plugins/acp/index.js +121 -0
  83. package/dist/plugins/acp/index.js.map +1 -1
  84. package/dist/plugins/message-bus/busy-reply.d.ts +5 -5
  85. package/dist/plugins/message-bus/busy-reply.js +30 -9
  86. package/dist/plugins/message-bus/busy-reply.js.map +1 -1
  87. package/dist/plugins/message-bus/cancel.d.ts +5 -11
  88. package/dist/plugins/message-bus/cancel.js +8 -14
  89. package/dist/plugins/message-bus/cancel.js.map +1 -1
  90. package/dist/plugins/message-bus/inbound.d.ts +18 -25
  91. package/dist/plugins/message-bus/inbound.js +23 -55
  92. package/dist/plugins/message-bus/inbound.js.map +1 -1
  93. package/dist/plugins/message-bus/index.d.ts +25 -44
  94. package/dist/plugins/message-bus/index.js +70 -111
  95. package/dist/plugins/message-bus/index.js.map +1 -1
  96. package/dist/plugins/message-bus/ms-channel-notifier.d.ts +24 -37
  97. package/dist/plugins/message-bus/ms-channel-notifier.js +39 -59
  98. package/dist/plugins/message-bus/ms-channel-notifier.js.map +1 -1
  99. package/dist/ports/transport.d.ts +11 -0
  100. package/dist/resources/parsers.js +17 -0
  101. package/dist/resources/parsers.js.map +1 -1
  102. package/package.json +4 -3
@@ -1,23 +1,54 @@
1
1
  /**
2
2
  * Adapter — `IProcessManager` implementation backed by `child_process.spawn`.
3
3
  *
4
- * Spawns and supervises up to three long-running siblings per bound device:
4
+ * 0.4.0 SINGLETON MCP TOPOLOGY:
5
5
  *
6
- * - **mcp** `device-mcp-server --backend <kind> --adb-serial <serial>
7
- * --host 127.0.0.1 --port <mcpPort>`
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:<mcpPort> --adb <serial>
10
- * [--http --http-port <httpPort>]`
11
- * - **scrcpy** `scrcpy-bridge` (no args; configured via env mirroring
12
- * `web/packages/core/src/runtime/scrcpy-bridge.ts` `buildEnv`).
13
- * Optional — only spawned when the binding's `videoMode === "scrcpy"`.
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 `GET /healthz` to return 200 (configurable timeout)
18
- * before emitting `mcp_started`. If readiness times out the spawn is
19
- * killed and an `mcp_exited` event is reported (so the FSM treats the
20
- * attempt as a crash and either retries or backs off).
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
- /** Initial readiness probe timeout for mcp `/healthz`. */
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?: {