mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
* test(codex): add web event rendering harness * fix(codex): surface plan updates in web * fix(codex): render MCP tool calls in web * fix(codex): improve terminal and context display * fix(codex): format token usage events * fix(codex): show status context in web * fix(codex): preserve tool result errors
160 lines
4.9 KiB
TypeScript
Executable File
160 lines
4.9 KiB
TypeScript
Executable File
#!/usr/bin/env bun
|
|
import { Database } from 'bun:sqlite'
|
|
import { mkdirSync, rmSync } from 'node:fs'
|
|
import { dirname, resolve } from 'node:path'
|
|
import { Store } from '../../hub/src/store'
|
|
|
|
function argValue(name: string, fallback?: string): string | undefined {
|
|
const prefix = `${name}=`
|
|
const directIndex = process.argv.indexOf(name)
|
|
if (directIndex >= 0) return process.argv[directIndex + 1]
|
|
const direct = process.argv.find((arg) => arg.startsWith(prefix))
|
|
return direct ? direct.slice(prefix.length) : fallback
|
|
}
|
|
|
|
const dbPath = resolve(argValue('--db', process.env.DB_PATH ?? '/tmp/hapi-dev-codex-web/hapi.db')!)
|
|
const reset = process.argv.includes('--reset')
|
|
const namespace = argValue('--namespace', 'default')!
|
|
const tag = argValue('--tag', 'codex-web-fixture')!
|
|
const now = Date.now()
|
|
|
|
mkdirSync(dirname(dbPath), { recursive: true })
|
|
if (reset) {
|
|
rmSync(dbPath, { force: true })
|
|
rmSync(`${dbPath}-wal`, { force: true })
|
|
rmSync(`${dbPath}-shm`, { force: true })
|
|
}
|
|
|
|
const store = new Store(dbPath)
|
|
const session = store.sessions.getOrCreateSession(tag, {
|
|
path: '/tmp/hapi-fixture-workspace',
|
|
host: 'hapi-dev-fixture',
|
|
version: 'dev',
|
|
flavor: 'codex',
|
|
codexSessionId: 'codex-fixture-session',
|
|
name: 'Codex Web Fixture'
|
|
}, {
|
|
controlledByUser: false,
|
|
requests: {},
|
|
completedRequests: {}
|
|
}, namespace, 'gpt-5.4', undefined, 'xhigh')
|
|
|
|
const messages = [
|
|
{
|
|
localId: 'fixture-user-1',
|
|
content: {
|
|
role: 'user',
|
|
content: { type: 'text', text: 'Fixture request: show Codex reasoning, MCP calls, and plan status.' },
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
},
|
|
{
|
|
localId: 'fixture-agent-message',
|
|
content: {
|
|
role: 'agent',
|
|
content: {
|
|
type: 'codex',
|
|
data: {
|
|
type: 'message',
|
|
message: 'Codex fixture response visible in HAPI Web.',
|
|
id: 'fixture-msg-1'
|
|
}
|
|
},
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
},
|
|
{
|
|
localId: 'fixture-reasoning',
|
|
content: {
|
|
role: 'agent',
|
|
content: {
|
|
type: 'codex',
|
|
data: {
|
|
type: 'reasoning',
|
|
message: 'Fixture reasoning detail: inspect event normalization before rendering.',
|
|
id: 'fixture-reasoning-1'
|
|
}
|
|
},
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
},
|
|
{
|
|
localId: 'fixture-mcp-call',
|
|
content: {
|
|
role: 'agent',
|
|
content: {
|
|
type: 'codex',
|
|
data: {
|
|
type: 'tool-call',
|
|
name: 'mcp__fixture__lookup_context',
|
|
callId: 'fixture-mcp-call-1',
|
|
input: {
|
|
server: 'fixture-mcp-server',
|
|
tool: 'lookup_context',
|
|
query: 'codex plan visibility'
|
|
},
|
|
id: 'fixture-tool-1'
|
|
}
|
|
},
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
},
|
|
{
|
|
localId: 'fixture-mcp-result',
|
|
content: {
|
|
role: 'agent',
|
|
content: {
|
|
type: 'codex',
|
|
data: {
|
|
type: 'tool-call-result',
|
|
callId: 'fixture-mcp-call-1',
|
|
output: {
|
|
server: 'fixture-mcp-server',
|
|
tool: 'lookup_context',
|
|
result: 'Fixture MCP result visible in Web.'
|
|
},
|
|
id: 'fixture-tool-result-1'
|
|
}
|
|
},
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
},
|
|
{
|
|
localId: 'fixture-plan-update',
|
|
content: {
|
|
role: 'agent',
|
|
content: {
|
|
type: 'codex',
|
|
data: {
|
|
type: 'plan_update',
|
|
plan: [
|
|
{ step: 'Inspect event stream', status: 'completed' },
|
|
{ step: 'Render plan card', status: 'in_progress' },
|
|
{ step: 'Verify web DOM', status: 'pending' }
|
|
],
|
|
id: 'fixture-plan-update-1'
|
|
}
|
|
},
|
|
meta: { sentFrom: 'fixture' }
|
|
}
|
|
}
|
|
]
|
|
|
|
for (const message of messages) {
|
|
store.messages.addMessage(session.id, message.content, message.localId)
|
|
}
|
|
|
|
// Make the fixture visually prominent in session lists without needing a live CLI heartbeat.
|
|
const db = new Database(dbPath)
|
|
db.prepare('UPDATE sessions SET active = 1, active_at = ?, updated_at = ? WHERE id = ?').run(now, now, session.id)
|
|
db.close()
|
|
|
|
console.log(JSON.stringify({
|
|
dbPath,
|
|
sessionId: session.id,
|
|
namespace,
|
|
tag,
|
|
urlPath: `/sessions/${session.id}`,
|
|
messageCount: messages.length
|
|
}, null, 2))
|