All checks were successful
ci/woodpecker/push/api Pipeline was successful
Add SpeechGateway with Socket.IO namespace /speech for real-time streaming transcription. Supports start-transcription, audio-chunk, and stop-transcription events with session management, authentication, and buffer size rate limiting. Includes 29 unit tests covering authentication, session lifecycle, error handling, cleanup, and client isolation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
/**
|
|
* SpeechModule
|
|
*
|
|
* NestJS module for speech-to-text (STT) and text-to-speech (TTS) services.
|
|
* Provides a provider abstraction layer with graceful fallback for TTS tiers.
|
|
*
|
|
* TTS providers are created dynamically based on configuration:
|
|
* - default: Kokoro-FastAPI (CPU, always available)
|
|
* - premium: Chatterbox (GPU, voice cloning)
|
|
* - fallback: Piper via OpenedAI Speech (ultra-lightweight CPU)
|
|
*
|
|
* Imports:
|
|
* - ConfigModule.forFeature(speechConfig) for speech configuration
|
|
* - AuthModule for WebSocket authentication
|
|
* - PrismaModule for workspace membership queries
|
|
*
|
|
* Providers:
|
|
* - SpeechService: High-level speech operations with provider selection
|
|
* - SpeechGateway: WebSocket gateway for streaming transcription (Issue #397)
|
|
* - TTS_PROVIDERS: Map<SpeechTier, ITTSProvider> populated by factory based on config
|
|
*
|
|
* Exports:
|
|
* - SpeechService for use by other modules (e.g., controllers, brain)
|
|
*
|
|
* Issue #389, #390, #391, #397
|
|
*/
|
|
|
|
import { Module, type OnModuleInit, Logger } from "@nestjs/common";
|
|
import { ConfigModule, ConfigService } from "@nestjs/config";
|
|
import {
|
|
speechConfig,
|
|
validateSpeechConfig,
|
|
isSttEnabled,
|
|
type SpeechConfig,
|
|
} from "./speech.config";
|
|
import { SpeechService } from "./speech.service";
|
|
import { SpeechController } from "./speech.controller";
|
|
import { SpeechGateway } from "./speech.gateway";
|
|
import { STT_PROVIDER, TTS_PROVIDERS } from "./speech.constants";
|
|
import { SpeachesSttProvider } from "./providers/speaches-stt.provider";
|
|
import { createTTSProviders } from "./providers/tts-provider.factory";
|
|
import { AuthModule } from "../auth/auth.module";
|
|
import { PrismaModule } from "../prisma/prisma.module";
|
|
|
|
@Module({
|
|
imports: [ConfigModule.forFeature(speechConfig), AuthModule, PrismaModule],
|
|
controllers: [SpeechController],
|
|
providers: [
|
|
SpeechService,
|
|
SpeechGateway,
|
|
// STT provider: conditionally register SpeachesSttProvider when STT is enabled
|
|
...(isSttEnabled()
|
|
? [
|
|
{
|
|
provide: STT_PROVIDER,
|
|
useClass: SpeachesSttProvider,
|
|
},
|
|
]
|
|
: []),
|
|
{
|
|
provide: TTS_PROVIDERS,
|
|
useFactory: (configService: ConfigService) => {
|
|
const config = configService.get<SpeechConfig>("speech");
|
|
if (!config) {
|
|
return new Map();
|
|
}
|
|
return createTTSProviders(config);
|
|
},
|
|
inject: [ConfigService],
|
|
},
|
|
],
|
|
exports: [SpeechService],
|
|
})
|
|
export class SpeechModule implements OnModuleInit {
|
|
private readonly logger = new Logger(SpeechModule.name);
|
|
|
|
onModuleInit(): void {
|
|
// Validate configuration at startup (fail fast)
|
|
validateSpeechConfig();
|
|
this.logger.log("Speech module initialized");
|
|
}
|
|
}
|