Skip to content

Commit 1b08a72

Browse files
authored
Merge pull request #1238 from Hack23/copilot/add-ai-powered-document-analysis-framework
Integrate document analysis framework with all content generators
2 parents 92a9ba1 + f8323be commit 1b08a72

15 files changed

Lines changed: 844 additions & 53 deletions

File tree

scripts/analysis-framework/lenses/government.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ export function analyzeGovernmentPerspective(
287287
): PerspectiveAnalysis {
288288
const keyActors: string[] = ['Prime Minister', 'Cabinet'];
289289
if (cia) {
290-
const govParties = cia.partyPerformance
290+
const govParties = (cia.partyPerformance ?? [])
291291
.filter(p => p.metrics.seats > 0)
292292
.slice(0, 3)
293293
.map(p => p.partyName);

scripts/analysis-framework/lenses/opposition.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ export function analyzeOppositionPerspective(
249249
const keyActors: string[] = ['Opposition Leader', 'Shadow Cabinet'];
250250
if (cia) {
251251
// Include parties that are not the largest governing bloc
252-
const parties = cia.partyPerformance.slice(0, 4).map(p => p.partyName);
252+
const parties = (cia.partyPerformance ?? []).slice(0, 4).map(p => p.partyName);
253253
keyActors.push(...parties);
254254
}
255255
if (doc.parti) keyActors.unshift(doc.parti);

scripts/data-transformers/constants/content-labels-part1.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
112112
deepAnalysisConsequences: 'Actions & Consequences',
113113
deepAnalysisCritical: 'Critical Assessment',
114114
deepAnalysisPerspectives: 'Multiple Perspectives',
115+
deepAnalysisPestle: 'PESTLE Analysis',
116+
deepAnalysisStakeholderImpact: 'Stakeholder Impact',
117+
deepAnalysisRisk: 'Risk Assessment',
118+
deepAnalysisImplementation: 'Implementation Assessment',
115119
swotAnalysis: 'SWOT Analysis',
116120
swotStrengths: 'Strengths',
117121
swotWeaknesses: 'Weaknesses',
@@ -235,6 +239,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
235239
deepAnalysisConsequences: 'Handlingar & konsekvenser',
236240
deepAnalysisCritical: 'Kritisk bedömning',
237241
deepAnalysisPerspectives: 'Flera perspektiv',
242+
deepAnalysisPestle: 'PESTLE-analys',
243+
deepAnalysisStakeholderImpact: 'Intressentpåverkan',
244+
deepAnalysisRisk: 'Riskbedömning',
245+
deepAnalysisImplementation: 'Genomförandebedömning',
238246
swotAnalysis: 'SWOT-analys',
239247
swotStrengths: 'Styrkor',
240248
swotWeaknesses: 'Svagheter',
@@ -358,6 +366,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
358366
deepAnalysisConsequences: 'Handlinger & konsekvenser',
359367
deepAnalysisCritical: 'Kritisk vurdering',
360368
deepAnalysisPerspectives: 'Flere perspektiver',
369+
deepAnalysisPestle: 'PESTLE-analyse',
370+
deepAnalysisStakeholderImpact: 'Interessentpåvirkning',
371+
deepAnalysisRisk: 'Risikovurdering',
372+
deepAnalysisImplementation: 'Implementeringsvurdering',
361373
swotAnalysis: 'SWOT-analyse',
362374
swotStrengths: 'Styrker',
363375
swotWeaknesses: 'Svagheder',
@@ -481,6 +493,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
481493
deepAnalysisConsequences: 'Handlinger & konsekvenser',
482494
deepAnalysisCritical: 'Kritisk vurdering',
483495
deepAnalysisPerspectives: 'Flere perspektiver',
496+
deepAnalysisPestle: 'PESTLE-analyse',
497+
deepAnalysisStakeholderImpact: 'Interessentpåvirkning',
498+
deepAnalysisRisk: 'Risikovurdering',
499+
deepAnalysisImplementation: 'Implementeringsvurdering',
484500
swotAnalysis: 'SWOT-analyse',
485501
swotStrengths: 'Styrker',
486502
swotWeaknesses: 'Svakheter',
@@ -604,6 +620,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
604620
deepAnalysisConsequences: 'Toimet & seuraukset',
605621
deepAnalysisCritical: 'Kriittinen arvio',
606622
deepAnalysisPerspectives: 'Useat näkökulmat',
623+
deepAnalysisPestle: 'PESTLE-analyysi',
624+
deepAnalysisStakeholderImpact: 'Sidosryhmävaikutus',
625+
deepAnalysisRisk: 'Riskiarvio',
626+
deepAnalysisImplementation: 'Toteutusarvio',
607627
swotAnalysis: 'SWOT-analyysi',
608628
swotStrengths: 'Vahvuudet',
609629
swotWeaknesses: 'Heikkoudet',
@@ -727,6 +747,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
727747
deepAnalysisConsequences: 'Handlungen & Konsequenzen',
728748
deepAnalysisCritical: 'Kritische Bewertung',
729749
deepAnalysisPerspectives: 'Mehrere Perspektiven',
750+
deepAnalysisPestle: 'PESTLE-Analyse',
751+
deepAnalysisStakeholderImpact: 'Auswirkung auf Interessengruppen',
752+
deepAnalysisRisk: 'Risikobewertung',
753+
deepAnalysisImplementation: 'Umsetzungsbewertung',
730754
swotAnalysis: 'SWOT-Analyse',
731755
swotStrengths: 'Stärken',
732756
swotWeaknesses: 'Schwächen',
@@ -850,6 +874,10 @@ export const CONTENT_LABELS_PART1: Partial<Record<string, ContentLabelSet>> = {
850874
deepAnalysisConsequences: 'Actions & conséquences',
851875
deepAnalysisCritical: 'Évaluation critique',
852876
deepAnalysisPerspectives: 'Perspectives multiples',
877+
deepAnalysisPestle: 'Analyse PESTLE',
878+
deepAnalysisStakeholderImpact: 'Impact sur les parties prenantes',
879+
deepAnalysisRisk: 'Évaluation des risques',
880+
deepAnalysisImplementation: 'Évaluation de la mise en œuvre',
853881
swotAnalysis: 'Analyse SWOT',
854882
swotStrengths: 'Forces',
855883
swotWeaknesses: 'Faiblesses',

scripts/data-transformers/constants/content-labels-part2.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
112112
deepAnalysisConsequences: 'Acciones y consecuencias',
113113
deepAnalysisCritical: 'Evaluación crítica',
114114
deepAnalysisPerspectives: 'Múltiples perspectivas',
115+
deepAnalysisPestle: 'Análisis PESTLE',
116+
deepAnalysisStakeholderImpact: 'Impacto en las partes interesadas',
117+
deepAnalysisRisk: 'Evaluación de riesgos',
118+
deepAnalysisImplementation: 'Evaluación de implementación',
115119
swotAnalysis: 'Análisis DAFO',
116120
swotStrengths: 'Fortalezas',
117121
swotWeaknesses: 'Debilidades',
@@ -235,6 +239,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
235239
deepAnalysisConsequences: 'Acties & gevolgen',
236240
deepAnalysisCritical: 'Kritische beoordeling',
237241
deepAnalysisPerspectives: 'Meerdere perspectieven',
242+
deepAnalysisPestle: 'PESTLE-analyse',
243+
deepAnalysisStakeholderImpact: 'Impact op belanghebbenden',
244+
deepAnalysisRisk: 'Risicobeoordeling',
245+
deepAnalysisImplementation: 'Uitvoeringsbeoordeling',
238246
swotAnalysis: 'SWOT-analyse',
239247
swotStrengths: 'Sterktes',
240248
swotWeaknesses: 'Zwaktes',
@@ -358,6 +366,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
358366
deepAnalysisConsequences: 'الإجراءات والعواقب',
359367
deepAnalysisCritical: 'تقييم نقدي',
360368
deepAnalysisPerspectives: 'وجهات نظر متعددة',
369+
deepAnalysisPestle: 'تحليل PESTLE',
370+
deepAnalysisStakeholderImpact: 'التأثير على أصحاب المصلحة',
371+
deepAnalysisRisk: 'تقييم المخاطر',
372+
deepAnalysisImplementation: 'تقييم التنفيذ',
361373
swotAnalysis: 'تحليل SWOT',
362374
swotStrengths: 'نقاط القوة',
363375
swotWeaknesses: 'نقاط الضعف',
@@ -481,6 +493,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
481493
deepAnalysisConsequences: 'פעולות והשלכות',
482494
deepAnalysisCritical: 'הערכה ביקורתית',
483495
deepAnalysisPerspectives: 'נקודות מבט מרובות',
496+
deepAnalysisPestle: 'ניתוח PESTLE',
497+
deepAnalysisStakeholderImpact: 'השפעה על בעלי עניין',
498+
deepAnalysisRisk: 'הערכת סיכונים',
499+
deepAnalysisImplementation: 'הערכת יישום',
484500
swotAnalysis: 'ניתוח SWOT',
485501
swotStrengths: 'חוזקות',
486502
swotWeaknesses: 'חולשות',
@@ -604,6 +620,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
604620
deepAnalysisConsequences: '行動と結果',
605621
deepAnalysisCritical: '批判的評価',
606622
deepAnalysisPerspectives: '多角的視点',
623+
deepAnalysisPestle: 'PESTLE分析',
624+
deepAnalysisStakeholderImpact: 'ステークホルダーへの影響',
625+
deepAnalysisRisk: 'リスク評価',
626+
deepAnalysisImplementation: '実施評価',
607627
swotAnalysis: 'SWOT分析',
608628
swotStrengths: '強み',
609629
swotWeaknesses: '弱み',
@@ -727,6 +747,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
727747
deepAnalysisConsequences: '행동과 결과',
728748
deepAnalysisCritical: '비판적 평가',
729749
deepAnalysisPerspectives: '다양한 관점',
750+
deepAnalysisPestle: 'PESTLE 분석',
751+
deepAnalysisStakeholderImpact: '이해관계자 영향',
752+
deepAnalysisRisk: '위험 평가',
753+
deepAnalysisImplementation: '이행 평가',
730754
swotAnalysis: 'SWOT 분석',
731755
swotStrengths: '강점',
732756
swotWeaknesses: '약점',
@@ -850,6 +874,10 @@ export const CONTENT_LABELS_PART2: Partial<Record<string, ContentLabelSet>> = {
850874
deepAnalysisConsequences: '行动与后果',
851875
deepAnalysisCritical: '批判性评估',
852876
deepAnalysisPerspectives: '多元视角',
877+
deepAnalysisPestle: 'PESTLE分析',
878+
deepAnalysisStakeholderImpact: '利益相关者影响',
879+
deepAnalysisRisk: '风险评估',
880+
deepAnalysisImplementation: '实施评估',
853881
swotAnalysis: 'SWOT分析',
854882
swotStrengths: '优势',
855883
swotWeaknesses: '劣势',

scripts/data-transformers/content-generators/committee.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
formatDocumentDate,
2222
} from '../helpers.js';
2323
import { detectPolicyDomains, generateDeepPolicyAnalysis } from '../policy-analysis.js';
24-
import { generateDeepAnalysisSection } from './shared.js';
24+
import { generateDeepAnalysisSection, analyzeDocumentsForContent } from './shared.js';
2525

2626
export function generateCommitteeContent(data: ArticleContentData, lang: Language | string): string {
2727
const reports = data.reports || [];
@@ -108,13 +108,18 @@ export function generateCommitteeContent(data: ArticleContentData, lang: Languag
108108
content += ` <p class="pillar-transition">${escapeHtml(pulseTransition)}</p>\n`;
109109
}
110110

111-
// Deep Analysis section (5W framework)
112-
content += generateDeepAnalysisSection({
113-
documents: reports,
114-
lang,
115-
cia: data.ciaContext,
116-
articleType: 'committee-reports',
117-
});
111+
// Deep Analysis section (5W framework + document analysis framework)
112+
if (reports.length >= 2) {
113+
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(reports, lang, data.ciaContext);
114+
content += generateDeepAnalysisSection({
115+
documents: reports,
116+
lang,
117+
cia: data.ciaContext,
118+
articleType: 'committee-reports',
119+
frameworkAnalysis,
120+
perspectiveAnalysis,
121+
});
122+
}
118123

119124
// Key takeaways section
120125
content += `\n <h2>${L(lang, 'keyTakeaways')}</h2>\n`;

scripts/data-transformers/content-generators/generic.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import {
2424
generateOppositionStrategySection,
2525
generateDocumentIntelligenceAnalysis,
2626
} from '../document-analysis.js';
27-
import { TITLE_SUFFIX_TEMPLATES, generateDeepAnalysisSection } from './shared.js';
27+
import { TITLE_SUFFIX_TEMPLATES, generateDeepAnalysisSection, analyzeDocumentsForContent } from './shared.js';
2828

2929
export function generateGenericContent(data: ArticleContentData, lang: Language | string): string {
3030
const docs = data.documents || [];
@@ -237,13 +237,18 @@ export function generateGenericContent(data: ArticleContentData, lang: Language
237237
content += ` <p class="pillar-transition">${escapeHtml(oppositionTransition)}</p>\n`;
238238
}
239239

240-
// Deep Analysis section (5W framework)
241-
content += generateDeepAnalysisSection({
242-
documents: docs,
243-
lang,
244-
cia,
245-
articleType: 'generic',
246-
});
240+
// Deep Analysis section (5W framework + document analysis framework)
241+
if (docs.length >= 2) {
242+
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(docs, lang, cia);
243+
content += generateDeepAnalysisSection({
244+
documents: docs,
245+
lang,
246+
cia,
247+
articleType: 'generic',
248+
frameworkAnalysis,
249+
perspectiveAnalysis,
250+
});
251+
}
247252

248253
// ── Key takeaways ────────────────────────────────────────────────────────
249254
content += `\n <h2>${L(lang, 'keyTakeaways')}</h2>\n`;

scripts/data-transformers/content-generators/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export { generateInterpellationsContent } from './interpellations.js';
3232
export { generateGenericContent } from './generic.js';
3333
export { generateMonthlyReviewContent } from './monthly-review.js';
3434
export { generateMonthAheadContent } from './month-ahead.js';
35-
export { generateDeepAnalysisSection, localizeDocType, DOC_TYPE_DISPLAY } from './shared.js';
35+
export { generateDeepAnalysisSection, localizeDocType, DOC_TYPE_DISPLAY, analyzeDocumentsForContent } from './shared.js';
3636
export type { DeepAnalysisOptions, DocTypeLocalization } from './shared.js';
3737
export { generateSwotSection } from './swot-section.js';
3838
export type { SwotSectionOptions } from './swot-section.js';

scripts/data-transformers/content-generators/interpellations.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @license Apache-2.0
88
*/
99

10-
import { generateDeepAnalysisSection } from './shared.js';
10+
import { generateDeepAnalysisSection, analyzeDocumentsForContent } from './shared.js';
1111
import { escapeHtml } from '../../html-utils.js';
1212
import type { Language } from '../../types/language.js';
1313
import type { ArticleContentData, RawDocument } from '../types.js';
@@ -85,13 +85,18 @@ export function generateInterpellationsContent(data: ArticleContentData, lang: L
8585
interpellations.forEach(interp => { content += renderInterpellationEntry(interp, lang); });
8686
}
8787

88-
// Deep Analysis section (5W framework)
89-
content += generateDeepAnalysisSection({
90-
documents: interpellations,
91-
lang,
92-
cia: data.ciaContext,
93-
articleType: 'interpellations',
94-
});
88+
// Deep Analysis section (5W framework + document analysis framework)
89+
if (interpellations.length >= 2) {
90+
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(interpellations, lang, data.ciaContext);
91+
content += generateDeepAnalysisSection({
92+
documents: interpellations,
93+
lang,
94+
cia: data.ciaContext,
95+
articleType: 'interpellations',
96+
frameworkAnalysis,
97+
perspectiveAnalysis,
98+
});
99+
}
95100

96101
// Party accountability breakdown
97102
if (partyCount > 0) {

scripts/data-transformers/content-generators/motions.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @license Apache-2.0
88
*/
99

10-
import { generateDeepAnalysisSection } from './shared.js';
10+
import { generateDeepAnalysisSection, analyzeDocumentsForContent } from './shared.js';
1111
import { escapeHtml } from '../../html-utils.js';
1212
import type { Language } from '../../types/language.js';
1313
import type { ArticleContentData, RawDocument } from '../types.js';
@@ -126,13 +126,18 @@ export function generateMotionsContent(data: ArticleContentData, lang: Language
126126
}
127127
}
128128

129-
// Deep Analysis section (5W framework)
130-
content += generateDeepAnalysisSection({
131-
documents: motions,
132-
lang,
133-
cia: data.ciaContext,
134-
articleType: 'motions',
135-
});
129+
// Deep Analysis section (5W framework + document analysis framework)
130+
if (motions.length >= 2) {
131+
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(motions, lang, data.ciaContext);
132+
content += generateDeepAnalysisSection({
133+
documents: motions,
134+
lang,
135+
cia: data.ciaContext,
136+
articleType: 'motions',
137+
frameworkAnalysis,
138+
perspectiveAnalysis,
139+
});
140+
}
136141

137142
// Party activity breakdown
138143
if (partyCount > 0) {

scripts/data-transformers/content-generators/propositions.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import { detectPolicyDomains, generateDeepPolicyAnalysis } from '../policy-analy
2323
import {
2424
groupPropositionsByCommittee,
2525
} from '../document-analysis.js';
26-
import { generateDeepAnalysisSection } from './shared.js';
26+
import { generateDeepAnalysisSection, analyzeDocumentsForContent } from './shared.js';
2727

2828
export function generatePropositionsContent(data: ArticleContentData, lang: Language | string): string {
2929
const propositions = data.propositions || [];
@@ -155,13 +155,18 @@ export function generatePropositionsContent(data: ArticleContentData, lang: Lang
155155
content += ` <p class="pillar-transition">${escapeHtml(propTransition)}</p>\n`;
156156
}
157157

158-
// Deep Analysis section (5W framework)
159-
content += generateDeepAnalysisSection({
160-
documents: propositions,
161-
lang,
162-
cia: data.ciaContext,
163-
articleType: 'propositions',
164-
});
158+
// Deep Analysis section (5W framework + document analysis framework)
159+
if (propositions.length >= 2) {
160+
const { frameworkAnalysis, perspectiveAnalysis } = analyzeDocumentsForContent(propositions, lang, data.ciaContext);
161+
content += generateDeepAnalysisSection({
162+
documents: propositions,
163+
lang,
164+
cia: data.ciaContext,
165+
articleType: 'propositions',
166+
frameworkAnalysis,
167+
perspectiveAnalysis,
168+
});
169+
}
165170

166171
// ── Key takeaways: synthesize propositions batch ──────────────────────────
167172
content += `\n <h2>${L(lang, 'keyTakeaways')}</h2>\n`;

0 commit comments

Comments
 (0)