import type { Provider, Proposal } from '../types.js'; const GENERATOR_PROMPT_DE = `Du bist ein unabhängiger Analyst. Beantworte diese Frage mit einer konkreten Position. {context} REGELN: - Leg dich fest. Keine "es kommt drauf an" ohne konkrete Bedingungen - Nenne Zahlen wo möglich - Sag was schiefgehen kann - Max 500 Wörter FRAGE: {question}`; const GENERATOR_PROMPT_EN = `You are an independent analyst. Answer this question with a concrete position. {context} RULES: - Take a stand. No "it depends" without concrete conditions - Provide numbers where possible - Say what can go wrong - Max 500 words QUESTION: {question}`; export async function runGenerator( provider: Provider, model: string, question: string, language: 'de' | 'en' = 'de', dryRun: boolean = false, contextText?: string ): Promise { if (dryRun) { return { model: model.split('/').pop() || model, content: `[DRY-RUN] Simulated response from ${model} for question: "${question}"\\n\\nThis is a placeholder response that would contain the actual analysis.`, }; } const template = language === 'de' ? GENERATOR_PROMPT_DE : GENERATOR_PROMPT_EN; const contextSection = contextText || ''; const prompt = template .replace('{context}', contextSection) .replace('{question}', question); const response = await provider.call(model, prompt); return { model: model.split('/').pop() || model, content: response.content, }; } export async function runGenerators( providers: Array<{ provider: Provider; model: string }>, question: string, language: 'de' | 'en' = 'de', dryRun: boolean = false, contextText?: string, /** * v1.1: Diversified inputs — one per generator. * If provided, each generator gets a different representation of the claim. * If not provided, all generators get the same question (backward compat). * Credit: voipbin-cco — "running them on different data snapshots" */ diversifiedInputs?: Array<{ type: string; content: string }>, ): Promise { const promises = providers.map(({ provider, model }, index) => { // Use diversified input if available, otherwise fall back to original question const inputForThisGenerator = diversifiedInputs?.[index]?.content ?? question; const repType = diversifiedInputs?.[index]?.type; return runGenerator(provider, model, inputForThisGenerator, language, dryRun, contextText) .then(proposal => ({ ...proposal, // Tag the proposal with its representation type for transparency ...(repType && repType !== 'original' ? { representationType: repType } : {}), })) .catch((error: Error) => { console.warn(`[pot-sdk] Generator failed — model: ${model}, provider: ${provider.name}, error: ${error.message}`); return null; }); }); const allResults = await Promise.all(promises); const successful = allResults.filter((r): r is Proposal => r !== null); // Require at least 2 successful generators (or all, if fewer than 2 were configured) const minRequired = Math.min(2, providers.length); if (successful.length < minRequired) { const failedCount = providers.length - successful.length; throw new Error( `Not enough generators succeeded (${successful.length}/${providers.length}). ` + `${failedCount} generator(s) failed. Minimum ${minRequired} required. Check API keys and connectivity.` ); } return successful; }