feat: Add intelligent auto-router and enhanced integrations

- Add intelligent-router.sh hook for automatic agent routing
- Add AUTO-TRIGGER-SUMMARY.md documentation
- Add FINAL-INTEGRATION-SUMMARY.md documentation
- Complete Prometheus integration (6 commands + 4 tools)
- Complete Dexto integration (12 commands + 5 tools)
- Enhanced Ralph with access to all agents
- Fix /clawd command (removed disable-model-invocation)
- Update hooks.json to v5 with intelligent routing
- 291 total skills now available
- All 21 commands with automatic routing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
admin
2026-01-28 00:27:56 +04:00
Unverified
parent 3b128ba3bd
commit b52318eeae
1724 changed files with 351216 additions and 0 deletions

View File

@@ -0,0 +1,338 @@
import { describe, it, expect, beforeEach } from 'vitest';
import { useChatStore, generateMessageId, type Message } from './chatStore.js';
// Helper to create a test message
function createTestMessage(overrides: Partial<Message> = {}): Message {
return {
id: generateMessageId(),
role: 'user',
content: 'Test message',
createdAt: Date.now(),
...overrides,
};
}
describe('chatStore', () => {
const sessionId = 'test-session';
beforeEach(() => {
// Reset store to default state
useChatStore.setState({ sessions: new Map() });
});
describe('generateMessageId', () => {
it('should generate unique IDs', () => {
const id1 = generateMessageId();
const id2 = generateMessageId();
expect(id1).not.toBe(id2);
});
it('should start with msg- prefix', () => {
const id = generateMessageId();
expect(id.startsWith('msg-')).toBe(true);
});
});
describe('initSession', () => {
it('should initialize a session with default state', () => {
useChatStore.getState().initSession(sessionId);
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.messages).toEqual([]);
expect(state.streamingMessage).toBeNull();
expect(state.processing).toBe(false);
expect(state.error).toBeNull();
expect(state.loadingHistory).toBe(false);
});
it('should not overwrite existing session', () => {
const message = createTestMessage();
useChatStore.getState().initSession(sessionId);
useChatStore.getState().addMessage(sessionId, message);
useChatStore.getState().initSession(sessionId);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(1);
});
});
describe('addMessage', () => {
it('should add a message to a session', () => {
const message = createTestMessage();
useChatStore.getState().addMessage(sessionId, message);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(1);
expect(messages[0]).toEqual(message);
});
it('should create session if not exists', () => {
const message = createTestMessage();
useChatStore.getState().addMessage('new-session', message);
const messages = useChatStore.getState().getMessages('new-session');
expect(messages).toHaveLength(1);
});
it('should append multiple messages in order', () => {
const msg1 = createTestMessage({ content: 'First' });
const msg2 = createTestMessage({ content: 'Second' });
useChatStore.getState().addMessage(sessionId, msg1);
useChatStore.getState().addMessage(sessionId, msg2);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(2);
expect(messages[0].content).toBe('First');
expect(messages[1].content).toBe('Second');
});
});
describe('updateMessage', () => {
it('should update an existing message', () => {
const message = createTestMessage({ content: 'Original' });
useChatStore.getState().addMessage(sessionId, message);
useChatStore.getState().updateMessage(sessionId, message.id, {
content: 'Updated',
});
const updated = useChatStore.getState().getMessage(sessionId, message.id);
expect(updated?.content).toBe('Updated');
});
it('should not modify state for non-existent message', () => {
const message = createTestMessage();
useChatStore.getState().addMessage(sessionId, message);
useChatStore.getState().updateMessage(sessionId, 'non-existent', {
content: 'Updated',
});
// State should be unchanged - original message still present
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(1);
expect(messages[0].content).toBe(message.content);
});
it('should not modify state for non-existent session', () => {
useChatStore.getState().updateMessage('non-existent', 'msg-id', {
content: 'Updated',
});
expect(useChatStore.getState().sessions.has('non-existent')).toBe(false);
});
});
describe('removeMessage', () => {
it('should remove a message from a session', () => {
const message = createTestMessage();
useChatStore.getState().addMessage(sessionId, message);
useChatStore.getState().removeMessage(sessionId, message.id);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(0);
});
it('should not affect other messages', () => {
const msg1 = createTestMessage({ content: 'Keep' });
const msg2 = createTestMessage({ content: 'Remove' });
useChatStore.getState().addMessage(sessionId, msg1);
useChatStore.getState().addMessage(sessionId, msg2);
useChatStore.getState().removeMessage(sessionId, msg2.id);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(1);
expect(messages[0].content).toBe('Keep');
});
});
describe('clearMessages', () => {
it('should clear all messages in a session', () => {
useChatStore.getState().addMessage(sessionId, createTestMessage());
useChatStore.getState().addMessage(sessionId, createTestMessage());
useChatStore.getState().clearMessages(sessionId);
const messages = useChatStore.getState().getMessages(sessionId);
expect(messages).toHaveLength(0);
});
it('should also clear streaming message', () => {
const streaming = createTestMessage({ role: 'assistant' });
useChatStore.getState().setStreamingMessage(sessionId, streaming);
useChatStore.getState().clearMessages(sessionId);
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage).toBeNull();
});
});
describe('streaming message', () => {
it('should set streaming message', () => {
const message = createTestMessage({ role: 'assistant', content: '' });
useChatStore.getState().setStreamingMessage(sessionId, message);
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage).toEqual(message);
});
it('should clear streaming message', () => {
const message = createTestMessage({ role: 'assistant' });
useChatStore.getState().setStreamingMessage(sessionId, message);
useChatStore.getState().setStreamingMessage(sessionId, null);
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage).toBeNull();
});
it('should append text content to streaming message', () => {
const message = createTestMessage({ role: 'assistant', content: 'Hello' });
useChatStore.getState().setStreamingMessage(sessionId, message);
useChatStore.getState().appendToStreamingMessage(sessionId, ' World');
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage?.content).toBe('Hello World');
});
it('should append reasoning content to streaming message', () => {
const message = createTestMessage({ role: 'assistant', content: '', reasoning: '' });
useChatStore.getState().setStreamingMessage(sessionId, message);
useChatStore.getState().appendToStreamingMessage(sessionId, 'Thinking...', 'reasoning');
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage?.reasoning).toBe('Thinking...');
});
it('should not append if no streaming message', () => {
// Should not throw
useChatStore.getState().appendToStreamingMessage(sessionId, 'Test');
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage).toBeNull();
});
it('should finalize streaming message', () => {
const message = createTestMessage({ role: 'assistant', content: 'Response' });
useChatStore.getState().setStreamingMessage(sessionId, message);
useChatStore.getState().finalizeStreamingMessage(sessionId, {
tokenUsage: { totalTokens: 100 },
});
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.streamingMessage).toBeNull();
expect(state.messages).toHaveLength(1);
expect(state.messages[0].content).toBe('Response');
expect(state.messages[0].tokenUsage?.totalTokens).toBe(100);
});
it('should not finalize if no streaming message', () => {
useChatStore.getState().finalizeStreamingMessage(sessionId);
const state = useChatStore.getState().getSessionState(sessionId);
expect(state.messages).toHaveLength(0);
});
});
describe('state flags', () => {
it('should set processing flag', () => {
useChatStore.getState().setProcessing(sessionId, true);
expect(useChatStore.getState().getSessionState(sessionId).processing).toBe(true);
useChatStore.getState().setProcessing(sessionId, false);
expect(useChatStore.getState().getSessionState(sessionId).processing).toBe(false);
});
it('should set error state', () => {
const error = {
id: 'error-1',
message: 'Test error',
timestamp: Date.now(),
};
useChatStore.getState().setError(sessionId, error);
expect(useChatStore.getState().getSessionState(sessionId).error).toEqual(error);
useChatStore.getState().setError(sessionId, null);
expect(useChatStore.getState().getSessionState(sessionId).error).toBeNull();
});
it('should set loading history flag', () => {
useChatStore.getState().setLoadingHistory(sessionId, true);
expect(useChatStore.getState().getSessionState(sessionId).loadingHistory).toBe(true);
});
});
describe('removeSession', () => {
it('should remove a session completely', () => {
useChatStore.getState().addMessage(sessionId, createTestMessage());
useChatStore.getState().removeSession(sessionId);
expect(useChatStore.getState().sessions.has(sessionId)).toBe(false);
});
});
describe('selectors', () => {
it('getSessionState should return default for unknown session', () => {
const state = useChatStore.getState().getSessionState('unknown');
expect(state.messages).toEqual([]);
expect(state.processing).toBe(false);
});
it('getMessage should find message by ID', () => {
const message = createTestMessage();
useChatStore.getState().addMessage(sessionId, message);
const found = useChatStore.getState().getMessage(sessionId, message.id);
expect(found).toEqual(message);
});
it('getMessage should return undefined for unknown ID', () => {
const found = useChatStore.getState().getMessage(sessionId, 'unknown');
expect(found).toBeUndefined();
});
it('getMessageByToolCallId should find tool message', () => {
const message = createTestMessage({
role: 'tool',
toolCallId: 'tool-call-123',
});
useChatStore.getState().addMessage(sessionId, message);
const found = useChatStore
.getState()
.getMessageByToolCallId(sessionId, 'tool-call-123');
expect(found).toEqual(message);
});
});
describe('session isolation', () => {
it('should keep sessions separate', () => {
const session1 = 'session-1';
const session2 = 'session-2';
useChatStore
.getState()
.addMessage(session1, createTestMessage({ content: 'Session 1' }));
useChatStore
.getState()
.addMessage(session2, createTestMessage({ content: 'Session 2' }));
expect(useChatStore.getState().getMessages(session1)).toHaveLength(1);
expect(useChatStore.getState().getMessages(session2)).toHaveLength(1);
expect(useChatStore.getState().getMessages(session1)[0].content).toBe('Session 1');
expect(useChatStore.getState().getMessages(session2)[0].content).toBe('Session 2');
});
it('should not affect other sessions when clearing', () => {
const session1 = 'session-1';
const session2 = 'session-2';
useChatStore.getState().addMessage(session1, createTestMessage());
useChatStore.getState().addMessage(session2, createTestMessage());
useChatStore.getState().clearMessages(session1);
expect(useChatStore.getState().getMessages(session1)).toHaveLength(0);
expect(useChatStore.getState().getMessages(session2)).toHaveLength(1);
});
});
});