Skip to content

feat(askui-nodejs)!: replace WebSocket UI Controller with gRPC AgentOS client#879

Merged
programminx-askui merged 5 commits into
mainfrom
feat/agentos-grpc-migration
Jul 10, 2026
Merged

feat(askui-nodejs)!: replace WebSocket UI Controller with gRPC AgentOS client#879
programminx-askui merged 5 commits into
mainfrom
feat/agentos-grpc-migration

Conversation

@programminx-askui

Copy link
Copy Markdown
Contributor

Summary

Replaces the legacy WebSocket "UI Controller" connection (port 6769) in `askui-nodejs` with a gRPC client for the new AskUI AgentOS (AskUI Remote Device Controller), mirroring how the AskUI Python SDK (`vision-agent`) connects.

The SDK now speaks gRPC to `localhost:23000` (standalone AgentOS) or `localhost:26000` (when the Windows `AskuiCoreService` manages it), using the vendored `Controller_V1.proto` (`Askui.API.TDKv1.ControllerAPI`).

What changed

  • New `AgentOsClient` (`src/execution/agent-os/`) using `@grpc/grpc-js` + `@grpc/proto-loader`.
    • Handshake: `StartSession` → `StartExecution` → `SetActiveDisplay`.
    • Actions run via `RunRecordedAction` + `Poll(ActionFinished)`; `ControlCommand` `InputEvent`s are mapped to the corresponding action classes.
    • Screenshots convert the `CaptureScreen` BGRA bitmap to a base64 PNG via `sharp`.
    • Detects the Windows `AskuiCoreService` and prefers the service-managed port.
  • Integration seam unchanged: `ExecutionRuntime` and the public `UiControlClient` API keep working; only the underlying transport changed. `disconnect()`/`close()` stay synchronous (session teardown is fire-and-forget).
  • Removed the legacy WebSocket client, the `runner-protocol` tree, and the `UiController` binary download/spawn stack. Dropped `ws`, `fkill`, and `wait-port`; added `@grpc/grpc-js` and `@grpc/proto-loader`.
  • Added `test.ts` (`npm run test:agentos`) — a manual end-to-end check that runs connect, screenshot, and the full range of mouse/keyboard/command actions against a running AgentOS.

Breaking changes

  • `startVideoRecording`, `stopVideoRecording`, `readVideoRecording`, and `annotateInteractively` are removed (no AgentOS equivalent).
  • The `UiController` export is removed (the controller is now the AgentOS service).
  • Android input events throw `AgentOsActionNotSupportedError` until Android support is reintroduced via the legacy controller in a follow-up.
  • Default `uiControllerUrl` changed from `http://127.0.0.1:6769\` to `localhost:23000`.

Testing

  • Unit tests: `npm test` — all suites pass.
  • Build + lint: clean (`npm run build`, ESLint 0 warnings).
  • E2E (`npm run test:agentos`): verified manually against a running AgentOS.

Follow-ups

  • Reintroduce Android automation via the legacy controller.
  • Consider npm-packaged AgentOS binaries (mirroring the Python `askui-agent-os` package) so the controller can be auto-discovered/spawned.

🤖 Generated with Claude Code

programminx-askui and others added 5 commits July 6, 2026 23:43
…S client

Connect to the AskUI AgentOS (AskUI Remote Device Controller) via gRPC on
localhost:23000 (standalone) or localhost:26000 (AskuiCoreService-managed),
mirroring the connection approach of the AskUI Python SDK (vision-agent).

- add AgentOsClient with vendored Controller_V1.proto (@grpc/grpc-js,
  @grpc/proto-loader); handshake: StartSession -> StartExecution ->
  SetActiveDisplay; actions via RunRecordedAction + Poll(ActionFinished)
- detect the Windows AskuiCoreService and prefer the service-managed port
- convert CaptureScreen BGRA bitmaps to base64 PNG via sharp
- remove the legacy WebSocket client, runner protocol, and UiController
  binary download/spawn stack; drop ws, fkill, and wait-port dependencies
- add test.ts (npm run test:agentos) as a manual end-to-end check against
  a running AgentOS

BREAKING CHANGE: startVideoRecording, stopVideoRecording,
readVideoRecording, annotateInteractively, and the UiController export
have been removed. Android input events throw
AgentOsActionNotSupportedError until Android support is reintroduced.
Default uiControllerUrl changed from http://127.0.0.1:6769 to
localhost:23000.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add an AndroidAdbClient that drives an Android device by shelling out to adb
directly (input tap/swipe/keyevent, screencap, wm size), replacing the legacy
UI Controller's WebSocket/adbkit path. No separate controller process or
bundled binary is required.

- introduce a transport-agnostic DeviceClient interface that both
  AgentOsClient (desktop, gRPC) and AndroidAdbClient (Android, adb) implement;
  ExecutionRuntime now depends on the interface
- select the client by a new ClientArgs.runtime ('desktop' | 'android'); the
  optional android options object carries device id, adb path, and keyboard
  mode. Desktop usage is unchanged (runtime defaults to 'desktop')
- getStartingArguments() reports runtime:'android', which re-activates the
  existing Android agent tool set and system prompt
- add test-android.ts (npm run test:android); verified end-to-end on a real
  device (tap, swipe, type, keyevents, screenshot, lifecycle)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…OsUrl

- add ClientArgs.agentOsUrl; keep uiControllerUrl as a deprecated alias
  (used only when agentOsUrl is unset) that logs a deprecation warning
- default the AgentOS address to the OS service (localhost:26000), which is
  the recommended install; connect to a standalone AgentOS by setting
  agentOsUrl to localhost:23000 explicitly
- drop the standalone auto-fallback and the Windows sc-query detection: the
  SDK does not download or spawn a standalone binary, so it now connects to a
  single configured address
- on connection failure, point users to the AgentOS installation docs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Android can now be automated either through the AskUI legacy UI Controller
(WebSocket runner-protocol) or directly via adb, selected by
ClientArgs.android.transport.

- add LegacyAndroidClient implementing DeviceClient over the legacy
  controller's WebSocket runner-protocol (CONTROL_REQUEST,
  CAPTURE_SCREENSHOT_REQUEST, GET_STARTING_ARGUMENTS_REQUEST), default
  ws://127.0.0.1:6769; single request in flight to match the controller
- default the Android transport to 'legacy-controller'; opt into direct adb
  with android.transport: 'adb'
- the controller must be started separately in Android mode
  (AskUI-StartController ... -r android)
- extend test-android.ts to cover both transports (TRANSPORT env var)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@programminx-askui programminx-askui merged commit bc62367 into main Jul 10, 2026
3 checks passed
@programminx-askui programminx-askui deleted the feat/agentos-grpc-migration branch July 10, 2026 14:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant