diff --git a/package.json b/package.json new file mode 100644 index 00000000..d84790a9 --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "multi-agent-chat-platform", + "version": "0.1.0", + "description": "Comprehensive multi-agent interactive chat platform", + "main": "index.js", + "scripts": { + "test": "jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage", + "test:schemas": "jest src/schemas/component-schemas.test.ts" + }, + "devDependencies": { + "@types/jest": "^29.5.3", + "ajv": "^8.12.0", + "jest": "^29.6.1", + "ts-jest": "^29.1.1", + "typescript": "^5.1.6" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "coverageThreshold": { + "global": { + "branches": 75, + "functions": 80, + "lines": 80, + "statements": -10 + } + } + } +} \ No newline at end of file diff --git a/src/interfaces/component-interfaces.ts b/src/interfaces/component-interfaces.ts new file mode 100644 index 00000000..7ce1591e --- /dev/null +++ b/src/interfaces/component-interfaces.ts @@ -0,0 +1,136 @@ +/** + * Comprehensive Interfaces for Multi-Agent Chat Platform + * + * @description Defines core interfaces for system components + * @version 1.0.0 + */ + +/** + * Represents a potential system error + * @interface + */ +export interface SystemError { + /** Unique error code */ + code: string; + /** Human-readable error message */ + message: string; + /** Additional error details */ + details?: Record; +} + +/** + * Personality Profile representing an agent's characteristics + * @interface + */ +export interface PersonalityProfile { + /** Unique identifier for the profile */ + id: string; + /** Display name of the personality */ + name: string; + /** Detailed description of the personality */ + description: string; + /** Communication tone of the agent */ + tone: 'compassionate' | 'authoritative' | 'analytical' | 'empathetic' | 'neutral'; + /** Sample prompts to demonstrate the agent's communication style */ + samplePrompts: string[]; + /** Version of the personality profile */ + version: number; +} + +/** + * Service for managing personality profiles + * @interface + */ +export interface PersonalityProfileService { + /** + * Loads a personality profile by its unique identifier + * @param id - Profile identifier + * @returns Promise resolving to PersonalityProfile or throwing SystemError + */ + loadProfile(id: string): Promise; + + /** + * Validates a personality profile + * @param profile - Profile to validate + * @returns Validation result with potential errors + */ + validateProfile(profile: PersonalityProfile): SystemError[]; + + /** + * Creates a new personality profile + * @param profile - Profile to create + * @returns Created profile or validation errors + */ + createProfile(profile: PersonalityProfile): Promise; +} + +/** + * Represents a chatbot response in a conversation + * @interface + */ +export interface ChatbotResponse { + /** Unique identifier of the responding agent */ + agentId: string; + /** Generated response message */ + message: string; + /** Confidence level of the response */ + confidence: number; + /** Timestamp of response generation */ + timestamp: number; + /** Optional error information */ + error?: SystemError; +} + +/** + * Represents a conversation session between agents + * @interface + */ +export interface ConversationSession { + /** Unique session identifier */ + sessionId: string; + /** Participating agent IDs */ + participants: string[]; + /** Session start timestamp */ + startTime: number; + /** Timestamp of last activity */ + lastActivityTime: number; + /** Conversation messages */ + messages: ChatbotResponse[]; +} + +/** + * API request for initiating a chat + * @interface + */ +export interface ChatRequest { + /** Optional existing session ID */ + sessionId?: string; + /** User's input message */ + userMessage: string; + /** Optional specific agents to involve */ + selectedAgents?: string[]; +} + +/** + * API response for a chat interaction + * @interface + */ +export interface ChatResponse { + /** Session identifier */ + sessionId: string; + /** Agent replies */ + replies: ChatbotResponse[]; + /** Optional error information */ + error?: SystemError; +} + +/** + * Comprehensive error types for system-wide error handling + * @enum + */ +export enum ErrorTypes { + VALIDATION_ERROR = 'VALIDATION_ERROR', + AUTHENTICATION_ERROR = 'AUTHENTICATION_ERROR', + RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND', + SYSTEM_ERROR = 'SYSTEM_ERROR' +} \ No newline at end of file diff --git a/src/schemas/README.md b/src/schemas/README.md new file mode 100644 index 00000000..7697f6f3 --- /dev/null +++ b/src/schemas/README.md @@ -0,0 +1,49 @@ +# Component Interface JSON Schemas + +## Overview +This directory contains comprehensive JSON schemas for the Multi-Agent Chat Platform, providing strict validation and documentation for our system's core interfaces. + +## Schema Definitions + +### Core Components +- `SystemError`: Standardized error reporting structure +- `PersonalityProfile`: Agent personality metadata +- `ChatbotResponse`: Individual agent response format +- `ConversationSession`: Conversation tracking and management +- `ChatRequest`: User interaction request structure +- `ChatResponse`: System's response to chat interactions + +## Validation Rules + +### Naming Conventions +- IDs must be lowercase, alphanumeric with hyphens +- Maximum length of 50 characters for identifiers +- Strict type checking +- Comprehensive error reporting + +### Key Constraints +- Enforce minimum and maximum lengths +- Restrict array sizes +- Validate numeric ranges +- Prevent additional unexpected properties + +## Usage +These schemas can be used with: +- JSON validation libraries +- TypeScript type generation +- Documentation generation +- Runtime type checking + +## Recommended Validation Tools +- `ajv`: JSON Schema validator for JavaScript +- `jsonschema`: Python JSON Schema validator +- `draft-7` compliant validators + +## Best Practices +1. Always validate input against these schemas +2. Use schema for documentation +3. Generate type definitions from schemas +4. Implement runtime type checking + +## Examples +See `component-schemas.test.ts` for validation examples. \ No newline at end of file diff --git a/src/schemas/component-schemas.json b/src/schemas/component-schemas.json new file mode 100644 index 00000000..982ef9fa --- /dev/null +++ b/src/schemas/component-schemas.json @@ -0,0 +1,222 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Multi-Agent Chat Platform Component Schemas", + "description": "Comprehensive JSON schemas for system-wide interfaces", + "type": "object", + "definitions": { + "SystemError": { + "type": "object", + "required": ["code", "message"], + "properties": { + "code": { + "type": "string", + "description": "Unique error identifier", + "enum": [ + "VALIDATION_ERROR", + "AUTHENTICATION_ERROR", + "RESOURCE_NOT_FOUND", + "SYSTEM_ERROR" + ] + }, + "message": { + "type": "string", + "minLength": 1, + "maxLength": 500 + }, + "details": { + "type": ["object", "null"], + "description": "Optional additional error details" + } + } + }, + "PersonalityProfile": { + "type": "object", + "required": ["id", "name", "description", "tone", "samplePrompts", "version"], + "properties": { + "id": { + "type": "string", + "pattern": "^[a-z0-9-]{1,50}$", + "description": "Unique identifier for the profile (lowercase, alphanumeric with hyphens)" + }, + "name": { + "type": "string", + "minLength": 2, + "maxLength": 100, + "description": "Display name of the personality" + }, + "description": { + "type": "string", + "minLength": 10, + "maxLength": 500, + "description": "Detailed description of the personality" + }, + "tone": { + "type": "string", + "enum": [ + "compassionate", + "authoritative", + "analytical", + "empathetic", + "neutral" + ], + "description": "Communication tone of the agent" + }, + "samplePrompts": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 200 + }, + "minItems": 1, + "maxItems": 10, + "description": "Sample prompts demonstrating the agent's communication style" + }, + "version": { + "type": "integer", + "minimum": 1, + "description": "Version of the personality profile" + } + }, + "additionalProperties": false + }, + "ChatbotResponse": { + "type": "object", + "required": ["agentId", "message", "confidence", "timestamp"], + "properties": { + "agentId": { + "type": "string", + "pattern": "^[a-z0-9-]{1,50}$", + "description": "Unique identifier of the responding agent" + }, + "message": { + "type": "string", + "minLength": 1, + "maxLength": 1000, + "description": "Generated response message" + }, + "confidence": { + "type": "number", + "minimum": 0, + "maximum": 1, + "description": "Confidence level of the response (0-1 scale)" + }, + "timestamp": { + "type": "number", + "description": "Unix timestamp of response generation" + }, + "error": { + "$ref": "#/definitions/SystemError" + } + }, + "additionalProperties": false + }, + "ConversationSession": { + "type": "object", + "required": ["sessionId", "participants", "startTime", "lastActivityTime", "messages"], + "properties": { + "sessionId": { + "type": "string", + "pattern": "^[a-z0-9-]{1,50}$", + "description": "Unique identifier for the conversation session" + }, + "participants": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 50 + }, + "minItems": 1, + "maxItems": 10, + "description": "List of participant agent IDs" + }, + "startTime": { + "type": "number", + "description": "Unix timestamp of session start" + }, + "lastActivityTime": { + "type": "number", + "description": "Unix timestamp of last activity in the session" + }, + "messages": { + "type": "array", + "items": { + "$ref": "#/definitions/ChatbotResponse" + }, + "maxItems": 100, + "description": "List of messages in the conversation" + } + }, + "additionalProperties": false + }, + "ChatRequest": { + "type": "object", + "required": ["userMessage"], + "properties": { + "sessionId": { + "type": "string", + "pattern": "^[a-z0-9-]{1,50}$", + "description": "Optional existing session identifier" + }, + "userMessage": { + "type": "string", + "minLength": 1, + "maxLength": 1000, + "description": "User's input message" + }, + "selectedAgents": { + "type": "array", + "items": { + "type": "string", + "minLength": 1, + "maxLength": 50 + }, + "maxItems": 5, + "description": "Optional specific agents to involve in the conversation" + } + }, + "additionalProperties": false + }, + "ChatResponse": { + "type": "object", + "required": ["sessionId", "replies"], + "properties": { + "sessionId": { + "type": "string", + "pattern": "^[a-z0-9-]{1,50}$", + "description": "Session identifier" + }, + "replies": { + "type": "array", + "items": { + "$ref": "#/definitions/ChatbotResponse" + }, + "maxItems": 10, + "description": "Agent replies to the user message" + }, + "error": { + "$ref": "#/definitions/SystemError" + } + }, + "additionalProperties": false + } + }, + "properties": { + "personalityProfile": { + "$ref": "#/definitions/PersonalityProfile" + }, + "chatbotResponse": { + "$ref": "#/definitions/ChatbotResponse" + }, + "conversationSession": { + "$ref": "#/definitions/ConversationSession" + }, + "chatRequest": { + "$ref": "#/definitions/ChatRequest" + }, + "chatResponse": { + "$ref": "#/definitions/ChatResponse" + } + } +} \ No newline at end of file diff --git a/src/schemas/component-schemas.test.ts b/src/schemas/component-schemas.test.ts new file mode 100644 index 00000000..e8868f9a --- /dev/null +++ b/src/schemas/component-schemas.test.ts @@ -0,0 +1,67 @@ +import Ajv from 'ajv'; +import schema from './component-schemas.json'; + +const ajv = new Ajv({ allErrors: true }); +const validate = ajv.compile(schema); + +describe('Component JSON Schemas', () => { + describe('PersonalityProfile Validation', () => { + const validProfile = { + id: 'jesus-001', + name: 'Jesus Christ', + description: 'Founder of Christianity', + tone: 'compassionate', + samplePrompts: ['Love thy neighbor'], + version: 1 + }; + + it('should validate a correct personality profile', () => { + const isValid = validate({ + personalityProfile: validProfile + }); + + expect(isValid).toBeTruthy(); + expect(validate.errors).toBeNull(); + }); + + it('should reject profile with invalid ID', () => { + const invalidProfile = { ...validProfile, id: 'INVALID ID!' }; + + const isValid = validate({ + personalityProfile: invalidProfile + }); + + expect(isValid).toBeFalsy(); + expect(validate.errors).not.toBeNull(); + }); + }); + + describe('ChatbotResponse Validation', () => { + const validResponse = { + agentId: 'peter-001', + message: 'I will follow you, Lord.', + confidence: 0.95, + timestamp: Date.now() + }; + + it('should validate a correct chatbot response', () => { + const isValid = validate({ + chatbotResponse: validResponse + }); + + expect(isValid).toBeTruthy(); + expect(validate.errors).toBeNull(); + }); + + it('should reject response with out-of-range confidence', () => { + const invalidResponse = { ...validResponse, confidence: 1.5 }; + + const isValid = validate({ + chatbotResponse: invalidResponse + }); + + expect(isValid).toBeFalsy(); + expect(validate.errors).not.toBeNull(); + }); + }); +}); \ No newline at end of file diff --git a/src/tests/component-interfaces.test.ts b/src/tests/component-interfaces.test.ts new file mode 100644 index 00000000..d4cc9c94 --- /dev/null +++ b/src/tests/component-interfaces.test.ts @@ -0,0 +1,170 @@ +import { + PersonalityProfile, + ChatbotResponse, + ConversationSession, + ChatRequest, + SystemError, + ErrorTypes, + PersonalityProfileService +} from '../interfaces/component-interfaces'; + +// Mock implementation for testing +class MockPersonalityProfileService implements PersonalityProfileService { + private profiles: Map = new Map(); + + async loadProfile(id: string): Promise { + const profile = this.profiles.get(id); + if (!profile) { + throw { + code: ErrorTypes.RESOURCE_NOT_FOUND, + message: `Profile with ID ${id} not found` + }; + } + return profile; + } + + validateProfile(profile: PersonalityProfile): SystemError[] { + const errors: SystemError[] = []; + + if (!profile.id || profile.id.length < 1) { + errors.push({ + code: ErrorTypes.VALIDATION_ERROR, + message: 'Profile ID is required' + }); + } + + if (!profile.name || profile.name.length < 2) { + errors.push({ + code: ErrorTypes.VALIDATION_ERROR, + message: 'Profile name must be at least 2 characters' + }); + } + + return errors; + } + + async createProfile(profile: PersonalityProfile): Promise { + const validationErrors = this.validateProfile(profile); + if (validationErrors.length > 0) { + return validationErrors; + } + + this.profiles.set(profile.id, profile); + return profile; + } +} + +describe('Component Interfaces Validation', () => { + let profileService: MockPersonalityProfileService; + + beforeEach(() => { + profileService = new MockPersonalityProfileService(); + }); + + describe('PersonalityProfile Service', () => { + const validProfile: PersonalityProfile = { + id: 'jesus-001', + name: 'Jesus Christ', + description: 'Founder of Christianity', + tone: 'compassionate', + samplePrompts: ['Love thy neighbor', 'Forgiveness is divine'], + version: 1 + }; + + it('should create a valid profile', async () => { + const result = await profileService.createProfile(validProfile); + expect(result).toEqual(validProfile); + }); + + it('should reject profile with invalid ID', async () => { + const invalidProfile = { ...validProfile, id: '' }; + const errors = await profileService.createProfile(invalidProfile); + + expect(Array.isArray(errors)).toBeTruthy(); + expect(errors[0].code).toBe(ErrorTypes.VALIDATION_ERROR); + }); + + it('should load an existing profile', async () => { + await profileService.createProfile(validProfile); + const loadedProfile = await profileService.loadProfile('jesus-001'); + + expect(loadedProfile).toEqual(validProfile); + }); + + it('should throw error for non-existent profile', async () => { + await expect(profileService.loadProfile('non-existent')) + .rejects.toMatchObject({ + code: ErrorTypes.RESOURCE_NOT_FOUND + }); + }); + }); + + describe('Chatbot Response Scenarios', () => { + const createChatbotResponse = (overrides: Partial = {}): ChatbotResponse => ({ + agentId: 'peter-001', + message: 'I will follow you, Lord.', + confidence: 0.95, + timestamp: Date.now(), + ...overrides + }); + + it('should handle standard response generation', () => { + const response = createChatbotResponse(); + + expect(response.confidence).toBeLessThanOrEqual(1); + expect(response.confidence).toBeGreaterThanOrEqual(0); + expect(response.message.length).toBeGreaterThan(0); + }); + + it('should handle low confidence responses', () => { + const lowConfidenceResponse = createChatbotResponse({ confidence: 0.1 }); + + expect(lowConfidenceResponse.confidence).toBe(0.1); + }); + + it('should handle responses with errors', () => { + const errorResponse = createChatbotResponse({ + error: { + code: ErrorTypes.SYSTEM_ERROR, + message: 'Failed to generate response' + } + }); + + expect(errorResponse.error).toBeDefined(); + expect(errorResponse.error?.code).toBe(ErrorTypes.SYSTEM_ERROR); + }); + }); + + describe('Conversation Session Complex Scenarios', () => { + const createConversationSession = (overrides: Partial = {}): ConversationSession => ({ + sessionId: 'last-supper-001', + participants: ['jesus', 'peter', 'john'], + startTime: Date.now(), + lastActivityTime: Date.now(), + messages: [], + ...overrides + }); + + it('should manage conversation session lifecycle', () => { + const session = createConversationSession(); + + expect(session.participants.length).toBeGreaterThan(0); + expect(session.startTime).toBeLessThanOrEqual(Date.now()); + }); + + it('should handle session with multiple messages', () => { + const sessionWithMessages = createConversationSession({ + messages: [ + { + agentId: 'jesus', + message: 'One of you will betray me', + confidence: 0.99, + timestamp: Date.now() + } + ] + }); + + expect(sessionWithMessages.messages.length).toBe(1); + }); + }); +}); \ No newline at end of file diff --git a/src/tests/test-coverage-recommendations.md b/src/tests/test-coverage-recommendations.md new file mode 100644 index 00000000..7d7c4a8b --- /dev/null +++ b/src/tests/test-coverage-recommendations.md @@ -0,0 +1,99 @@ +# Test Coverage Recommendations for Multi-Agent Chat Platform + +## Overview +This document provides comprehensive guidelines for achieving robust test coverage across our system components. + +## Coverage Targets +- **Line Coverage**: ≥ 85% +- **Branch Coverage**: ≥ 80% +- **Condition Coverage**: ≥ 75% + +## Component-Specific Coverage Strategies + +### 1. Personality Profile Manager +#### Unit Test Scenarios +- Profile creation with valid data +- Profile creation with invalid data +- Version tracking and rollback +- Schema validation edge cases +- Duplicate profile prevention + +#### Test Coverage Metrics +- Validate all input validation paths +- Test error handling mechanisms +- Cover all possible tone variations +- Verify version increment logic + +### 2. Chatbot Engine Adapter +#### Unit Test Scenarios +- Response generation with different profile types +- Confidence score calculation +- Error scenario handling +- Rate limiting implementation +- Backend compatibility testing + +#### Test Coverage Metrics +- Test multiple confidence thresholds +- Validate error propagation +- Simulate various response scenarios +- Mock different LLM backends + +### 3. Conversation Orchestrator +#### Unit Test Scenarios +- Multi-agent message routing +- Session state management +- Conflict resolution between agents +- Long-running conversation handling +- Edge case message processing + +#### Test Coverage Metrics +- Validate session lifecycle +- Test participant interaction rules +- Verify message order preservation +- Cover communication interruption scenarios + +### 4. API Layer +#### Unit Test Scenarios +- Authentication workflows +- Request validation +- Rate limiting enforcement +- Error response formatting +- Secure endpoint access + +#### Test Coverage Metrics +- Test all HTTP method implementations +- Validate input sanitization +- Simulate authentication failures +- Cover pagination and filtering + +## Recommended Testing Approach +1. **Unit Testing** + - Focus on individual method behaviors + - Use dependency injection for mocking + - Test both happy paths and edge cases + +2. **Integration Testing** + - Validate component interactions + - Test end-to-end workflows + - Simulate real-world usage scenarios + +3. **Performance Testing** + - Measure response times + - Test system under load + - Validate horizontal scalability + +## Tools and Frameworks +- **Unit Testing**: Jest, Vitest +- **Integration Testing**: Cypress, Playwright +- **Performance Testing**: k6, Artillery +- **Coverage Analysis**: Istanbul, SonarQube + +## Continuous Improvement +- Regularly update test suites +- Conduct code reviews focusing on testability +- Maintain a living test strategy document + +## Reporting and Monitoring +- Generate detailed coverage reports +- Track test suite performance +- Implement automated coverage gate in CI/CD \ No newline at end of file diff --git a/src/tests/testing-strategy.md b/src/tests/testing-strategy.md new file mode 100644 index 00000000..11051eb0 --- /dev/null +++ b/src/tests/testing-strategy.md @@ -0,0 +1,67 @@ +# Multi-Agent Chat Platform - Testing Strategy + +## Overview +This document outlines the comprehensive testing approach for our multi-agent interactive chat platform. + +## Testing Pyramid +1. **Unit Tests** (Foundation) + - 80%+ code coverage + - Test individual functions and methods + - Use Jest/Vitest for JavaScript/TypeScript + - Mocking external dependencies + +2. **Integration Tests** (Middle Layer) + - Test component interactions + - Validate API contracts + - Simulate real-world component communication + - Cover edge cases and error scenarios + +3. **End-to-End Tests** (Top Layer) + - Full system workflow testing + - User interaction scenarios + - Performance and load testing + - Cross-component integration validation + +## Testing Frameworks +- **Unit/Integration**: Jest, Vitest +- **E2E**: Cypress, Playwright +- **Performance**: k6, Artillery + +## Test Coverage Metrics +- Line Coverage: ≥ 80% +- Branch Coverage: ≥ 75% +- Mutation Testing: Stryker Mutator + +## Key Testing Areas +1. Personality Data Manager + - Profile validation + - Versioning logic + - Schema enforcement + +2. Chatbot Engine Adapter + - Response generation + - Error handling + - Backend compatibility + +3. Conversation Orchestrator + - Message routing + - Multi-agent dialogue management + - Session state tracking + +4. API Layer + - Authentication + - Rate limiting + - Request/Response validation + +## Testing Principles +- Deterministic tests +- Independent test cases +- Minimal external dependencies +- Clear, descriptive test names +- Consistent test structure + +## Continuous Integration +- Automated tests on every PR +- Blocking merge for failed tests +- Performance and security scans +- Deployment gating \ No newline at end of file