npm package: @multiplayer-app/ai-agent-mongo
Description: Shared MongoDB schemas and connection for Multiplayer AI agent services
Latest version: 0.1.0-beta.70

# @multiplayer-app/ai-agent-mongo

MongoDB implementation of the database repository interfaces for Multiplayer AI agent services. This library provides concrete Mongoose-based implementations of `AgentChatRepository` and `AgentMessageRepository`, along with MongoDB connection management and client-side encryption support.

## Features

- **MongoDB Implementation**: Complete Mongoose-based implementation of repository interfaces
- **Type-Safe Schemas**: Mongoose schemas with full TypeScript support
- **Client-Side Encryption**: Support for MongoDB client-side field-level encryption (CSFLE)
- **Connection Management**: Automatic connection handling with reconnection support
- **Indexed Queries**: Optimized database indexes for common query patterns
- **Aggregation Support**: Complex queries with message aggregation
- **Transaction Support**: MongoDB transaction support for multi-document operations

## Prerequisites

- Node.js >= 18
- TypeScript >= 5.0
- MongoDB >= 6.0 (for encryption features)
- MongoDB instance (local or remote)

## Quick Start

### Basic Setup

```typescript
import mongo from '@multiplayer-app/ai-agent-mongo';
import { MongoAgentChatRepository, MongoAgentMessageRepository } from '@multiplayer-app/ai-agent-mongo';

// Connect to MongoDB
await mongo.connect();

// Initialize repositories
const chatRepository = new MongoAgentChatRepository();
const messageRepository = new MongoAgentMessageRepository();

// Use repositories
const chat = await chatRepository.findById('chat-id');
const messages = await messageRepository.findByChatId('chat-id');

// Disconnect when done
await mongo.disconnect();
```

### Environment Variables

Configure MongoDB connection and encryption via environment variables:

```bash
# MongoDB Connection
MONGODB_URI=mongodb://localhost:27017/ai-agent

# MongoDB Debug Mode (optional)
MONGO_DEBUG=false

# Encryption Configuration
MONGODB_ENCRYPTION_KEY_VAULT_DB_NAME=encryption
MONGODB_ENCRYPTION_KEY_VAULT_COLLECTION_NAME=__keyVault
MONGODB_ENCRYPTION_DEK_NAME=data-key
MONGODB_ENCRYPTION_MASTER_KEY_PROVIDER=local  # or 'aws'

# AWS KMS Configuration (if using AWS KMS)
AWS_KMS_KEY_ARN=arn:aws:kms:region:account:key/key-id
AWS_REGION=us-east-1
```

## Architecture

This library implements the abstract repository interfaces from `@multiplayer-app/ai-agent-db` using Mongoose as the ODM (Object Document Mapper) for MongoDB.

### Core Components

#### Repositories

- **`MongoAgentChatRepository`**: Implements `AgentChatRepository` interface
- **`MongoAgentMessageRepository`**: Implements `AgentMessageRepository` interface

#### Schemas

- **`AgentChatSchema`**: Mongoose schema for `AgentChat` entities
- **`AgentMessageSchema`**: Mongoose schema for `AgentMessage` entities

#### MongoDB Connection

- **`mongo.connect()`**: Establishes MongoDB connection with encryption setup
- **`mongo.disconnect()`**: Closes MongoDB connection
- **`mongo.connected()`**: Checks connection status

#### Encryption

- **`mongo.encryption.encrypt()`**: Encrypt data using client-side encryption
- **`mongo.encryption.decrypt()`**: Decrypt encrypted data
- Supports both local key provider and AWS KMS

## Usage

### Connection Management

```typescript
import mongo from '@multiplayer-app/ai-agent-mongo';

// Connect to MongoDB
await mongo.connect();

// Check connection status
if (mongo.connected()) {
  console.log('Connected to MongoDB');
}

// Disconnect
await mongo.disconnect();
```

### Using Repositories

#### AgentChatRepository

```typescript
import { MongoAgentChatRepository } from '@multiplayer-app/ai-agent-mongo';
import { SortOrder } from '@multiplayer-app/ai-agent-types';

const chatRepository = new MongoAgentChatRepository();

// Find chat by ID
const chat = await chatRepository.findById('chat-id');

// Find chats by user
const userChats = await chatRepository.findByUserId('user-123');

// Find chats by context
const contextChats = await chatRepository.findByContextKey('context-key');

// Find chats with pagination and sorting
const recentChats = await chatRepository.find(
  { contextKey: 'my-context' },
  {
    sort: { field: 'updatedAt', order: SortOrder.Desc },
    limit: 10
  }
);

// Find chats with messages (aggregation)
const chatsWithMessages = await chatRepository.findWithMessages(
  { userId: 'user-123' },
  { sort: { field: 'createdAt', order: SortOrder.Desc } }
);

// Create a new chat
const newChat = await chatRepository.create({
  title: 'New Chat',
  contextKey: 'context-key',
  userId: 'user-123',
  status: AgentStatus.Active,
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
});

// Update chat title
await chatRepository.updateTitle('chat-id', 'Updated Title');

// Delete chat
await chatRepository.delete('chat-id');
```

