ai-codegen-cli-vrk 2.0.1 → 2.0.2
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 -4
- package/src/aiClient.js +33 -12
- package/src/runner.js +2 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-codegen-cli-vrk",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Minimalist Terminal-based AI code generator",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,8 +14,5 @@
|
|
|
14
14
|
"@google/generative-ai": "^0.21.0",
|
|
15
15
|
"fs-extra": "^11.2.0",
|
|
16
16
|
"readline-sync": "^1.4.10"
|
|
17
|
-
},
|
|
18
|
-
"engines": {
|
|
19
|
-
"node": ">=18.0.0"
|
|
20
17
|
}
|
|
21
18
|
}
|
package/src/aiClient.js
CHANGED
|
@@ -1,26 +1,50 @@
|
|
|
1
1
|
import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
2
2
|
|
|
3
3
|
let genAI = null;
|
|
4
|
-
let
|
|
4
|
+
let SELECTED_MODEL_NAME = null;
|
|
5
5
|
|
|
6
6
|
export function setApiKey(apiKey) {
|
|
7
7
|
genAI = new GoogleGenerativeAI(apiKey);
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Automatically finds a model that doesn't return 404
|
|
12
|
+
*/
|
|
13
|
+
async function getWorkingModel() {
|
|
14
|
+
if (SELECTED_MODEL_NAME) return genAI.getGenerativeModel({ model: SELECTED_MODEL_NAME });
|
|
15
|
+
|
|
16
|
+
const candidates = ["gemini-1.5-flash", "gemini-1.5-flash-latest", "gemini-pro"];
|
|
17
|
+
|
|
18
|
+
for (const name of candidates) {
|
|
19
|
+
try {
|
|
20
|
+
const model = genAI.getGenerativeModel({ model: name });
|
|
21
|
+
// Quick test call to verify if model exists for this key
|
|
22
|
+
await model.generateContent({ contents: [{ role: "user", parts: [{ text: "hi" }] }], generationConfig: { maxOutputTokens: 5 } });
|
|
23
|
+
SELECTED_MODEL_NAME = name;
|
|
24
|
+
return model;
|
|
25
|
+
} catch (err) {
|
|
26
|
+
// If it's a 404, try the next model
|
|
27
|
+
if (err.message.includes("404")) continue;
|
|
28
|
+
throw err; // Stop if it's an Auth or Quota error
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new Error("No compatible Gemini models found for your API key.");
|
|
10
32
|
}
|
|
11
33
|
|
|
12
34
|
export async function generateFullProject(task, tests) {
|
|
13
|
-
if (!genAI) throw new Error("API Key not
|
|
35
|
+
if (!genAI) throw new Error("API Key not initialized");
|
|
36
|
+
|
|
37
|
+
const model = await getWorkingModel();
|
|
14
38
|
|
|
15
39
|
const prompt = `
|
|
16
40
|
You are an expert automated coding exam solver.
|
|
17
41
|
Generate the ENTIRE project in a SINGLE continuous text response.
|
|
18
42
|
|
|
19
43
|
### RULES:
|
|
20
|
-
1.
|
|
21
|
-
2. MINIMALIST:
|
|
22
|
-
3. FLAT STRUCTURE:
|
|
23
|
-
4.
|
|
44
|
+
1. Test cases are the ONLY specification.
|
|
45
|
+
2. MINIMALIST: Bare minimum code to pass. No extra logic.
|
|
46
|
+
3. FLAT STRUCTURE: Standard patterns.
|
|
47
|
+
4. No talk, no explanations.
|
|
24
48
|
|
|
25
49
|
### FORMATTING (STRICT):
|
|
26
50
|
Every file MUST start with this EXACT header style:
|
|
@@ -42,15 +66,12 @@ ${task}
|
|
|
42
66
|
|
|
43
67
|
### TESTS:
|
|
44
68
|
${tests}
|
|
45
|
-
|
|
46
|
-
### OUTPUT:
|
|
47
|
-
Return ONLY the code sections. No talk. No markdown backticks.
|
|
48
69
|
`;
|
|
49
70
|
|
|
50
71
|
const result = await model.generateContent(prompt);
|
|
51
72
|
const response = await result.response;
|
|
52
73
|
const text = response.text();
|
|
53
74
|
|
|
54
|
-
//
|
|
75
|
+
// Clean markdown backticks
|
|
55
76
|
return text.replace(/```[a-z]*\n([\s\S]*?)\n```/gi, "$1").trim();
|
|
56
77
|
}
|
package/src/runner.js
CHANGED
|
@@ -4,8 +4,7 @@ import { setApiKey, generateFullProject } from "./aiClient.js";
|
|
|
4
4
|
import { writeSingleFile } from "./fileWriter.js";
|
|
5
5
|
|
|
6
6
|
async function main() {
|
|
7
|
-
|
|
8
|
-
const apiKey = readlineSync.question("--- ");
|
|
7
|
+
const apiKey = readlineSync.question("--- ", { hideEchoBack: true });
|
|
9
8
|
if (!apiKey || apiKey.trim().length === 0) process.exit(1);
|
|
10
9
|
setApiKey(apiKey.trim());
|
|
11
10
|
|
|
@@ -29,13 +28,12 @@ async function main() {
|
|
|
29
28
|
const projectContent = await generateFullProject(task, tests);
|
|
30
29
|
|
|
31
30
|
if (!projectContent || projectContent.length < 20) {
|
|
32
|
-
throw new Error("AI
|
|
31
|
+
throw new Error("AI output too short or empty.");
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
await writeSingleFile(process.cwd(), projectContent);
|
|
36
35
|
process.exit(0);
|
|
37
36
|
} catch (error) {
|
|
38
|
-
// Report errors explicitly instead of exiting silently
|
|
39
37
|
console.error("\n❌ Error:", error.message);
|
|
40
38
|
process.exit(1);
|
|
41
39
|
}
|