Add execution graph to chat history (#776)
This commit is contained in:
committed by
GitHub
Unverified
parent
91c735c9f4
commit
c866205eac
156
tests/unit/task-visualization.test.ts
Normal file
156
tests/unit/task-visualization.test.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { deriveTaskSteps, parseSubagentCompletionInfo } from '@/pages/Chat/task-visualization';
|
||||
import type { RawMessage, ToolStatus } from '@/stores/chat';
|
||||
|
||||
describe('deriveTaskSteps', () => {
|
||||
it('builds running steps from streaming thinking and tool status', () => {
|
||||
const streamingTools: ToolStatus[] = [
|
||||
{
|
||||
name: 'web_search',
|
||||
status: 'running',
|
||||
updatedAt: Date.now(),
|
||||
summary: 'Searching docs',
|
||||
},
|
||||
];
|
||||
|
||||
const steps = deriveTaskSteps({
|
||||
messages: [],
|
||||
streamingMessage: {
|
||||
role: 'assistant',
|
||||
content: [
|
||||
{ type: 'thinking', thinking: 'Compare a few approaches before coding.' },
|
||||
{ type: 'tool_use', id: 'tool-1', name: 'web_search', input: { query: 'openclaw task list' } },
|
||||
],
|
||||
},
|
||||
streamingTools,
|
||||
sending: true,
|
||||
pendingFinal: false,
|
||||
showThinking: true,
|
||||
});
|
||||
|
||||
expect(steps).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'stream-thinking',
|
||||
label: 'Thinking',
|
||||
status: 'running',
|
||||
kind: 'thinking',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
label: 'web_search',
|
||||
status: 'running',
|
||||
kind: 'tool',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps recent completed steps from assistant history', () => {
|
||||
const messages: RawMessage[] = [
|
||||
{
|
||||
role: 'assistant',
|
||||
id: 'assistant-1',
|
||||
content: [
|
||||
{ type: 'thinking', thinking: 'Reviewing the code path.' },
|
||||
{ type: 'tool_use', id: 'tool-2', name: 'read_file', input: { path: 'src/App.tsx' } },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const steps = deriveTaskSteps({
|
||||
messages,
|
||||
streamingMessage: null,
|
||||
streamingTools: [],
|
||||
sending: false,
|
||||
pendingFinal: false,
|
||||
showThinking: true,
|
||||
});
|
||||
|
||||
expect(steps).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'history-thinking-assistant-1',
|
||||
label: 'Thinking',
|
||||
status: 'completed',
|
||||
kind: 'thinking',
|
||||
depth: 1,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: 'tool-2',
|
||||
label: 'read_file',
|
||||
status: 'completed',
|
||||
kind: 'tool',
|
||||
depth: 1,
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('builds a branch for spawned subagents', () => {
|
||||
const messages: RawMessage[] = [
|
||||
{
|
||||
role: 'assistant',
|
||||
id: 'assistant-2',
|
||||
content: [
|
||||
{
|
||||
type: 'tool_use',
|
||||
id: 'spawn-1',
|
||||
name: 'sessions_spawn',
|
||||
input: { agentId: 'coder', task: 'inspect repo' },
|
||||
},
|
||||
{
|
||||
type: 'tool_use',
|
||||
id: 'yield-1',
|
||||
name: 'sessions_yield',
|
||||
input: { message: 'wait coder finishes' },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const steps = deriveTaskSteps({
|
||||
messages,
|
||||
streamingMessage: null,
|
||||
streamingTools: [],
|
||||
sending: false,
|
||||
pendingFinal: false,
|
||||
showThinking: true,
|
||||
});
|
||||
|
||||
expect(steps).toEqual([
|
||||
expect.objectContaining({
|
||||
id: 'spawn-1',
|
||||
label: 'sessions_spawn',
|
||||
depth: 1,
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: 'spawn-1:branch',
|
||||
label: 'coder run',
|
||||
depth: 2,
|
||||
parentId: 'spawn-1',
|
||||
}),
|
||||
expect.objectContaining({
|
||||
id: 'yield-1',
|
||||
label: 'sessions_yield',
|
||||
depth: 3,
|
||||
parentId: 'spawn-1:branch',
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it('parses internal subagent completion events from injected user messages', () => {
|
||||
const info = parseSubagentCompletionInfo({
|
||||
role: 'user',
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: `[Internal task completion event]
|
||||
source: subagent
|
||||
session_key: agent:coder:subagent:child-123
|
||||
session_id: child-session-id
|
||||
status: completed successfully`,
|
||||
}],
|
||||
} as RawMessage);
|
||||
|
||||
expect(info).toEqual({
|
||||
sessionKey: 'agent:coder:subagent:child-123',
|
||||
sessionId: 'child-session-id',
|
||||
agentId: 'coder',
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user