fix(sync): keep pending questions answerable after restart (#2005)
Co-authored-by: bashrusakh <bashrusakh@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
co-authored by
bashrusakh
parent
fbcf4ea2b9
commit
420582984e
@@ -55,4 +55,44 @@ describe('listGlobalSessionPages', () => {
|
|||||||
expect(session.revert).toEqual({ messageID: 'msg_1' })
|
expect(session.revert).toEqual({ messageID: 'msg_1' })
|
||||||
expect(session.summary).toEqual({ additions: 5, deletions: 3, files: 2 })
|
expect(session.summary).toEqual({ additions: 5, deletions: 3, files: 2 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('paginates through all session-list pages', async () => {
|
||||||
|
const calls: Array<Record<string, unknown>> = []
|
||||||
|
const apiClient = {
|
||||||
|
experimental: {
|
||||||
|
session: {
|
||||||
|
list: async (options: Record<string, unknown>) => {
|
||||||
|
calls.push(options)
|
||||||
|
if (options.cursor === undefined) {
|
||||||
|
return {
|
||||||
|
data: [
|
||||||
|
{ id: 'ses_root', time: { updated: 20 } },
|
||||||
|
{ id: 'ses_child_1', time: { updated: 10 } },
|
||||||
|
],
|
||||||
|
response: { headers: new Headers({ 'x-next-cursor': '10' }) },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
data: [
|
||||||
|
{ id: 'ses_child_2', time: { updated: 5 } },
|
||||||
|
],
|
||||||
|
response: { headers: new Headers() },
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as unknown as OpencodeClient
|
||||||
|
|
||||||
|
const sessions = await listGlobalSessionPages(apiClient, {
|
||||||
|
directory: '/repo',
|
||||||
|
archived: false,
|
||||||
|
roots: false,
|
||||||
|
pageSize: 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(calls).toHaveLength(2)
|
||||||
|
expect(calls[0]).toEqual({ directory: '/repo', archived: false, roots: false, limit: 2 })
|
||||||
|
expect(calls[1]).toEqual({ directory: '/repo', archived: false, roots: false, limit: 2, cursor: 10 })
|
||||||
|
expect(sessions.map((session) => session.id)).toEqual(['ses_root', 'ses_child_1', 'ses_child_2'])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1738,21 +1738,18 @@ export function SyncProvider(props: {
|
|||||||
.filter((s) => !!s?.id)
|
.filter((s) => !!s?.id)
|
||||||
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
|
.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
|
||||||
|
|
||||||
// Also load child sessions (sub-agent delegations) so they
|
// Also load child sessions (sub-agent delegations) with pagination
|
||||||
// appear in the sidebar immediately instead of relying on
|
// so pending questions can scope to them immediately after restart.
|
||||||
// the async global session store.
|
|
||||||
let allSessions: typeof rootSessions = []
|
let allSessions: typeof rootSessions = []
|
||||||
try {
|
try {
|
||||||
const allResult = await props.sdk.session.list({
|
allSessions = await listGlobalSessionPages(props.sdk, {
|
||||||
directory: dir,
|
directory: dir,
|
||||||
limit: 200,
|
archived: false,
|
||||||
|
roots: false,
|
||||||
|
pageSize: 500,
|
||||||
})
|
})
|
||||||
const allError = (allResult as { error?: unknown }).error
|
|
||||||
if (!allError) {
|
|
||||||
allSessions = ((allResult as { data?: unknown }).data ?? []) as typeof rootSessions
|
|
||||||
}
|
|
||||||
} catch {
|
} catch {
|
||||||
// Child load is best-effort; fall back to roots only
|
// Child load is best-effort; fall back to roots only.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge: keep root sessions from the first query (for accurate
|
// Merge: keep root sessions from the first query (for accurate
|
||||||
|
|||||||
Reference in New Issue
Block a user