@@ -6,10 +6,31 @@ import { PromptTemplateService } from './prompt-template.service';
66import { ClaudeProvider } from './providers/claude.provider' ;
77import { OpenaiProvider } from './providers/openai.provider' ;
88
9- function validateAiConfig ( configService : ConfigService ) : void {
10- const provider = configService . get < string > ( 'AI_PROVIDER' ) ;
11- if ( provider && ! [ 'openai' , 'claude' ] . includes ( provider ) ) {
12- throw new Error ( `Invalid AI_PROVIDER: ${ provider } . Must be 'openai' or 'claude'.` ) ;
9+ /**
10+ * BA-076: Validate the AI configuration at startup, before any request
11+ * arrives.
12+ *
13+ * Rules:
14+ * - `AI_PROVIDER=openai` requires `OPENAI_API_KEY`.
15+ * - `AI_PROVIDER=claude` requires `ANTHROPIC_API_KEY`.
16+ * - `AI_PROVIDER=mock` (or unset) requires no credentials.
17+ *
18+ * Error messages are actionable and sanitized: they name the missing
19+ * variable and the fix, but never echo credential values.
20+ */
21+ export function validateAiConfig ( configService : ConfigService ) : void {
22+ const provider = configService . get < string > ( 'AI_PROVIDER' ) ?? 'mock' ;
23+
24+ if ( provider === 'openai' || provider === 'claude' ) {
25+ const credentialsKey =
26+ provider === 'openai' ? 'OPENAI_API_KEY' : 'ANTHROPIC_API_KEY' ;
27+ const apiKey = configService . get < string > ( credentialsKey ) ;
28+ if ( ! apiKey || apiKey . trim ( ) . length === 0 ) {
29+ throw new Error (
30+ `AI_PROVIDER is "${ provider } " but ${ credentialsKey } is not set. ` +
31+ `Set ${ credentialsKey } to your API key, or switch AI_PROVIDER to "mock" for local development.` ,
32+ ) ;
33+ }
1334 }
1435
1536 const numericParams : Array < { key : string ; min : number ; max : number ; integer ?: boolean } > = [
@@ -31,7 +52,7 @@ function validateAiConfig(configService: ConfigService): void {
3152 throw new Error ( `AI config ${ param . key } must be an integer, got "${ raw } ".` ) ;
3253 }
3354 if ( num < param . min || num > param . max ) {
34- throw new Error ( `AI config ${ param . key } must be tween ${ param . min } and ${ param . max } , got "${ raw } ".` ) ;
55+ throw new Error ( `AI config ${ param . key } must be between ${ param . min } and ${ param . max } , got "${ raw } ".` ) ;
3556 }
3657 process . env [ param . key ] = String ( num ) ;
3758 }
@@ -43,7 +64,7 @@ function validateAiConfig(configService: ConfigService): void {
4364 const lower = raw . toLowerCase ( ) ;
4465 if ( [ 'true' , '1' , 'yes' , 'y' , 'on' ] . includes ( lower ) ) {
4566 process . env [ key ] = 'true' ;
46- } else if ( [ 'false' , '0' , 'no' , 'n' , 'off' ] . includes ( lower ) ) {
67+ } else if ( [ 'false' , '0' , 'no' , 'n' , 'off' ] . includes ( lower ) ) {
4768 process . env [ key ] = 'false' ;
4869 } else {
4970 throw new Error ( `AI config ${ key } must be a boolean, got "${ raw } ".` ) ;
@@ -65,7 +86,6 @@ const aiProviderFactory = {
6586
6687@Module ( {
6788 controllers : [ AiController ] ,
68- //ai controller
6989 providers : [ AiService , PromptTemplateService , aiProviderFactory ] ,
7090 exports : [ AiService , PromptTemplateService ] ,
7191} )
0 commit comments