@himamshus06/git-auto 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ai.js +68 -10
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@himamshus06/git-auto",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/ai.js CHANGED
@@ -8,6 +8,11 @@ const openai = new OpenAI({
8
8
 
9
9
  /**
10
10
  * Generates a professional commit message based on the provided git diff.
11
+ * For large diffs, it uses a map-reduce approach:
12
+ * 1. Splits the diff into manageable chunks.
13
+ * 2. Summarizes each chunk.
14
+ * 3. Combines summaries into one final commit message.
15
+ *
11
16
  * @param {string} diff - The git diff of staged changes.
12
17
  * @returns {Promise<string>} - The generated commit message.
13
18
  * @throws {Error} - If API key is missing or API call fails.
@@ -17,24 +22,77 @@ async function generateCommitMessage(diff) {
17
22
  throw new Error('GROQ_API_KEY is missing from .env file.');
18
23
  }
19
24
 
20
- // TRUNCATION LOGIC:
21
- // Prevent "Request too large" errors by limiting the diff size.
22
- // 10,000 characters is usually enough to understand the changes
23
- // while staying safely under free-tier token limits.
24
- const MAX_DIFF_LENGTH = 10000;
25
- let processedDiff = diff;
26
- if (diff.length > MAX_DIFF_LENGTH) {
27
- processedDiff = diff.substring(0, MAX_DIFF_LENGTH) +
28
- '\n\n... (diff truncated due to size)';
25
+ const CHUNK_SIZE = 8000; // Characters per chunk to stay under token limits
26
+ const isLargeDiff = diff.length > CHUNK_SIZE;
27
+
28
+ if (!isLargeDiff) {
29
+ return await getSingleCommitMessage(diff);
30
+ }
31
+
32
+ console.log(`Large diff detected (${diff.length} chars). Using chunked summary approach...`);
33
+
34
+ // 1. Map: Split diff into chunks and generate summaries for each
35
+ const chunks = [];
36
+ for (let i = 0; i < diff.length; i += CHUNK_SIZE) {
37
+ chunks.push(diff.substring(i, i + CHUNK_SIZE));
38
+ }
39
+
40
+ const summaryPromises = chunks.map(async (chunk, index) => {
41
+ const prompt = `Analyze this portion (${index + 1}/${chunks.length}) of a git diff and provide a 1-sentence summary of the changes.
42
+ Diff snippet:
43
+ ${chunk}`;
44
+
45
+ try {
46
+ const response = await openai.chat.completions.create({
47
+ model: 'qwen/qwen3.8-27b',
48
+ messages: [{ role: 'user', content: prompt }],
49
+ temperature: 0.2,
50
+ max_tokens: 100,
51
+ });
52
+ return response.choices[0].message.content.trim();
53
+ } catch (e) {
54
+ return `Error summarizing chunk ${index + 1}: ${e.message}`;
55
+ }
56
+ });
57
+
58
+ const summaries = await Promise.all(summaryPromises);
59
+ const combinedSummaries = summaries.join('\n');
60
+
61
+ // 2. Reduce: Combine all summaries into one final professional commit message
62
+ const finalPrompt = `
63
+ Based on the following summaries of changes across multiple files, write one professional, concise commit message.
64
+ Follow the Conventional Commits specification (e.g., feat: ..., fix: ..., chore: ..., docs: ..., style: ..., refactor: ..., perf: ..., test: ...).
65
+ Only return the commit message string itself, without any quotes or explanation.
66
+
67
+ Summaries:
68
+ ${combinedSummaries}
69
+ `.trim();
70
+
71
+ try {
72
+ const response = await openai.chat.completions.create({
73
+ model: 'qwen/qwen3.8-27b',
74
+ messages: [{ role: 'user', content: finalPrompt }],
75
+ temperature: 0.2,
76
+ max_tokens: 100,
77
+ });
78
+
79
+ return response.choices[0].message.content.trim();
80
+ } catch (error) {
81
+ throw new Error(`Final reduction failed: ${error.message}`);
29
82
  }
83
+ }
30
84
 
85
+ /**
86
+ * Helper to generate a commit message from a single diff (used for small changes).
87
+ */
88
+ async function getSingleCommitMessage(diff) {
31
89
  const prompt = `
32
90
  Analyze the following git diff and write a professional, concise commit message.
33
91
  Follow the Conventional Commits specification (e.g., feat: ..., fix: ..., chore: ..., docs: ..., style: ..., refactor: ..., perf: ..., test: ...).
34
92
  Only return the commit message string itself, without any quotes or explanation.
35
93
 
36
94
  Diff:
37
- ${processedDiff}
95
+ ${diff}
38
96
  `.trim();
39
97
 
40
98
  try {