diff --git a/src/commands/aicommits.ts b/src/commands/aicommits.ts index 2c6cb2ba..0f12c58f 100644 --- a/src/commands/aicommits.ts +++ b/src/commands/aicommits.ts @@ -63,6 +63,7 @@ export default async ( config['max-length'], config.type, config.timeout, + config.hostname, config.proxy, ); } finally { diff --git a/src/commands/prepare-commit-msg-hook.ts b/src/commands/prepare-commit-msg-hook.ts index b8ec3e25..f450475d 100644 --- a/src/commands/prepare-commit-msg-hook.ts +++ b/src/commands/prepare-commit-msg-hook.ts @@ -48,6 +48,7 @@ export default () => (async () => { config['max-length'], config.type, config.timeout, + config.hostname, config.proxy, ); } finally { diff --git a/src/utils/config.ts b/src/utils/config.ts index 47429e5d..b2e74f79 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -104,6 +104,16 @@ const configParsers = { return parsed; }, + hostname(hostname?: string) { + if (!hostname) { + return 'api.openai.com'; + } + + parseAssert('hostname', /^(?:[a-zA-Z\d](?:[a-zA-Z\d-]{0,61}[a-zA-Z\d])?\.)+[a-zA-Z]{2,}$/.test(hostname) + || /^(?:\d{1,3}\.){3}\d{1,3}$/.test(hostname), 'Must be an hostname'); + + return hostname; + }, } as const; type ConfigKeys = keyof typeof configParsers; diff --git a/src/utils/openai.ts b/src/utils/openai.ts index 9dd31514..06d65f24 100644 --- a/src/utils/openai.ts +++ b/src/utils/openai.ts @@ -67,10 +67,11 @@ const createChatCompletion = async ( apiKey: string, json: CreateChatCompletionRequest, timeout: number, + hostname: string, proxy?: string, ) => { const { response, data } = await httpsPost( - 'api.openai.com', + hostname, '/v1/chat/completions', { Authorization: `Bearer ${apiKey}`, @@ -131,6 +132,7 @@ export const generateCommitMessage = async ( maxLength: number, type: CommitType, timeout: number, + hostname: string, proxy?: string, ) => { try { @@ -157,6 +159,7 @@ export const generateCommitMessage = async ( n: completions, }, timeout, + hostname, proxy, ); diff --git a/tests/specs/config.ts b/tests/specs/config.ts index 43f566c3..ba4f7b88 100644 --- a/tests/specs/config.ts +++ b/tests/specs/config.ts @@ -101,6 +101,36 @@ export default testSuite(({ describe }) => { }); }); + await describe('hostname', ({ test }) => { + test('must be an hostname', async () => { + const { stderr } = await aicommits(['config', 'set', 'hostname=https://api.openai.com'], { + reject: false, + }); + + expect(stderr).toMatch('Must be an hostname'); + }); + + test('updates config', async () => { + let hostname = 'hostname=api.chatanywhere.com.cn'; + await aicommits(['config', 'set', hostname]); + + let configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(hostname); + + let get = await aicommits(['config', 'get', 'hostname']); + expect(get.stdout).toBe(hostname); + + hostname = 'hostname=127.0.0.1'; + await aicommits(['config', 'set', hostname]); + + configFile = await fs.readFile(configPath, 'utf8'); + expect(configFile).toMatch(hostname); + + get = await aicommits(['config', 'get', 'hostname']); + expect(get.stdout).toBe(hostname); + }); + }); + await test('set config file', async () => { await aicommits(['config', 'set', openAiToken]); diff --git a/tests/specs/openai/conventional-commits.ts b/tests/specs/openai/conventional-commits.ts index b89255eb..e2f58f30 100644 --- a/tests/specs/openai/conventional-commits.ts +++ b/tests/specs/openai/conventional-commits.ts @@ -137,7 +137,7 @@ export default testSuite(({ describe }) => { 'max-length': 50, ...configOverrides, } as ValidConfig; - const commitMessages = await generateCommitMessage(OPENAI_KEY!, 'gpt-3.5-turbo', config.locale, gitDiff, config.generate, config['max-length'], config.type, 7000); + const commitMessages = await generateCommitMessage(OPENAI_KEY!, 'gpt-3.5-turbo', config.locale, gitDiff, config.generate, config['max-length'], config.type, 7000, config.hostname); return commitMessages[0]; }