mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-24 08:34:23 +00:00
* feat(agent-core): re-export wire record types for in-monorepo consumers * chore(vis): purge legacy wire protocol code * feat(vis): introduce single-source agent-record types * test(vis): add fixture session and builder helper * feat(vis): implement new session store reader * feat(vis): wire new session list/detail routes * refactor(vis): drop legacy path config * feat(vis): adapt session list page to new DTO * feat(vis): implement per-agent wire reader * feat(vis): rewrite wire route for new protocol * feat(vis): rewrite wire type metadata for new protocol * feat(vis): rewrite wire row + headline for new record union * feat(vis): wire tab detail panel + multi-agent selector * feat(vis): rebuild wire issues detection for new protocol * feat(vis): implement context projector * feat(vis): rewrite context route on projector * feat(vis): rebuild context tab for new ContextMessage shape * feat(vis): implement agent tree builder * feat(vis): rewrite agents route * feat(vis): rebuild subagents tab around state.json.agents * feat(vis): rebuild state tab on raw state.json * chore(vis): purge residual legacy field references * vis: rewrite complete on new agent-core protocol * fix(vis): adapt to wire protocol 1.1 with flattened tool calls * fix(vis): populate workDir from session index * fix(vis): return broken-state sessions from detail lookup * fix(vis): tolerate per-session wire read failures during listing * fix(vis): read wire files from canonical session path * feat(vis): restore session detail page with full tab layout * feat(vis): wire subagent context tab to real ContextTab * fix(vis): sync wire and context tab agentId with prop changes * feat(vis): auto-pick a free dev port when 3001 is busy * feat(vis): accept v1.0 wire files via agent-core migration chain * refactor(vis): default API to 5174 and pick a non-colliding vite port * feat(vis): make long strings expandable with copy in JsonViewer * fix(vis): stop gating session health on protocol version * refactor(vis): split wire records into raw + projected; best-effort unknown protocol * feat(vis): pair tool.call with tool.result via inline cross-reference and hover highlight * feat(vis): open session folder and copy its path from the detail header * fix(vis): reconstruct assistant and tool messages from loop events * fix(vis): keep system prompt bubble within the message column width * feat(vis): collapse tool result bubble by default in context view * feat(vis): expose broken_main_wire in the session health filter * fix(vis): reset wire and context tab agent when navigating sessions * fix(vis): fall back to a generic headline for unknown wire record types * fix(vis): emit compaction summary as an assistant message with origin * fix(vis): harden session-store reads for broken wires, broken state, and path-traversal agent ids * feat(vis): inline image previews for image_url content parts
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { buildAgentTree } from '../../src/lib/agent-tree';
|
|
import type { AgentInfo } from '../../src/lib/agent-record-types';
|
|
|
|
function info(overrides: Partial<AgentInfo> & Pick<AgentInfo, 'agentId'>): AgentInfo {
|
|
return {
|
|
type: 'sub',
|
|
parentAgentId: null,
|
|
homedir: `/tmp/${overrides.agentId}`,
|
|
wireExists: true,
|
|
wireRecordCount: 0,
|
|
wireProtocolVersion: '1.1',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
describe('agent-tree', () => {
|
|
it('returns single main agent as the only root', () => {
|
|
const tree = buildAgentTree([info({ agentId: 'main', type: 'main' })]);
|
|
expect(tree).toHaveLength(1);
|
|
expect(tree[0]!.agentId).toBe('main');
|
|
expect(tree[0]!.children).toEqual([]);
|
|
});
|
|
|
|
it('attaches a sub agent to its main parent', () => {
|
|
const tree = buildAgentTree([
|
|
info({ agentId: 'main', type: 'main' }),
|
|
info({ agentId: 'agent-0', type: 'sub', parentAgentId: 'main' }),
|
|
]);
|
|
expect(tree).toHaveLength(1);
|
|
expect(tree[0]!.agentId).toBe('main');
|
|
expect(tree[0]!.children).toHaveLength(1);
|
|
expect(tree[0]!.children[0]!.agentId).toBe('agent-0');
|
|
expect(tree[0]!.children[0]!.parentAgentId).toBe('main');
|
|
});
|
|
|
|
it('treats orphan parentAgentId as a root node', () => {
|
|
const tree = buildAgentTree([
|
|
info({ agentId: 'main', type: 'main' }),
|
|
info({ agentId: 'agent-0', type: 'sub', parentAgentId: 'does-not-exist' }),
|
|
]);
|
|
expect(tree).toHaveLength(2);
|
|
const ids = tree.map((n) => n.agentId).sort();
|
|
expect(ids).toEqual(['agent-0', 'main']);
|
|
// orphan is still a root, no children attached anywhere
|
|
const orphan = tree.find((n) => n.agentId === 'agent-0')!;
|
|
expect(orphan.children).toEqual([]);
|
|
});
|
|
|
|
it('sorts main as the first root regardless of input order', () => {
|
|
const tree = buildAgentTree([
|
|
info({ agentId: 'agent-1', type: 'sub', parentAgentId: 'orphan' }),
|
|
info({ agentId: 'main', type: 'main' }),
|
|
info({ agentId: 'agent-2', type: 'sub', parentAgentId: 'orphan' }),
|
|
]);
|
|
expect(tree[0]!.agentId).toBe('main');
|
|
});
|
|
});
|