mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
fix(agents): keep remote launches on the optimistic delivery verdict
Receipt eligibility reads LOCAL evidence — locally-observed hook statuses and the local managed-home install probe — which says nothing about a remote host whose hooks may silently not fire. In a mixed local+remote session that evidence would strict-gate an SSH launch and false-fail a delivered prompt (review finding F1). Remote launches keep the optimistic legacy verdict until host-scoped observed evidence exists (follow-up). Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -284,5 +284,26 @@ describe('deliverLaunchPromptToAgentTab', () => {
|
||||
|
||||
expect(mocks.watchForPromptSubmitReceipt).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('keeps the optimistic verdict for remote launches', async () => {
|
||||
// Why: eligibility reads LOCAL hook evidence, which says nothing about a
|
||||
// remote host whose hooks may silently not fire — strict-gating there
|
||||
// would false-fail delivered prompts. Remote graduates in a follow-up
|
||||
// with host-scoped observed evidence.
|
||||
mocks.isPromptReceiptEligible.mockResolvedValue(true)
|
||||
|
||||
await expect(
|
||||
deliverLaunchPromptToAgentTab({
|
||||
tabId: 'tab-1',
|
||||
agent: 'codex',
|
||||
content: 'Fix failing checks',
|
||||
submit: true,
|
||||
forcePaste: true,
|
||||
remoteLaunch: true
|
||||
})
|
||||
).resolves.toBe(true)
|
||||
|
||||
expect(mocks.watchForPromptSubmitReceipt).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -20,10 +20,16 @@ export async function deliverLaunchPromptToAgentTab(args: {
|
||||
content: string
|
||||
submit: boolean
|
||||
forcePaste: boolean
|
||||
/** Why: receipt eligibility reads LOCAL evidence (local hook install state,
|
||||
* locally-observed statuses), which says nothing about a remote host whose
|
||||
* hooks may silently not fire — strict-gating there would false-fail
|
||||
* delivered prompts. Remote launches keep the optimistic verdict until
|
||||
* host-scoped evidence exists (follow-up). */
|
||||
remoteLaunch?: boolean
|
||||
timeoutMs?: number
|
||||
onTimeout?: (reason?: LaunchPromptDeliveryFailureReason) => void
|
||||
}): Promise<boolean> {
|
||||
const { tabId, agent, content, submit, forcePaste, timeoutMs, onTimeout } = args
|
||||
const { tabId, agent, content, submit, forcePaste, remoteLaunch, timeoutMs, onTimeout } = args
|
||||
const shouldSeed =
|
||||
submit === true && content.trim().length > 0 && isNativeChatSupportedAgent(agent)
|
||||
|
||||
@@ -49,7 +55,10 @@ export async function deliverLaunchPromptToAgentTab(args: {
|
||||
// delivery has no submitted paste, so it never waits on a receipt (which
|
||||
// would never arrive).
|
||||
const requireReceipt =
|
||||
submit === true && !deliversViaNativePrefill && (await isPromptReceiptEligible(agent))
|
||||
submit === true &&
|
||||
remoteLaunch !== true &&
|
||||
!deliversViaNativePrefill &&
|
||||
(await isPromptReceiptEligible(agent))
|
||||
const receiptWatch = requireReceipt
|
||||
? watchForPromptSubmitReceipt({ tabId, agent, since: Date.now() })
|
||||
: null
|
||||
|
||||
@@ -309,6 +309,7 @@ export function launchAgentInNewTab(args: LaunchAgentInNewTabArgs): LaunchAgentI
|
||||
agent,
|
||||
submit: submitPastedPrompt,
|
||||
forcePaste: forcePasteAfterLaunch,
|
||||
remoteLaunch: isRemote || runtimeEnvironmentId != null,
|
||||
onTimeout: (reason) => {
|
||||
const state = useAppStore.getState()
|
||||
const tabsForWorktree = state.tabsByWorktree[worktreeId] ?? []
|
||||
|
||||
@@ -142,14 +142,23 @@ export async function pasteDirectWorkItemDraftWhenAgentReady(args: {
|
||||
content: string
|
||||
submit?: boolean
|
||||
forcePaste?: boolean
|
||||
remoteLaunch?: boolean
|
||||
}): Promise<void> {
|
||||
const { primaryTabId, startupPlan, content, submit = false, forcePaste = false } = args
|
||||
const {
|
||||
primaryTabId,
|
||||
startupPlan,
|
||||
content,
|
||||
submit = false,
|
||||
forcePaste = false,
|
||||
remoteLaunch
|
||||
} = args
|
||||
await deliverLaunchPromptToAgentTab({
|
||||
tabId: primaryTabId,
|
||||
content,
|
||||
agent: startupPlan.agent,
|
||||
submit,
|
||||
forcePaste,
|
||||
remoteLaunch,
|
||||
onTimeout: (reason) => {
|
||||
const label = submit ? 'prompt' : 'work item context'
|
||||
toast.message(
|
||||
|
||||
@@ -326,7 +326,8 @@ export async function launchWorkItemDirect(args: LaunchWorkItemDirectArgs): Prom
|
||||
startupPlan,
|
||||
content: draftContent,
|
||||
submit: promptDelivery === 'submit-after-ready',
|
||||
forcePaste: promptDelivery === 'submit-after-ready'
|
||||
forcePaste: promptDelivery === 'submit-after-ready',
|
||||
remoteLaunch: typeof getConnectionId(worktreeId) === 'string'
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user