/** * 回合事件时序冒烟:验证 agent_settled 是否会在多回合工作(含 >600ms 慢工具)中途发出。 * 背景:渲染层回合折叠绑定 agent_settled(54b99a1),若 settled 在回合间被发出, * 折叠会随 live 抖动反复展开/收起。本脚本在隔离的临时 cwd 下跑一轮真实多回合工作。 * 运行:node scripts/smoke-turn-events.mjs */ import { mkdtempSync } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { createAgentSessionServices, createAgentSessionFromServices, defineTool, getAgentDir, SessionManager } from '@earendil-works/pi-coding-agent' import { Type } from '@earendil-works/pi-ai' const cwd = mkdtempSync(join(tmpdir(), 'aso-smoke-')) const t0 = Date.now() const ts = () => `${((Date.now() - t0) / 1000).toFixed(2).padStart(7)}s` const slowTool = defineTool({ name: 'slow_probe', label: '慢探针', description: '等待 1500ms 后返回 done(模拟浏览器工具耗时,测试回合折叠时序)', promptSnippet: 'slow_probe: 测试用慢工具', parameters: Type.Object({}), async execute() { await new Promise((r) => setTimeout(r, 1500)) return { content: [{ type: 'text', text: 'done' }] } } }) const loggingExtension = { name: 'smoke-log', factory: (pi) => { for (const type of ['session_start', 'agent_start', 'agent_end', 'agent_settled', 'message_start', 'message_end', 'tool_call']) { pi.on(type, (event) => console.log(ts(), `[ext] ${type}${event?.toolName ? ` (${event.toolName})` : ''}`)) } } } const toolExtension = { name: 'smoke-tools', factory: (pi) => { pi.registerTool(slowTool) } } const services = await createAgentSessionServices({ cwd, agentDir: getAgentDir(), resourceLoaderOptions: { extensionFactories: [loggingExtension, toolExtension] } }) const sessionManager = SessionManager.continueRecent(cwd) const { session } = await createAgentSessionFromServices({ services, sessionManager }) const unsubscribe = session.subscribe((event) => { const message = event.message ?? {} const detail = event.type === 'tool_execution_start' || event.type === 'tool_execution_end' ? ` (${event.toolName})` : event.type === 'message_start' || event.type === 'message_end' ? ` (role=${message.role ?? '?'})` : '' console.log(ts(), `[session] ${event.type}${detail}`) }) console.log(ts(), '--- prompt 开始:两次串行 slow_probe + 总结 ---') try { await session.prompt('调用 slow_probe 工具两次(串行调用,不要并行),然后只回复"完成"两个字。') console.log(ts(), '--- prompt 返回(整个工作结束) ---') } finally { unsubscribe() await session.abort?.().catch(() => undefined) process.exit(0) }