fix(agents): refresh remote detection on new launch surfaces (#21659)

This commit is contained in:
Neil
2026-09-19 05:12:42 -07:00
committed by GitHub
parent ae9c06c941
commit 6abd1ce53b
2 changed files with 85 additions and 11 deletions
@@ -237,6 +237,22 @@ describe('useDetectedAgents (ssh call site)', () => {
expect(detectRemoteAgents).toHaveBeenCalledTimes(2)
expect(useAppStore.getState().remoteDetectedAgentIds['ssh-1']).toEqual(['kilo'])
})
it('refreshes a non-empty SSH cache when a new launch surface opens', async () => {
useAppStore.setState({ remoteDetectedAgentIds: { 'ssh-1': ['claude'] } })
detectRemoteAgents.mockResolvedValueOnce(['claude', 'devin'])
const root = await renderProbe({ kind: 'ssh', connectionId: 'ssh-1' })
expect(detectRemoteAgents).toHaveBeenCalledTimes(1)
expect(useAppStore.getState().remoteDetectedAgentIds['ssh-1']).toEqual(['claude', 'devin'])
await act(async () => {
root.render(createElement(HookProbe, { target: { kind: 'ssh', connectionId: 'ssh-1' } }))
})
await flushEffects()
expect(detectRemoteAgents).toHaveBeenCalledTimes(1)
})
})
describe('useDetectedAgents (unresolved target)', () => {
@@ -283,6 +299,56 @@ describe('useDetectedAgents (runtime call site)', () => {
).toHaveLength(2)
})
it('refreshes a non-empty runtime cache when a new launch surface opens', async () => {
useAppStore.setState({ runtimeDetectedAgentIds: { 'env-1': ['claude'] } })
runtimeEnvironmentCall.mockImplementation(({ method }: { method: string }) => {
const result =
method === 'status.get'
? {
runtimeId: 'remote-runtime',
rendererGraphEpoch: 1,
graphStatus: 'ready',
authoritativeWindowId: null,
liveTabCount: 0,
liveLeafCount: 0,
runtimeProtocolVersion: RUNTIME_PROTOCOL_VERSION,
minCompatibleRuntimeClientVersion: MIN_COMPATIBLE_RUNTIME_CLIENT_VERSION
}
: {
agents: ['claude', 'devin'],
addedPathSegments: [],
shellHydrationOk: true,
pathSource: 'shell_hydrate',
pathFailureReason: 'none'
}
return Promise.resolve({
id: method,
ok: true,
result,
_meta: { runtimeId: 'remote-runtime' }
})
})
const root = await renderProbe({ kind: 'runtime', environmentId: 'env-1' })
expect(
runtimeEnvironmentCall.mock.calls.filter(
([{ method }]) => method === 'preflight.refreshAgents'
)
).toHaveLength(1)
expect(useAppStore.getState().runtimeDetectedAgentIds['env-1']).toEqual(['claude', 'devin'])
await act(async () => {
root.render(createElement(HookProbe, { target: { kind: 'runtime', environmentId: 'env-1' } }))
})
await flushEffects()
expect(
runtimeEnvironmentCall.mock.calls.filter(
([{ method }]) => method === 'preflight.refreshAgents'
)
).toHaveLength(1)
})
it('does not re-probe after an explicit refresh finds no agents', async () => {
useAppStore.setState({
runtimeDetectedAgentIds: { 'env-1': ['claude'] },
@@ -324,16 +390,18 @@ describe('useDetectedAgents (runtime call site)', () => {
})
})
await renderProbe({ kind: 'runtime', environmentId: 'env-1' })
await renderProbe({ kind: 'runtime', environmentId: 'env-1' })
await act(async () => {
await latestHookResult?.refresh()
})
const root = await renderProbe({ kind: 'runtime', environmentId: 'env-1' })
await flushEffects()
expect(refreshCalls).toBe(1)
expect(detectCalls).toBe(0)
expect(useAppStore.getState().runtimeDetectedAgentIds['env-1']).toEqual([])
await act(async () => {
root.render(createElement(HookProbe, { target: { kind: 'runtime', environmentId: 'env-1' } }))
})
await flushEffects()
expect(refreshCalls).toBe(1)
})
it('retries a cached empty runtime result when the launch surface is reopened', async () => {
+12 -6
View File
@@ -155,17 +155,23 @@ export function useDetectedAgents(
if (targetKind === 'ssh' && targetId) {
if (detectedIds === null) {
void state.ensureRemoteDetectedAgents(targetId)
} else if (detectedIds.length === 0 && isNewRemoteTarget) {
// Why: a newly opened remote launch surface should get one fresh probe
// after a prior empty result, but must not spin while the host has no agents.
} else if (isNewRemoteTarget && detectedIds.length > 0) {
// Why: a host can install an agent after its cached list was populated;
// refresh once when a new launch surface first observes that host.
void state.refreshRemoteDetectedAgents(targetId)
} else if (isNewRemoteTarget) {
// Empty results are intentionally retryable through the normal probe.
void state.ensureRemoteDetectedAgents(targetId)
}
} else if (targetKind === 'runtime' && targetId) {
if (detectedIds === null) {
void state.ensureRuntimeDetectedAgents(targetId)
} else if (detectedIds.length === 0 && isNewRemoteTarget) {
// Why: remote `orca serve` users can install/fix PATH without reconnecting;
// retry once per mounted surface so the menu can pick that up.
} else if (isNewRemoteTarget && detectedIds.length > 0) {
// Why: a host can install an agent after its cached list was populated;
// refresh once when a new launch surface first observes that host.
void state.refreshRuntimeDetectedAgents(targetId)
} else if (isNewRemoteTarget) {
// Empty results are intentionally retryable through the normal probe.
void state.ensureRuntimeDetectedAgents(targetId)
}
} else {