fix(chat): reconcile reply recovery with continuous agent conversations
This commit is contained in:
1 parent
44b16f8fbd
commit
cafebca057
13 files changed
+159
-34
No files matched your search
@@ -41,6 +41,37 @@ const props = { projectId: 'project-a', projectName: '天气', sourceId: 'source
|
||||
async function mount() { let view!: ReturnType<typeof render>; await act(async () => { view = render(<TeacherChatPanel {...props} />); }); return view; }
|
||||
|
||||
describe('continuous agent panel', () => {
|
||||
it('retries incomplete prose only in its original project/source and keeps current drafts and one send identity', async () => {
|
||||
const original = { ...request('broken', '现在项目是什么阶段?'), response: '它早就不是', replyIncomplete: true,
|
||||
references: [{ kind: 'code' as const, text: '原项目代码' }] };
|
||||
api.conversation.mockResolvedValue({ topic: topic([original]), before: null });
|
||||
api.seenConversation.mockImplementation(async () => topic([original]));
|
||||
let finish!: (value: TeacherTopic) => void;
|
||||
api.sendConversation.mockImplementation(() => new Promise<TeacherTopic>(resolve => { finish = resolve; }));
|
||||
const view = await mount();
|
||||
expect(screen.getByRole('status')).toHaveTextContent('这次回复未能完整显示');
|
||||
expect(screen.queryByTestId('teacher-reply')).toBeNull();
|
||||
expect(api.sendConversation).not.toHaveBeenCalled();
|
||||
fireEvent.change(screen.getByRole('textbox'), { target: { value: '仍在编辑的草稿' } });
|
||||
view.rerender(<TeacherChatPanel {...props} projectId="project-b" sourceId="source-b" />);
|
||||
expect(screen.getByRole('button', { name: '重新回答' })).toBeDisabled();
|
||||
view.rerender(<TeacherChatPanel {...props} sourceId="another-source" />);
|
||||
expect(screen.getByRole('button', { name: '重新回答' })).toBeDisabled();
|
||||
view.rerender(<TeacherChatPanel {...props} />);
|
||||
const retry = screen.getByRole('button', { name: '重新回答' });
|
||||
fireEvent.click(retry); fireEvent.click(retry);
|
||||
expect(api.sendConversation).toHaveBeenCalledTimes(1);
|
||||
const sent = api.sendConversation.mock.calls[0][1];
|
||||
expect(sent).toEqual({ requestId: expect.any(String), projectId: 'project-a', sourceConversationId: 'source-a',
|
||||
text: original.text, references: original.references });
|
||||
expect(sent.requestId).not.toBe(original.id);
|
||||
fireEvent.change(screen.getByRole('textbox'), { target: { value: '等待时补充的草稿' } });
|
||||
await act(async () => finish({ ...topic([original, { ...request(sent.requestId), response: '完整回答' }]), revision: 2 }));
|
||||
expect(screen.getByText('完整回答')).toBeVisible();
|
||||
expect(screen.getByRole('textbox')).toHaveValue('等待时补充的草稿');
|
||||
expect(JSON.parse(localStorage.getItem(`makelore-consultation-draft:kid-${identity.id}:agent:agent-a`)!)).toMatchObject({ text: '等待时补充的草稿' });
|
||||
});
|
||||
|
||||
it('opens one chat without topic controls or creating a topic, and preserves it across project switches', async () => {
|
||||
const view = await mount();
|
||||
expect(screen.queryByRole('button', { name: '智能体新话题' })).toBeNull();
|
||||
|
||||
Reference in new issue
Block a user