Agents/Agent Types
Content Generation Agent
ID: content-generation
Purpose
Transform analysis results into a well-structured newsletter with executive-friendly format. The agent dynamically generates sections based on available analysis results, allowing newsletters to adapt automatically when new analysis types are added or removed.
Inputs
interface ContentGenerationInput {
tickerId: number; // Required: Foreign key to the Ticker table
jobId?: string; // Optional: Job ID for tracking this run
}Configurations
Configuration is stored in AgentConfig with identifier content-generation and the following structure:
{
ai: {
model: 'gpt-4',
temperature: 0.7,
maxTokens: 4000,
systemPrompt: string // Base prompt template
},
tone: {
style: 'executive' | 'analytical' | 'concise',
formality: 'professional',
length: 'brief' | 'moderate' | 'detailed'
},
structure: {
sections: Array<{
id: string, // Unique section identifier
type: 'executiveSummary' | 'keyInsights' | 'analysisSection' | 'actionItems',
analysisType?: string, // Maps to analysis type for dynamic sections (e.g., 'sentiment', 'competitive')
enabled: boolean, // Whether to include this section
maxLength: number, // Maximum length for this section
template?: string, // Optional custom template
title?: string // Optional custom title
}>,
sectionMapping: { // Maps analysis types to section IDs
[analysisType: string]: string // e.g., { 'sentiment': 'sentimentSection', 'competitive': 'competitiveLandscape' }
},
defaultSections: { // Default section configuration
executiveSummary: { maxLength: 200, enabled: true },
keyInsights: { maxLength: 500, enabled: true },
actionItems: { maxLength: 300, enabled: true }
}
},
personalization: {
includeCharts: true,
detailLevel: 'high' | 'medium' | 'low',
focusAreas: string[] // User's areas of interest
},
templates: {
email: 'templates/email-newsletter.html',
dashboard: 'templates/dashboard-newsletter.html'
}
}Outputs
The newsletter structure is dynamic and adapts to available analysis results:
{
agentId: 'content-generation',
agentVersion: string, // Semantic version (e.g., "1.2.3") of the agent that generated this output
tickerId: number,
jobId: string,
timestamp: Date,
executionTime: number,
newsletter: {
id: string,
title: string,
date: Date,
sections: {
// Always present sections
executiveSummary: {
content: string,
keyPoints: string[]
},
keyInsights: Array<{
title: string,
description: string,
priority: 'high' | 'medium' | 'low',
source: string,
analysisType: string // Which analysis type generated this insight
}>,
// Dynamic sections based on available analyses
[sectionId: string]: { // Dynamic: sections generated from analysis results
analysisType: string, // Which analysis type this section represents
content: string, // Generated content
data: any // Type-safe data from analysis results
},
// Optional sections
actionItems?: Array<{
action: string,
rationale: string,
priority: 'high' | 'medium' | 'low'
}>
},
metadata: {
wordCount: number,
readingTime: number,
personalizationScore: number,
abTestVariant?: string,
includedAnalysisTypes: string[] // Which analysis types were included
}
},
rawContent: string, // Full markdown/HTML
emailHtml: string,
dashboardHtml: string
}Dynamic Section Generation:
- Sections are generated only for analysis types that have results available
- Section templates are resolved from the analysis plugin's
getSectionTemplate()method or configuration - If an analysis type has no results, its corresponding section is omitted
- New analysis types automatically get sections generated when their results are available
Process:
-
Initialize:
- Load newsletter template, AI config
- Load section configuration and mapping from database
-
Read Data:
- Query database for analysis results
- Query
AnalysisTypeRegistryfor section templates
-
Section Resolution:
- Determine which sections to generate based on:
- Available analysis results in database
- Section configuration (enabled/disabled)
- Section mapping (which analysis types map to which sections)
- Load section templates from analysis plugins or configuration
- Filter out sections for analysis types with no results
- Determine which sections to generate based on:
-
Context Building:
- Combine analysis results into structured context
- Map analysis results to their corresponding sections
- Include previous newsletter for trend context (if available)
- Determine A/B test variant (if active)
-
Prompt Construction:
- Build system prompt with tone/style guidelines
- Create section-specific prompts for resolved sections
- Include examples of good newsletter content
- Include analysis-specific context for each section
-
Content Generation (AI calls, sequential):
- Executive Summary: Generate 2-3 sentence overview from all analyses
- Key Insights: Extract top 3-5 insights with priorities across all analysis types
- Dynamic Analysis Sections: For each resolved analysis section:
- Load section template (from plugin or config)
- Generate content using analysis results
- Format according to section configuration
- Action Items: Generate actionable recommendations (if enabled)
-
Formatting:
- Apply newsletter template
- Generate email HTML version
- Generate dashboard HTML version
- Create chart data for visualizations
- Include only resolved sections in output
-
Quality Check:
- Basic validation (length, structure, completeness)
- Verify all required sections are present
- Verify analysis sections match available results
-
Return: Complete newsletter content with dynamic sections