mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-17 06:19:41 +02:00
- Add apiKey option to TranscriptionModuleOptions - Send X-API-Key header in all STT requests when configured - Support config via module options, stt.apiKey, or STT_API_KEY env var - Update CLAUDE.md documentation with API key usage example Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
334 lines
10 KiB
Markdown
334 lines
10 KiB
Markdown
# @manacore/bot-services
|
|
|
|
Shared business logic services for Matrix bots and the Gateway.
|
|
|
|
## Purpose
|
|
|
|
This package provides **transport-agnostic** services that contain all business logic for the Matrix bot ecosystem. Services in this package:
|
|
|
|
- Have no Matrix-specific code
|
|
- Can be used by individual bots OR the unified Gateway
|
|
- Support pluggable storage (file-based, in-memory, database)
|
|
- Are fully testable in isolation
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
│ @manacore/bot-services │
|
|
├─────────────────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ TodoService │ │ CalendarSvc │ │ AiService │ │ ClockService│ │
|
|
│ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
│ │
|
|
│ Pure business logic - no Matrix code! │
|
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
│
|
|
┌───────────────┼───────────────┐
|
|
▼ ▼ ▼
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
│ Gateway │ │ Todo Bot │ │ CLI │
|
|
│ (Matrix) │ │ (Matrix) │ │ Tool │
|
|
└──────────┘ └──────────┘ └──────────┘
|
|
```
|
|
|
|
## Available Services
|
|
|
|
### Business Logic Services
|
|
|
|
| Service | Storage | Description |
|
|
|---------|---------|-------------|
|
|
| `TodoService` | File (JSON) | Task management with projects, priorities, dates |
|
|
| `CalendarService` | File (JSON) | Events, calendars, reminders |
|
|
| `AiService` | In-memory | Ollama LLM integration, chat sessions, vision |
|
|
| `ClockService` | External API | Timers, alarms, world clocks |
|
|
|
|
### Infrastructure Services
|
|
|
|
| Service | Storage | Description |
|
|
|---------|---------|-------------|
|
|
| `SessionService` | In-memory | User authentication via mana-core-auth |
|
|
| `TranscriptionService` | External API | Speech-to-text via mana-stt service |
|
|
|
|
### Placeholder Services (to be implemented)
|
|
|
|
| Service | Description |
|
|
|---------|-------------|
|
|
| `NutritionService` | Meal tracking |
|
|
| `QuotesService` | Daily quotes |
|
|
| `StatsService` | Analytics reports |
|
|
| `DocsService` | Documentation generation |
|
|
|
|
## Usage
|
|
|
|
### In NestJS (Bot or Gateway)
|
|
|
|
```typescript
|
|
import { Module } from '@nestjs/common';
|
|
import {
|
|
TodoModule,
|
|
CalendarModule,
|
|
AiModule,
|
|
ClockModule,
|
|
SessionModule,
|
|
TranscriptionModule,
|
|
} from '@manacore/bot-services';
|
|
|
|
@Module({
|
|
imports: [
|
|
// File-based storage (default)
|
|
TodoModule.register({ storagePath: './data/todos.json' }),
|
|
CalendarModule.register({ storagePath: './data/calendar.json' }),
|
|
|
|
// External services
|
|
AiModule.register({ baseUrl: 'http://ollama:11434' }),
|
|
ClockModule.register({ apiUrl: 'http://clock-backend:3017/api/v1' }),
|
|
|
|
// Infrastructure services (use ConfigService by default)
|
|
SessionModule.forRoot(),
|
|
TranscriptionModule.forRoot(),
|
|
],
|
|
})
|
|
export class AppModule {}
|
|
```
|
|
|
|
### Session Service (Authentication)
|
|
|
|
```typescript
|
|
import { SessionService } from '@manacore/bot-services';
|
|
|
|
// Login a Matrix user
|
|
const result = await sessionService.login(
|
|
'@user:matrix.org',
|
|
'email@example.com',
|
|
'password'
|
|
);
|
|
|
|
if (result.success) {
|
|
// Get token for API calls
|
|
const token = sessionService.getToken('@user:matrix.org');
|
|
|
|
// Check if logged in
|
|
const isLoggedIn = sessionService.isLoggedIn('@user:matrix.org');
|
|
}
|
|
|
|
// Logout
|
|
sessionService.logout('@user:matrix.org');
|
|
|
|
// Store custom session data
|
|
sessionService.setSessionData('@user:matrix.org', 'currentConversationId', 'abc123');
|
|
const convId = sessionService.getSessionData<string>('@user:matrix.org', 'currentConversationId');
|
|
```
|
|
|
|
### Transcription Service (Speech-to-Text)
|
|
|
|
```typescript
|
|
import { TranscriptionService, TranscriptionModule } from '@manacore/bot-services';
|
|
|
|
// Module registration with API key
|
|
TranscriptionModule.register({
|
|
sttUrl: 'http://mana-stt:3020',
|
|
apiKey: process.env.STT_API_KEY, // Optional: for authenticated STT service
|
|
defaultLanguage: 'de'
|
|
})
|
|
|
|
// Or use forRoot() which reads from config:
|
|
// - stt.url / STT_URL
|
|
// - stt.apiKey / STT_API_KEY
|
|
|
|
// Transcribe audio buffer
|
|
const text = await transcriptionService.transcribe(audioBuffer, { language: 'de' });
|
|
|
|
// Get full response with metadata
|
|
const result = await transcriptionService.transcribeWithMetadata(audioBuffer);
|
|
console.log(result.text, result.language, result.model);
|
|
|
|
// Health check
|
|
const isHealthy = await transcriptionService.checkHealth();
|
|
```
|
|
|
|
### Direct Service Usage
|
|
|
|
```typescript
|
|
import { TodoService } from '@manacore/bot-services/todo';
|
|
import { AiService } from '@manacore/bot-services/ai';
|
|
|
|
// Create task
|
|
const task = await todoService.createTask('@user:matrix.org', {
|
|
title: 'Buy groceries',
|
|
priority: 2,
|
|
dueDate: '2025-01-30',
|
|
});
|
|
|
|
// AI chat
|
|
const response = await aiService.chatSimple('@user:matrix.org', 'What is TypeScript?');
|
|
```
|
|
|
|
### Custom Storage Provider
|
|
|
|
```typescript
|
|
import { TodoModule, StorageProvider, TodoData } from '@manacore/bot-services';
|
|
|
|
// PostgreSQL storage example
|
|
class PostgresTodoStorage implements StorageProvider<TodoData> {
|
|
async load(): Promise<TodoData> {
|
|
// Load from database
|
|
}
|
|
async save(data: TodoData): Promise<void> {
|
|
// Save to database
|
|
}
|
|
}
|
|
|
|
// Use custom storage
|
|
TodoModule.forRoot(new PostgresTodoStorage());
|
|
```
|
|
|
|
## Input Parsing
|
|
|
|
Services include German-language natural input parsing:
|
|
|
|
### Todo
|
|
|
|
```typescript
|
|
const parsed = todoService.parseTaskInput('Einkaufen !p1 @morgen #haushalt');
|
|
// { title: 'Einkaufen', priority: 1, dueDate: '2025-01-30', project: 'haushalt' }
|
|
```
|
|
|
|
### Calendar
|
|
|
|
```typescript
|
|
const parsed = calendarService.parseEventInput('Meeting morgen um 14:30');
|
|
// { title: 'Meeting', startTime: Date, endTime: Date, isAllDay: false }
|
|
```
|
|
|
|
### Clock
|
|
|
|
```typescript
|
|
const seconds = clockService.parseDuration('1h30m'); // 5400
|
|
const time = clockService.parseAlarmTime('14 Uhr 30'); // '14:30:00'
|
|
```
|
|
|
|
## Development
|
|
|
|
```bash
|
|
# Type check
|
|
pnpm --filter @manacore/bot-services type-check
|
|
|
|
# Install in a bot
|
|
pnpm --filter matrix-todo-bot add @manacore/bot-services
|
|
```
|
|
|
|
## Adding New Services
|
|
|
|
1. Create directory: `src/{service}/`
|
|
2. Add files:
|
|
- `types.ts` - Interfaces and types
|
|
- `{service}.service.ts` - Business logic
|
|
- `{service}.module.ts` - NestJS module
|
|
- `index.ts` - Exports
|
|
3. Export from `src/index.ts`
|
|
4. Update `package.json` exports
|
|
|
|
## File Structure
|
|
|
|
```
|
|
packages/bot-services/
|
|
├── src/
|
|
│ ├── index.ts # Main exports
|
|
│ ├── shared/
|
|
│ │ ├── types.ts # Common types
|
|
│ │ ├── storage.ts # Storage providers
|
|
│ │ ├── utils.ts # Utility functions
|
|
│ │ └── index.ts
|
|
│ ├── todo/
|
|
│ ├── calendar/
|
|
│ ├── ai/
|
|
│ ├── clock/
|
|
│ ├── session/ # NEW: User authentication
|
|
│ │ ├── types.ts
|
|
│ │ ├── session.service.ts
|
|
│ │ ├── session.module.ts
|
|
│ │ └── index.ts
|
|
│ ├── transcription/ # NEW: Speech-to-text
|
|
│ │ ├── types.ts
|
|
│ │ ├── transcription.service.ts
|
|
│ │ ├── transcription.module.ts
|
|
│ │ └── index.ts
|
|
│ └── ...
|
|
├── package.json
|
|
├── tsconfig.json
|
|
└── CLAUDE.md
|
|
```
|
|
|
|
## Migrating Bots to Shared Services
|
|
|
|
To migrate a bot from local services to shared services:
|
|
|
|
### 1. Add dependency
|
|
|
|
```bash
|
|
# In package.json
|
|
"dependencies": {
|
|
"@manacore/bot-services": "workspace:*",
|
|
...
|
|
}
|
|
```
|
|
|
|
### 2. Update module imports
|
|
|
|
```typescript
|
|
// bot.module.ts - BEFORE
|
|
import { SessionModule } from '../session/session.module';
|
|
import { TranscriptionModule } from '../transcription/transcription.module';
|
|
|
|
@Module({
|
|
imports: [SessionModule, TranscriptionModule],
|
|
})
|
|
|
|
// bot.module.ts - AFTER
|
|
import { SessionModule, TranscriptionModule } from '@manacore/bot-services';
|
|
|
|
@Module({
|
|
imports: [SessionModule.forRoot(), TranscriptionModule.forRoot()],
|
|
})
|
|
```
|
|
|
|
### 3. Update service imports
|
|
|
|
```typescript
|
|
// matrix.service.ts - BEFORE
|
|
import { SessionService } from '../session/session.service';
|
|
import { TranscriptionService } from '../transcription/transcription.service';
|
|
|
|
// matrix.service.ts - AFTER
|
|
import { SessionService, TranscriptionService } from '@manacore/bot-services';
|
|
```
|
|
|
|
### 4. Delete local modules
|
|
|
|
```bash
|
|
rm -rf src/session/
|
|
rm -rf src/transcription/
|
|
```
|
|
|
|
### Migrated Bots
|
|
|
|
| Bot | SessionService | TranscriptionService |
|
|
|-----|----------------|---------------------|
|
|
| matrix-todo-bot | - | ✅ |
|
|
| matrix-picture-bot | ✅ | - |
|
|
| matrix-clock-bot | - | ✅ |
|
|
| matrix-zitare-bot | ✅ | ✅ |
|
|
| matrix-chat-bot | ✅ | - |
|
|
| matrix-contacts-bot | ✅ | - |
|
|
| matrix-nutriphi-bot | ✅ | ✅ |
|
|
| matrix-project-doc-bot | - | ✅ |
|
|
| matrix-skilltree-bot | ✅ | - |
|
|
| matrix-presi-bot | ✅ | - |
|
|
| matrix-questions-bot | ✅ | - |
|
|
| matrix-storage-bot | ✅ | - |
|
|
| matrix-planta-bot | ✅ | - |
|
|
| matrix-manadeck-bot | ✅ | - |
|
|
|
|
**All bots with SessionService and TranscriptionService have been migrated.**
|