返回 ViMax
events.test.ts
根目录 / web / src / events.test.ts
1 import {describe, expect, it} from 'vitest';
2 import {applyAgentEvent, appendLocalUser, composeAgentPrompt, createChatState, humanize} from './events';
3
4 describe('agent event mapping', () => {
5 it('streams assistant text into one message', () => {
6 let state = appendLocalUser(createChatState(), 'Make a short film');
7 state = applyAgentEvent(state, {type: 'turn', turn_id: 'turn-1'});
8 state = applyAgentEvent(state, {type: 'token', turn_id: 'turn-1', delta: 'Planning'});
9 state = applyAgentEvent(state, {type: 'token', turn_id: 'turn-1', delta: ' ready'});
10 state = applyAgentEvent(state, {type: 'done', turn_id: 'turn-1'});
11 expect(state.messages.at(-1)).toMatchObject({role: 'assistant', text: 'Planning ready'});
12 expect(state.busy).toBe(false);
13 });
14
15 it('updates a running tool instead of appending every progress event', () => {
16 let state = createChatState();
17 state = applyAgentEvent(state, {type: 'tool_start', turn_id: 'turn-1', tool: {id: 'tool-1', name: 'vimax_render_video'}});
18 state = applyAgentEvent(state, {type: 'tool_progress', turn_id: 'turn-1', tool: {name: 'vimax_render_video'}, progress: {stage: 'generate_frames', message: 'Generating frames'}});
19 state = applyAgentEvent(state, {type: 'tool_result', turn_id: 'turn-1', tool_result: {name: 'vimax_render_video', ok: true}});
20 expect(state.messages).toHaveLength(1);
21 expect(state.messages[0]).toMatchObject({tool: 'vimax_render_video', status: 'done', text: 'Completed'});
22 });
23
24 it('keeps each composer submission on one stdin line', () => {
25 expect(composeAgentPrompt('first line\nsecond line')).toBe('first line second line');
26 expect(composeAgentPrompt('Use these references', ['uploads/script.txt', 'uploads/look.png']))
27 .toBe('Use these references <workspace_uploads>["uploads/script.txt","uploads/look.png"]</workspace_uploads>');
28 expect(humanize('vimax_narrative_planning')).toBe('ViMax Narrative Planning');
29 });
30
31 it('ends running tools when the agent process stops', () => {
32 let state = applyAgentEvent(createChatState(), {
33 type: 'tool_start',
34 turn_id: 'turn-1',
35 tool: {id: 'tool-1', name: 'vimax_render_video'},
36 });
37 state = applyAgentEvent(state, {
38 type: 'bridge_status',
39 status: 'stopped',
40 message: 'Configuration updated',
41 });
42 expect(state.busy).toBe(false);
43 expect(state.messages[0]).toMatchObject({
44 tool: 'vimax_render_video',
45 status: 'error',
46 stage: 'interrupted',
47 text: 'Configuration updated',
48 });
49 });
50 });
51
51 lines TYPESCRIPT