moving
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled

This commit is contained in:
Oleg Maslov
2026-09-02 10:10:29 +02:00
commit 0c3e2ead3b
3841 changed files with 970576 additions and 0 deletions

View File

@@ -0,0 +1,95 @@
import { describe, it, expect } from 'vitest';
import { CapabilityRouter, type CapabilityRouterDeps } from '../src/capability-router.js';
function createDeps(overrides?: Partial<CapabilityRouterDeps>): CapabilityRouterDeps {
return {
toolNames: ['search_memory', 'save_memory', 'bash'],
skills: [{ name: 'research-workflow', content: 'research and investigate topics' }],
plugins: [],
mcpServers: [],
subAgentRoles: ['researcher', 'writer'],
connectors: [
{ id: 'github', name: 'GitHub', service: 'github.com', connected: true, actions: ['list_repos', 'create_issue', 'list_prs'] },
{ id: 'slack', name: 'Slack', service: 'slack.com', connected: true, actions: ['send_message', 'list_channels'] },
{ id: 'jira', name: 'Jira', service: 'atlassian.net', connected: false, actions: ['create_issue', 'list_issues'] },
{ id: 'email', name: 'Email (SendGrid)', service: 'sendgrid.com', connected: true, actions: ['send_email'] },
],
...overrides,
};
}
describe('Connector routing in CapabilityRouter', () => {
it('resolve("jira") returns connector source when jira is registered', () => {
const router = new CapabilityRouter(createDeps());
const routes = router.resolve('jira');
const connectorRoute = routes.find(r => r.source === 'connector');
expect(connectorRoute).toBeDefined();
expect(connectorRoute!.name).toBe('jira');
expect(connectorRoute!.confidence).toBe(0.75);
expect(connectorRoute!.available).toBe(false); // Jira is disconnected
expect(connectorRoute!.suggestion).toContain('not connected');
});
it('resolve("github") returns connector with available=true when connected', () => {
const router = new CapabilityRouter(createDeps());
const routes = router.resolve('github');
const connectorRoute = routes.find(r => r.source === 'connector');
expect(connectorRoute).toBeDefined();
expect(connectorRoute!.available).toBe(true);
expect(connectorRoute!.suggestion).toBeUndefined();
});
it('resolve("create github issue") matches via action name', () => {
const router = new CapabilityRouter(createDeps());
const routes = router.resolve('create issue');
// Both GitHub and Jira have "create_issue" action
const connectorRoutes = routes.filter(r => r.source === 'connector');
expect(connectorRoutes.length).toBeGreaterThanOrEqual(2);
expect(connectorRoutes.some(r => r.name === 'github')).toBe(true);
expect(connectorRoutes.some(r => r.name === 'jira')).toBe(true);
});
it('resolve("send email") returns email connector', () => {
const router = new CapabilityRouter(createDeps());
const routes = router.resolve('send email');
const emailRoute = routes.find(r => r.source === 'connector' && r.name === 'email');
expect(emailRoute).toBeDefined();
expect(emailRoute!.available).toBe(true);
});
it('connector routes rank at 0.75 between native (0.8-1.0) and skill (0.5-0.7)', () => {
const router = new CapabilityRouter(createDeps());
const routes = router.resolve('slack');
const connectorRoute = routes.find(r => r.source === 'connector');
expect(connectorRoute!.confidence).toBe(0.75);
// Verify ordering: native first (if any), then connector, then skill
const nativeIdx = routes.findIndex(r => r.source === 'native');
const connectorIdx = routes.findIndex(r => r.source === 'connector');
if (nativeIdx >= 0) {
expect(routes[nativeIdx].confidence).toBeGreaterThanOrEqual(0.75);
}
// Connector should come before skill-level entries
const skillIdx = routes.findIndex(r => r.source === 'skill');
if (skillIdx >= 0 && connectorIdx >= 0) {
expect(connectorIdx).toBeLessThan(skillIdx);
}
});
it('works with no connectors (backward compatible)', () => {
const router = new CapabilityRouter(createDeps({ connectors: undefined }));
const routes = router.resolve('github');
const connectorRoutes = routes.filter(r => r.source === 'connector');
expect(connectorRoutes).toHaveLength(0);
});
it('missing route suggestion mentions connectors', () => {
const router = new CapabilityRouter(createDeps({ connectors: [] }));
const routes = router.resolve('xyznonexistent');
const missing = routes.find(r => r.source === 'missing');
expect(missing).toBeDefined();
expect(missing!.suggestion).toContain('Connectors');
});
});