banatie-service/apps/api-service/src/services/promptEnhancement/PromptEnhancementService.ts

132 lines
4.3 KiB
TypeScript

import {
PromptEnhancementOptions,
PromptEnhancementContext,
PromptEnhancementResult,
} from './types';
import { getAgent } from './agents';
import { validatePromptLength } from './validators';
import { EnhancementLogger } from './EnhancementLogger';
import { NetworkErrorDetector } from '../../utils/NetworkErrorDetector';
export class PromptEnhancementService {
private apiKey: string;
private model = 'gemini-2.5-flash';
constructor(apiKey: string) {
if (!apiKey) {
throw new Error('Gemini API key is required');
}
this.apiKey = apiKey;
}
async enhancePrompt(
rawPrompt: string,
options: PromptEnhancementOptions = {},
context?: PromptEnhancementContext,
): Promise<PromptEnhancementResult> {
const timestamp = new Date().toISOString();
console.log(
`[${timestamp}] Starting prompt enhancement for: "${rawPrompt.substring(0, 50)}..."`,
);
console.log(`[${timestamp}] Template: ${options.template || 'general (auto-select)'}`);
if (options.tags && options.tags.length > 0) {
console.log(`[${timestamp}] Tags: ${options.tags.join(', ')}`);
}
// Pre-validate input prompt
const inputValidation = validatePromptLength(rawPrompt, 5000);
if (!inputValidation.valid) {
return {
success: false,
originalPrompt: rawPrompt,
error: inputValidation.error || 'Validation failed',
};
}
try {
// Get appropriate agent
const agent = getAgent(this.apiKey, options.template);
// Enhance the prompt
const agentResult = await agent.enhance(rawPrompt, options);
if (!agentResult.success || !agentResult.enhancedPrompt) {
return {
success: false,
originalPrompt: rawPrompt,
error: agentResult.error || 'Enhancement failed',
};
}
// Post-validate enhanced prompt length
const outputValidation = validatePromptLength(agentResult.enhancedPrompt, 2000);
if (!outputValidation.valid) {
console.warn(
`[${timestamp}] Enhanced prompt exceeds 2000 characters (${agentResult.enhancedPrompt.length}), truncating...`,
);
agentResult.enhancedPrompt = agentResult.enhancedPrompt.substring(0, 2000);
}
const result: PromptEnhancementResult = {
success: true,
originalPrompt: rawPrompt,
enhancedPrompt: agentResult.enhancedPrompt,
...(agentResult.detectedLanguage && {
detectedLanguage: agentResult.detectedLanguage,
}),
appliedTemplate: agentResult.appliedTemplate || options.template || 'general',
metadata: {
style: agentResult.appliedTemplate || options.template || 'general',
enhancements: agentResult.enhancements,
},
};
// Log the enhancement if context is provided
if (context) {
EnhancementLogger.getInstance().log({
timestamp,
orgId: context.orgId,
projectId: context.projectId,
originalPrompt: rawPrompt,
enhancedPrompt: agentResult.enhancedPrompt,
...(context.meta && { meta: context.meta }),
template: agentResult.appliedTemplate || options.template || 'general',
...(agentResult.detectedLanguage && {
detectedLanguage: agentResult.detectedLanguage,
}),
enhancements: agentResult.enhancements,
model: this.model,
});
}
console.log(`[${timestamp}] Enhancement completed successfully`);
return result;
} catch (error) {
// Enhanced error detection with network diagnostics
if (error instanceof Error) {
// Classify the error and check for network issues (only on failure)
const errorAnalysis = await NetworkErrorDetector.classifyError(error, 'Gemini API');
// Log the detailed error for debugging
console.error(
`[${timestamp}] [PromptEnhancementService] ${NetworkErrorDetector.formatErrorForLogging(errorAnalysis)}`,
);
return {
success: false,
originalPrompt: rawPrompt,
error: errorAnalysis.userMessage,
};
}
console.error(`[${timestamp}] Prompt enhancement failed:`, error);
return {
success: false,
originalPrompt: rawPrompt,
error: 'Enhancement failed',
};
}
}
}