import { z } from 'zod';
import { createLogger } from '../utils/logger.js';
/**
* Response Transformer Service
*
* Transforms raw tool outputs into semantic-rich, multi-layered responses
* optimized for AI agent consumption.
*/
// Schema for transformed responses
export const TransformedResponseSchema = z.object({
executive_summary: z.object({
headline: z.string(),
confidence: z.enum(['low', 'medium', 'high']),
key_insight: z.string(),
primary_metric: z.string().optional()
}),
insights: z.object({
primary: z.array(z.string()).describe('Top 3-5 key insights'),
risks: z.array(z.string()).describe('Key risk factors'),
opportunities: z.array(z.string()).describe('Growth opportunities'),
patterns: z.array(z.string()).optional().describe('Detected patterns across data')
}),
recommendations: z.object({
next_action: z.string(),
timeline: z.string(),
success_criteria: z.string(),
prerequisites: z.array(z.string()).optional(),
alternatives: z.array(z.object({
action: z.string(),
tradeoff: z.string()
})).optional()
}),
narrative: z.object({
context: z.string().describe('Business context and background'),
analysis: z.string().describe('Detailed analysis narrative'),
conclusion: z.string().describe('Summary and next steps')
}).optional(),
detailed_analysis: z.any().describe('Original detailed data'),
metadata: z.object({
confidence_score: z.number().min(0).max(1),
data_quality: z.enum(['low', 'medium', 'high']),
assumptions_impact: z.enum(['low', 'medium', 'high']),
generated_at: z.string().datetime(),
response_version: z.string().default('2.0'),
tool_name: z.string(),
processing_time_ms: z.number().optional()
})
});
export type TransformedResponse = z.infer<typeof TransformedResponseSchema>;
export class ResponseTransformer {
private logger = createLogger({ component: 'ResponseTransformer' });
/**
* Transform predict_roi tool response
*/
async transformPredictROI(response: any): Promise<TransformedResponse> {
const startTime = Date.now();
try {
const { summary, financial_metrics, use_cases, metadata } = response;
// Generate executive summary
const executiveSummary = this.generateExecutiveSummary(summary);
// Extract insights
const insights = this.extractROIInsights(summary, financial_metrics, use_cases);
// Generate recommendations
const recommendations = this.generateROIRecommendations(
summary,
use_cases,
insights.primary
);
// Create narrative (optional for now)
const narrative = this.generateROINarrative(summary, insights);
// Calculate metadata
const responseMetadata = this.calculateMetadata(
'predict_roi',
metadata,
startTime
);
return {
executive_summary: executiveSummary,
insights,
recommendations,
narrative,
detailed_analysis: response,
metadata: responseMetadata
};
} catch (error) {
this.logger.error('Failed to transform predict_roi response', error as Error);
throw error;
}
}
/**
* Transform compare_projects tool response
*/
async transformCompareProjects(response: any): Promise<TransformedResponse> {
const startTime = Date.now();
try {
const { projects, rankings, insights, recommendations } = response;
// Generate executive summary
const executiveSummary = this.generateComparativeExecutiveSummary(
projects,
rankings,
insights
);
// Enhance existing insights
const enhancedInsights = this.enhanceComparativeInsights(insights, projects);
// Structure recommendations
const structuredRecommendations = this.structureComparativeRecommendations(
recommendations,
insights
);
// Generate narrative
const narrative = this.generateComparativeNarrative(projects, rankings);
// Calculate metadata
const responseMetadata = this.calculateMetadata(
'compare_projects',
response.metadata,
startTime
);
return {
executive_summary: executiveSummary,
insights: enhancedInsights,
recommendations: structuredRecommendations,
narrative,
detailed_analysis: response,
metadata: responseMetadata
};
} catch (error) {
this.logger.error('Failed to transform compare_projects response', error as Error);
throw error;
}
}
// Private helper methods
private generateExecutiveSummary(summary: any): TransformedResponse['executive_summary'] {
const roi = summary.expected_roi;
const payback = summary.payback_period_months;
let confidence: 'low' | 'medium' | 'high' = 'medium';
let headline = '';
if (roi > 200 && payback < 12) {
confidence = 'high';
headline = `Exceptional ROI opportunity with ${roi.toFixed(0)}% return in ${payback} months`;
} else if (roi > 100 && payback < 18) {
confidence = 'high';
headline = `Strong ROI potential of ${roi.toFixed(0)}% with ${payback}-month payback`;
} else if (roi > 50) {
confidence = 'medium';
headline = `Solid investment case with ${roi.toFixed(0)}% ROI over 5 years`;
} else {
confidence = 'low';
headline = `Moderate returns expected with ${roi.toFixed(0)}% ROI`;
}
const key_insight = this.generateKeyInsight(summary, payback);
const primary_metric = `$${(summary.net_present_value / 1000).toFixed(0)}K NPV`;
return { headline, confidence, key_insight, primary_metric };
}
private generateKeyInsight(summary: any, payback: number): string {
if (payback <= 6) {
return 'Rapid payback enables quick reinvestment in additional AI initiatives';
} else if (payback <= 12) {
return 'Sub-year payback provides strong business case for immediate implementation';
} else if (payback <= 24) {
return 'Investment timeline aligns well with typical enterprise planning cycles';
} else {
return 'Long-term value creation requires sustained commitment and phased approach';
}
}
private extractROIInsights(
summary: any,
financial_metrics: any,
use_cases: any[]
): TransformedResponse['insights'] {
const insights = {
primary: [] as string[],
risks: [] as string[],
opportunities: [] as string[],
patterns: [] as string[]
};
// Analyze use case distribution
const categories = use_cases.reduce((acc, uc) => {
acc[uc.category] = (acc[uc.category] || 0) + uc.monthly_benefit;
return acc;
}, {} as Record<string, number>);
const topCategory = Object.entries(categories)
.sort(([,a], [,b]) => (b as number) - (a as number))[0];
if (topCategory) {
insights.primary.push(
`${topCategory[0]} use cases drive ${(((topCategory[1] as number) / summary.total_investment) * 100).toFixed(0)}% of total value`
);
}
// ROI insights
if (summary.expected_roi > 150) {
insights.primary.push('ROI exceeds typical enterprise hurdle rates by 3-5x');
}
// Payback insights
if (summary.payback_period_months < 12) {
insights.primary.push('Quick payback reduces financial risk and enables rapid scaling');
}
// Risk factors
if (summary.payback_period_months > 24) {
insights.risks.push('Extended payback period increases execution risk');
}
if (use_cases.length > 5) {
insights.risks.push('Multiple concurrent use cases may strain implementation resources');
}
// Opportunities
insights.opportunities.push('Consider phased rollout to capture quick wins first');
if (summary.expected_roi > 100) {
insights.opportunities.push('High ROI justifies accelerated timeline with additional resources');
}
return insights;
}
private generateROIRecommendations(
summary: any,
use_cases: any[],
primaryInsights: string[]
): TransformedResponse['recommendations'] {
// Sort use cases by benefit
const sortedUseCases = [...use_cases].sort((a, b) => b.monthly_benefit - a.monthly_benefit);
const topUseCase = sortedUseCases[0];
let next_action = '';
let timeline = '';
let success_criteria = '';
if (summary.payback_period_months <= 12) {
next_action = `Launch pilot program for ${topUseCase.name}`;
timeline = 'Begin within 30 days';
success_criteria = `Achieve ${(topUseCase.monthly_benefit * 0.7).toFixed(0)} monthly benefit within 90 days`;
} else {
next_action = 'Conduct detailed feasibility study for top 3 use cases';
timeline = 'Complete within 60 days';
success_criteria = 'Validate assumptions and refine implementation plan';
}
return {
next_action,
timeline,
success_criteria,
prerequisites: [
'Secure executive sponsorship',
'Allocate dedicated project team',
'Establish success metrics baseline'
]
};
}
private generateROINarrative(
summary: any,
insights: TransformedResponse['insights']
): TransformedResponse['narrative'] {
const context = `This AI investment analysis evaluates a total investment of $${(summary.total_investment / 1000).toFixed(0)}K ` +
`with projected returns of ${summary.expected_roi.toFixed(0)}% over 5 years.`;
const analysis = `The financial analysis reveals a ${summary.payback_period_months}-month payback period ` +
`with a net present value of $${(summary.net_present_value / 1000).toFixed(0)}K. ` +
insights.primary.join('. ') + '.';
const conclusion = `Based on the analysis, this investment presents a ${
summary.expected_roi > 100 ? 'compelling' : 'solid'
} opportunity with ${
summary.payback_period_months <= 18 ? 'rapid' : 'reasonable'
} time to value. ` +
`Key success factors include focused execution and phased implementation.`;
return { context, analysis, conclusion };
}
private generateComparativeExecutiveSummary(
projects: any[],
rankings: any,
insights: any
): TransformedResponse['executive_summary'] {
const topProject = projects.find(p => p.id === rankings.by_roi[0].project_id);
const confidence = this.assessComparativeConfidence(projects);
const headline = insights.best_overall
? `${insights.best_overall} emerges as the optimal choice across multiple dimensions`
: `Portfolio analysis reveals diverse strengths across ${projects.length} projects`;
const key_insight = this.extractTopComparativeInsight(projects, rankings);
return {
headline,
confidence,
key_insight,
primary_metric: topProject
? `Top ROI: ${topProject.financial_summary.expected_roi.toFixed(0)}%`
: undefined
};
}
private enhanceComparativeInsights(
existingInsights: any,
projects: any[]
): TransformedResponse['insights'] {
const insights = {
primary: [] as string[],
risks: [] as string[],
opportunities: [] as string[],
patterns: [] as string[]
};
// Add existing insights
if (existingInsights.best_overall) {
insights.primary.push(`${existingInsights.best_overall} offers the best overall value`);
}
if (existingInsights.quickest_payback) {
insights.primary.push(`${existingInsights.quickest_payback} provides fastest time to value`);
}
// Analyze patterns
const avgROI = projects.reduce((sum, p) => sum + p.financial_summary.expected_roi, 0) / projects.length;
insights.patterns.push(`Portfolio average ROI: ${avgROI.toFixed(0)}%`);
// Risk analysis
if (existingInsights.highest_risk) {
insights.risks.push(`${existingInsights.highest_risk} requires careful risk management`);
}
// Opportunities from synergies
if (existingInsights.synergies && existingInsights.synergies.length > 0) {
insights.opportunities.push('Synergy opportunities identified between projects');
}
return insights;
}
private structureComparativeRecommendations(
recommendations: string[],
insights: any
): TransformedResponse['recommendations'] {
const next_action = recommendations[0] || 'Prioritize projects based on strategic alignment';
return {
next_action,
timeline: 'Review within 2 weeks',
success_criteria: 'Select 1-2 projects for immediate implementation',
alternatives: recommendations.slice(1, 3).map(rec => ({
action: rec,
tradeoff: 'May require different resource allocation'
}))
};
}
private generateComparativeNarrative(
projects: any[],
rankings: any
): TransformedResponse['narrative'] {
const context = `This analysis compares ${projects.length} AI investment opportunities ` +
`to identify optimal resource allocation strategies.`;
const analysis = `Projects range from ${
Math.min(...projects.map(p => p.financial_summary.total_investment)) / 1000
}K to ${
Math.max(...projects.map(p => p.financial_summary.total_investment)) / 1000
}K in investment with ROIs between ${
Math.min(...projects.map(p => p.financial_summary.expected_roi))
}% and ${
Math.max(...projects.map(p => p.financial_summary.expected_roi))
}%.`;
const conclusion = 'Portfolio approach enables risk diversification while maximizing overall returns.';
return { context, analysis, conclusion };
}
private calculateMetadata(
toolName: string,
originalMetadata: any,
startTime: number
): TransformedResponse['metadata'] {
return {
confidence_score: originalMetadata?.confidence_level || 0.85,
data_quality: this.assessDataQuality(originalMetadata),
assumptions_impact: 'medium', // Could be calculated based on variance
generated_at: new Date().toISOString(),
response_version: '2.0',
tool_name: toolName,
processing_time_ms: Date.now() - startTime
};
}
private assessDataQuality(metadata: any): 'low' | 'medium' | 'high' {
if (!metadata) return 'medium';
if (metadata.calculated_with_benchmarks && metadata.confidence_level > 0.9) {
return 'high';
}
if (metadata.confidence_level < 0.7) {
return 'low';
}
return 'medium';
}
private assessComparativeConfidence(projects: any[]): 'low' | 'medium' | 'high' {
if (projects.length >= 3 && projects.every(p => p.ml_insights)) {
return 'high';
}
if (projects.length >= 2) {
return 'medium';
}
return 'low';
}
private extractTopComparativeInsight(projects: any[], rankings: any): string {
const roiSpread = Math.max(...projects.map(p => p.financial_summary.expected_roi)) -
Math.min(...projects.map(p => p.financial_summary.expected_roi));
if (roiSpread > 100) {
return 'Significant ROI variance suggests careful project selection critical';
} else if (roiSpread < 30) {
return 'Similar ROI profiles indicate selection should focus on strategic fit';
} else {
return 'Balanced portfolio approach recommended for risk mitigation';
}
}
}
// Export singleton instance
export const responseTransformer = new ResponseTransformer();