ai-codegen-cli-vrk 2.0.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ai-codegen-cli-vrk",
3
- "version": "2.0.0",
4
- "description": "Minimalist Terminal-based AI code generator using Gemini",
3
+ "version": "2.0.2",
4
+ "description": "Minimalist Terminal-based AI code generator",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "ai-codegen": "bin/index.js"
@@ -11,10 +11,8 @@
11
11
  "src"
12
12
  ],
13
13
  "dependencies": {
14
+ "@google/generative-ai": "^0.21.0",
14
15
  "fs-extra": "^11.2.0",
15
16
  "readline-sync": "^1.4.10"
16
- },
17
- "engines": {
18
- "node": ">=18.0.0"
19
17
  }
20
18
  }
package/src/aiClient.js CHANGED
@@ -1,45 +1,50 @@
1
- let API_KEY = null;
2
- let SELECTED_MODEL = null;
1
+ import { GoogleGenerativeAI } from "@google/generative-ai";
2
+
3
+ let genAI = null;
4
+ let SELECTED_MODEL_NAME = null;
3
5
 
4
6
  export function setApiKey(apiKey) {
5
- API_KEY = apiKey;
7
+ genAI = new GoogleGenerativeAI(apiKey);
6
8
  }
7
9
 
8
10
  /**
9
- * Automatically finds the exact model name assigned to your key.
11
+ * Automatically finds a model that doesn't return 404
10
12
  */
11
- async function getValidModel() {
12
- if (SELECTED_MODEL) return SELECTED_MODEL;
13
- const url = `https://generativelanguage.googleapis.com/v1/models?key=${API_KEY}`;
14
- try {
15
- const response = await fetch(url);
16
- const data = await response.json();
17
- if (!response.ok) throw new Error();
18
- const found = (data.models || []).find(m =>
19
- m.supportedGenerationMethods.includes("generateContent") &&
20
- (m.name.includes("flash") || m.name.includes("pro"))
21
- );
22
- SELECTED_MODEL = found ? found.name : "models/gemini-1.5-flash";
23
- return SELECTED_MODEL;
24
- } catch {
25
- SELECTED_MODEL = "models/gemini-1.5-flash";
26
- return SELECTED_MODEL;
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
+ }
27
30
  }
31
+ throw new Error("No compatible Gemini models found for your API key.");
28
32
  }
29
33
 
30
34
  export async function generateFullProject(task, tests) {
31
- const modelPath = await getValidModel();
32
- const url = `https://generativelanguage.googleapis.com/v1/${modelPath}:generateContent?key=${API_KEY}`;
33
-
35
+ if (!genAI) throw new Error("API Key not initialized");
36
+
37
+ const model = await getWorkingModel();
38
+
34
39
  const prompt = `
35
40
  You are an expert automated coding exam solver.
36
41
  Generate the ENTIRE project in a SINGLE continuous text response.
37
42
 
38
43
  ### RULES:
39
- 1. ABSOLUTE PRIORITY: Test cases are the ONLY specification.
40
- 2. MINIMALIST: Generate the bare minimum code to pass. No extra logic, no comments, no console logs.
41
- 3. FLAT STRUCTURE: Use simple, standard patterns.
42
- 4. DEPENDENCIES: Only use 'express', 'mongoose', 'jsonwebtoken', and 'cookie-parser' if needed.
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.
43
48
 
44
49
  ### FORMATTING (STRICT):
45
50
  Every file MUST start with this EXACT header style:
@@ -63,16 +68,10 @@ ${task}
63
68
  ${tests}
64
69
  `;
65
70
 
66
- const response = await fetch(url, {
67
- method: "POST",
68
- headers: { "Content-Type": "application/json" },
69
- body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }] })
70
- });
71
-
72
- const data = await response.json();
73
- if (!response.ok) throw new Error();
74
-
75
- const text = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
76
- // Strip markdown backticks to return clean text
71
+ const result = await model.generateContent(prompt);
72
+ const response = await result.response;
73
+ const text = response.text();
74
+
75
+ // Clean markdown backticks
77
76
  return text.replace(/```[a-z]*\n([\s\S]*?)\n```/gi, "$1").trim();
78
77
  }
package/src/runner.js CHANGED
@@ -4,16 +4,13 @@ import { setApiKey, generateFullProject } from "./aiClient.js";
4
4
  import { writeSingleFile } from "./fileWriter.js";
5
5
 
6
6
  async function main() {
7
- // Input: API Key
8
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
 
12
- // Input: Task
13
11
  const task = readlineSync.question("- ");
14
12
  if (!task || task.trim().length === 0) process.exit(1);
15
13
 
16
- // Input: Test cases (Path or Raw Text)
17
14
  const testsInput = readlineSync.question("-- ");
18
15
  let tests = "";
19
16
  try {
@@ -27,19 +24,17 @@ async function main() {
27
24
  }
28
25
 
29
26
  try {
30
- // Silent Indicator
31
27
  console.log(".....");
32
-
33
- // Process Single Request
34
28
  const projectContent = await generateFullProject(task, tests);
35
29
 
36
- // Save to file
30
+ if (!projectContent || projectContent.length < 20) {
31
+ throw new Error("AI output too short or empty.");
32
+ }
33
+
37
34
  await writeSingleFile(process.cwd(), projectContent);
38
-
39
- // Silent Exit on Success
40
35
  process.exit(0);
41
- } catch {
42
- // Silent Exit on Failure
36
+ } catch (error) {
37
+ console.error("\n❌ Error:", error.message);
43
38
  process.exit(1);
44
39
  }
45
40
  }