initialize Electron desktop app and remove unused files
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
import { describe, expect, it, vi, beforeEach } from 'vitest'
|
||||
import { applyResponseStreamEvent, flushResponseRunToDb } from '../../packages/server/src/services/hermes/run-chat/response-stream'
|
||||
import type { SessionState } from '../../packages/server/src/services/hermes/run-chat/types'
|
||||
|
||||
const { addMessageMock } = vi.hoisted(() => ({
|
||||
addMessageMock: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('../../packages/server/src/db/hermes/session-store', () => ({
|
||||
addMessage: addMessageMock,
|
||||
}))
|
||||
|
||||
describe('response stream reasoning storage', () => {
|
||||
beforeEach(() => {
|
||||
addMessageMock.mockReset()
|
||||
})
|
||||
|
||||
it('buffers reasoning without creating an empty assistant message before text arrives', () => {
|
||||
const state: SessionState = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.created', {
|
||||
response: { id: 'resp-1', status: 'in_progress' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.reasoning.delta', {
|
||||
delta: 'think first',
|
||||
})
|
||||
|
||||
expect(state.messages).toEqual([])
|
||||
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_text.delta', {
|
||||
delta: 'answer',
|
||||
})
|
||||
|
||||
expect(state.messages).toEqual([
|
||||
expect.objectContaining({
|
||||
role: 'assistant',
|
||||
content: 'answer',
|
||||
reasoning: 'think first',
|
||||
reasoning_content: 'think first',
|
||||
}),
|
||||
])
|
||||
})
|
||||
|
||||
it('keeps reasoning deltas in session memory across tool boundaries', () => {
|
||||
const state: SessionState = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.created', {
|
||||
response: { id: 'resp-1', status: 'in_progress' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.reasoning.delta', {
|
||||
delta: 'think before. ',
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_text.delta', {
|
||||
delta: 'Before tool.',
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_item.done', {
|
||||
item: { type: 'function_call', call_id: 'tool-1', name: 'Bash', arguments: '{}' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.reasoning.delta', {
|
||||
delta: 'think after. ',
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_item.done', {
|
||||
item: { type: 'function_call_output', call_id: 'tool-1', output: 'tool output' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_text.delta', {
|
||||
delta: 'After tool.',
|
||||
})
|
||||
|
||||
expect(state.messages.map(message => message.role)).toEqual(['assistant', 'assistant', 'tool', 'assistant'])
|
||||
expect(state.messages[0]).toMatchObject({
|
||||
role: 'assistant',
|
||||
content: 'Before tool.',
|
||||
reasoning: 'think before. think after. ',
|
||||
reasoning_content: 'think before. think after. ',
|
||||
})
|
||||
expect(state.messages[3]).toMatchObject({
|
||||
role: 'assistant',
|
||||
content: 'After tool.',
|
||||
})
|
||||
})
|
||||
|
||||
it('flushes reasoning fields to message storage', () => {
|
||||
const state: SessionState = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.created', {
|
||||
response: { id: 'resp-1', status: 'in_progress' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.reasoning.delta', {
|
||||
delta: 'stored thinking',
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.output_text.delta', {
|
||||
delta: 'answer',
|
||||
})
|
||||
|
||||
flushResponseRunToDb(state, 'session-1')
|
||||
|
||||
expect(addMessageMock).toHaveBeenCalledWith(expect.objectContaining({
|
||||
session_id: 'session-1',
|
||||
role: 'assistant',
|
||||
content: 'answer',
|
||||
reasoning: 'stored thinking',
|
||||
reasoning_content: 'stored thinking',
|
||||
}))
|
||||
})
|
||||
|
||||
it('deduplicates final reasoning snapshots after streamed reasoning deltas', () => {
|
||||
const state: SessionState = { messages: [], isWorking: false, events: [], queue: [] }
|
||||
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.created', {
|
||||
response: { id: 'resp-1', status: 'in_progress' },
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.reasoning.delta', {
|
||||
delta: 'Need inspect.',
|
||||
})
|
||||
applyResponseStreamEvent(state, 'session-1', 'run-1', 'response.completed', {
|
||||
response: {
|
||||
id: 'resp-1',
|
||||
output: [
|
||||
{ type: 'reasoning', summary: [{ text: 'Need inspect.' }] },
|
||||
{ type: 'message', content: [{ type: 'output_text', text: 'answer' }] },
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
expect(state.messages[0]).toMatchObject({
|
||||
content: 'answer',
|
||||
reasoning: 'Need inspect.',
|
||||
reasoning_content: 'Need inspect.',
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user