test: update tests

This commit is contained in:
s41r4j
2026-06-09 02:18:17 +05:30
parent 807d5bcb20
commit a54d529f31
6 changed files with 414 additions and 344 deletions
+49 -38
View File
@@ -1,3 +1,5 @@
const fs = require('fs');
const path = require('path');
const { OpenAI } = require('openai');
const { GoogleGenAI } = require('@google/genai');
const { Progress } = require('../utils/progress');
@@ -9,31 +11,17 @@ const { color } = require('../utils/colors');
class AIProviderManager {
constructor(config = {}) {
this.config = config;
this.cache = new Map();
this.maxCacheSize = 100;
}
resolveProvider(preference = 'auto') {
if (preference === 'none') return 'none';
// Check if preferred provider's key is available
if (preference === 'openai' && process.env.OPENAI_API_KEY) return 'openai';
if (preference === 'gemini' && process.env.GEMINI_API_KEY) return 'gemini';
if (preference === 'groq' && process.env.GROQ_API_KEY) return 'groq';
// Fallback: try any available provider (priority: Gemini → OpenAI → Groq)
if (process.env.GEMINI_API_KEY) return 'gemini';
if (process.env.OPENAI_API_KEY) return 'openai';
if (process.env.GROQ_API_KEY) return 'groq';
return 'none';
this.cacheFile = path.join(
process.env.HOME || process.env.USERPROFILE || process.cwd(),
'.gims', 'cache.json'
);
}
getDefaultModel(provider) {
const defaults = {
'gemini': 'gemini-3-flash-preview', // Latest Gemini model
'openai': 'gpt-5.2-2025-12-11', // Latest GPT model
'groq': 'groq/compound' // Latest Groq model
'gemini': 'gemini-2.0-flash',
'openai': 'gpt-4o-mini',
'groq': 'llama-3.3-70b-versatile'
};
return defaults[provider] || '';
}
@@ -46,26 +34,36 @@ class AIProviderManager {
getFromCache(cacheKey) {
if (!this.config.cacheEnabled) return null;
return this.cache.get(cacheKey);
try {
if (!fs.existsSync(this.cacheFile)) return null;
const data = JSON.parse(fs.readFileSync(this.cacheFile, 'utf8'));
return data[cacheKey] || null;
} catch {
return null;
}
}
setCache(cacheKey, result, usedLocal = false) {
if (!this.config.cacheEnabled) return;
if (this.cache.size >= this.maxCacheSize) {
const firstKey = this.cache.keys().next().value;
this.cache.delete(firstKey);
}
this.cache.set(cacheKey, {
result,
usedLocal,
timestamp: Date.now()
});
try {
const dir = path.dirname(this.cacheFile);
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
let data = {};
if (fs.existsSync(this.cacheFile)) {
try { data = JSON.parse(fs.readFileSync(this.cacheFile, 'utf8')); } catch {}
}
const keys = Object.keys(data);
if (keys.length >= 100) {
const oldest = keys.sort((a, b) => (data[a].timestamp || 0) - (data[b].timestamp || 0));
oldest.slice(0, keys.length - 99).forEach(k => delete data[k]);
}
data[cacheKey] = { result, usedLocal, timestamp: Date.now() };
fs.writeFileSync(this.cacheFile, JSON.stringify(data));
} catch {}
}
async generateWithProvider(provider, prompt, options = {}) {
const { model = '', temperature = 0.3, maxTokens = 200 } = options;
const { model = '' } = options;
try {
switch (provider) {
@@ -79,7 +77,14 @@ class AIProviderManager {
throw new Error(`Unknown provider: ${provider}`);
}
} catch (error) {
throw new Error(`${provider} generation failed: ${error.message}`);
const msg = error.message || '';
if (msg.includes('429') || /rate.?limit/i.test(msg)) {
throw new Error(`${provider} rate limit hit — try again in a moment`);
}
if (msg.includes('401') || /invalid.api.key|api_key/i.test(msg)) {
throw new Error(`${provider} API key invalid — run: g setup --api-key ${provider}`);
}
throw new Error(`${provider} generation failed: ${msg}`);
}
}
@@ -135,8 +140,14 @@ class AIProviderManager {
verbose = false
} = options;
// Truncate oversized diffs before sending to AI
const maxDiffSize = this.config.maxDiffSize || 100000;
const truncatedDiff = diff.length > maxDiffSize
? diff.substring(0, maxDiffSize) + '\n... (diff truncated for AI)'
: diff;
// Check cache first
const cacheKey = this.getCacheKey(diff, { conventional, body });
const cacheKey = this.getCacheKey(truncatedDiff, { conventional, body });
const cached = this.getFromCache(cacheKey);
if (cached && Date.now() - cached.timestamp < 3600000) { // 1 hour cache
if (verbose) Progress.info('Using cached result');
@@ -148,12 +159,12 @@ class AIProviderManager {
for (const provider of providerChain) {
try {
if (provider === 'local') {
const result = await this.generateLocalHeuristic(diff, options);
const result = await this.generateLocalHeuristic(truncatedDiff, options);
this.setCache(cacheKey, result, true);
return { message: result, usedLocal: true };
}
const prompt = this.buildPrompt(diff, { conventional, body });
const prompt = this.buildPrompt(truncatedDiff, { conventional, body });
const result = await this.generateWithProvider(provider, prompt, options);
const cleaned = this.cleanCommitMessage(result, { body });