feat: daemon SDK MVP — connectDaemon, DaemonConnection, DaemonSession#48
Open
varin-nair-factory wants to merge 3 commits into
Open
feat: daemon SDK MVP — connectDaemon, DaemonConnection, DaemonSession#48varin-nair-factory wants to merge 3 commits into
varin-nair-factory wants to merge 3 commits into
Conversation
Adds daemon mode as a sibling to the existing exec-based API. The daemon SDK connects to a running droid daemon over WebSocket and supports both interactive streaming and fire-and-forget headless delegation. New public API: - connectDaemon() — resolve SDKMachineConfig to WebSocket URL, authenticate - DaemonConnection — createSession, resumeSession, interruptSession, close - DaemonSession — stream() for interactive use, send() for fire-and-forget - WebSocketTransport — DroidClientTransport over WebSocket (ws package) - MachineType enum, SDKMachineConfig type Key design: - SharedTransportMultiplexer broadcasts messages to multiple DroidClient instances sharing one WebSocket connection - Same DroidStreamEvent/MessageBridge/StreamStateTracker stack as exec mode - URL resolution: MachineType.Ephemeral → e2b sandbox, Computer → relay Includes API design doc (docs/daemon-sdk-api-design.md) with consumer migration breakdown for Slack, Linear, automations, and REST API. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
… routing, token injection Three critical fixes to make the daemon SDK work with the actual daemon protocol: 1. Method prefix remapping: ProtocolEngine now supports a methodPrefix option that remaps droid.* to daemon.* on outgoing requests and daemon.* to droid.* on incoming messages. DroidClient passes this through to ProtocolEngine. 2. Session-aware multiplexer: SharedTransportMultiplexer now routes responses by matching request IDs, and notifications/server-requests by sessionId. This enables correct concurrent multi-session support. 3. Token/sessionId injection: DaemonConnection injects the auth token into initialize_session and load_session params (daemon requires it). DroidClient injects sessionId into all session-scoped requests when in daemon mode. Verified against live daemon with 16/16 stress tests passing: - Basic connect + auth, create session + stream, multi-turn context, interrupt, concurrent sessions, error handling, notifications. Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Export ensureLocalDaemon and resolveLocalAuthToken from daemon barrel - Update FACTORY_PROTOCOL_VERSION test to match 1.51.0 - Add local daemon URL resolution tests - Add local daemon export tests Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds daemon mode as a sibling to the existing exec-based
run()/createSession()API. The daemon SDK connects to a runningdroid daemonover WebSocket and supports both interactive streaming and fire-and-forget headless delegation.Usage Examples
1. Interactive streaming (connect to a computer via relay)
2. Fire-and-forget delegation (Slack/Linear pattern)
3. Multi-turn session with follow-up
4. Resume and interrupt an existing session
New Public API
connectDaemon(options?)— entry point. ResolvesSDKMachineConfigto a WebSocket URL, connects, authenticates.DaemonConnection—createSession(),resumeSession(),interruptSession(),close()DaemonSession—stream()for interactive use,send()for fire-and-forgetWebSocketTransport—DroidClientTransportimplementation over WebSocketMachineTypeenum (Ephemeral,Computer,Local)SDKMachineConfigtype — discriminated union matching mono-alpha'sMachineConfigDesign
SharedTransportMultiplexerbroadcasts WebSocket messages to multipleDroidClientinstances sharing one connectionProtocolEngine/DroidClient/MessageBridge/StreamStateTrackerstack — daemon sessions produce the sameDroidStreamEventtypes as exec modeMachineType.Ephemeral→ e2b sandbox URL,MachineType.Computer→ Factory relay URLdaemon.authenticateJSON-RPC handshake (matches mono-alpha protocol)Consumer Coverage
This MVP covers 100% of headless consumer workflows in mono-alpha:
archiveSession,getSessionMessages)Files
src/daemon/types.tssrc/daemon/transport.tsWebSocketTransportwith retry + backoffsrc/daemon/session.tsDaemonSession—stream()andsend()src/daemon/connection.tsconnectDaemon(),DaemonConnection,SharedTransportMultiplexersrc/daemon/index.tsdocs/daemon-sdk-api-design.mdValidation
New dependency
ws(Node.js WebSocket client) +@types/ws