diff --git a/gadget-code/src/lib/code-session.ts b/gadget-code/src/lib/code-session.ts index 56a6a7a..126acf6 100644 --- a/gadget-code/src/lib/code-session.ts +++ b/gadget-code/src/lib/code-session.ts @@ -123,8 +123,6 @@ export class CodeSession extends SocketSession { droneSession.socket.emit( "processWorkOrder", this.selectedDrone, - this.project, - this.chatSession, turn, (success: boolean, message?: string) => { if (success) { diff --git a/gadget-code/tests/code-session.test.ts b/gadget-code/tests/code-session.test.ts index b51baaa..96ced13 100644 --- a/gadget-code/tests/code-session.test.ts +++ b/gadget-code/tests/code-session.test.ts @@ -150,8 +150,6 @@ describe("CodeSession", () => { expect(mockDroneSession.socket.emit).toHaveBeenCalledWith( "processWorkOrder", mockDrone, - mockProject, - mockChatSession, mockTurn, expect.any(Function), ); diff --git a/gadget-drone/src/gadget-drone.ts b/gadget-drone/src/gadget-drone.ts index 03fbaa6..ac2082b 100644 --- a/gadget-drone/src/gadget-drone.ts +++ b/gadget-drone/src/gadget-drone.ts @@ -33,6 +33,11 @@ interface UserCredentials { password: string; } +interface ISessionLock { + project: IProject; + session: IChatSession; +} + type ClientSocket = Socket; class GadgetDrone extends GadgetProcess { @@ -40,7 +45,7 @@ class GadgetDrone extends GadgetProcess { private user: IUser | undefined; private workspaceMode: WorkspaceMode = WorkspaceMode.Syncing; - private chatSession: IChatSession | undefined; + private sessionLock: ISessionLock | undefined; private socket: ClientSocket | undefined; private isShuttingDown: boolean = false; @@ -245,16 +250,22 @@ class GadgetDrone extends GadgetProcess { * Check if the chat session lock is already held. */ - if (this.chatSession) { - if (chatSession._id !== this.chatSession._id) { + if (this.sessionLock) { + if (chatSession._id !== this.sessionLock.session._id) { this.log.warn("rejecting session lock request", { - chatSession: { - _id: this.chatSession._id, - name: this.chatSession.name, + sessionLock: { + project: { + _id: this.sessionLock.project._id, + name: this.sessionLock.project.name, + }, + session: { + _id: this.sessionLock.session._id, + name: this.sessionLock.session.name, + }, }, workspaceMode: this.workspaceMode, }); - return cb(false, this.chatSession._id); + return cb(false, this.sessionLock.session._id); } // fall through to grant this lock request this.log.info("chat session is re-connecting to session lock"); @@ -269,7 +280,10 @@ class GadgetDrone extends GadgetProcess { project: { _id: project._id, slug: project.slug }, chatSession: { _id: chatSession._id, name: chatSession.name }, }); - this.chatSession = chatSession; + this.sessionLock = { + project, + session: chatSession, + }; this.workspaceMode = WorkspaceMode.Idle; cb(true, chatSession._id); @@ -282,10 +296,10 @@ class GadgetDrone extends GadgetProcess { mode: WorkspaceMode, cb: RequestWorkspaceModeCallback, ) { - if (!this.chatSession) { + if (!this.sessionLock) { return cb(false, this.workspaceMode); } - if (chatSession._id !== this.chatSession._id) { + if (chatSession._id !== this.sessionLock.session._id) { this.log.warn("rejecting workspace mode request", { chatSession: { _id: chatSession._id, name: chatSession.name }, }); @@ -306,17 +320,24 @@ class GadgetDrone extends GadgetProcess { async onProcessWorkOrder( registration: IDroneRegistration, - project: IProject, - chatSession: IChatSession, turn: IChatTurn, cb: ProcessWorkOrderCallback, ) { - if (!this.chatSession) { + const project = turn.project as IProject; + const session = turn.session as IChatSession; + + if (!this.sessionLock) { return cb(false, "this drone is not locked to a chat session"); } - if (this.chatSession._id !== chatSession._id) { + if (this.sessionLock.session._id !== session._id) { return cb(false, "this drone is not locked to your chat session"); } + if (this.sessionLock.project._id !== project._id) { + return cb( + false, + `this drone is locked to a different project: ${this.sessionLock.project.name}`, + ); + } if (this.workspaceMode !== WorkspaceMode.Agent) { return cb(false, "this drone's workspace is not in Agent mode"); } @@ -329,7 +350,7 @@ class GadgetDrone extends GadgetProcess { this.log.info("processWorkOrder received", { registration: { _id: registration._id }, project: { _id: project._id, name: project.name }, - chatSession: { _id: chatSession._id, name: chatSession.name }, + session: { _id: session._id, name: session.name }, turn: { _id: turn._id, mode: turn.mode, userPrompt: turn.prompts.user }, }); diff --git a/packages/api/src/messages/drone.ts b/packages/api/src/messages/drone.ts index 57cbaf4..1156f52 100644 --- a/packages/api/src/messages/drone.ts +++ b/packages/api/src/messages/drone.ts @@ -13,8 +13,6 @@ export type ProcessWorkOrderCallback = ( ) => void; export type ProcessWorkOrderMessage = ( registration: IDroneRegistration, - project: IProject, - chatSession: IChatSession, turn: IChatTurn, cb: ProcessWorkOrderCallback, ) => void;