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

@@ -3,10 +3,12 @@ import type { RawMessage } from '@/types/chat';
import {
buildAgentSessionData,
flushPendingAgentSessionSync,
queueCodingConversationSessionSync,
queueAgentSessionSync,
resetAgentSessionSyncForTests,
sanitizeAgentSessionText,
} from '@/lib/agent-session-sync';
import { createProductSnapshot } from '../fixtures/coding-conversation-product-fixtures';
const getAuthStateMock = vi.hoisted(() => vi.fn());
const getProfileStateMock = vi.hoisted(() => vi.fn());
@@ -145,6 +147,79 @@ describe('local Agent session sync', () => {
]));
});
it('uploads natural-language messages from the final product Conversation snapshot', async () => {
queueCodingConversationSessionSync({
...createProductSnapshot('conversation-1'),
conversation: {
...createProductSnapshot('conversation-1').conversation,
projectId: 'project-1',
},
nodes: [
{
kind: 'message',
id: 'user-1',
role: 'user',
status: 'complete',
blocks: [{ kind: 'text', id: 'user-text', text: '解释一下。', status: 'complete' }],
},
{
kind: 'message',
id: 'assistant-1',
role: 'assistant',
status: 'complete',
blocks: [
{ kind: 'thinking', id: 'thought', text: '内部推理', status: 'complete' },
{ kind: 'text', id: 'answer', text: '这是自然语言回答。', status: 'complete' },
],
},
],
run: {
status: 'idle',
runId: 'run-1',
settledAt: Date.parse('2026-08-24T08:00:00.000Z'),
terminalReason: 'completed',
},
});
await flushPendingAgentSessionSync();
expect(pushSessionDataMock).toHaveBeenCalledWith(
'user-a',
'access-token',
{
project_id: 'project-1',
session_id: 'conversation-1',
updated_at: '2026-08-24T08:00:00.000Z',
messages: [
{ id: 'user-1', role: 'user', text: '解释一下。' },
{ id: 'assistant-1', role: 'assistant', text: '这是自然语言回答。' },
],
},
);
});
it('does not queue a product Conversation without assistant natural language', async () => {
const base = createProductSnapshot('conversation-1');
queueCodingConversationSessionSync({
...base,
nodes: [{
kind: 'message',
id: 'assistant-1',
role: 'assistant',
status: 'complete',
blocks: [{ kind: 'thinking', id: 'thought', text: '内部推理', status: 'complete' }],
}],
run: {
status: 'idle',
runId: 'run-1',
settledAt: Date.parse('2026-08-24T08:00:00.000Z'),
terminalReason: 'completed',
},
});
await flushPendingAgentSessionSync();
expect(pushSessionDataMock).not.toHaveBeenCalled();
});
it('never uploads a pending snapshot under a different authenticated account', async () => {
queueAgentSessionSync('prj_1', 'ses_1', [
{ id: 'user-1', role: 'user', content: '账号 A 的问题' },