overai 1.4.14 → 1.4.16
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/dist/cli/create.js +81 -22
- package/package.json +1 -1
package/dist/cli/create.js
CHANGED
|
@@ -41,8 +41,30 @@ const child_process_1 = require("child_process");
|
|
|
41
41
|
const util_1 = require("util");
|
|
42
42
|
const readline = __importStar(require("readline"));
|
|
43
43
|
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
44
|
+
const rl = readline.createInterface({
|
|
45
|
+
input: process.stdin,
|
|
46
|
+
output: process.stdout
|
|
47
|
+
});
|
|
44
48
|
// 1. Define Tools for the Agent
|
|
45
49
|
const fileTools = [
|
|
50
|
+
{
|
|
51
|
+
name: "ask_user",
|
|
52
|
+
description: "Ask the user for input or confirmation. Use this when you need clarification or want to confirm an action.",
|
|
53
|
+
parameters: {
|
|
54
|
+
type: "object",
|
|
55
|
+
properties: {
|
|
56
|
+
question: { type: "string", description: "The question to ask the user" }
|
|
57
|
+
},
|
|
58
|
+
required: ["question"]
|
|
59
|
+
},
|
|
60
|
+
execute: async ({ question: q }) => {
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
rl.question(`\n❓ ${q}\n> `, (answer) => {
|
|
63
|
+
resolve(answer);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
},
|
|
46
68
|
{
|
|
47
69
|
name: "write_file",
|
|
48
70
|
description: "Write content to a file. Use this to create code files.",
|
|
@@ -112,11 +134,12 @@ const fileTools = [
|
|
|
112
134
|
}
|
|
113
135
|
}
|
|
114
136
|
];
|
|
115
|
-
const rl = readline.createInterface({
|
|
116
|
-
input: process.stdin,
|
|
117
|
-
output: process.stdout
|
|
118
|
-
});
|
|
119
137
|
async function main() {
|
|
138
|
+
// 3. Get User Input
|
|
139
|
+
const question = (query) => {
|
|
140
|
+
return new Promise((resolve) => rl.question(query, resolve));
|
|
141
|
+
};
|
|
142
|
+
// 3. Get User Input already defined above
|
|
120
143
|
// Model Selection Logic
|
|
121
144
|
let model = "gpt-4o";
|
|
122
145
|
const args = process.argv.slice(2);
|
|
@@ -127,26 +150,56 @@ async function main() {
|
|
|
127
150
|
args.splice(modelArgIndex, 2); // Remove flag from args so it doesn't become part of the prompt
|
|
128
151
|
}
|
|
129
152
|
else {
|
|
130
|
-
//
|
|
153
|
+
// Interactive Selection
|
|
154
|
+
const availableModels = [];
|
|
131
155
|
if (process.env.OPENAI_API_KEY) {
|
|
132
|
-
|
|
156
|
+
availableModels.push({ name: "OpenAI: GPT-4o", value: "gpt-4o" });
|
|
157
|
+
availableModels.push({ name: "OpenAI: GPT-4o-mini", value: "gpt-4o-mini" });
|
|
133
158
|
}
|
|
134
|
-
|
|
135
|
-
|
|
159
|
+
if (process.env.GOOGLE_API_KEY) {
|
|
160
|
+
availableModels.push({ name: "Google: Gemini 2.0 Flash", value: "google/gemini-2.0-flash-exp" });
|
|
161
|
+
availableModels.push({ name: "Google: Gemini 1.5 Pro", value: "google/gemini-1.5-pro" });
|
|
136
162
|
}
|
|
137
|
-
|
|
138
|
-
|
|
163
|
+
if (process.env.ANTHROPIC_API_KEY) {
|
|
164
|
+
availableModels.push({ name: "Anthropic: Claude 3.5 Sonnet", value: "anthropic/claude-3-5-sonnet-20240620" });
|
|
165
|
+
availableModels.push({ name: "Anthropic: Claude 3 Haiku", value: "anthropic/claude-3-haiku-20240307" });
|
|
139
166
|
}
|
|
140
|
-
|
|
167
|
+
if (process.env.DEEPSEEK_API_KEY) {
|
|
168
|
+
availableModels.push({ name: "DeepSeek: V3", value: "deepseek/deepseek-chat" });
|
|
169
|
+
}
|
|
170
|
+
if (availableModels.length === 0) {
|
|
141
171
|
console.error("❌ Error: No API Key found.");
|
|
142
|
-
console.error("Please set ONE of the following environment variables:");
|
|
172
|
+
console.error("Please set at least ONE of the following environment variables:");
|
|
143
173
|
console.error(" export OPENAI_API_KEY=sk-...");
|
|
144
174
|
console.error(" export GOOGLE_API_KEY=AIza...");
|
|
145
175
|
console.error(" export ANTHROPIC_API_KEY=sk-ant-...");
|
|
146
176
|
process.exit(1);
|
|
147
177
|
}
|
|
178
|
+
// If we have models, ask the user
|
|
179
|
+
console.log("\n🤖 **Select AI Model**:");
|
|
180
|
+
availableModels.forEach((m, index) => {
|
|
181
|
+
console.log(` ${index + 1}. ${m.name}`);
|
|
182
|
+
});
|
|
183
|
+
console.log(` ${availableModels.length + 1}. Custom (enter model name manually)`);
|
|
184
|
+
const choice = await question(`\n👉 Choose a model (1-${availableModels.length + 1}) [default: 1]: `);
|
|
185
|
+
const choiceIndex = parseInt(choice.trim()) - 1;
|
|
186
|
+
if (!choice.trim()) {
|
|
187
|
+
model = availableModels[0].value;
|
|
188
|
+
}
|
|
189
|
+
else if (choiceIndex >= 0 && choiceIndex < availableModels.length) {
|
|
190
|
+
model = availableModels[choiceIndex].value;
|
|
191
|
+
}
|
|
192
|
+
else if (choiceIndex === availableModels.length) {
|
|
193
|
+
model = await question("👉 Enter custom model name (e.g., 'ollama/llama3'): ");
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
// Fallback to first available if invalid input
|
|
197
|
+
if (availableModels.length > 0)
|
|
198
|
+
model = availableModels[0].value;
|
|
199
|
+
}
|
|
148
200
|
}
|
|
149
201
|
console.log(`🧠 Using AI Model: \x1b[36m${model}\x1b[0m`);
|
|
202
|
+
console.log(`📂 Working in: ${process.cwd()}`);
|
|
150
203
|
// 2. Create the "AutoCoder" Agent
|
|
151
204
|
const coder = new index_1.Agent({
|
|
152
205
|
name: "AutoCoder",
|
|
@@ -160,24 +213,28 @@ async function main() {
|
|
|
160
213
|
|
|
161
214
|
PROCESS:
|
|
162
215
|
1. ANALYZE: Understand the user's request and technology stack (Node, Python, React, etc.).
|
|
216
|
+
- If the request is vague or you need preferences (e.g., "Tailwind or CSS?"), use 'ask_user' tool.
|
|
163
217
|
2. PLAN: Decide on the directory structure and necessary files.
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
218
|
+
- You CAN ask the user for confirmation of your plan if it involves many files.
|
|
219
|
+
3. SCAFFOLD: Create the project directory (e.g. "mkdir my-project").
|
|
220
|
+
4. IMPLEMENT: Create the core files with working code.
|
|
221
|
+
IMPORTANT: When using 'write_file', you MUST use the project directory prefix (e.g. "my-project/index.js").
|
|
222
|
+
The 'write_file' tool operates from the root, so you must always specify the full relative path.
|
|
223
|
+
5. DEPENDENCIES: Install necessary packages (e.g. "cd my-project && npm install ...").
|
|
167
224
|
6. VERIFY: Run a command to prove the project works or builds successfully.
|
|
168
225
|
|
|
169
226
|
RULES:
|
|
170
|
-
- ALWAYS start by creating a new directory for the project
|
|
227
|
+
- ALWAYS start by creating a new directory for the project.
|
|
228
|
+
- ALL file paths in 'write_file' MUST include the project directory name (e.g., 'project-name/README.md').
|
|
229
|
+
- Do not rely on 'cd' in 'run_command' to change the directory for 'write_file' calls.
|
|
171
230
|
- Be comprehensive: Include README.md, .gitignore, and config files.
|
|
172
231
|
- If something fails, try to fix it or report the specific error.
|
|
173
|
-
- Do not ask for permission for each step, proceed autonomously until completion
|
|
232
|
+
- Do not ask for permission for each step, proceed autonomously until completion.
|
|
233
|
+
- INTERACTIVITY: Use 'ask_user' when you need key decisions from the user. Don't be too chatty, but ask when it matters.`,
|
|
174
234
|
llm: model,
|
|
175
235
|
tools: fileTools
|
|
176
236
|
});
|
|
177
|
-
// 3. Get User Input
|
|
178
|
-
const question = (query) => {
|
|
179
|
-
return new Promise((resolve) => rl.question(query, resolve));
|
|
180
|
-
};
|
|
237
|
+
// 3. Get User Input (Defined at top of main)
|
|
181
238
|
console.log("\n🚀 **OverAI Auto-Coder** initialized.");
|
|
182
239
|
console.log("I can build any project for you (Node.js, Python, simple websites, scripts...).");
|
|
183
240
|
// If argument provided via CLI, use it. Otherwise ask.
|
|
@@ -188,7 +245,6 @@ async function main() {
|
|
|
188
245
|
else {
|
|
189
246
|
console.log(`\n🛠️ Request received: "${userRequest}"`);
|
|
190
247
|
}
|
|
191
|
-
rl.close();
|
|
192
248
|
if (!userRequest.trim()) {
|
|
193
249
|
console.log("❌ No request provided. Exiting.");
|
|
194
250
|
return;
|
|
@@ -215,5 +271,8 @@ async function main() {
|
|
|
215
271
|
catch (error) {
|
|
216
272
|
console.error("❌ Mission Failed:", error);
|
|
217
273
|
}
|
|
274
|
+
finally {
|
|
275
|
+
rl.close();
|
|
276
|
+
}
|
|
218
277
|
}
|
|
219
278
|
main();
|