Skip to content

Commit 4a1071e

Browse files
committed
add support for any open ai server
1 parent 830c756 commit 4a1071e

4 files changed

Lines changed: 90 additions & 63 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,11 @@ This tool is still in its alpha stage, so expect some hiccups as we fine-tune ou
5454

5555
## 🔥 Features
5656

57-
- **AI Service Selection**: Pick between Ollama and ChatGPT to generate scripts for you.
57+
- **AI Service Selection**: Pick between Ollama, ChatGPT, and any OpenAI compatable server.
5858
- **Easy Configuration**: Set everything up quickly with a few prompts.
59-
- **Execution Plans**: See what’s going to happen before it happens.
60-
- **Optional Logging**: Keep track of everything for debugging or just for fun.
59+
- **Command Line Power**: Ask the AI to do any task(s) you would want to do at the command line.
60+
- **DB Power**: Ask the AI for any information from your DB in plain language.
61+
- **Conversational AI**: Start a conversation with the AI.
6162

6263
## 📋 Requirements
6364

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import OpenAI from "openai";
22
import BaseAdapter from "./BaseAdapter.js";
33

4-
class ChatGPTAdapter extends BaseAdapter {
4+
class OpenAIAdapter extends BaseAdapter {
55
constructor(config) {
66
super(config);
7-
this.apiKey = config.chatgptApiKey;
8-
this.model = config.chatgptModel;
9-
this.apiUrl = config.chatgptApiUrl || "https://api.openai.com/v1";
7+
this.apiKey = config.openAIApiKey;
8+
this.model = config.openAIModel;
9+
this.apiUrl = config.openAIApiUrl || "https://api.openai.com/v1";
1010
}
1111

1212
async generateResponse(command) {
@@ -37,4 +37,4 @@ class ChatGPTAdapter extends BaseAdapter {
3737
}
3838
}
3939

40-
export default ChatGPTAdapter;
40+
export default OpenAIAdapter;

lib/aiClient/aiClient.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import OllamaAdapter from "./adapters/OllamaAdapter.js";
2-
import ChatGPTAdapter from "./adapters/ChatGPTAdapter.js";
2+
import OpenAIAdapter from "./adapters/OpenAIAdapter.js";
33

44
class AIClient {
55
constructor(config) {
66
this.adapter =
7-
config.aiService === "ChatGPT"
8-
? new ChatGPTAdapter(config)
7+
config.aiService === "ChatGPT" || "OpenAI"
8+
? new OpenAIAdapter(config)
99
: new OllamaAdapter(config);
1010
}
1111

lib/config.js

Lines changed: 78 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { Ollama } from "ollama";
77
import gradient from "gradient-string";
88

99
const configPath = path.join(os.homedir(), ".commandai", "config.json");
10-
const defaultChatGPTModel = "gpt-4o";
11-
const defaultChatGPTApiUrl = "https://api.openai.com/v1";
10+
const defaultOpenAIModel = "gpt-4o";
11+
const defaultOpenAIApiUrl = "https://api.openai.com/v1";
1212
const defaultOllamaUrl = "http://127.0.0.1:11434";
1313

1414
async function checkOllamaActive(url = defaultOllamaUrl) {
@@ -26,8 +26,32 @@ function loadConfig() {
2626
if (fs.existsSync(configPath)) {
2727
const configFile = fs.readFileSync(configPath);
2828
const config = JSON.parse(configFile);
29+
30+
if (!config.openAIApiUrl) {
31+
config.openAIApiUrl = config.chatgptApiUrl;
32+
33+
delete config.chatgptApiUrl;
34+
}
35+
36+
if (!config.openAIModel) {
37+
config.openAIModel = config.chatgptModel;
38+
39+
delete config.chatgptModel;
40+
}
41+
42+
if (!config.openAIApiKey) {
43+
config.openAIApiKey = config.chatgptApiKey;
44+
45+
delete config.chatgptApiKey;
46+
}
47+
2948
config.model =
30-
config.aiService === "Ollama" ? config.ollamaModel : config.chatgptModel;
49+
config.aiService === "Ollama" ? config.ollamaModel : config.openAIModel;
50+
51+
if (config.aiService === "ChatGPT") {
52+
config.openAIApiUrl = defaultOpenAIApiUrl;
53+
}
54+
3155
return config;
3256
} else {
3357
return null;
@@ -36,7 +60,7 @@ function loadConfig() {
3660

3761
async function saveConfig(config) {
3862
config.model =
39-
config.aiService === "Ollama" ? config.ollamaModel : config.chatgptModel;
63+
config.aiService === "Ollama" ? config.ollamaModel : config.openAIModel;
4064
const dir = path.dirname(configPath);
4165
if (!fs.existsSync(dir)) {
4266
fs.mkdirSync(dir, { recursive: true });
@@ -47,9 +71,9 @@ async function saveConfig(config) {
4771
console.log();
4872
}
4973

50-
async function validateApiKey(apiKey, chatgptApiUrl) {
74+
async function validateApiKey(apiKey, openAIApiUrl) {
5175
try {
52-
const openai = new OpenAI({ baseURL: chatgptApiUrl, apiKey: apiKey });
76+
const openai = new OpenAI({ baseURL: openAIApiUrl, apiKey: apiKey });
5377
await openai.models.list();
5478
return true;
5579
} catch (error) {
@@ -58,9 +82,9 @@ async function validateApiKey(apiKey, chatgptApiUrl) {
5882
}
5983
}
6084

61-
async function fetchChatGPTModels(apiKey, chatgptApiUrl) {
85+
async function fetchOpenAIModels(openAIApiUrl, apiKey) {
6286
try {
63-
const openai = new OpenAI({ baseURL: chatgptApiUrl, apiKey: apiKey });
87+
const openai = new OpenAI({ baseURL: openAIApiUrl, apiKey: apiKey });
6488
const response = await openai.models.list();
6589
return response.data.map((model) => model.id);
6690
} catch (error) {
@@ -162,28 +186,28 @@ async function promptOllamaConfig(defaultUrl, defaultModel) {
162186
};
163187
}
164188

165-
async function promptChatGPTAPIKey(defaultApiKey, chatgptApiUrl) {
166-
const chatgptConfig = await inquirer.prompt([
189+
async function promptOpenAIAPIKey(defaultApiKey, openAIApiUrl) {
190+
const openAIConfig = await inquirer.prompt([
167191
{
168192
type: "input",
169-
name: "chatgptApiKey",
193+
name: "openAIApiKey",
170194
message: "Enter your OpenAI API key:",
171195
default: defaultApiKey,
172196
},
173197
]);
174198

175-
const isValidApiKey = await validateApiKey(chatgptConfig.chatgptApiKey, chatgptApiUrl);
199+
const isValidApiKey = await validateApiKey(openAIConfig.openAIApiKey, openAIApiUrl);
176200

177201
if (!isValidApiKey) {
178202
return null;
179203
}
180204

181-
return chatgptConfig;
205+
return openAIConfig;
182206
}
183207

184208

185-
async function promptChatGPTModels(defaultModel, chatgptApiUrl) {
186-
const models = await fetchChatGPTModels(chatgptApiUrl);
209+
async function promptOpenAIModels(defaultModel, openAIApiUrl, openAIApiKey) {
210+
const models = await fetchOpenAIModels(openAIApiUrl, openAIApiKey);
187211

188212
if (models.length === 0) {
189213
console.error(
@@ -192,58 +216,60 @@ async function promptChatGPTModels(defaultModel, chatgptApiUrl) {
192216
return null;
193217
}
194218

195-
const chatgptModel = await inquirer.prompt([
219+
const openAIModel = await inquirer.prompt([
196220
{
197221
type: "list",
198-
name: "chatgptModel",
199-
message: "Select the ChatGPT model:",
222+
name: "openAIModel",
223+
message: "Select the OpenAI model:",
200224
choices: models,
201225
default: defaultModel,
202226
},
203227
]);
204228

205-
return chatgptModel;
229+
return openAIModel;
206230
}
207231

208-
async function promptChatGPTURL(defaultUrl) {
209-
const chatgptApiUrl = await inquirer.prompt([
232+
async function promptOpenAIURL(defaultUrl) {
233+
const openAIApiUrl = await inquirer.prompt([
210234
{
211235
type: "input",
212-
name: "chatgptApiUrl",
213-
message: "Enter the URL for the Ollama server:",
236+
name: "openAIApiUrl",
237+
message: "Enter the URL for the OpenAI server:",
214238
default: defaultUrl,
215239
},
216240
]);
217241

218-
return chatgptApiUrl;
242+
return openAIApiUrl;
219243
}
220244

221-
async function promptChatGPTConfig(config) {
222-
let chatgptApiUrl = { chatgptApiUrl: config.chatgptApiUrl || defaultChatGPTApiUrl };
245+
async function promptOpenAIConfig(config) {
246+
let openAIApiUrl = { openAIApiUrl: config.openAIApiUrl || defaultOpenAIApiUrl };
223247

224248
if (config.aiService === "OpenAI") {
225-
chatgptApiUrl = await promptChatGPTURL(config.chatgptApiUrl);
226-
if (!chatgptApiUrl) return null;
249+
openAIApiUrl = await promptOpenAIURL(config.openAIApiUrl);
250+
if (!openAIApiUrl) return null;
251+
} else {
252+
openAIApiUrl = { openAIApiUrl: defaultOpenAIApiUrl };
227253
}
228254

229-
const chatgptConfig = await promptChatGPTAPIKey(config.chatgptApiKey, chatgptApiUrl.chatgptApiUrl);
255+
const openAIConfig = await promptOpenAIAPIKey(config.openAIApiKey, openAIApiUrl.openAIApiUrl);
230256

231-
if (!chatgptConfig) return null;
257+
if (!openAIConfig) return null;
232258

233-
const chatgptModel = await promptChatGPTModels(config.chatgptModel, chatgptApiUrl.chatgptApiUrl);
259+
const openAIModel = await promptOpenAIModels(config.openAIModel, openAIApiUrl.openAIApiUrl, config.openAIApiKey);
234260

235-
if (!chatgptModel) return null;
261+
if (!openAIModel) return null;
236262

237-
if (chatgptApiUrl) {
263+
if (openAIApiUrl) {
238264
return {
239-
chatgptApiKey: chatgptConfig.chatgptApiKey,
240-
chatgptModel: chatgptModel.chatgptModel,
241-
chatgptApiUrl: chatgptApiUrl.chatgptApiUrl,
265+
openAIApiKey: openAIConfig.openAIApiKey,
266+
openAIModel: openAIModel.openAIModel,
267+
openAIApiUrl: openAIApiUrl.openAIApiUrl,
242268
};
243269
} else {
244270
return {
245-
chatgptApiKey: chatgptConfig.chatgptApiKey,
246-
chatgptModel: chatgptModel.chatgptModel,
271+
openAIApiKey: openAIConfig.openAIApiKey,
272+
openAIModel: openAIModel.openAIModel,
247273
};
248274
}
249275
}
@@ -262,9 +288,9 @@ async function configure(
262288
aiService: "",
263289
ollamaUrl: defaultOllamaUrl,
264290
ollamaModel: "",
265-
chatgptApiKey: "",
266-
chatgptModel: defaultChatGPTModel,
267-
chatgptApiUrl: defaultChatGPTApiUrl,
291+
openAIApiKey: "",
292+
openAIModel: defaultOpenAIModel,
293+
openAIApiUrl: defaultOpenAIApiUrl,
268294
showExecutionDescription: true,
269295
showExecutionPlan: true,
270296
enableLogging: false,
@@ -299,7 +325,7 @@ async function promptAndConfigureAIService(finalConfig, aiServiceChoices) {
299325
finalConfig.model =
300326
finalConfig.aiService === "Ollama"
301327
? finalConfig.ollamaModel
302-
: finalConfig.chatgptModel;
328+
: finalConfig.openAIModel;
303329

304330
validConfig = true;
305331
}
@@ -311,9 +337,9 @@ async function configureSelectedAIService(finalConfig) {
311337
if (finalConfig.aiService === "Ollama") {
312338
return await configureOllamaService(finalConfig);
313339
} else if (finalConfig.aiService === "ChatGPT") {
314-
return await configureChatGPTService(finalConfig);
340+
return await configureOpenAIService(finalConfig);
315341
} else if (finalConfig.aiService === "OpenAI") {
316-
return await configureChatGPTService(finalConfig);
342+
return await configureOpenAIService(finalConfig);
317343
}
318344
return null;
319345
}
@@ -331,20 +357,20 @@ async function configureOllamaService(finalConfig) {
331357
};
332358
}
333359

334-
async function configureChatGPTService(finalConfig) {
335-
const chatgptConfig = await promptChatGPTConfig(finalConfig);
336-
if (!chatgptConfig) return null;
360+
async function configureOpenAIService(finalConfig) {
361+
const openAIConfig = await promptOpenAIConfig(finalConfig);
362+
if (!openAIConfig) return null;
337363

338364
if (finalConfig.aiService === "OpenAI") {
339365
return {
340-
chatgptApiKey: chatgptConfig.chatgptApiKey,
341-
chatgptModel: chatgptConfig.chatgptModel,
342-
chatgptApiUrl: chatgptConfig.chatgptApiUrl,
366+
openAIApiKey: openAIConfig.openAIApiKey,
367+
openAIModel: openAIConfig.openAIModel,
368+
openAIApiUrl: openAIConfig.openAIApiUrl,
343369
};
344370
} else {
345371
return {
346-
chatgptApiKey: chatgptConfig.chatgptApiKey,
347-
chatgptModel: chatgptConfig.chatgptModel,
372+
openAIApiKey: openAIConfig.openAIApiKey,
373+
openAIModel: openAIConfig.openAIModel,
348374
};
349375
}
350376
}

0 commit comments

Comments
 (0)