fix: use native Ollama API instead of OpenAI compat for thinking models
This commit is contained in:
@@ -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}\`.`;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user