feat(api): enhance commit summary with Gitea API integration

Add functionality to fetch commit diffs from the Gitea API and incorporate them into the German summary prompt. Update the summarizeMostRecentCommitDE function to handle webhook payloads for improved commit data retrieval. Maintain fallback to local git for compatibility.
This commit is contained in:
sebseb7
2025-08-04 14:30:06 +02:00
parent c2c7e11e00
commit a5db1f34cb

81
x.js
View File

@@ -8,6 +8,9 @@ const { exec, spawn } = require('child_process');
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
// Use built-in fetch (Node.js 18+) or fallback to node-fetch
const fetch = globalThis.fetch || require('node-fetch');
// --- Helpers: Git log + LLM summarization for Executive Summary (DE) --- // --- Helpers: Git log + LLM summarization for Executive Summary (DE) ---
// Promise-based exec wrapper with timeout // Promise-based exec wrapper with timeout
@@ -106,8 +109,46 @@ async function callLLMOpenAICompatible({ baseUrl, apiKey, model, system, user, t
} }
} }
// Summarize the most recent commit in German // Get commit diff from Gitea API
async function summarizeMostRecentCommitDE() { async function getCommitDiffFromGitea(giteaBaseUrl, repoOwner, repoName, commitHash) {
const giteaToken = process.env.GITEA_TOKEN;
if (!giteaToken) {
logMessage('GITEA_TOKEN not configured; cannot fetch diff from API', 'warn');
return null;
}
try {
const apiUrl = `${giteaBaseUrl}/api/v1/repos/${repoOwner}/${repoName}/git/commits/${commitHash}.diff`;
logMessage(`Fetching commit diff from: ${apiUrl}`);
const response = await fetch(apiUrl, {
headers: {
'Authorization': `token ${giteaToken}`,
'Accept': 'text/plain'
},
timeout: 10000
});
if (!response.ok) {
logMessage(`Gitea API request failed: ${response.status} ${response.statusText}`, 'warn');
return null;
}
const diffText = await response.text();
if (diffText && diffText.trim()) {
return diffText;
}
return null;
} catch (e) {
logMessage(`Failed to fetch commit diff from Gitea API: ${e.message}`, 'warn');
return null;
}
}
// Summarize the most recent commit in German using webhook payload data
async function summarizeMostRecentCommitDE(webhookPayload = null) {
// Determine provider // Determine provider
const provider = (process.env.LLM_PROVIDER || 'openrouter').toLowerCase(); const provider = (process.env.LLM_PROVIDER || 'openrouter').toLowerCase();
const model = process.env.LLM_MODEL || (provider === 'openrouter' ? 'openrouter/anthropic/claude-3.5-sonnet' : 'gpt-4o-mini'); const model = process.env.LLM_MODEL || (provider === 'openrouter' ? 'openrouter/anthropic/claude-3.5-sonnet' : 'gpt-4o-mini');
@@ -128,15 +169,41 @@ async function summarizeMostRecentCommitDE() {
return null; return null;
} }
// Pull commits from the current working directory (assumed repo root or subdir) let commits = [];
const commits = await getLastCommits({ count: 10, repoDir: process.cwd() }); let diff = '';
if (webhookPayload && webhookPayload.commits && webhookPayload.commits.length > 0) {
// Use webhook payload data
commits = webhookPayload.commits.map(commit => ({
hash: commit.id,
author: commit.author?.name || 'Unknown',
date: commit.timestamp || new Date().toISOString(),
subject: commit.message?.split('\n')[0] || 'No subject',
body: commit.message?.split('\n').slice(1).join('\n') || ''
}));
// Extract Gitea base URL from webhook payload
const giteaBaseUrl = webhookPayload.repository?.html_url?.match(/^https?:\/\/[^\/]+/)?.[0];
const repoOwner = webhookPayload.repository?.owner?.login;
const repoName = webhookPayload.repository?.name;
const latestCommitHash = commits[0]?.hash;
if (giteaBaseUrl && repoOwner && repoName && latestCommitHash) {
diff = await getCommitDiffFromGitea(giteaBaseUrl, repoOwner, repoName, latestCommitHash);
}
} else {
// Fallback to local git (original behavior)
commits = await getLastCommits({ count: 10, repoDir: process.cwd() });
if (!commits.length) return null;
diff = await getLastCommitDiff({ repoDir: process.cwd(), contextLines: 3 });
}
if (!commits.length) return null; if (!commits.length) return null;
const prompt = buildMostRecentCommitPromptGerman(commits); const prompt = buildMostRecentCommitPromptGerman(commits);
if (!prompt) return null; if (!prompt) return null;
// Also include the unified diff of the latest commit in the system prompt // Include the diff in the system prompt
const diff = await getLastCommitDiff({ repoDir: process.cwd(), contextLines: 3 });
const systemWithDiff = const systemWithDiff =
`${prompt.system}\n\n` + `${prompt.system}\n\n` +
`Kontext (unified diff der neuesten Änderung):\n` + `Kontext (unified diff der neuesten Änderung):\n` +
@@ -322,7 +389,7 @@ function formatCommitMessage(payload) {
return (async () => { return (async () => {
let summaryBlock = ''; let summaryBlock = '';
try { try {
const summary = await summarizeMostRecentCommitDE(); const summary = await summarizeMostRecentCommitDE(payload);
if (summary) { if (summary) {
const escapedSummary = escapeMdV2(summary); const escapedSummary = escapeMdV2(summary);
summaryBlock = `\n\n———————————————\n\n📋 *Executive Summary*\n\n${escapedSummary}\n\n\n`; summaryBlock = `\n\n———————————————\n\n📋 *Executive Summary*\n\n${escapedSummary}\n\n\n`;