8.0 KiB
8.0 KiB
Gadget Code Socket Protocol Reference
This document serves as a "Cheat Sheet" for AI agents and developers working on the Gadget Code real-time messaging system.
1. Components & Connections
| Component | Role | Protocol | Auth Method |
|---|---|---|---|
gadget-code:web |
Hub / Router / Server | Socket.IO Server | N/A |
gadget-code:ide |
Frontend Control Surface | Socket.IO Client | JWT Token |
gadget-drone |
Worker / AWL Runner | Socket.IO Client | Drone Registration ID |
2. Event Map Overview
Defined in packages/api/src/messages/socket.ts.
IDE -> Web (Client to Server)
requestSessionLock: Request to exclusive-lock a drone for a project session.requestWorkspaceMode: Request a mode change (Idle, User, Agent).submitPrompt: Submit a user prompt for agent processing.
Drone -> Web (Client to Server)
thinking: Stream reasoning/thought process text.response: Stream natural language response text.toolCall: Emit a specific tool execution event with result.workOrderComplete: Signal that a prompt processing turn is finished.requestCrashRecovery: Inbound from drone on restart if it finds a stalled work order.requestTermination: Acknowledgment from drone that termination request was received.
Web -> Drone (Server to Client)
processWorkOrder: Command to start processing a specific prompt/turn.crashRecoveryResponse: Command todiscardorretrya stalled work order.requestTermination: Command to immediately terminate the drone process.
Web -> IDE (Server to Client)
sessionUpdated: Notify the IDE that a chat session property has changed (e.g. auto-generated name).
3. Core Sequences & Routing
3.1 Prompt Submission Flow
- IDE emits
submitPrompt(content). - Web (
CodeSession.ts):- Creates a
ChatTurndocument (status:processing). - Increments the chat session's
stats.turnCount. - Finds the target
DroneSession. - Caches the updated session and signals the IDE to enter Processing state.
- Emits
processWorkOrderto the Drone. - On first prompt (name is still the default), calls AI API to auto-generate session name.
- Emits
sessionUpdated({ name })to IDE if the name changed.
- Creates a
- Drone (
gadget-drone.ts):- Writes a local
.gadget/work-order.jsoncache (for crash recovery). - Calls
AgentService.process(). - Emits streaming events back to Web.
- Writes a local
3.2 Result Streaming Flow
- Drone emits
thinking(text),response(text), ortoolCall(id, name, args, result). - Web (
DroneSession.ts):- Locates the associated
CodeSessionviaSocketService.getCodeSessionByChatSessionId(). - Updates the
ChatTurndocument in MongoDB incrementally. - Forwards the event to the IDE.
- Locates the associated
- IDE: Updates the UI in real-time.
3.3 Session Termination
- Drone emits
workOrderComplete(turnId, success, message). - Web (
DroneSession.ts):- Sets
ChatTurnstatus tofinishedorerror. - Forwards event to IDE.
- Clears
currentTurnIdfrom the drone session.
- Sets
3.4 Drone Termination Flow
- User clicks "Terminate" button in Drone Manager UI.
- IDE calls
POST /api/v1/drone/registration/:id/terminate. - Web (
DroneService.ts):- Checks if drone is already offline → returns error if so.
- Looks up
DroneSessionviaSocketService.getDroneSession(). - If drone not connected → marks as offline immediately, returns success.
- Emits
requestTerminationto drone socket with callback. - Starts 10-second timeout.
- Web (
DroneSession.ts):- Receives
requestTerminationevent. - Logs the termination request.
- Forwards
requestTerminationto drone socket (passthrough).
- Receives
- Drone (
gadget-drone.ts):- Receives
requestTerminationfrom platform. - Calls callback with
success: true. - Sends
SIGINTto self, triggering graceful shutdown. - Updates status to
Offlineduring shutdown.
- Receives
- Web (
DroneService.ts):- Drone accepts termination → polls DB every 500ms waiting for
Offlinestatus. - Drone goes offline → resolves with success.
- Timeout expires (10s) → forces status to
Offline, resolves with success.
- Drone accepts termination → polls DB every 500ms waiting for
4. Message Signatures (TS Reference)
IDE -> Web
type RequestSessionLockMessage = (
registration: IDroneRegistration,
project: IProject,
chatSession: IChatSession,
cb: (success: boolean, chatSessionId: string) => void
) => void;
type SubmitPromptMessage = (prompt: string) => void;
Web -> Drone
type ProcessWorkOrderMessage = (
registration: IDroneRegistration,
project: IProject,
chatSession: IChatSession,
turn: IChatTurn,
cb: (success: boolean, message?: string) => void
) => void;
type RequestTerminationMessage = (
cb: (success: boolean) => void
) => void;
Web -> IDE
type SessionUpdatedMessage = (
updates: Partial<IChatSession>
) => void;
Drone -> Web (Streaming)
type ThinkingMessage = (content: string) => void;
type ResponseMessage = (content: string) => void;
type ToolCallMessage = (
callId: string,
name: string,
params: string, // JSON.stringify
response: string // JSON.stringify
) => void;
type WorkOrderCompleteMessage = (
workOrderId: string,
success: boolean,
message?: string
) => void;
type RequestTerminationMessage = (
cb: (success: boolean) => void
) => void;
5. Session Implementation Guide (Web Server)
The web server (gadget-code:web) implements two wrapper classes in src/lib/:
CodeSession.ts
Manages the IDE socket.
- Logic: Maps User ID -> Socket ID.
- Routing: When an IDE sends a message,
CodeSessionfinds the selected drone'sDroneSessionand forwards the command.
DroneSession.ts
Manages the Drone socket.
- Logic: Maps Drone Registration ID -> Socket ID.
- Routing: When a drone streams,
DroneSessionlooks up thechatSessionIdin theSocketServiceindex to find the return path to the IDE. - Session Lookup:
SocketServicemaintains adroneRegistrationIndexMap that mapsregistration._id→DroneSessionfor efficient lookup by registration ID.
Session Indexing Architecture
The SocketService maintains multiple indexes for efficient session lookup:
droneSessions: Map<socket.id, DroneSession> - Primary storage by socket IDdroneRegistrationIndex: Map<registration._id, DroneSession> - Lookup by drone registrationcodeSessions: Map<socket.id, CodeSession> - Primary storage by socket IDcodeSessionUserIndex: Map<user._id, CodeSession> - Lookup by user IDchatSessionIndex: Map<chatSessionId, CodeSession> - Reverse lookup from chat session to IDE
All indexes are kept in sync during connection and disconnection.
6. Workspace Crash Recovery
- Drone starts -> checks for
.gadget/work-order.json. - If found, emits
requestCrashRecovery({ workspaceId, turnId, chatSessionId }). - Web (
DroneSession.ts):- Checks DB for
ChatTurnstatus. - If turn is already
finished, responds with{ action: "discard" }. - If turn is
processing, responds with{ action: "retry" }and schedules a newprocessWorkOrderafter a delay.
- Checks DB for
- Drone: Deletes local cache upon receiving any
crashRecoveryResponse.
7. Extending the Protocol
To add a new message:
- Add the message type to
packages/api/src/messages/ide.ts,drone.ts, orweb.ts. - Register it in
ClientToServerEventsorServerToClientEventsinpackages/api/src/messages/socket.ts. - Re-export from
packages/api/src/index.ts. - Implement the sender (emit) in the Client (
ideordrone) or Server (CodeSession/DroneSession). - Implement the handler in the corresponding class or frontend component.
- Implement the forward-path routing if needed.