fix: close PI-140 cutover gaps

Back up unknown legacy Agents, reconnect settled Conversation observation, remove remaining active repository residue, and restore the bundled Python verifier import.
This commit is contained in:
2026-08-24 12:47:16 +08:00
parent 5a275b93a7
commit 7a15b1b49c
12 changed files with 286 additions and 247 deletions

View File

@@ -138,6 +138,75 @@ function ids() {
}
describe('coding Conversation store', () => {
it('queues observation sync only for a live completed ordinary prompt', () => {
const queueSettledSessionSync = vi.fn();
const store = createCodingConversationStore({
getSnapshot: vi.fn(),
openEvents: vi.fn(),
submitPrompt: vi.fn(),
queueSettledSessionSync,
createId: ids(),
});
const running = {
...snapshot('conversation-a', 1, 3),
run: { status: 'running', runId: 'run-a', mode: 'prompt' } as const,
};
store.getState().applySnapshotEvent(snapshotEvent(running));
expect(queueSettledSessionSync).not.toHaveBeenCalled();
store.getState().applyPatchBatchEvent(patchEvent('conversation-a', 4, {
op: 'run.state',
run: {
status: 'idle',
runId: 'run-a',
settledAt: 1_004,
terminalReason: 'completed',
},
}));
expect(queueSettledSessionSync).toHaveBeenCalledTimes(1);
expect(queueSettledSessionSync).toHaveBeenCalledWith(expect.objectContaining({
conversation: expect.objectContaining({ id: 'conversation-a', projectId: 'project-a' }),
run: expect.objectContaining({ status: 'idle', terminalReason: 'completed' }),
cursor: expect.objectContaining({ seq: 4 }),
}));
});
it('does not queue observation sync for hydration or a follow-up settlement', () => {
const queueSettledSessionSync = vi.fn();
const store = createCodingConversationStore({
getSnapshot: vi.fn(),
openEvents: vi.fn(),
submitPrompt: vi.fn(),
queueSettledSessionSync,
createId: ids(),
});
store.getState().applySnapshotEvent(snapshotEvent({
...snapshot('conversation-a', 1, 3),
run: {
status: 'idle',
runId: 'hydrated-run',
settledAt: 1_003,
terminalReason: 'completed',
},
}));
store.getState().applySnapshotEvent(snapshotEvent({
...snapshot('conversation-b', 1, 3),
run: { status: 'running', runId: 'run-b', mode: 'follow-up' },
}));
store.getState().applyPatchBatchEvent(patchEvent('conversation-b', 4, {
op: 'run.state',
run: {
status: 'idle',
runId: 'run-b',
settledAt: 1_004,
terminalReason: 'completed',
},
}));
expect(queueSettledSessionSync).not.toHaveBeenCalled();
});
it('isolates interleaved snapshot and patch state for two Conversations', async () => {
const source = new FakeEventSource();
const getSnapshot = vi.fn(async (conversationId: string) => snapshot(conversationId));