@@ -7,7 +7,8 @@ import { Ollama } from "ollama";
77import gradient from "gradient-string" ;
88
99const configPath = path . join ( os . homedir ( ) , ".commandai" , "config.json" ) ;
10- const defaultChatGPTModel = "gpt-4o" ;
10+ const defaultOpenAIModel = "gpt-4o" ;
11+ const defaultOpenAIApiUrl = "https://api.openai.com/v1" ;
1112const defaultOllamaUrl = "http://127.0.0.1:11434" ;
1213
1314async function checkOllamaActive ( url = defaultOllamaUrl ) {
@@ -25,8 +26,32 @@ function loadConfig() {
2526 if ( fs . existsSync ( configPath ) ) {
2627 const configFile = fs . readFileSync ( configPath ) ;
2728 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+
2848 config . model =
29- 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+
3055 return config ;
3156 } else {
3257 return null ;
@@ -35,7 +60,7 @@ function loadConfig() {
3560
3661async function saveConfig ( config ) {
3762 config . model =
38- config . aiService === "Ollama" ? config . ollamaModel : config . chatgptModel ;
63+ config . aiService === "Ollama" ? config . ollamaModel : config . openAIModel ;
3964 const dir = path . dirname ( configPath ) ;
4065 if ( ! fs . existsSync ( dir ) ) {
4166 fs . mkdirSync ( dir , { recursive : true } ) ;
@@ -46,9 +71,9 @@ async function saveConfig(config) {
4671 console . log ( ) ;
4772}
4873
49- async function validateApiKey ( apiKey ) {
74+ async function validateApiKey ( apiKey , openAIApiUrl ) {
5075 try {
51- const openai = new OpenAI ( { apiKey : apiKey } ) ;
76+ const openai = new OpenAI ( { baseURL : openAIApiUrl , apiKey : apiKey } ) ;
5277 await openai . models . list ( ) ;
5378 return true ;
5479 } catch ( error ) {
@@ -57,9 +82,9 @@ async function validateApiKey(apiKey) {
5782 }
5883}
5984
60- async function fetchChatGPTModels ( apiKey ) {
85+ async function fetchOpenAIModels ( openAIApiUrl , apiKey ) {
6186 try {
62- const openai = new OpenAI ( { apiKey : apiKey } ) ;
87+ const openai = new OpenAI ( { baseURL : openAIApiUrl , apiKey : apiKey } ) ;
6388 const response = await openai . models . list ( ) ;
6489 return response . data . map ( ( model ) => model . id ) ;
6590 } catch ( error ) {
@@ -161,67 +186,100 @@ async function promptOllamaConfig(defaultUrl, defaultModel) {
161186 } ;
162187}
163188
164- async function promptChatGPTAPIKey ( defaultApiKey ) {
165- const chatgptConfig = await inquirer . prompt ( [
189+ async function promptOpenAIAPIKey ( defaultApiKey , openAIApiUrl ) {
190+ const openAIConfig = await inquirer . prompt ( [
166191 {
167192 type : "input" ,
168- name : "chatgptApiKey " ,
193+ name : "openAIApiKey " ,
169194 message : "Enter your OpenAI API key:" ,
170195 default : defaultApiKey ,
171196 } ,
172197 ] ) ;
173198
174- const isValidApiKey = await validateApiKey ( chatgptConfig . chatgptApiKey ) ;
199+ const isValidApiKey = await validateApiKey ( openAIConfig . openAIApiKey , openAIApiUrl ) ;
175200
176201 if ( ! isValidApiKey ) {
177202 return null ;
178203 }
179204
180- return chatgptConfig ;
205+ return openAIConfig ;
181206}
182207
183- async function promptChatGPTModels ( defaultModel , defaultApiKey ) {
184- const models = await fetchChatGPTModels ( defaultApiKey ) ;
208+
209+ async function promptOpenAIModels ( defaultModel , openAIApiUrl , openAIApiKey ) {
210+ const models = await fetchOpenAIModels ( openAIApiUrl , openAIApiKey ) ;
211+
185212 if ( models . length === 0 ) {
186213 console . error (
187214 "No models found for the provided API key. Please try again." ,
188215 ) ;
189216 return null ;
190217 }
191218
192- const chatgptModel = await inquirer . prompt ( [
219+ const openAIModel = await inquirer . prompt ( [
193220 {
194221 type : "list" ,
195- name : "chatgptModel " ,
196- message : "Select the ChatGPT model:" ,
222+ name : "openAIModel " ,
223+ message : "Select the OpenAI model:" ,
197224 choices : models ,
198225 default : defaultModel ,
199226 } ,
200227 ] ) ;
201228
202- return chatgptModel ;
229+ return openAIModel ;
230+ }
231+
232+ async function promptOpenAIURL ( defaultUrl ) {
233+ const openAIApiUrl = await inquirer . prompt ( [
234+ {
235+ type : "input" ,
236+ name : "openAIApiUrl" ,
237+ message : "Enter the URL for the OpenAI server:" ,
238+ default : defaultUrl ,
239+ } ,
240+ ] ) ;
241+
242+ return openAIApiUrl ;
203243}
204244
205- async function promptChatGPTConfig ( defaultApiKey , defaultModel ) {
206- const chatgptConfig = await promptChatGPTAPIKey ( defaultApiKey ) ;
245+ async function promptOpenAIConfig ( config ) {
246+ let openAIApiUrl = { openAIApiUrl : config . openAIApiUrl || defaultOpenAIApiUrl } ;
207247
208- if ( ! chatgptConfig ) return null ;
248+ if ( config . aiService === "OpenAI" ) {
249+ openAIApiUrl = await promptOpenAIURL ( config . openAIApiUrl ) ;
250+ if ( ! openAIApiUrl ) return null ;
251+ } else {
252+ openAIApiUrl = { openAIApiUrl : defaultOpenAIApiUrl } ;
253+ }
209254
210- const chatgptModel = await promptChatGPTModels ( defaultModel , defaultApiKey ) ;
255+ const openAIConfig = await promptOpenAIAPIKey ( config . openAIApiKey , openAIApiUrl . openAIApiUrl ) ;
211256
212- if ( ! chatgptModel ) return null ;
257+ if ( ! openAIConfig ) return null ;
213258
214- return {
215- chatgptApiKey : chatgptConfig . chatgptApiKey ,
216- chatgptModel : chatgptModel . chatgptModel ,
217- } ;
259+ const openAIModel = await promptOpenAIModels ( config . openAIModel , openAIApiUrl . openAIApiUrl , config . openAIApiKey ) ;
260+
261+ if ( ! openAIModel ) return null ;
262+
263+ if ( openAIApiUrl ) {
264+ return {
265+ openAIApiKey : openAIConfig . openAIApiKey ,
266+ openAIModel : openAIModel . openAIModel ,
267+ openAIApiUrl : openAIApiUrl . openAIApiUrl ,
268+ } ;
269+ } else {
270+ return {
271+ openAIApiKey : openAIConfig . openAIApiKey ,
272+ openAIModel : openAIModel . openAIModel ,
273+ } ;
274+ }
218275}
219276
220277async function getAIServiceChoices ( ) {
221278 const isOllamaActive = await checkOllamaActive ( ) ;
222279 return [
223280 { name : isOllamaActive ? "Ollama (Running)" : "Ollama" , value : "Ollama" } ,
224281 { name : "ChatGPT" , value : "ChatGPT" } ,
282+ { name : "OpenAI" , value : "OpenAI" } ,
225283 ] ;
226284}
227285
@@ -230,8 +288,9 @@ async function configure(
230288 aiService : "" ,
231289 ollamaUrl : defaultOllamaUrl ,
232290 ollamaModel : "" ,
233- chatgptApiKey : "" ,
234- chatgptModel : defaultChatGPTModel ,
291+ openAIApiKey : "" ,
292+ openAIModel : defaultOpenAIModel ,
293+ openAIApiUrl : defaultOpenAIApiUrl ,
235294 showExecutionDescription : true ,
236295 showExecutionPlan : true ,
237296 enableLogging : false ,
@@ -266,7 +325,7 @@ async function promptAndConfigureAIService(finalConfig, aiServiceChoices) {
266325 finalConfig . model =
267326 finalConfig . aiService === "Ollama"
268327 ? finalConfig . ollamaModel
269- : finalConfig . chatgptModel ;
328+ : finalConfig . openAIModel ;
270329
271330 validConfig = true ;
272331 }
@@ -278,7 +337,9 @@ async function configureSelectedAIService(finalConfig) {
278337 if ( finalConfig . aiService === "Ollama" ) {
279338 return await configureOllamaService ( finalConfig ) ;
280339 } else if ( finalConfig . aiService === "ChatGPT" ) {
281- return await configureChatGPTService ( finalConfig ) ;
340+ return await configureOpenAIService ( finalConfig ) ;
341+ } else if ( finalConfig . aiService === "OpenAI" ) {
342+ return await configureOpenAIService ( finalConfig ) ;
282343 }
283344 return null ;
284345}
@@ -296,17 +357,22 @@ async function configureOllamaService(finalConfig) {
296357 } ;
297358}
298359
299- async function configureChatGPTService ( finalConfig ) {
300- const chatgptConfig = await promptChatGPTConfig (
301- finalConfig . chatgptApiKey ,
302- finalConfig . chatgptModel ,
303- ) ;
304- if ( ! chatgptConfig ) return null ;
360+ async function configureOpenAIService ( finalConfig ) {
361+ const openAIConfig = await promptOpenAIConfig ( finalConfig ) ;
362+ if ( ! openAIConfig ) return null ;
305363
306- return {
307- chatgptApiKey : chatgptConfig . chatgptApiKey ,
308- chatgptModel : chatgptConfig . chatgptModel ,
309- } ;
364+ if ( finalConfig . aiService === "OpenAI" ) {
365+ return {
366+ openAIApiKey : openAIConfig . openAIApiKey ,
367+ openAIModel : openAIConfig . openAIModel ,
368+ openAIApiUrl : openAIConfig . openAIApiUrl ,
369+ } ;
370+ } else {
371+ return {
372+ openAIApiKey : openAIConfig . openAIApiKey ,
373+ openAIModel : openAIConfig . openAIModel ,
374+ } ;
375+ }
310376}
311377
312378export { loadConfig , saveConfig , configure } ;
0 commit comments