fix: use native Ollama API instead of OpenAI compat for thinking models

This commit is contained in:
2026-04-24 23:15:45 +02:00
parent 7f2aefc98b
commit 606c205980

View File

@@ -622,45 +622,61 @@ export function exportToCSV(stats: RepoStats, filename: string = "git-stats"): s
export async function generateAISummary(stats: RepoStats, model?: string): Promise<string> {
const selectedModel = model || (await detectOllamaModel());
if (!selectedModel) return "Aucun modèle Ollama disponible. Lancez `ollama pull llama3.2`.";
if (!selectedModel) return "Aucun modèle Ollama disponible. Lancez `ollama pull gemma4`.";
try {
const openai = new OpenAI({ baseURL: OLLAMA_BASE_URL, apiKey: "ollama" });
// Build context from recent commits
const commitSamples = (stats.recentCommits || []).slice(0, 30)
// Build context
const commitSamples = (stats.recentCommits || []).slice(0, 15)
.map((c) => `[${c.author}] ${c.message}`)
.join("\n");
const prompt = `Tu es un expert en analyse de projets Git. Analyse ce dépôt et donne un résumé en français (5-8 phrases max) :
const systemPrompt = `Tu es un expert en analyse de projets Git. Réponds TOUJOURS en français, de façon concise. Format demandé :
📊 Activité : [1 phrase]
👥 Équipe : [1 phrase]
🔧 Code : [1 phrase]
💡 Conseil : [1 phrase]`;
**Projet** : ${stats.repoName}
**Période** : ${stats.activeDays} jours actifs, ${stats.totalCommits} commits
const userPrompt = `Projet : ${stats.repoName}
Période : ${stats.activeDays}j actifs, ${stats.totalCommits} commits
+${stats.totalLinesAdded} / ${stats.totalLinesDeleted} lignes
${stats.contributors.length} contributeurs : ${stats.contributors.slice(0, 5).map(c => c.name).join(", ")}
Types : ${stats.commitTypes.filter(t => t.count > 0).map(t => `${t.type} ${t.percentage}%`).join(", ")}
Fichiers modifiés : ${stats.totalFilesChanged}
**Statistiques clés** :
- ${stats.totalLinesAdded} lignes ajoutées / ${stats.totalLinesDeleted} supprimées
- ${stats.contributors.length} contributeur(s) : ${stats.contributors.slice(0, 5).map((c) => c.name).join(", ")}
- Types de commits : ${stats.commitTypes.filter((t) => t.count > 0).map((t) => `${t.type} (${t.percentage}%)`).join(", ")}
- Fichiers modifiés : ${stats.totalFilesChanged}
Commits récents :
${commitSamples}`;
**Derniers commits** :
${commitSamples}
Réponds avec ce format :
1. 📊 **Activité** : tendance générale
2. 👥 **Équipe** : qui fait quoi
3. 🔧 **Code** : types de changements principaux
4. 💡 **Conseil** : une suggestion pertinente`;
const response = await openai.chat.completions.create({
model: selectedModel,
messages: [{ role: "user" as const, content: prompt }],
max_tokens: 500,
temperature: 0.7,
// Use Ollama native API (more reliable than OpenAI compat for thinking models)
const ollamaUrl = OLLAMA_BASE_URL.replace(/\/v1$/, "");
const res = await fetch(`${ollamaUrl}/api/chat`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
model: selectedModel,
messages: [
{ role: "system", content: systemPrompt },
{ role: "user", content: userPrompt },
],
stream: false,
options: { temperature: 0.7, num_predict: 400 },
}),
});
return response.choices[0]?.message?.content?.trim() || "Pas de résumé généré.";
if (!res.ok) {
const err = await res.text();
throw new Error(`HTTP ${res.status}: ${err.slice(0, 200)}`);
}
const data = await res.json();
const content = data.message?.content?.trim();
if (!content || content.length < 10) {
// Maybe the model returned thinking output instead of content
return `Erreur : réponse vide du modèle ${selectedModel}. Le modèle peut nécessiter un format différent. Essayez \`ollama pull llama3.2\`.`;
}
return content;
} catch (error: any) {
return `Erreur Ollama (${selectedModel}) : ${error?.message || "inconnue"}. Vérifiez \`ollama pull ${selectedModel}\`.`;
return `Erreur Ollama (${selectedModel}) : ${error?.message || "inconnue"}. Vérifiez \`ollama serve\` et \`ollama pull ${selectedModel}\`.`;
}
}