Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "multi-agent-chat-platform",
"version": "0.1.0",
"description": "Multi-agent interactive chat platform",
"main": "index.js",
"scripts": {
"test": "jest",
"lint": "eslint . --ext .ts"
},
"dependencies": {
"typescript": "^4.9.5"
},
"devDependencies": {
"@types/jest": "^29.5.1",
"jest": "^29.5.0",
"ts-jest": "^29.1.0",
"eslint": "^8.40.0",
"@typescript-eslint/parser": "^5.59.2",
"@typescript-eslint/eslint-plugin": "^5.59.2"
},
"jest": {
"preset": "ts-jest",
"testEnvironment": "node"
}
}
28 changes: 28 additions & 0 deletions src/interfaces/chatbot-engine-adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Chatbot Engine Adapter Interface
import { PersonalityProfile } from './personality-data-manager';

export interface ChatHistory {
messages: Array<{
role: 'user' | 'agent';
content: string;
}>;
}

export interface ChatbotEngineAdapter {
/**
* Generate a response from an AI agent
* @param profile Personality profile for response context
* @param history Conversation history
* @returns Generated AI response
*/
generateResponse(
profile: PersonalityProfile,
history: ChatHistory
): Promise<string>;

/**
* Check the health and availability of the underlying LLM backend
* @returns Boolean indicating backend readiness
*/
checkBackendHealth(): Promise<boolean>;
}
29 changes: 29 additions & 0 deletions src/interfaces/conversation-orchestrator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Conversation Orchestrator Interface
import { PersonalityProfile } from './personality-data-manager';
import { ChatbotEngineAdapter } from './chatbot-engine-adapter';

export interface OrchestratorAgentReply {
agentId: string;
profile: PersonalityProfile;
reply: string;
}

export interface ConversationOrchestrator {
/**
* Handle an incoming user message in a conversation session
* @param sessionId Unique session identifier
* @param userMessage Incoming user message
* @returns Array of agent replies
*/
handleMessage(
sessionId: string,
userMessage: string
): Promise<OrchestratorAgentReply[]>;

/**
* Initialize a new conversation session
* @param selectedAgentIds Agents to be included in the session
* @returns Unique session identifier
*/
initializeSession(selectedAgentIds: string[]): string;
}
32 changes: 32 additions & 0 deletions src/interfaces/personality-data-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Personality Data Manager Interface
export interface PersonalityProfile {
id: string;
name: string;
description: string;
tone: string;
samplePrompts: string[];
version: number;
}

export interface PersonalityDataManager {
/**
* Load a personality profile by its unique identifier
* @param id Profile identifier
* @returns Loaded personality profile or null if not found
*/
loadProfile(id: string): PersonalityProfile | null;

/**
* Validate a personality profile's schema
* @param profile Profile to validate
* @returns Boolean indicating validation result or throws detailed error
*/
validateProfile(profile: PersonalityProfile): boolean;

/**
* Save or update a personality profile
* @param profile Profile to save
* @returns Version number of saved profile
*/
saveProfile(profile: PersonalityProfile): number;
}
110 changes: 110 additions & 0 deletions tests/component-interfaces.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { PersonalityProfile, PersonalityDataManager } from '../src/interfaces/personality-data-manager';
import { ChatbotEngineAdapter, ChatHistory } from '../src/interfaces/chatbot-engine-adapter';
import { ConversationOrchestrator, OrchestratorAgentReply } from '../src/interfaces/conversation-orchestrator';

describe('Component Interfaces', () => {
describe('Personality Data Manager', () => {
const mockPersonalityDataManager: PersonalityDataManager = {
loadProfile: (id: string) => {
if (id === 'valid_profile') {
return {
id: 'valid_profile',
name: 'Test Profile',
description: 'A mock profile',
tone: 'philosophical',
samplePrompts: ['What is truth?'],
version: 1
};
}
return null;
},
validateProfile: (profile: PersonalityProfile) => {
return profile.name.length > 0 && profile.samplePrompts.length > 0;
},
saveProfile: (profile: PersonalityProfile) => {
return profile.version + 1;
}
};

it('should load a valid profile', () => {
const profile = mockPersonalityDataManager.loadProfile('valid_profile');
expect(profile).toBeTruthy();
expect(profile?.name).toBe('Test Profile');
});

it('should validate profile correctly', () => {
const validProfile: PersonalityProfile = {
id: 'test',
name: 'Valid Profile',
description: 'Test Description',
tone: 'neutral',
samplePrompts: ['Hello'],
version: 1
};
expect(mockPersonalityDataManager.validateProfile(validProfile)).toBeTruthy();
});
});

describe('Chatbot Engine Adapter', () => {
const mockChatbotEngineAdapter: ChatbotEngineAdapter = {
generateResponse: async (profile, history) => {
return `Mocked response for ${profile.name}`;
},
checkBackendHealth: async () => true
};

it('should generate a response', async () => {
const mockProfile: PersonalityProfile = {
id: 'test_profile',
name: 'Test Agent',
description: 'A test agent',
tone: 'formal',
samplePrompts: ['Greetings'],
version: 1
};
const mockHistory: ChatHistory = { messages: [] };

const response = await mockChatbotEngineAdapter.generateResponse(mockProfile, mockHistory);
expect(response).toContain('Mocked response');
});

it('should check backend health', async () => {
const health = await mockChatbotEngineAdapter.checkBackendHealth();
expect(health).toBeTruthy();
});
});

describe('Conversation Orchestrator', () => {
const mockConversationOrchestrator: ConversationOrchestrator = {
handleMessage: async (sessionId, userMessage) => {
const mockReply: OrchestratorAgentReply[] = [{
agentId: 'agent1',
profile: {
id: 'agent1',
name: 'Test Agent',
description: 'A mock agent',
tone: 'philosophical',
samplePrompts: ['What is meaning?'],
version: 1
},
reply: 'A philosophical response'
}];
return mockReply;
},
initializeSession: (selectedAgentIds) => {
return 'mock_session_' + selectedAgentIds.join('_');
}
};

it('should handle messages and return agent replies', async () => {
const replies = await mockConversationOrchestrator.handleMessage('session1', 'Hello');
expect(replies.length).toBeGreaterThan(0);
expect(replies[0].reply).toBe('A philosophical response');
});

it('should initialize a session with selected agents', () => {
const sessionId = mockConversationOrchestrator.initializeSession(['agent1', 'agent2']);
expect(sessionId).toContain('mock_session_agent1_agent2');
});
});
});
14 changes: 14 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"outDir": "./dist"
},
"include": ["src/**/*", "tests/**/*"],
"exclude": ["node_modules"]
}