Refine agents command center topology visuals
Strengthen the Ultron command center with clearer blueprint-style hierarchy, embedded route telemetry, and test coverage for active path visualization. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
121
frontend/src/pages/agents/agentsPage.test.ts
Normal file
121
frontend/src/pages/agents/agentsPage.test.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
getHierarchyStats: vi.fn(),
|
||||
updateConfig: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/api/agent', () => ({
|
||||
agentApi: {
|
||||
getHierarchyStats: mocks.getHierarchyStats,
|
||||
updateConfig: mocks.updateConfig,
|
||||
},
|
||||
}))
|
||||
|
||||
import AgentsPage from './index.vue'
|
||||
|
||||
const hierarchyStats = {
|
||||
main_agents: [
|
||||
{
|
||||
agent_id: 'planner',
|
||||
call_count: 12,
|
||||
current_task: null,
|
||||
status: 'idle',
|
||||
sub_commanders: [
|
||||
{ agent_id: 'planner_scope', call_count: 4, current_task: null, status: 'idle' },
|
||||
{ agent_id: 'planner_steps', call_count: 9, current_task: '拆解执行步骤', status: 'active' },
|
||||
],
|
||||
},
|
||||
{
|
||||
agent_id: 'executor',
|
||||
call_count: 8,
|
||||
current_task: null,
|
||||
status: 'idle',
|
||||
sub_commanders: [
|
||||
{ agent_id: 'executor_tasks', call_count: 8, current_task: null, status: 'idle' },
|
||||
{ agent_id: 'executor_forum', call_count: 4, current_task: null, status: 'idle' },
|
||||
],
|
||||
},
|
||||
{
|
||||
agent_id: 'librarian',
|
||||
call_count: 5,
|
||||
current_task: null,
|
||||
status: 'idle',
|
||||
sub_commanders: [
|
||||
{ agent_id: 'librarian_retrieval', call_count: 5, current_task: null, status: 'idle' },
|
||||
{ agent_id: 'librarian_graph', call_count: 2, current_task: null, status: 'idle' },
|
||||
],
|
||||
},
|
||||
{
|
||||
agent_id: 'analyst',
|
||||
call_count: 3,
|
||||
current_task: null,
|
||||
status: 'idle',
|
||||
sub_commanders: [
|
||||
{ agent_id: 'analyst_progress', call_count: 2, current_task: null, status: 'idle' },
|
||||
{ agent_id: 'analyst_insights', call_count: 3, current_task: null, status: 'idle' },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
describe('agents page pcb command center', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
vi.useFakeTimers()
|
||||
mocks.getHierarchyStats.mockResolvedValue(hierarchyStats)
|
||||
mocks.updateConfig.mockResolvedValue({})
|
||||
})
|
||||
|
||||
it('shows commander skills and active route telemetry for an active sub commander path', async () => {
|
||||
const wrapper = mount(AgentsPage)
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
|
||||
const skillsPanel = wrapper.get('[data-testid="commander-skills"]')
|
||||
expect(skillsPanel.text()).toContain('指挥官技能')
|
||||
expect(skillsPanel.text()).toContain('路径拆解')
|
||||
|
||||
const activeSkill = wrapper.get('[data-testid="commander-skill-skill_planner"]')
|
||||
expect(activeSkill.classes()).toContain('active')
|
||||
|
||||
const plannerBus = wrapper.get('[data-testid="bus-link-planner"]')
|
||||
expect(plannerBus.classes()).toContain('energized')
|
||||
|
||||
const plannerStepsBranch = wrapper.get('[data-testid="sub-link-planner_steps"]')
|
||||
expect(plannerStepsBranch.classes()).toContain('energized')
|
||||
|
||||
const routeTelemetry = wrapper.get('[data-testid="route-telemetry"]')
|
||||
expect(routeTelemetry.text()).toContain('ACTIVE ROUTE')
|
||||
expect(routeTelemetry.text()).toContain('PLANNER')
|
||||
expect(routeTelemetry.text()).toContain('STEPS')
|
||||
})
|
||||
|
||||
it('keeps the configuration drawer available when selecting a main agent chip', async () => {
|
||||
const wrapper = mount(AgentsPage)
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
|
||||
await wrapper.get('[data-testid="agent-chip-planner"]').trigger('click')
|
||||
|
||||
expect(wrapper.text()).toContain('AGENT CONFIGURATION')
|
||||
expect(wrapper.find('input').exists()).toBe(true)
|
||||
})
|
||||
|
||||
it('cycles the energized demo path when hierarchy stats are offline', async () => {
|
||||
mocks.getHierarchyStats.mockRejectedValue(new Error('offline'))
|
||||
const wrapper = mount(AgentsPage)
|
||||
await Promise.resolve()
|
||||
await Promise.resolve()
|
||||
|
||||
expect(wrapper.get('[data-testid="bus-link-planner"]').classes()).toContain('energized')
|
||||
expect(wrapper.get('[data-testid="sub-link-planner_scope"]').classes()).toContain('energized')
|
||||
|
||||
await vi.advanceTimersByTimeAsync(1700)
|
||||
|
||||
expect(wrapper.get('[data-testid="sub-link-planner_scope"]').classes()).not.toContain('energized')
|
||||
expect(wrapper.get('[data-testid="sub-link-planner_steps"]').classes()).toContain('energized')
|
||||
})
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user