ai-codegen-cli-vrk 2.0.3 → 2.0.5

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,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-codegen-cli-vrk",
3
- "version": "2.0.3",
3
+ "version": "2.0.5",
4
4
  "description": "Minimalist Terminal-based AI code generator",
5
5
  "type": "module",
6
6
  "bin": {
package/src/aiClient.js CHANGED
@@ -5,87 +5,66 @@ 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
- if (match) {
32
- SELECTED_MODEL_PATH = match.name; // e.g. "models/gemini-1.5-flash"
33
- return SELECTED_MODEL_PATH;
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
31
  const prompt = `
50
- Generate the ENTIRE coding project in a SINGLE continuous text response.
32
+ Generate the ENTIRE project in a SINGLE response.
51
33
  Strictly pass all test cases.
52
34
 
53
- ### FORMATTING (STRICT):
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
-
35
+ ### FORMATTING:
36
+ File headers must be exactly:
63
37
  // ==========================================
64
38
  // FILE: path/to/filename.js
65
39
  // ==========================================
66
- [CODE HERE]
67
40
 
68
- ### TASK:
41
+ TASK:
69
42
  ${task}
70
43
 
71
- ### TESTS:
44
+ TESTS:
72
45
  ${tests}
73
46
 
74
47
  ### RULES:
75
- - Minimalist logic. No extra logic.
48
+ - Minimalist logic only.
76
49
  - Bare minimum code to pass.
77
- - No explanations.
50
+ - No talk or explanations.
78
51
  `;
79
52
 
80
53
  const response = await fetch(url, {
81
54
  method: "POST",
82
55
  headers: { "Content-Type": "application/json" },
83
- body: JSON.stringify({
84
- contents: [{ parts: [{ text: prompt }] }]
85
- })
56
+ body: JSON.stringify({ contents: [{ parts: [{ text: prompt }] }] })
86
57
  });
87
58
 
88
59
  const data = await response.json();
60
+
61
+ // If overloaded (503) or rate limited (429), wait 10 seconds and retry
62
+ if ((response.status === 503 || response.status === 429) && retryCount < 5) {
63
+ console.log(`..... (Server busy, waiting 10s to retry ${retryCount + 1}/5)`);
64
+ await new Promise(r => setTimeout(r, 10000));
65
+ return generateFullProject(task, tests, retryCount + 1);
66
+ }
67
+
89
68
  if (!response.ok) throw new Error(data.error?.message || "Generation failed");
90
69
 
91
70
  const text = data.candidates?.[0]?.content?.parts?.[0]?.text || "";
package/src/runner.js CHANGED
@@ -4,13 +4,16 @@ import { setApiKey, generateFullProject } from "./aiClient.js";
4
4
  import { writeSingleFile } from "./fileWriter.js";
5
5
 
6
6
  async function main() {
7
- const apiKey = readlineSync.question("--- ", { hideEchoBack: true });
7
+ // Input API Key - set to visible
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
 
12
+ // Input Task
11
13
  const task = readlineSync.question("- ");
12
14
  if (!task || task.trim().length === 0) process.exit(1);
13
15
 
16
+ // Input Tests
14
17
  const testsInput = readlineSync.question("-- ");
15
18
  let tests = "";
16
19
  try {
@@ -28,7 +31,7 @@ async function main() {
28
31
  const projectContent = await generateFullProject(task, tests);
29
32
 
30
33
  if (!projectContent || projectContent.length < 50) {
31
- throw new Error("AI returned empty content. Check your task/tests.");
34
+ throw new Error("AI returned no content.");
32
35
  }
33
36
 
34
37
  await writeSingleFile(process.cwd(), projectContent);