@@ -31,7 +31,8 @@ import {
3131 isTerminalAsyncStatus ,
3232} from '@/lib/mothership/async-runs/lifecycle'
3333import { DESKTOP_TOOL_PICKUP_GRACE_MS } from '@/lib/mothership/constants'
34- import { DESKTOP_TOOL_CALL_NAMES } from '@/lib/mothership/tools/desktop-tools'
34+ import { NAMED_DESKTOP_TOOL_NAMES } from '@/lib/mothership/tools/desktop-tools'
35+ import { USER_LOCAL_VFS_ROOT } from '@/lib/mothership/tools/local-filesystem'
3536
3637const LIVE_RUN_STATUSES : CopilotRunStatus [ ] = [ 'active' , 'paused_waiting_for_tool' , 'resuming' ]
3738
@@ -61,6 +62,26 @@ function pickupOverdueAt(at: SQL) {
6162 sql `${ pickupDeadline } <= ${ at } `
6263 )
6364}
65+
66+ function isUserLocalVfsPath ( path : SQL ) {
67+ return sql `(${ path } = ${ USER_LOCAL_VFS_ROOT } OR ${ path } LIKE ${ `${ USER_LOCAL_VFS_ROOT } /%` } )`
68+ }
69+
70+ /**
71+ * The SQL form of `isDesktopToolCall`, so a query limits only over calls the desktop runs: a
72+ * desktop tool by name, or a VFS read of a granted local folder (not a read of Sim's own files).
73+ */
74+ const isDesktopToolCallRow = or (
75+ inArray ( copilotAsyncToolCalls . toolName , [ ...NAMED_DESKTOP_TOOL_NAMES ] ) ,
76+ and (
77+ inArray ( copilotAsyncToolCalls . toolName , [ 'read' , 'grep' ] ) ,
78+ isUserLocalVfsPath ( sql `${ copilotAsyncToolCalls . args } ->>'path'` )
79+ ) ,
80+ and (
81+ eq ( copilotAsyncToolCalls . toolName , 'glob' ) ,
82+ isUserLocalVfsPath ( sql `${ copilotAsyncToolCalls . args } ->>'pattern'` )
83+ )
84+ )
6485const INBOX_ROW_LIMIT = 500
6586
6687export interface DesktopDeviceRegistration {
@@ -183,7 +204,7 @@ export async function listDesktopInboxRows(identity: Omit<DesktopDeviceIdentity,
183204 eq ( copilotRuns . desktopDeviceId , identity . deviceId ) ,
184205 eq ( copilotRuns . userId , identity . userId ) ,
185206 sql `${ copilotRuns . startedAt } > now() - make_interval(hours => ${ DESKTOP_INBOX_HORIZON_HOURS } )` ,
186- inArray ( copilotAsyncToolCalls . toolName , [ ... DESKTOP_TOOL_CALL_NAMES ] ) ,
207+ isDesktopToolCallRow ,
187208 state
188209 )
189210 )
@@ -366,7 +387,7 @@ export async function getDesktopToolCallDeadlines(toolCallId: string) {
366387 and (
367388 eq ( copilotAsyncToolCalls . toolCallId , toolCallId ) ,
368389 isNotNull ( copilotRuns . desktopDeviceId ) ,
369- inArray ( copilotAsyncToolCalls . toolName , [ ... DESKTOP_TOOL_CALL_NAMES ] )
390+ isDesktopToolCallRow
370391 )
371392 )
372393 . limit ( 1 )
@@ -380,28 +401,29 @@ export type DesktopToolCallDeadlines = NonNullable<
380401/**
381402 * Bound desktop calls a deadline passed for at least `slackMs` ago: unclaimed past their pickup
382403 * deadline (offered or not), or claimed by the executor with a lapsed lease. A live waiter settles
383- * these within its 5 s poll, so anything this finds lost its waiter. Only runs inside the inbox's
384- * horizon are scanned, oldest calls first.
404+ * these within its 5 s poll, so anything this finds lost its waiter. Only deadlines that lapsed
405+ * within the inbox's horizon are scanned, whatever the run's age , oldest calls first.
385406 */
386407export async function listOverdueDesktopToolCalls ( input : { slackMs : number ; limit : number } ) {
387408 const overdue = sql `clock_timestamp() - ${ input . slackMs } * interval '1 millisecond'`
409+ const horizon = sql `clock_timestamp() - make_interval(hours => ${ DESKTOP_INBOX_HORIZON_HOURS } )`
388410 const rows = await db
389411 . select ( { toolCallId : copilotAsyncToolCalls . toolCallId } )
390412 . from ( copilotAsyncToolCalls )
391413 . innerJoin ( copilotRuns , eq ( copilotRuns . id , copilotAsyncToolCalls . runId ) )
392414 . where (
393415 and (
394416 isNotNull ( copilotRuns . desktopDeviceId ) ,
395- sql `${ copilotRuns . startedAt } > now() - make_interval(hours => ${ DESKTOP_INBOX_HORIZON_HOURS } )` ,
396- inArray ( copilotAsyncToolCalls . toolName , [ ...DESKTOP_TOOL_CALL_NAMES ] ) ,
417+ isDesktopToolCallRow ,
397418 or (
398- pickupOverdueAt ( overdue ) ,
419+ and ( pickupOverdueAt ( overdue ) , sql ` ${ pickupDeadline } > ${ horizon } ` ) ,
399420 and (
400421 eq ( copilotAsyncToolCalls . status , ASYNC_TOOL_STATUS . running ) ,
401422 inArray ( copilotAsyncToolCalls . claimedBy , Object . values ( DESKTOP_TOOL_CLAIM_OWNER ) ) ,
402423 isNotNull ( copilotAsyncToolCalls . executionOwnerToken ) ,
403424 isNull ( copilotAsyncToolCalls . executionRevokedAt ) ,
404- sql `${ copilotAsyncToolCalls . executionLeaseExpiresAt } < ${ overdue } `
425+ sql `${ copilotAsyncToolCalls . executionLeaseExpiresAt } < ${ overdue } ` ,
426+ sql `${ copilotAsyncToolCalls . executionLeaseExpiresAt } > ${ horizon } `
405427 )
406428 )
407429 )
0 commit comments