feat(core): add command, intent, and routing primitives

This commit is contained in:
William Valentin
2026-02-12 22:47:22 -08:00
parent 7ae0fb51c2
commit 6e8984f788
25 changed files with 1469 additions and 0 deletions
+104
View File
@@ -0,0 +1,104 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import type { GatewayEvent, GatewayRequest, OutboundMessage } from '../protocol.js';
import { LaneQueue } from '../lane-queue.js';
import { createAgentHandlers } from './agent.js';
import { CommandRegistry, registerBuiltinCommands } from '../../commands/index.js';
describe('createAgentHandlers command fast-path', () => {
const mockAgent = {
process: vi.fn(async () => 'agent response'),
getUsage: vi.fn(() => ({
primary: { inputTokens: 10, outputTokens: 5, calls: 1 },
delegation: {},
total: { inputTokens: 10, outputTokens: 5, calls: 1, estimatedCost: 0 },
})),
getModelTier: vi.fn(() => 'default'),
setModelTier: vi.fn(),
compact: vi.fn(async () => null),
reset: vi.fn(),
};
const sessionBridge = {
getAgent: vi.fn(() => mockAgent),
getSessionId: vi.fn(() => 'ws:conn-1'),
setBusy: vi.fn(),
setOnToolUse: vi.fn(),
isBusy: vi.fn(() => false),
};
const sessionManager = {
setSessionConfig: vi.fn(),
deleteSessionConfig: vi.fn(),
};
const commandRegistry = new CommandRegistry();
registerBuiltinCommands(commandRegistry);
const handlers = createAgentHandlers({
sessionBridge: sessionBridge as any,
laneQueue: new LaneQueue(),
sessionManager: sessionManager as any,
commandRegistry,
});
beforeEach(() => {
vi.clearAllMocks();
mockAgent.process.mockResolvedValue('agent response');
mockAgent.compact.mockResolvedValue(null);
});
it('handles known commands without calling agent.process', async () => {
const sent: OutboundMessage[] = [];
const send = vi.fn((msg: OutboundMessage) => sent.push(msg));
const req: GatewayRequest = {
id: 1,
method: 'agent.send',
params: { message: '/usage', connectionId: 'conn-1' },
};
await handlers['agent.send'](req, send);
expect(mockAgent.process).not.toHaveBeenCalled();
expect(sent).toHaveLength(1);
const event = sent[0] as GatewayEvent;
expect(event.event).toBe('done');
expect((event.data as { content: string }).content).toContain('Token Usage');
});
it('handles metadata commands via fast-path', async () => {
const sent: OutboundMessage[] = [];
const send = vi.fn((msg: OutboundMessage) => sent.push(msg));
const req: GatewayRequest = {
id: 2,
method: 'agent.send',
params: {
message: '/reset',
connectionId: 'conn-1',
metadata: { isCommand: true, command: 'reset' },
},
};
await handlers['agent.send'](req, send);
expect(mockAgent.reset).toHaveBeenCalledOnce();
expect(sessionManager.deleteSessionConfig).toHaveBeenCalledWith('ws', 'ws:conn-1', 'modelTier');
expect(mockAgent.process).not.toHaveBeenCalled();
expect(((sent[0] as GatewayEvent).data as { content: string }).content).toContain('Session reset.');
});
it('falls through to agent.process for unknown commands', async () => {
const sent: OutboundMessage[] = [];
const send = vi.fn((msg: OutboundMessage) => sent.push(msg));
const req: GatewayRequest = {
id: 3,
method: 'agent.send',
params: { message: '/not-a-real-command', connectionId: 'conn-1' },
};
await handlers['agent.send'](req, send);
expect(mockAgent.process).toHaveBeenCalledWith('/not-a-real-command', undefined);
expect((sent[0] as GatewayEvent).event).toBe('done');
expect(((sent[0] as GatewayEvent).data as { content: string }).content).toBe('agent response');
});
});