Skip to main content
Glama
mkXultra
by mkXultra
RealAdapters.test.ts15.5 kB
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { promises as fs } from 'fs'; import path from 'path'; import { LockService } from '../../../src/services/LockService.js'; import { MessagingAdapter } from '../../../src/adapters/MessagingAdapter.js'; import { RoomsAdapter } from '../../../src/adapters/RoomsAdapter.js'; import { ManagementAdapter } from '../../../src/adapters/ManagementAdapter.js'; import { RoomNotFoundError, AgentNotInRoomError, RoomAlreadyExistsError } from '../../../src/errors/index.js'; describe('Real Adapters Integration Tests', () => { let testDataDir: string; let lockService: LockService; let messagingAdapter: MessagingAdapter; let roomsAdapter: RoomsAdapter; let managementAdapter: ManagementAdapter; beforeEach(async () => { // Create temporary test directory testDataDir = path.join(process.cwd(), 'test-data-' + Date.now()); await fs.mkdir(testDataDir, { recursive: true }); // Set environment variable to use our test directory process.env.AGENT_COMM_DATA_DIR = testDataDir; // Initialize services lockService = new LockService(testDataDir); messagingAdapter = new MessagingAdapter(lockService); roomsAdapter = new RoomsAdapter(lockService); managementAdapter = new ManagementAdapter(lockService); // Set up cross-adapter dependencies messagingAdapter.setRoomsAdapter(roomsAdapter); managementAdapter.setRoomsAdapter(roomsAdapter); managementAdapter.setMessageAdapter(messagingAdapter); // Initialize adapters await Promise.all([ messagingAdapter.initialize(), roomsAdapter.initialize(), managementAdapter.initialize() ]); }); afterEach(async () => { // Clean up test directory try { await fs.rm(testDataDir, { recursive: true, force: true }); } catch (error) { // Ignore cleanup errors } // Clean up environment variable delete process.env.AGENT_COMM_DATA_DIR; }); describe('Rooms Adapter with Real Implementation', () => { it('should create and list rooms', async () => { // Initially no rooms const initialRooms = await roomsAdapter.listRooms(); expect(initialRooms.rooms).toEqual([]); // Create room const createResult = await roomsAdapter.createRoom({ roomName: 'test-room', description: 'A test room' }); expect(createResult.success).toBe(true); expect(createResult.roomName).toBe('test-room'); // List rooms should now include the new room const rooms = await roomsAdapter.listRooms(); expect(rooms.rooms).toHaveLength(1); expect(rooms.rooms[0].name).toBe('test-room'); expect(rooms.rooms[0].description).toBe('A test room'); }); it('should handle agent room membership', async () => { // Create room await roomsAdapter.createRoom({ roomName: 'membership-test' }); // Initially no users const initialUsers = await roomsAdapter.listRoomUsers({ roomName: 'membership-test' }); expect(initialUsers.users).toEqual([]); // Agent enters room const enterResult = await roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'membership-test' }); expect(enterResult.success).toBe(true); // Verify agent is in room const users = await roomsAdapter.listRoomUsers({ roomName: 'membership-test' }); expect(users.users.map(u => u.name)).toContain('agent1'); // Agent leaves room const leaveResult = await roomsAdapter.leaveRoom({ agentName: 'agent1', roomName: 'membership-test' }); expect(leaveResult.success).toBe(true); // Verify agent is no longer in room (may remain with offline status) const finalUsers = await roomsAdapter.listRoomUsers({ roomName: 'membership-test' }); const onlineUsers = finalUsers.users.filter(u => u.status === 'online'); expect(onlineUsers).toEqual([]); }); it('should enforce room existence for operations', async () => { // Try to enter non-existent room await expect(roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'non-existent' })).rejects.toThrow(RoomNotFoundError); // Try to list users of non-existent room await expect(roomsAdapter.listRoomUsers({ roomName: 'non-existent' })).rejects.toThrow(RoomNotFoundError); }); }); describe('Messaging Adapter with Real Implementation', () => { beforeEach(async () => { // Set up room and agent for messaging tests await roomsAdapter.createRoom({ roomName: 'chat-room' }); await roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'chat-room' }); }); it('should send and retrieve messages', async () => { // Send message const sendResult = await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'chat-room', message: 'Hello, world!' }); expect(sendResult.success).toBe(true); expect(sendResult.messageId).toBeDefined(); expect(sendResult.mentions).toEqual([]); // Retrieve messages const messages = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'chat-room' }); expect(messages.messages).toHaveLength(1); expect(messages.messages[0].message).toBe('Hello, world!'); expect(messages.messages[0].agentName).toBe('agent1'); }); it('should extract mentions correctly', async () => { const sendResult = await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'chat-room', message: 'Hey @agent2 and @agent3, check this out!' }); expect(sendResult.mentions).toEqual(['agent2', 'agent3']); // Verify mentions are stored const messages = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'chat-room' }); expect(messages.messages[0].mentions).toEqual(['agent2', 'agent3']); }); it('should enforce room membership for messaging', async () => { // Try to send message from non-member await expect(messagingAdapter.sendMessage({ agentName: 'agent2', roomName: 'chat-room', message: 'Should fail' })).rejects.toThrow(AgentNotInRoomError); // Try to get messages as non-member await expect(messagingAdapter.getMessages({ agentName: 'agent2', roomName: 'chat-room' })).rejects.toThrow(AgentNotInRoomError); }); it('should support message pagination', async () => { // Send multiple messages for (let i = 1; i <= 10; i++) { await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'chat-room', message: `Message ${i}` }); } // Get first page const firstPage = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'chat-room', limit: 5 }); expect(firstPage.messages).toHaveLength(5); expect(firstPage.messages[0].message).toBe('Message 10'); expect(firstPage.messages[4].message).toBe('Message 6'); // Get second page const secondPage = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'chat-room', limit: 5, offset: 5 }); expect(secondPage.messages).toHaveLength(5); expect(secondPage.messages[0].message).toBe('Message 5'); expect(secondPage.messages[4].message).toBe('Message 1'); }); }); describe('Management Adapter with Real Implementation', () => { beforeEach(async () => { // Set up test data await roomsAdapter.createRoom({ roomName: 'stats-room-1' }); await roomsAdapter.createRoom({ roomName: 'stats-room-2' }); await roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'stats-room-1' }); await roomsAdapter.enterRoom({ agentName: 'agent2', roomName: 'stats-room-1' }); await roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'stats-room-2' }); }); it('should provide accurate system status', async () => { // Send some messages await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'stats-room-1', message: 'First message' }); await messagingAdapter.sendMessage({ agentName: 'agent2', roomName: 'stats-room-1', message: 'Second message' }); const status = await managementAdapter.getStatus(); expect(status.totalRooms).toBe(2); expect(status.totalMessages).toBeGreaterThanOrEqual(2); expect(status.totalOnlineUsers).toBeGreaterThanOrEqual(2); expect(status.rooms).toHaveLength(2); const room1 = status.rooms.find(r => r.name === 'stats-room-1'); expect(room1?.onlineUsers).toBe(2); }); it('should clear room messages', async () => { // Send messages await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'stats-room-1', message: 'Message 1' }); await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'stats-room-1', message: 'Message 2' }); // Verify messages exist const beforeClear = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'stats-room-1' }); expect(beforeClear.messages).toHaveLength(2); // Clear messages const clearResult = await managementAdapter.clearRoomMessages({ roomName: 'stats-room-1', confirm: true }); expect(clearResult.success).toBe(true); expect(clearResult.clearedCount).toBe(2); // Verify messages are gone const afterClear = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'stats-room-1' }); expect(afterClear.messages).toHaveLength(0); }); it('should enforce room existence for management operations', async () => { await expect(managementAdapter.clearRoomMessages({ roomName: 'non-existent' })).rejects.toThrow(RoomNotFoundError); }); }); describe('Cross-Adapter Integration', () => { it('should maintain consistency across all adapters', async () => { // Create room await roomsAdapter.createRoom({ roomName: 'integration-room', description: 'Full integration test' }); // Agents join await roomsAdapter.enterRoom({ agentName: 'alice', roomName: 'integration-room' }); await roomsAdapter.enterRoom({ agentName: 'bob', roomName: 'integration-room' }); // Send messages await messagingAdapter.sendMessage({ agentName: 'alice', roomName: 'integration-room', message: 'Hello @bob!' }); await messagingAdapter.sendMessage({ agentName: 'bob', roomName: 'integration-room', message: 'Hi @alice, how are you?' }); // Verify through rooms adapter const users = await roomsAdapter.listRoomUsers({ roomName: 'integration-room' }); const userNames = users.users.map(u => u.name); expect(userNames).toContain('alice'); expect(userNames).toContain('bob'); // Verify through messaging adapter const messages = await messagingAdapter.getMessages({ agentName: 'alice', roomName: 'integration-room' }); expect(messages.messages).toHaveLength(2); // Messages are returned newest first expect(messages.messages[0].mentions).toContain('alice'); // Bob's message expect(messages.messages[1].mentions).toContain('bob'); // Alice's message // Verify through management adapter const status = await managementAdapter.getStatus(); expect(status.totalRooms).toBe(1); expect(status.totalMessages).toBe(2); expect(status.totalOnlineUsers).toBe(2); const room = status.rooms.find(r => r.name === 'integration-room'); expect(room).toBeDefined(); expect(room?.totalMessages).toBe(2); expect(room?.onlineUsers).toBe(2); }); it('should handle complex workflow scenarios', async () => { // Multi-room scenario await roomsAdapter.createRoom({ roomName: 'general' }); await roomsAdapter.createRoom({ roomName: 'dev-team' }); // Agents with different room memberships await roomsAdapter.enterRoom({ agentName: 'alice', roomName: 'general' }); await roomsAdapter.enterRoom({ agentName: 'alice', roomName: 'dev-team' }); await roomsAdapter.enterRoom({ agentName: 'bob', roomName: 'general' }); await roomsAdapter.enterRoom({ agentName: 'charlie', roomName: 'dev-team' }); // Messages in different rooms await messagingAdapter.sendMessage({ agentName: 'alice', roomName: 'general', message: 'General announcement' }); await messagingAdapter.sendMessage({ agentName: 'alice', roomName: 'dev-team', message: '@charlie ready for code review?' }); await messagingAdapter.sendMessage({ agentName: 'charlie', roomName: 'dev-team', message: '@alice yes, please review PR #123' }); // Verify isolation const generalMessages = await messagingAdapter.getMessages({ agentName: 'alice', roomName: 'general' }); expect(generalMessages.messages).toHaveLength(1); const devMessages = await messagingAdapter.getMessages({ agentName: 'alice', roomName: 'dev-team' }); expect(devMessages.messages).toHaveLength(2); // Bob shouldn't see dev-team messages await expect(messagingAdapter.getMessages({ agentName: 'bob', roomName: 'dev-team' })).rejects.toThrow(AgentNotInRoomError); // Final status check const finalStatus = await managementAdapter.getStatus(); expect(finalStatus.totalRooms).toBe(2); expect(finalStatus.totalMessages).toBe(3); expect(finalStatus.totalOnlineUsers).toBe(3); // Unique users: alice, bob, charlie }); }); describe('Error Handling in Real Implementation', () => { it('should maintain data consistency on errors', async () => { await roomsAdapter.createRoom({ roomName: 'error-test' }); await roomsAdapter.enterRoom({ agentName: 'agent1', roomName: 'error-test' }); // Send valid message await messagingAdapter.sendMessage({ agentName: 'agent1', roomName: 'error-test', message: 'Valid message' }); // Try invalid operation try { await messagingAdapter.sendMessage({ agentName: 'agent2', // Not in room roomName: 'error-test', message: 'Should fail' }); } catch (error) { expect(error).toBeInstanceOf(AgentNotInRoomError); } // Verify original message still exists const messages = await messagingAdapter.getMessages({ agentName: 'agent1', roomName: 'error-test' }); expect(messages.messages).toHaveLength(1); expect(messages.messages[0].message).toBe('Valid message'); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mkXultra/agent-communication-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server