mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-07-10 02:30:15 +00:00
0bfa9d2ed4
* fix(coding-agent): persist API mode per session * docs(chat-chain): document coding agent API mode persistence --------- Co-authored-by: x1051445024 <你的GitHub注册邮箱>
123 lines
3.5 KiB
TypeScript
123 lines
3.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
const mocks = vi.hoisted(() => {
|
|
const updateParentRun = vi.fn()
|
|
const insertSessionRun = vi.fn()
|
|
const insertMessageRun = vi.fn(() => ({ lastInsertRowid: 42 }))
|
|
const updateForkPointRun = vi.fn()
|
|
const selectSessionGet = vi.fn()
|
|
const prepare = vi.fn((sql: string) => {
|
|
if (sql.includes('UPDATE sessions SET ended_at')) return { run: updateParentRun }
|
|
if (sql.includes('UPDATE sessions SET fork_point_message_id')) return { run: updateForkPointRun }
|
|
if (sql.includes('INSERT INTO sessions')) return { run: insertSessionRun }
|
|
if (sql.includes('INSERT INTO messages')) return { run: insertMessageRun }
|
|
if (sql.includes('SELECT * FROM sessions WHERE id = ?')) return { get: selectSessionGet }
|
|
throw new Error(`unexpected SQL: ${sql}`)
|
|
})
|
|
const exec = vi.fn()
|
|
const db = { prepare, exec }
|
|
return {
|
|
updateParentRun,
|
|
insertSessionRun,
|
|
insertMessageRun,
|
|
updateForkPointRun,
|
|
selectSessionGet,
|
|
prepare,
|
|
exec,
|
|
db,
|
|
copyCompressionSnapshot: vi.fn(),
|
|
}
|
|
})
|
|
|
|
vi.mock('../../packages/server/src/db/index', () => ({
|
|
isSqliteAvailable: vi.fn(() => true),
|
|
getDb: vi.fn(() => mocks.db),
|
|
}))
|
|
|
|
vi.mock('../../packages/server/src/db/hermes/compression-snapshot', () => ({
|
|
copyCompressionSnapshot: mocks.copyCompressionSnapshot,
|
|
}))
|
|
|
|
describe('createBranchedSession', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
mocks.selectSessionGet.mockReturnValue({
|
|
id: 'child-session',
|
|
profile: 'default',
|
|
source: 'cli',
|
|
agent: 'hermes',
|
|
agent_mode: '',
|
|
agent_session_id: '',
|
|
agent_native_session_id: '',
|
|
user_id: null,
|
|
model: 'openai/gpt-5.4',
|
|
provider: 'openai-codex',
|
|
api_mode: 'chat_completions',
|
|
title: 'Forked child',
|
|
parent_session_id: 'parent-session',
|
|
fork_point_message_id: '42',
|
|
started_at: 123,
|
|
ended_at: null,
|
|
end_reason: null,
|
|
message_count: 1,
|
|
tool_call_count: 0,
|
|
input_tokens: 0,
|
|
output_tokens: 0,
|
|
cache_read_tokens: 0,
|
|
cache_write_tokens: 0,
|
|
reasoning_tokens: 0,
|
|
billing_provider: null,
|
|
estimated_cost_usd: 0,
|
|
actual_cost_usd: null,
|
|
cost_status: '',
|
|
preview: '',
|
|
last_active: 123,
|
|
workspace: '/repo',
|
|
})
|
|
})
|
|
|
|
it('copies the parent compression snapshot inside the fork transaction', async () => {
|
|
const { createBranchedSession } = await import('../../packages/server/src/db/hermes/session-store')
|
|
|
|
const result = createBranchedSession({
|
|
parent_session_id: 'parent-session',
|
|
id: 'child-session',
|
|
profile: 'default',
|
|
source: 'cli',
|
|
agent: 'hermes',
|
|
model: 'openai/gpt-5.4',
|
|
provider: 'openai-codex',
|
|
api_mode: 'chat_completions',
|
|
title: 'Forked child',
|
|
workspace: '/repo',
|
|
ended_at: 123,
|
|
last_active: 123,
|
|
messages: [
|
|
{ role: 'user', content: 'hello', timestamp: 100 },
|
|
],
|
|
})
|
|
|
|
expect(result?.id).toBe('child-session')
|
|
expect(mocks.exec).toHaveBeenNthCalledWith(1, 'BEGIN')
|
|
expect(mocks.copyCompressionSnapshot).toHaveBeenCalledWith('parent-session', 'child-session')
|
|
expect(mocks.updateForkPointRun).toHaveBeenCalledWith('42', 'child-session')
|
|
expect(mocks.exec).toHaveBeenLastCalledWith('COMMIT')
|
|
expect(mocks.insertMessageRun).toHaveBeenCalledWith(
|
|
'child-session',
|
|
'user',
|
|
'hello',
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
100,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
null,
|
|
)
|
|
})
|
|
})
|