v0.6.0: beautifului 整合 + 会话/工作区/队列/权限/命令/附件全链路

- beautifului.dev 组件直连:Sidebar Nav、Tool Chips、Approval Card(抽屉化)、Streaming/Thinking、Code Block、Selection Actions、Prompt Bar、Search
This commit is contained in:
Rick Ye
2026-09-06 09:57:14 +08:00
parent 3c2e9e96c5
commit a5951849c8
96 changed files with 11828 additions and 4649 deletions
+103
View File
@@ -0,0 +1,103 @@
// 复现渲染层"输出一闪而过":用与 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)