#### AgentMessageRepository

```typescript
import { MongoAgentMessageRepository } from '@multiplayer-app/ai-agent-mongo';
import { MessageRole } from '@multiplayer-app/ai-agent-types';

const messageRepository = new MongoAgentMessageRepository();

// Find messages by chat ID
const messages = await messageRepository.findByChatId('chat-id');

// Find messages by role
const assistantMessages = await messageRepository.findByRole(MessageRole.Assistant);

// Find messages by chat and role
const userMessages = await messageRepository.findByChatIdAndRole(
  'chat-id',
  MessageRole.User
);

// Find messages with tool calls
const toolCallMessages = await messageRepository.findWithToolCalls('chat-id');

// Find messages with attachments
const messagesWithAttachments = await messageRepository.findWithAttachments('chat-id');

// Create a new message
const newMessage = await messageRepository.create({
  chat: 'chat-id',
  role: MessageRole.User,
  content: 'Hello, AI!',
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString()
});

// Delete messages by chat
await messageRepository.deleteByChatId('chat-id');
```

### Using Schemas Directly

You can also use the Mongoose models directly for advanced operations:

```typescript
import { AgentChatModel, AgentMessageModel } from '@multiplayer-app/ai-agent-mongo';

// Direct Mongoose queries
const chat = await AgentChatModel.findOne({ userId: 'user-123' });

// Aggregation pipelines
const stats = await AgentChatModel.aggregate([
  { $match: { contextKey: 'context-key' } },
  { $group: { _id: '$status', count: { $sum: 1 } } }
]);
```

### Encryption

The library supports MongoDB client-side field-level encryption (CSFLE):

```typescript
import mongo from '@multiplayer-app/ai-agent-mongo';

// Encrypt sensitive data
const encrypted = await mongo.encryption.encrypt('sensitive-data');

// Decrypt data
const decrypted = await mongo.encryption.decrypt(encrypted);
```

#### Encryption Providers

**Local Key Provider** (Development):
```bash
MONGODB_ENCRYPTION_MASTER_KEY_PROVIDER=local
```

**AWS KMS** (Production):
```bash
MONGODB_ENCRYPTION_MASTER_KEY_PROVIDER=aws
AWS_KMS_KEY_ARN=arn:aws:kms:region:account:key/key-id
AWS_REGION=us-east-1
```

## Database Indexes

The library automatically creates indexes for optimal query performance:

### AgentChat Indexes
- `contextKey` (single field)
- `userId` (single field, sparse)
- `userId + contextKey` (compound)

### AgentMessage Indexes
- `chat` (single field)
- `role` (single field)
- `chat + role` (compound)

## Type Safety

All operations are fully typed using TypeScript:

```typescript
import type { AgentChat, AgentMessage } from '@multiplayer-app/ai-agent-types';
import { MongoAgentChatRepository } from '@multiplayer-app/ai-agent-mongo';

const chatRepository = new MongoAgentChatRepository();

// TypeScript ensures type safety
const chat: AgentChat | null = await chatRepository.findById('id');
const chats: AgentChat[] = await chatRepository.findByUserId('user-id');
```

## Error Handling

The library handles MongoDB connection errors and provides logging:

```typescript
import mongo from '@multiplayer-app/ai-agent-mongo';

try {
  await mongo.connect();
} catch (error) {
  console.error('Failed to connect to MongoDB:', error);
}
```
## Testing

The library includes test utilities using `mongodb-memory-server` for in-memory MongoDB testing:

```bash
# Run tests
npm test

# Watch mode
npm run test:watch

# Coverage
npm run test:coverage
```

## Best Practices

1. **Connection Lifecycle**: Always call `mongo.connect()` before using repositories and `mongo.disconnect()` when shutting down
2. **Repository Instances**: Create repository instances once and reuse them (they're stateless)
3. **Error Handling**: Wrap repository calls in try-catch blocks for proper error handling
4. **Transactions**: Use MongoDB sessions for multi-document transactions when needed
5. **Indexes**: The library creates indexes automatically, but ensure your MongoDB instance has sufficient resources
6. **Encryption**: Use AWS KMS in production, local keys only for development

## Performance Considerations

- **Connection Pooling**: The library uses Mongoose connection pooling (minPoolSize: 3)
- **Indexes**: All common query patterns are indexed for optimal performance
- **Aggregation**: Complex queries use MongoDB aggregation pipelines for efficiency
- **ObjectId Conversion**: Automatic conversion between string IDs and MongoDB ObjectIds

## Related Packages

- `@multiplayer-app/ai-agent-db`: Abstract repository interfaces
- `@multiplayer-app/ai-agent-types`: Type definitions for AgentChat, AgentMessage, etc.
- `@multiplayer-app/ai-agent-node`: Node.js library that uses these repositories

## License

MIT