openpencil/tests/helpers/chat/reasoning.ts
Danila Poyarkov b4e479d9d0
feat: persist AI conversations and add chat history (#661)
* feat: persist AI conversations and add chat history

Store transcripts and attachment previews in IndexedDB, separate conversation history from transport lifetime, and add document-aware switching with shared Storybook coverage. Preserve interrupted activity and guard stale writes and async switches.

* test: group chat history tests by domain

* feat: simplify chat history navigation and diagnostics

Use a compact header with searchable document-scoped history and a correctly anchored conversation menu. Move diagnostic copying into the menu with copy-result feedback, and separate Storybook fixtures from composition.

* fix: address chat history review findings

* test: cover harness shutdown and restored chat scrolling

* fix: preserve Portless proxy port in MCP routes

* docs: clarify UI animation conventions

* feat: configure reasoning display and animate disclosure

* fix: separate transcript following from reasoning disclosure

* fix: restore selected chat after document recovery

* refactor: separate chat history persistence and sessions

* style: format reasoning story imports
2026-09-08 11:19:07 +03:00

46 lines
1.6 KiB
TypeScript

import type { Page } from '@playwright/test'
/** Hold reasoning open until the test explicitly completes the turn. */
export async function installReasoningTransport(page: Page): Promise<void> {
await page.evaluate(() => {
window.openPencil?.setChatTransport(() => ({
async sendMessages() {
return new ReadableStream({
start(controller) {
controller.enqueue({ type: 'start', messageId: crypto.randomUUID() })
controller.enqueue({ type: 'reasoning-start', id: 'thinking' })
controller.enqueue({
type: 'reasoning-delta',
id: 'thinking',
delta: 'Inspecting the selected layout.'
})
window.addEventListener(
'finish-test-reasoning',
() => {
controller.enqueue({ type: 'reasoning-end', id: 'thinking' })
controller.enqueue({ type: 'text-start', id: 'answer' })
controller.enqueue({
type: 'text-delta',
id: 'answer',
delta: 'Finished inspecting the layout.'
})
controller.enqueue({ type: 'text-end', id: 'answer' })
controller.enqueue({ type: 'finish', finishReason: 'stop' })
controller.close()
},
{ once: true }
)
}
})
},
async reconnectToStream() {
return null
}
}))
})
}
export async function finishReasoning(page: Page): Promise<void> {
await page.evaluate(() => window.dispatchEvent(new Event('finish-test-reasoning')))
}