@@ -10,13 +10,19 @@ import postgres from 'postgres'
1010import type { z } from 'zod'
1111import {
1212 type ClaimDesktopToolBody ,
13+ type ClaimDesktopToolResponse ,
1314 type CompleteDesktopToolBody ,
15+ type CompleteDesktopToolResponse ,
1416 claimDesktopToolResponseSchema ,
1517 completeDesktopToolResponseSchema ,
1618 type DesktopInboxItem ,
19+ type DesktopInboxQuery ,
20+ type DesktopInboxResponse ,
1721 desktopInboxResponseSchema ,
1822 type RegisterDesktopDeviceBody ,
23+ type RegisterDesktopDeviceResponse ,
1924 type RenewDesktopToolLeaseBody ,
25+ type RenewDesktopToolLeaseResponse ,
2026 registerDesktopDeviceResponseSchema ,
2127 renewDesktopToolLeaseResponseSchema ,
2228} from '@/lib/api/contracts/desktop-executor'
@@ -154,7 +160,7 @@ async function signIn(existing?: Desktop): Promise<Desktop> {
154160 return { userId, workspaceId, sessionId, cookie, deviceId : generateId ( ) }
155161}
156162
157- async function register ( desktop : Desktop ) {
163+ async function register ( desktop : Desktop ) : Promise < RegisterDesktopDeviceResponse > {
158164 const body : RegisterDesktopDeviceBody = {
159165 deviceId : desktop . deviceId ,
160166 name : 'E2E MacBook' ,
@@ -168,6 +174,14 @@ async function register(desktop: Desktop) {
168174 } )
169175}
170176
177+ /** The device's reconciling pull, the same request on every doorbell and timer tick. */
178+ async function pullInbox ( desktop : Desktop ) : Promise < DesktopInboxResponse > {
179+ const query : DesktopInboxQuery = { deviceId : desktop . deviceId }
180+ return request ( desktop , 'GET' , `/api/desktop/inbox?${ new URLSearchParams ( query ) } ` , {
181+ schema : desktopInboxResponseSchema ,
182+ } )
183+ }
184+
171185/** A chat whose running turn was bound to the device at admission. */
172186async function boundChat ( desktop : Desktop , title : string ) {
173187 const chatId = generateId ( )
@@ -280,24 +294,22 @@ function startExecutor(desktop: Desktop, doorbell: ReturnType<typeof openDoorbel
280294 try {
281295 do {
282296 rerun = false
283- const inbox = await request (
284- desktop ,
285- 'GET' ,
286- `/api/desktop/inbox?deviceId=${ desktop . deviceId } ` ,
287- {
288- schema : desktopInboxResponseSchema ,
289- }
290- )
297+ const inbox = await pullInbox ( desktop )
291298 for ( const item of inbox . items ) {
292299 if ( item . kind !== 'call' || ran . has ( item . toolCallId ) ) continue
293300 const claimBody : ClaimDesktopToolBody = {
294301 deviceId : desktop . deviceId ,
295302 toolCallId : item . toolCallId ,
296303 }
297- const claim = await request ( desktop , 'POST' , '/api/desktop/tool/claim' , {
298- body : claimBody ,
299- schema : claimDesktopToolResponseSchema ,
300- } )
304+ const claim : ClaimDesktopToolResponse = await request (
305+ desktop ,
306+ 'POST' ,
307+ '/api/desktop/tool/claim' ,
308+ {
309+ body : claimBody ,
310+ schema : claimDesktopToolResponseSchema ,
311+ }
312+ )
301313 ran . set ( item . toolCallId , {
302314 toolName : claim . toolName ,
303315 chatId : claim . chatId ,
@@ -308,10 +320,13 @@ function startExecutor(desktop: Desktop, doorbell: ReturnType<typeof openDoorbel
308320 toolCallId : item . toolCallId ,
309321 executionToken : claim . executionToken ,
310322 }
311- await request ( desktop , 'POST' , '/api/desktop/tool/lease' , {
312- body : renewBody ,
313- schema : renewDesktopToolLeaseResponseSchema ,
314- } )
323+ const renewed : RenewDesktopToolLeaseResponse = await request (
324+ desktop ,
325+ 'POST' ,
326+ '/api/desktop/tool/lease' ,
327+ { body : renewBody , schema : renewDesktopToolLeaseResponseSchema }
328+ )
329+ assert ( Date . parse ( renewed . leaseExpiresAt ) > Date . now ( ) )
315330 const completeBody : CompleteDesktopToolBody = {
316331 deviceId : desktop . deviceId ,
317332 toolCallId : item . toolCallId ,
@@ -320,10 +335,15 @@ function startExecutor(desktop: Desktop, doorbell: ReturnType<typeof openDoorbel
320335 message : `${ claim . toolName } done` ,
321336 data : { ran : claim . toolName , chatId : claim . chatId } ,
322337 }
323- const completedCall = await request ( desktop , 'POST' , '/api/desktop/tool/complete' , {
324- body : completeBody ,
325- schema : completeDesktopToolResponseSchema ,
326- } )
338+ const completedCall : CompleteDesktopToolResponse = await request (
339+ desktop ,
340+ 'POST' ,
341+ '/api/desktop/tool/complete' ,
342+ {
343+ body : completeBody ,
344+ schema : completeDesktopToolResponseSchema ,
345+ }
346+ )
327347 assert . deepEqual ( completedCall , { outcome : 'recorded' , status : 'completed' } )
328348 completed . add ( item . toolCallId )
329349 }
@@ -452,7 +472,7 @@ async function run() {
452472 { silent : true }
453473 )
454474 await waitFor (
455- ( ) => executor . ran . has ( toolCallId ) ,
475+ ( ) => executor . completed . has ( toolCallId ) ,
456476 PICKUP_GRACE_SECONDS * 1000 ,
457477 'the reconcile pull'
458478 )
@@ -486,14 +506,7 @@ async function run() {
486506 { operation : 'run' , command : 'npm run deploy' } ,
487507 { offer : false }
488508 )
489- const inbox = await request (
490- desktop ,
491- 'GET' ,
492- `/api/desktop/inbox?deviceId=${ desktop . deviceId } ` ,
493- {
494- schema : desktopInboxResponseSchema ,
495- }
496- )
509+ const inbox = await pullInbox ( desktop )
497510 const expected : DesktopInboxItem = {
498511 kind : 'approval_needed' ,
499512 toolCallId,
@@ -546,17 +559,13 @@ async function run() {
546559 executionToken : claim . executionToken ,
547560 }
548561 await request ( desktop , 'POST' , '/api/desktop/tool/lease' , { body : lease , expected : 410 } )
549- const inbox = await request ( desktop , 'GET' , `/api/desktop/inbox?deviceId=${ desktop . deviceId } ` , {
550- schema : desktopInboxResponseSchema ,
551- } )
562+ const inbox = await pullInbox ( desktop )
552563 assert ( inbox . items . some ( ( item ) => item . kind === 'cancel' && item . toolCallId === toolCallId ) )
553564 await request ( desktop , 'POST' , '/api/desktop/tool/complete' , {
554565 body : { ...lease , status : 'cancelled' } satisfies CompleteDesktopToolBody ,
555566 schema : completeDesktopToolResponseSchema ,
556567 } )
557- const after = await request ( desktop , 'GET' , `/api/desktop/inbox?deviceId=${ desktop . deviceId } ` , {
558- schema : desktopInboxResponseSchema ,
559- } )
568+ const after = await pullInbox ( desktop )
560569 assert ( ! after . items . some ( ( item ) => item . toolCallId === toolCallId ) )
561570 } )
562571
@@ -572,14 +581,7 @@ async function run() {
572581 { ref : 'e9' } ,
573582 { silent : true }
574583 )
575- const inbox = await request (
576- otherMac ,
577- 'GET' ,
578- `/api/desktop/inbox?deviceId=${ otherMac . deviceId } ` ,
579- {
580- schema : desktopInboxResponseSchema ,
581- }
582- )
584+ const inbox = await pullInbox ( otherMac )
583585 assert . deepEqual ( inbox . items , [ ] )
584586 await request ( otherMac , 'POST' , '/api/desktop/tool/claim' , {
585587 body : { deviceId : otherMac . deviceId , toolCallId } ,
0 commit comments