Shared MongoDB schemas and connection for Multiplayer AI agent services
npm install @multiplayer-app/ai-agent-dbA database-agnostic repository abstraction layer for Multiplayer AI agent services. This library provides TypeScript interfaces for data access operations, allowing you to implement repository patterns for any database backend (MongoDB, PostgreSQL, MySQL, etc.).
- Database-Agnostic Interfaces: Abstract repository interfaces that work with any database
- Type-Safe Operations: Full TypeScript support with generic types
- Repository Pattern: Clean separation of data access logic from business logic
- Specialized Repositories: Domain-specific interfaces for AgentChat and AgentMessage entities
- Flexible Querying: Support for filtering, sorting, and pagination
- Node.js >= 18
- TypeScript >= 5.0
- A database implementation library (e.g., @multiplayer-app/ai-agent-mongo for MongoDB)
This library provides interfaces only - no concrete implementations. It follows the Repository pattern to abstract database operations, making your code database-agnostic and easily testable.
#### BaseRepository
Generic interface providing standard CRUD operations:
``typescript`
interface BaseRepository
findById(id: ID): Promise
find(filter?: Partial
findOne(filter: Partial
create(entity: Omit
update(id: ID, updates: Partial
delete(id: ID): Promise
exists(id: ID): Promise
count(filter?: Partial
}
#### AgentChatRepository
Extends BaseRepository with chat-specific operations:
- findByUserId(userId: string): Find all chats for a userfindByContextKey(contextKey: string)
- : Find all chats for a contextfindByUserIdAndContextKey(userId: string, contextKey: string)
- : Find chats by user and contextfindGuestChatsByContextKey(contextKey: string)
- : Find guest chats (no userId)updateTitle(id: string, title: string)
- : Update chat titledeleteByUserId(userId: string)
- : Delete all chats for a userdeleteByContextKey(contextKey: string)
- : Delete all chats for a contextfindWithMessages(...)
- : Find chats with related messages (aggregation)
#### AgentMessageRepository
Extends BaseRepository with message-specific operations:
- findByChatId(chatId: string): Find all messages for a chatfindByRole(role: MessageRole)
- : Find messages by rolefindByChatIdAndRole(chatId: string, role?: MessageRole)
- : Find messages by chat and rolefindWithToolCalls(chatId?: string)
- : Find messages with tool callsfindWithAttachments(chatId?: string)
- : Find messages with attachmentsdeleteByChatId(chatId: string)
- : Delete all messages for a chatdeleteByRole(role: MessageRole)
- : Delete messages by roledeleteByChatIdAndRole(chatId: string, role: MessageRole)
- : Delete messages by chat and role
The easiest way to use this library is with the MongoDB implementation:
`typescript
import { MongoAgentChatRepository, MongoAgentMessageRepository } from '@multiplayer-app/ai-agent-mongo';
// Initialize repositories
const chatRepository = new MongoAgentChatRepository();
const messageRepository = new MongoAgentMessageRepository();
// Use the repositories
const chat = await chatRepository.findById('chat-id');
const messages = await messageRepository.findByChatId('chat-id');
`
To implement these interfaces for a different database (e.g., PostgreSQL, MySQL):
`typescript
import type { AgentChatRepository } from '@multiplayer-app/ai-agent-db';
import type { AgentChat } from '@multiplayer-app/ai-agent-types';
export class PostgresAgentChatRepository implements AgentChatRepository {
async findById(id: string): Promise
// Your PostgreSQL implementation
const result = await db.query('SELECT * FROM chats WHERE id = $1', [id]);
return result.rows[0] || null;
}
async find(
filter?: Partial
options?: { sort?: { field: string; order: SortOrder }; limit?: number }
): Promise
// Your implementation with filtering, sorting, and pagination
}
// Implement all other required methods...
}
`
`typescript
import type { AgentChatRepository } from '@multiplayer-app/ai-agent-db';
// Find all chats for a user
const userChats = await chatRepository.findByUserId('user-123');
// 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 } }
);
`
`typescript
import type { AgentMessageRepository } from '@multiplayer-app/ai-agent-db';
// Find all messages in a chat
const messages = await messageRepository.findByChatId('chat-id');
// Find only assistant messages
const assistantMessages = await messageRepository.findByChatIdAndRole(
'chat-id',
MessageRole.Assistant
);
// Find messages with tool calls
const toolCallMessages = await messageRepository.findWithToolCalls('chat-id');
// Create a new message
const newMessage = await messageRepository.create({
chat: 'chat-id',
role: MessageRole.User,
content: 'Hello, AI!'
});
`
The BaseRepository interface provides a consistent API across all entity types:
`typescript
// Works with any entity type
const repository: BaseRepository
// Standard CRUD operations
const entity = await repository.findById('id');
const entities = await repository.find({ status: 'active' });
const created = await repository.create({ name: 'New Entity' });
const updated = await repository.update('id', { name: 'Updated' });
const deleted = await repository.delete('id');
const exists = await repository.exists('id');
const count = await repository.count({ status: 'active' });
`
See @multiplayer-app/ai-agent-mongo for a complete MongoDB implementation using Mongoose:
- Uses Mongoose schemas and models
- Handles ObjectId conversion
- Implements aggregation pipelines for complex queries
- Provides transaction support
All interfaces are fully typed using TypeScript generics and types from @multiplayer-app/ai-agent-types:
`typescript
import type { AgentChat, AgentMessage, SortOrder } from '@multiplayer-app/ai-agent-types';
import type { AgentChatRepository, AgentMessageRepository } from '@multiplayer-app/ai-agent-db';
// TypeScript ensures type safety
const chat: AgentChat = await chatRepository.findById('id');
const messages: AgentMessage[] = await messageRepository.findByChatId('chat-id');
`
1. Dependency Injection: Pass repository instances to your services rather than creating them directly
2. Error Handling: Implement proper error handling in your repository implementations
3. Transactions: For databases that support it, implement transaction support in your repositories
4. Caching: Consider adding caching layers above the repository layer for frequently accessed data
5. Testing: Use the interfaces to create mock repositories for unit testing
- @multiplayer-app/ai-agent-types: Type definitions for AgentChat, AgentMessage, etc.@multiplayer-app/ai-agent-mongo
- : MongoDB implementation of these interfaces@multiplayer-app/ai-agent-node`: Node.js library that uses these repositories
-
MIT