From dd0722471a69c74b2a816d118ab2e2c3a489e2f0 Mon Sep 17 00:00:00 2001 From: Jakevin Date: Thu, 25 Apr 2024 22:58:04 +0900 Subject: [PATCH 1/8] init --- services/openai.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/openai.js b/services/openai.js index aa1ac599..1d966820 100644 --- a/services/openai.js +++ b/services/openai.js @@ -23,6 +23,8 @@ const client = axios.create({ timeout: config.OPENAI_TIMEOUT, headers: { 'Accept-Encoding': 'gzip, deflate, compress', + "HTTP-Referer": `https://line.me`, // Optional, for including your app on openrouter.ai rankings. + "X-Title": `LINE Chatbot`, // Optional, for including your app on openrouter.ai rankings. }, }); From bc6cfc7859d2cf356fe8aceea20cc53a875e46eb Mon Sep 17 00:00:00 2001 From: Jakevin Date: Thu, 25 Apr 2024 23:28:29 +0900 Subject: [PATCH 2/8] =?UTF-8?q?fix:=20=E6=88=91=E5=8F=AA=E7=94=A8=20chat?= =?UTF-8?q?=20=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/generate-completion.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/utils/generate-completion.js b/utils/generate-completion.js index 458570e3..f08ea1a5 100644 --- a/utils/generate-completion.js +++ b/utils/generate-completion.js @@ -20,10 +20,12 @@ class Completion { } } -const isChatCompletionModel = (model) => ( - String(model).startsWith('ft:gpt') - || String(model).startsWith('gpt') -); +// const isChatCompletionModel = (model) => ( +// String(model).startsWith('ft:gpt') +// || String(model).startsWith('gpt') +// ); + +const isChatCompletionModel = (model) => (true); /** * @param {Object} param From 3e9992c34a28a365140a12fb9c305a83922ab342 Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 00:26:37 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4API=20path?= =?UTF-8?q?=E7=9A=84v1=E6=96=87=E5=AD=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/index.js | 2 +- services/openai.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/index.js b/config/index.js index ba16065e..5dcfb25f 100644 --- a/config/index.js +++ b/config/index.js @@ -34,7 +34,7 @@ const config = Object.freeze({ VERCEL_DEPLOY_HOOK_URL: env.VERCEL_DEPLOY_HOOK_URL || null, OPENAI_TIMEOUT: env.OPENAI_TIMEOUT || env.APP_API_TIMEOUT, OPENAI_API_KEY: env.OPENAI_API_KEY || null, - OPENAI_BASE_URL: env.OPENAI_BASE_URL || 'https://api.openai.com', + OPENAI_BASE_URL: env.OPENAI_BASE_URL || 'https://api.openai.com/v1', OPENAI_COMPLETION_MODEL: env.OPENAI_COMPLETION_MODEL || 'gpt-3.5-turbo', OPENAI_COMPLETION_TEMPERATURE: Number(env.OPENAI_COMPLETION_TEMPERATURE) || 1, OPENAI_COMPLETION_MAX_TOKENS: Number(env.OPENAI_COMPLETION_MAX_TOKENS) || 64, diff --git a/services/openai.js b/services/openai.js index 1d966820..b9de6688 100644 --- a/services/openai.js +++ b/services/openai.js @@ -47,7 +47,7 @@ const createChatCompletion = ({ maxTokens = config.OPENAI_COMPLETION_MAX_TOKENS, frequencyPenalty = config.OPENAI_COMPLETION_FREQUENCY_PENALTY, presencePenalty = config.OPENAI_COMPLETION_PRESENCE_PENALTY, -}) => client.post('/v1/chat/completions', { +}) => client.post('/chat/completions', { model, messages, temperature, @@ -64,7 +64,7 @@ const createTextCompletion = ({ frequencyPenalty = config.OPENAI_COMPLETION_FREQUENCY_PENALTY, presencePenalty = config.OPENAI_COMPLETION_PRESENCE_PENALTY, stop = config.OPENAI_COMPLETION_STOP_SEQUENCES, -}) => client.post('/v1/completions', { +}) => client.post('/completions', { model, prompt, temperature, @@ -78,7 +78,7 @@ const createImage = ({ prompt, n = 1, size = IMAGE_SIZE_256, -}) => client.post('/v1/images/generations', { +}) => client.post('/images/generations', { prompt, n, size, @@ -92,7 +92,7 @@ const createAudioTranscriptions = ({ const formData = new FormData(); formData.append('file', buffer, file); formData.append('model', model); - return client.post('/v1/audio/transcriptions', formData.getBuffer(), { + return client.post('/audio/transcriptions', formData.getBuffer(), { headers: formData.getHeaders(), }); }; From 4c84c34613756f5036f21d9933938ab28cbbcafe Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 00:51:27 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20provider=20?= =?UTF-8?q?=E8=B3=87=E8=A8=8A=E3=80=81=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/index.js | 3 +++ services/openai.js | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/config/index.js b/config/index.js index 5dcfb25f..d5bd34f3 100644 --- a/config/index.js +++ b/config/index.js @@ -48,6 +48,9 @@ const config = Object.freeze({ SERPAPI_TIMEOUT: env.SERPAPI_TIMEOUT || env.APP_API_TIMEOUT, SERPAPI_API_KEY: env.SERPAPI_API_KEY || null, SERPAPI_LOCATION: env.SERPAPI_LOCATION || 'tw', + PROVIDER_BASE_URL: env.PROVIDER_BASE_URL || 'https://api.openai.com/v1', + PROVIDER_BASE_TOKEN: env.PROVIDER_BASE_TOKEN || null, + PROVIDER_BASE_MODEL: env.PROVIDER_BASE_MODEL || 'gpt-3.5-turbo', }); export default config; diff --git a/services/openai.js b/services/openai.js index b9de6688..f4822f8e 100644 --- a/services/openai.js +++ b/services/openai.js @@ -18,8 +18,9 @@ export const MODEL_GPT_3_5_TURBO = 'gpt-3.5-turbo'; export const MODEL_GPT_4 = 'gpt-4'; export const MODEL_WHISPER_1 = 'whisper-1'; +const BASE_URL = config.PROVIDER_BASE_URL; + const client = axios.create({ - baseURL: config.OPENAI_BASE_URL, timeout: config.OPENAI_TIMEOUT, headers: { 'Accept-Encoding': 'gzip, deflate, compress', @@ -29,7 +30,7 @@ const client = axios.create({ }); client.interceptors.request.use((c) => { - c.headers.Authorization = `Bearer ${config.OPENAI_API_KEY}`; + c.headers.Authorization = `Bearer ${config.PROVIDER_BASE_TOKEN}`; return handleRequest(c); }); @@ -41,13 +42,13 @@ client.interceptors.response.use(handleFulfilled, (err) => { }); const createChatCompletion = ({ - model = config.OPENAI_COMPLETION_MODEL, + model = config.PROVIDER_BASE_MODEL, messages, temperature = config.OPENAI_COMPLETION_TEMPERATURE, maxTokens = config.OPENAI_COMPLETION_MAX_TOKENS, frequencyPenalty = config.OPENAI_COMPLETION_FREQUENCY_PENALTY, presencePenalty = config.OPENAI_COMPLETION_PRESENCE_PENALTY, -}) => client.post('/chat/completions', { +}) => client.post(BASE_URL + '/chat/completions', { model, messages, temperature, @@ -57,14 +58,14 @@ const createChatCompletion = ({ }); const createTextCompletion = ({ - model = config.OPENAI_COMPLETION_MODEL, + model = config.PROVIDER_BASE_MODEL, prompt, temperature = config.OPENAI_COMPLETION_TEMPERATURE, maxTokens = config.OPENAI_COMPLETION_MAX_TOKENS, frequencyPenalty = config.OPENAI_COMPLETION_FREQUENCY_PENALTY, presencePenalty = config.OPENAI_COMPLETION_PRESENCE_PENALTY, stop = config.OPENAI_COMPLETION_STOP_SEQUENCES, -}) => client.post('/completions', { +}) => client.post(BASE_URL + '/completions', { model, prompt, temperature, @@ -78,10 +79,14 @@ const createImage = ({ prompt, n = 1, size = IMAGE_SIZE_256, -}) => client.post('/images/generations', { +}) => client.post(config.OPENAI_BASE_URL + '/images/generations', { prompt, n, size, +}, { + headers: { + Authorization: `Bearer ${config.OPENAI_API_KEY}` + }, }); const createAudioTranscriptions = ({ @@ -92,8 +97,11 @@ const createAudioTranscriptions = ({ const formData = new FormData(); formData.append('file', buffer, file); formData.append('model', model); - return client.post('/audio/transcriptions', formData.getBuffer(), { - headers: formData.getHeaders(), + var headers = formData.getHeaders(); + headers['Authorization'] = `Bearer ${config.OPENAI_API_KEY}`; + + return client.post(config.OPENAI_BASE_URL + '/audio/transcriptions', formData.getBuffer(), { + headers: headers, }); }; From a39dfa824dc8e30c6394166186a0f717f988223c Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 01:00:56 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=E6=A0=B9=E6=93=9A=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E7=9A=84Provider=20=E6=8F=90=E4=BE=9B=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E7=9A=84=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/openai.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/services/openai.js b/services/openai.js index f4822f8e..197f29d0 100644 --- a/services/openai.js +++ b/services/openai.js @@ -23,6 +23,7 @@ const BASE_URL = config.PROVIDER_BASE_URL; const client = axios.create({ timeout: config.OPENAI_TIMEOUT, headers: { + 'Provieder': '', 'Accept-Encoding': 'gzip, deflate, compress', "HTTP-Referer": `https://line.me`, // Optional, for including your app on openrouter.ai rankings. "X-Title": `LINE Chatbot`, // Optional, for including your app on openrouter.ai rankings. @@ -30,7 +31,13 @@ const client = axios.create({ }); client.interceptors.request.use((c) => { - c.headers.Authorization = `Bearer ${config.PROVIDER_BASE_TOKEN}`; + if (c.headers.Provieder === 'openai') { + c.headers.Authorization = `Bearer ${config.OPENAI_API_KEY}`; + + } else { + c.headers.Authorization = `Bearer ${config.PROVIDER_BASE_TOKEN}`; + + } return handleRequest(c); }); @@ -85,7 +92,7 @@ const createImage = ({ size, }, { headers: { - Authorization: `Bearer ${config.OPENAI_API_KEY}` + Provieder: 'openai', }, }); @@ -98,8 +105,7 @@ const createAudioTranscriptions = ({ formData.append('file', buffer, file); formData.append('model', model); var headers = formData.getHeaders(); - headers['Authorization'] = `Bearer ${config.OPENAI_API_KEY}`; - + headers['Provieder'] = 'openai'; return client.post(config.OPENAI_BASE_URL + '/audio/transcriptions', formData.getBuffer(), { headers: headers, }); From c6d800e01a6ed7af06004739f2df7c6a9b2161f0 Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 01:39:19 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=20DALL.E=203=20S?= =?UTF-8?q?tandard=20=E8=88=87=20HD=20=E7=9A=84=E7=9B=B8=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 7 +++++++ config/index.js | 2 ++ services/openai.js | 2 ++ 3 files changed, 11 insertions(+) diff --git a/.env.example b/.env.example index e7f75f0f..ce8fccd3 100644 --- a/.env.example +++ b/.env.example @@ -35,6 +35,8 @@ OPENAI_COMPLETION_MAX_TOKENS= OPENAI_COMPLETION_FREQUENCY_PENALTY= OPENAI_COMPLETION_PRESENCE_PENALTY= OPENAI_IMAGE_GENERATION_SIZE= +OPENAI_IMAGE_GENERATION_MODEL= +OPENAI_IMAGE_GENERATION_QUALITY= LINE_TIMEOUT= LINE_CHANNEL_ACCESS_TOKEN= @@ -43,3 +45,8 @@ LINE_CHANNEL_SECRET= SERPAPI_TIMEOUT= SERPAPI_API_KEY= SERPAPI_LOCATION= + +PROVIDER_BASE_URL= +PROVIDER_BASE_TOKEN= +PROVIDER_BASE_MODEL= + diff --git a/config/index.js b/config/index.js index d5bd34f3..d6b677f9 100644 --- a/config/index.js +++ b/config/index.js @@ -42,6 +42,8 @@ const config = Object.freeze({ OPENAI_COMPLETION_PRESENCE_PENALTY: Number(env.OPENAI_COMPLETION_PRESENCE_PENALTY) || 0.6, OPENAI_COMPLETION_STOP_SEQUENCES: env.OPENAI_COMPLETION_STOP_SEQUENCES ? String(env.OPENAI_COMPLETION_STOP_SEQUENCES).split(',') : [' assistant:', ' user:'], OPENAI_IMAGE_GENERATION_SIZE: env.OPENAI_IMAGE_GENERATION_SIZE || '256x256', + OPENAI_IMAGE_GENERATION_MODEL: env.OPENAI_IMAGE_GENERATION_MODEL || 'dall-e-2', + OPENAI_IMAGE_GENERATION_QUALITY: env.OPENAI_IMAGE_GENERATION_QUALITY || 'standard', LINE_TIMEOUT: env.LINE_TIMEOUT || env.APP_API_TIMEOUT, LINE_CHANNEL_ACCESS_TOKEN: env.LINE_CHANNEL_ACCESS_TOKEN || null, LINE_CHANNEL_SECRET: env.LINE_CHANNEL_SECRET || null, diff --git a/services/openai.js b/services/openai.js index 197f29d0..4ea49f5e 100644 --- a/services/openai.js +++ b/services/openai.js @@ -87,6 +87,8 @@ const createImage = ({ n = 1, size = IMAGE_SIZE_256, }) => client.post(config.OPENAI_BASE_URL + '/images/generations', { + "model": config.OPENAI_IMAGE_GENERATION_MODEL, + "quality": config.OPENAI_IMAGE_GENERATION_QUALITY, prompt, n, size, From a88b8db5efeb9abac6d34c0a36c71a549c7fb46a Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 01:49:35 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix:=20DALL-3=20=E5=8F=AA=E6=9C=89=E6=94=AF?= =?UTF-8?q?=E6=8F=B4=201024*1024=20=E4=BB=A5=E4=B8=8A=E7=9A=84=E5=B0=BA?= =?UTF-8?q?=E5=90=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/openai.js | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/services/openai.js b/services/openai.js index 4ea49f5e..c0b72424 100644 --- a/services/openai.js +++ b/services/openai.js @@ -86,17 +86,25 @@ const createImage = ({ prompt, n = 1, size = IMAGE_SIZE_256, -}) => client.post(config.OPENAI_BASE_URL + '/images/generations', { - "model": config.OPENAI_IMAGE_GENERATION_MODEL, - "quality": config.OPENAI_IMAGE_GENERATION_QUALITY, - prompt, - n, - size, -}, { - headers: { - Provieder: 'openai', - }, -}); +}) => { + + // DALL-E 3 only supports 1024x1024 images. + if (config.OPENAI_IMAGE_GENERATION_MODEL === 'dall-e-3' && size === IMAGE_SIZE_256) { + size = IMAGE_SIZE_1024; + } + + return client.post(config.OPENAI_BASE_URL + '/images/generations', { + "model": config.OPENAI_IMAGE_GENERATION_MODEL, + "quality": config.OPENAI_IMAGE_GENERATION_QUALITY, + prompt, + n, + size, + }, { + headers: { + Provieder: 'openai', + }, + }) +}; const createAudioTranscriptions = ({ buffer, From 3389324be4dc1ba1dda5dd121c581156e4c2b8cb Mon Sep 17 00:00:00 2001 From: Jakevin Date: Fri, 26 Apr 2024 01:53:41 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=20dall-e-3=20?= =?UTF-8?q?=E6=99=82=EF=BC=8C=E5=9C=96=E7=89=87=E5=B0=8F=E6=96=BC1024?= =?UTF-8?q?=E7=9A=84=EF=BC=8C=E9=83=BD=E6=8F=90=E5=8D=87=E5=88=B01024?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D=E5=A0=B1=E9=8C=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/openai.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/openai.js b/services/openai.js index c0b72424..b050d6ea 100644 --- a/services/openai.js +++ b/services/openai.js @@ -89,7 +89,7 @@ const createImage = ({ }) => { // DALL-E 3 only supports 1024x1024 images. - if (config.OPENAI_IMAGE_GENERATION_MODEL === 'dall-e-3' && size === IMAGE_SIZE_256) { + if (config.OPENAI_IMAGE_GENERATION_MODEL === 'dall-e-3' && (size === IMAGE_SIZE_256 || size === IMAGE_SIZE_512)) { size = IMAGE_SIZE_1024; }