/** * pi SDK 会话管理冒烟测试(v0.2.0) * 验证:runtime 创建、list、newSession、switchSession(历史恢复)、rename、删除(回收站)。 */ import { createAgentSessionRuntime, createAgentSessionServices, createAgentSessionFromServices, getAgentDir, SessionManager } from '@earendil-works/pi-coding-agent' import { homedir } from 'node:os' import { join } from 'node:path' const cwd = homedir() const agentDir = getAgentDir() console.log('[smoke2] listing sessions (cwd=%s)...', cwd) const before = await SessionManager.list(cwd) console.log('[smoke2] found %d sessions', before.length) const initialServices = await createAgentSessionServices({ cwd, agentDir }) const factory = async ({ cwd: nextCwd, agentDir: nextAgentDir, sessionManager, sessionStartEvent }) => { const services = nextCwd === initialServices.cwd && nextAgentDir === initialServices.agentDir ? initialServices : await createAgentSessionServices({ cwd: nextCwd, agentDir: nextAgentDir }) const result = await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent }) return { ...result, services, diagnostics: services.diagnostics } } const sessionManager = SessionManager.create(cwd) const runtime = await createAgentSessionRuntime(factory, { cwd, agentDir, sessionManager }) let rebindCount = 0 runtime.setRebindSession(async () => { rebindCount += 1 }) console.log('[smoke2] runtime ready, session=%s', runtime.session.sessionId) // 重命名 runtime.session.setSessionName('smoke-测试会话') console.log('[smoke2] renamed to: %s', runtime.session.sessionName) // 会话里追加用户+助手消息(直接写会话文件,不触发 LLM) // pi 约定:只有出现 assistant 消息后才会真正落盘(避免空会话残留文件) runtime.session.sessionManager.appendMessage({ role: 'user', content: '这是一条冒烟测试消息', timestamp: Date.now() }) runtime.session.sessionManager.appendMessage({ role: 'assistant', content: [{ type: 'text', text: '冒烟回复(不经过 LLM)' }], api: 'openai-completions', provider: 'smoke', model: 'smoke-model', usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0, cost: 0 }, stopReason: 'stop', timestamp: Date.now() }) console.log('[smoke2] messages in session:', runtime.session.messages.length) const listAfter = await SessionManager.list(cwd) const mine = listAfter.find((s) => s.name === 'smoke-测试会话' || s.firstMessage.includes('冒烟测试')) console.log('[smoke2] session visible in list: %s (total %d)', Boolean(mine), listAfter.length) if (mine) { console.log('[smoke2] meta: name=%s firstMessage=%s count=%d', mine.name, JSON.stringify(mine.firstMessage.slice(0, 30)), mine.messageCount) // 新会话(切换) await runtime.newSession() console.log('[smoke2] newSession ok, rebind=%d, new id=%s, messages=%d', rebindCount, runtime.session.sessionId, runtime.session.messages.length) // 切回 await runtime.switchSession(mine.path) console.log( '[smoke2] switch back ok, rebind=%d, id=%s, messages restored=%d, name=%s', rebindCount, runtime.session.sessionId, runtime.session.messages.length, runtime.session.sessionName ?? '(none)' ) } await runtime.dispose() console.log('[smoke2] done') process.exit(0)