Add Ask Mento, customer mood, and Pipecat speech-to-text.

Ship assistant answers, contact moods, voice dictation, and the related CRM UI so these can be deployed to production.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-03 14:20:55 +03:30
co-authored by Cursor
parent 0dd2966f3c
commit 7757c0837d
43 changed files with 5156 additions and 1741 deletions
+58
View File
@@ -0,0 +1,58 @@
import {
Body,
Controller,
Get,
Param,
Post,
UploadedFile,
UseGuards,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { memoryStorage } from 'multer';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { CurrentUser } from '../auth/current-user.decorator';
import type { Actor } from '../common/record-scope';
import { AiAskService } from './ai-ask.service';
import { AskMentoDto } from './dto';
import { AiService } from './ai.service';
import { AiSttService } from './ai-stt.service';
@Controller('ai')
@UseGuards(JwtAuthGuard)
export class AiController {
constructor(
private readonly ai: AiService,
private readonly ask: AiAskService,
private readonly stt: AiSttService,
) {}
@Get('status')
status() {
return { enabled: this.ai.isEnabled(), stt: this.stt.isEnabled() };
}
@Post('transcribe')
@UseInterceptors(
FileInterceptor('audio', {
storage: memoryStorage(),
limits: { fileSize: 8 * 1024 * 1024 },
}),
)
transcribe(@UploadedFile() file: Express.Multer.File) {
return this.stt.transcribe(file);
}
@Post('ask')
askMento(@CurrentUser() user: Actor, @Body() dto: AskMentoDto) {
return this.ask.ask(user, dto.question, dto.personId);
}
@Get('people/:personId/summary')
personSummary(
@CurrentUser() user: Actor,
@Param('personId') personId: string,
) {
return this.ask.summarizePerson(user, personId);
}
}