mirror of
https://github.com/EKKOLearnAI/hermes-web-ui.git
synced 2026-05-25 21:40:13 +00:00
9a9416c99c
* feat: support profile-aware group chat bridge flows * feat: route cron jobs through hermes cli * Fix group chat routing and isolate bridge tests * Add Grok image-to-video media skill * Default Grok videos to media directory * Fix bridge profile fallback and cron repeat clearing * Refine bridge chat and gateway platform handling * Filter bridge tool-call text deltas * Preserve structured bridge chat history * Prepare beta release build artifacts * Fix Windows run profile resolution * Fix Windows path compatibility checks * Fix profile-scoped model page display * Hide Windows subprocess windows for jobs and updates * Hide Windows file backend subprocess windows * Avoid Windows gateway restart lock conflicts * Treat Windows gateway lock as running on startup * Force release Windows gateway lock on restart * Tighten Windows gateway lock cleanup * Update chat e2e source expectation * Bump package version to 0.5.30 --------- Co-authored-by: Codex <codex@openai.com>
119 lines
3.8 KiB
TypeScript
119 lines
3.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { mount } from '@vue/test-utils'
|
|
import { createPinia, setActivePinia } from 'pinia'
|
|
import { defineComponent } from 'vue'
|
|
|
|
vi.mock('vue-i18n', () => ({
|
|
useI18n: () => ({
|
|
t: (key: string) => key,
|
|
}),
|
|
}))
|
|
|
|
vi.mock('@/composables/useTheme', () => ({
|
|
useTheme: () => ({ isDark: false }),
|
|
}))
|
|
|
|
import MessageList from '@/components/hermes/chat/MessageList.vue'
|
|
import HistoryMessageList from '@/components/hermes/chat/HistoryMessageList.vue'
|
|
import { useChatStore, type Message, type Session } from '@/stores/hermes/chat'
|
|
import { useToolTraceVisibility } from '@/composables/useToolTraceVisibility'
|
|
|
|
const MessageItemStub = defineComponent({
|
|
name: 'MessageItem',
|
|
props: {
|
|
message: { type: Object, required: true },
|
|
highlight: { type: Boolean, default: false },
|
|
},
|
|
template: '<div class="stub-message" :data-role="message.role" :data-id="message.id">{{ message.toolName || message.content }}</div>',
|
|
})
|
|
|
|
function makeSession(messages: Message[]): Session {
|
|
return {
|
|
id: 'session-1',
|
|
title: 'Tool trace visibility',
|
|
messages,
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
}
|
|
}
|
|
|
|
const sampleMessages: Message[] = [
|
|
{ id: 'user-1', role: 'user', content: 'inspect repo', timestamp: 1 },
|
|
{ id: 'tool-named', role: 'tool', content: '', timestamp: 2, toolName: 'read_file', toolResult: 'ok', toolStatus: 'done' },
|
|
{ id: 'tool-internal', role: 'tool', content: '', timestamp: 3, toolResult: 'internal', toolStatus: 'done' },
|
|
{ id: 'assistant-1', role: 'assistant', content: 'done', timestamp: 4 },
|
|
]
|
|
|
|
describe('tool trace visibility', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
localStorage.removeItem('hermes_show_tool_calls')
|
|
useToolTraceVisibility().setToolTraceVisible(true)
|
|
})
|
|
|
|
function mountLiveList() {
|
|
const chatStore = useChatStore()
|
|
chatStore.activeSessionId = 'session-1'
|
|
chatStore.activeSession = makeSession(sampleMessages)
|
|
chatStore.abortState = { aborting: true, synced: false }
|
|
|
|
return mount(MessageList, {
|
|
global: {
|
|
stubs: {
|
|
MessageItem: MessageItemStub,
|
|
Transition: false,
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
it('shows named transcript and live tool traces by default while keeping unnamed internal tools hidden', () => {
|
|
const wrapper = mountLiveList()
|
|
|
|
expect(wrapper.findAll('.stub-message').map(node => node.attributes('data-id'))).toEqual([
|
|
'user-1',
|
|
'tool-named',
|
|
'assistant-1',
|
|
])
|
|
expect(wrapper.findAll('.tool-call-name').map(node => node.text())).toContain('read_file')
|
|
})
|
|
|
|
it('applies the same default-visible rule to history sessions', () => {
|
|
const wrapper = mount(HistoryMessageList, {
|
|
props: { session: makeSession(sampleMessages) },
|
|
global: {
|
|
stubs: { MessageItem: MessageItemStub },
|
|
},
|
|
})
|
|
|
|
expect(wrapper.findAll('.stub-message').map(node => node.attributes('data-id'))).toEqual([
|
|
'user-1',
|
|
'tool-named',
|
|
'assistant-1',
|
|
])
|
|
})
|
|
|
|
it('hides named transcript traces when the toggle is off while keeping live tool stream visible', () => {
|
|
useToolTraceVisibility().setToolTraceVisible(false)
|
|
|
|
const liveWrapper = mountLiveList()
|
|
expect(liveWrapper.findAll('.stub-message').map(node => node.attributes('data-id'))).toEqual([
|
|
'user-1',
|
|
'assistant-1',
|
|
])
|
|
expect(liveWrapper.findAll('.tool-call-name').map(node => node.text())).toContain('read_file')
|
|
|
|
const historyWrapper = mount(HistoryMessageList, {
|
|
props: { session: makeSession(sampleMessages) },
|
|
global: {
|
|
stubs: { MessageItem: MessageItemStub },
|
|
},
|
|
})
|
|
expect(historyWrapper.findAll('.stub-message').map(node => node.attributes('data-id'))).toEqual([
|
|
'user-1',
|
|
'assistant-1',
|
|
])
|
|
})
|
|
})
|