ai-codegen-cli-vrk 2.0.3 → 2.0.4
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.
- package/package.json +1 -1
- package/src/aiClient.js +21 -58
- package/src/runner.js +3 -2
package/package.json
CHANGED
package/src/aiClient.js
CHANGED
|
@@ -5,87 +5,50 @@ export function setApiKey(apiKey) {
|
|
|
5
5
|
API_KEY = apiKey;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Automatically finds a model that is active for your account.
|
|
10
|
-
* This prevents the "404 Not Found" error.
|
|
11
|
-
*/
|
|
12
8
|
async function findActiveModel() {
|
|
13
9
|
if (SELECTED_MODEL_PATH) return SELECTED_MODEL_PATH;
|
|
14
|
-
|
|
15
|
-
// Use the stable v1 API to list models
|
|
16
10
|
const url = `https://generativelanguage.googleapis.com/v1/models?key=${API_KEY}`;
|
|
17
|
-
|
|
18
11
|
try {
|
|
19
12
|
const response = await fetch(url);
|
|
20
13
|
const data = await response.json();
|
|
21
|
-
|
|
22
14
|
if (!response.ok) throw new Error(data.error?.message || "Invalid API Key");
|
|
23
|
-
|
|
24
|
-
// Find the first model that supports content generation
|
|
25
|
-
const models = data.models || [];
|
|
26
|
-
const match = models.find(m =>
|
|
15
|
+
const match = (data.models || []).find(m =>
|
|
27
16
|
m.supportedGenerationMethods.includes("generateContent") &&
|
|
28
17
|
(m.name.includes("flash") || m.name.includes("pro"))
|
|
29
18
|
);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
} catch (err) {
|
|
36
|
-
// If listing fails, fall back to a standard guess
|
|
19
|
+
SELECTED_MODEL_PATH = match ? match.name : "models/gemini-1.5-flash";
|
|
20
|
+
return SELECTED_MODEL_PATH;
|
|
21
|
+
} catch {
|
|
22
|
+
SELECTED_MODEL_PATH = "models/gemini-1.5-flash";
|
|
23
|
+
return SELECTED_MODEL_PATH;
|
|
37
24
|
}
|
|
38
|
-
|
|
39
|
-
SELECTED_MODEL_PATH = "models/gemini-1.5-flash";
|
|
40
|
-
return SELECTED_MODEL_PATH;
|
|
41
25
|
}
|
|
42
26
|
|
|
43
|
-
export async function generateFullProject(task, tests) {
|
|
27
|
+
export async function generateFullProject(task, tests, retryCount = 0) {
|
|
44
28
|
const modelPath = await findActiveModel();
|
|
45
|
-
|
|
46
|
-
// Use v1 (stable) to avoid v1beta 404 issues
|
|
47
29
|
const url = `https://generativelanguage.googleapis.com/v1/${modelPath}:generateContent?key=${API_KEY}`;
|
|
48
30
|
|
|
49
|
-
const prompt = `
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
Every file MUST start with this EXACT header style:
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* ==========================================
|
|
58
|
-
* FILE: package.json (Reference)
|
|
59
|
-
* ==========================================
|
|
60
|
-
* [List Dependencies here]
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
|
-
// ==========================================
|
|
64
|
-
// FILE: path/to/filename.js
|
|
65
|
-
// ==========================================
|
|
66
|
-
[CODE HERE]
|
|
67
|
-
|
|
68
|
-
### TASK:
|
|
69
|
-
${task}
|
|
70
|
-
|
|
71
|
-
### TESTS:
|
|
72
|
-
${tests}
|
|
73
|
-
|
|
74
|
-
### RULES:
|
|
75
|
-
- Minimalist logic. No extra logic.
|
|
76
|
-
- Bare minimum code to pass.
|
|
77
|
-
- No explanations.
|
|
78
|
-
`;
|
|
31
|
+
const prompt = `Generate the ENTIRE project in ONE response. Strictly pass tests.
|
|
32
|
+
Header: // ==========================================
|
|
33
|
+
Header: // FILE: path/filename.js
|
|
34
|
+
TASK: ${task}
|
|
35
|
+
TESTS: ${tests}`;
|
|
79
36
|
|
|
80
37
|
const response = await fetch(url, {
|
|
81
38
|
method: "POST",
|
|
82
39
|
headers: { "Content-Type": "application/json" },
|
|
83
|
-
body: JSON.stringify({
|
|
84
|
-
contents: [{ parts: [{ text: prompt }] }]
|
|
85
|
-
})
|
|
40
|
+
body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }] })
|
|
86
41
|
});
|
|
87
42
|
|
|
88
43
|
const data = await response.json();
|
|
44
|
+
|
|
45
|
+
// Handle Overloaded / Service Unavailable (503) or Rate Limit (429)
|
|
46
|
+
if ((response.status === 503 || response.status === 429) && retryCount < 3) {
|
|
47
|
+
console.log(`..... (retrying due to server load)`);
|
|
48
|
+
await new Promise(r => setTimeout(r, 5000)); // Wait 5 seconds
|
|
49
|
+
return generateFullProject(task, tests, retryCount + 1);
|
|
50
|
+
}
|
|
51
|
+
|
|
89
52
|
if (!response.ok) throw new Error(data.error?.message || "Generation failed");
|
|
90
53
|
|
|
91
54
|
const text = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
|
package/src/runner.js
CHANGED
|
@@ -4,7 +4,8 @@ import { setApiKey, generateFullProject } from "./aiClient.js";
|
|
|
4
4
|
import { writeSingleFile } from "./fileWriter.js";
|
|
5
5
|
|
|
6
6
|
async function main() {
|
|
7
|
-
|
|
7
|
+
// CHANGED: hideEchoBack is now false so you can see the key
|
|
8
|
+
const apiKey = readlineSync.question("--- ", { hideEchoBack: false });
|
|
8
9
|
if (!apiKey || apiKey.trim().length === 0) process.exit(1);
|
|
9
10
|
setApiKey(apiKey.trim());
|
|
10
11
|
|
|
@@ -28,7 +29,7 @@ async function main() {
|
|
|
28
29
|
const projectContent = await generateFullProject(task, tests);
|
|
29
30
|
|
|
30
31
|
if (!projectContent || projectContent.length < 50) {
|
|
31
|
-
throw new Error("AI returned
|
|
32
|
+
throw new Error("AI returned no content.");
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
await writeSingleFile(process.cwd(), projectContent);
|