// 复现渲染层"输出一闪而过":用与 agent-service.ts 相同的 SDK 调用链, // 订阅全部事件并打印事件序列与消息对象结构。 import os from 'node:os' import { createAgentSessionRuntime, createAgentSessionServices, createAgentSessionFromServices, getAgentDir, SessionManager } from '@earendil-works/pi-coding-agent' const cwd = os.homedir() const agentDir = getAgentDir() const services = await createAgentSessionServices({ cwd, agentDir }) const factory = async (opts) => { const result = await createAgentSessionFromServices({ services, sessionManager: opts.sessionManager, sessionStartEvent: opts.sessionStartEvent }) return { ...result, services, diagnostics: services.diagnostics } } const sessionManager = SessionManager.continueRecent(cwd) const runtime = await createAgentSessionRuntime(factory, { cwd, agentDir, sessionManager }) const session = runtime.session let rebindCount = 0 runtime.setRebindSession(async (s) => { rebindCount++ console.log(`\n>>> REBIND fired (#${rebindCount}) — 渲染层会收到 session_switched,messages.length=${s.messages.length}`) }) session.subscribe((event) => { switch (event.type) { case 'message_start': console.log('EVT message_start role=', JSON.stringify(event.message?.role)) break case 'message_update': { const inner = event.assistantMessageEvent if (inner) { if (inner.type.endsWith('_delta')) { process.stdout.write(`.`) } else { console.log(`EVT message_update ${inner.type}`) } } break } case 'message_end': { const m = event.message console.log('\nEVT message_end role=', m?.role) console.log(' message keys:', Object.keys(m ?? {})) try { JSON.stringify(m) console.log(' JSON.stringify: OK, length=', JSON.stringify(m).length) } catch (err) { console.log(' JSON.stringify FAILED ->', err.message, '(toCloneable 会变成 null → 渲染层消息变空!)') } if (m?.role === 'assistant') { console.log(' stopReason=', m.stopReason, ' errorMessage=', m.errorMessage) console.log(' content types=', (m.content ?? []).map((b) => b.type).join(',')) for (const b of m.content ?? []) { if (b.type === 'text') console.log(' text block:', JSON.stringify(b.text).slice(0, 200)) } } break } case 'agent_end': console.log(`\nEVT agent_end willRetry=${event.willRetry} messages=${event.messages?.length}`) break default: console.log('EVT', event.type) } }) console.log('--- session:', session.sessionId, 'messages:', session.messages.length) console.log('--- model:', session.model?.provider + '/' + session.model?.id) console.log('--- sending "hi" ...') try { await session.prompt('hi') console.log('\n--- prompt resolved') } catch (err) { console.log('\n--- prompt THREW:', err?.message) } // 等待 agent_settled 之后的异步收尾 await new Promise((r) => setTimeout(r, 1500)) console.log('\n=== final session.messages ===') for (const [i, m] of session.messages.entries()) { const blocks = Array.isArray(m.content) ? m.content.map((b) => b.type).join(',') : typeof m.content === 'string' ? 'str:' + m.content.slice(0, 30) : '??' console.log(`#${i} ${m.role} [${blocks}]`) } console.log('\nrebindCount=', rebindCount) process.exit(0)