Skip to content

Commit

Permalink
feat(openai): Allow to specify custom API url for OpenAI API requests
Browse files Browse the repository at this point in the history
  • Loading branch information
andris9 committed Oct 24, 2023
1 parent ef89d83 commit 047647d
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 23 deletions.
11 changes: 11 additions & 0 deletions lib/routes-ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,8 @@ function applyRoutes(server, call) {
return true;`
),

openAiAPIUrl: ((await settings.get('openAiAPIUrl')) || '').toString(),

openAiTemperature: ((await settings.get('openAiTemperature')) || '').toString(),
openAiTopP: ((await settings.get('openAiTopP')) || '').toString()
};
Expand Down Expand Up @@ -1436,6 +1438,7 @@ return true;`
let data = {
generateEmailSummary: request.payload.generateEmailSummary,
openAiModel: request.payload.openAiModel,
openAiAPIUrl: request.payload.openAiAPIUrl,
openAiPrompt: (request.payload.openAiPrompt || '').toString(),
openAiPreProcessingFn: contentFn,
openAiTemperature: request.payload.openAiTemperature,
Expand All @@ -1452,6 +1455,10 @@ return true;`
data.openAiAPIKey = request.payload.openAiAPIKey;
}

if (typeof request.payload.openAiAPIUrl === 'string') {
data.openAiAPIUrl = request.payload.openAiAPIUrl;
}

for (let key of Object.keys(data)) {
await settings.set(key, data[key]);
}
Expand Down Expand Up @@ -1582,6 +1589,8 @@ return true;`
openAiAPIKey: settingsSchema.openAiAPIKey.empty(''),
openAiModel: settingsSchema.openAiModel.empty(''),

openAiAPIUrl: settingsSchema.openAiAPIUrl.default(''),

openAiPrompt: settingsSchema.openAiPrompt.default(''),

contentFnJson: Joi.string()
Expand Down Expand Up @@ -1619,6 +1628,7 @@ return true;`
},
openAiAPIKey: request.payload.openAiAPIKey,
openAiModel: request.payload.openAiModel,
openAiAPIUrl: request.payload.openAiAPIUrl,
openAiPrompt: request.payload.openAiPrompt,
openAiTemperature: request.payload.openAiTemperature,
openAiTopP: request.payload.openAiTopP
Expand Down Expand Up @@ -1661,6 +1671,7 @@ return true;`
emailFile: Joi.string().base64({ paddingRequired: false }).required(),
openAiAPIKey: settingsSchema.openAiAPIKey.empty(''),
openAiModel: settingsSchema.openAiModel.empty(''),
openAiAPIUrl: settingsSchema.openAiAPIUrl.default(''),
openAiPrompt: settingsSchema.openAiPrompt.default(''),
openAiTemperature: settingsSchema.openAiTemperature.empty(''),
openAiTopP: settingsSchema.openAiTopP.empty('')
Expand Down
10 changes: 10 additions & 0 deletions lib/schemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ const settingsSchema = {
.description('OpenAI API Model')
.label('OpenAiModel'),

openAiAPIUrl: Joi.string()
.uri({
scheme: ['http', 'https'],
allowRelative: false
})
.allow('')
.example('https://api.openai.com')
.description('OpenAI API URL')
.label('openAiAPIUrl'),

documentStoreChatModel: Joi.string()
.allow('')
.valid('gpt-3.5-turbo', 'gpt-4')
Expand Down
12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,11 @@
"@hapi/vision": "7.0.3",
"@phc/pbkdf2": "1.1.14",
"@postalsys/certs": "1.0.6",
"@postalsys/email-ai-tools": "1.6.3",
"@postalsys/email-ai-tools": "1.7.0",
"@postalsys/email-text-tools": "2.1.2",
"@postalsys/hecks": "3.0.0-fork.3",
"@postalsys/templates": "1.0.6",
"ace-builds": "1.30.0",
"ace-builds": "1.31.0",
"base32.js": "0.1.0",
"bull-arena": "4.0.1",
"bullmq": "4.12.5",
Expand Down Expand Up @@ -92,8 +92,8 @@
"murmurhash": "2.0.1",
"nanoid": "3.3.4",
"node-gettext": "3.0.0",
"nodemailer": "6.9.6",
"pino": "8.16.0",
"nodemailer": "6.9.7",
"pino": "8.16.1",
"prom-client": "15.0.0",
"psl": "1.9.0",
"pubface": "1.0.6",
Expand All @@ -104,15 +104,15 @@
"speakeasy": "2.0.0",
"startbootstrap-sb-admin-2": "3.3.7",
"timezones-list": "3.0.2",
"undici": "5.26.4",
"undici": "5.26.5",
"uuid": "9.0.1",
"wild-config": "1.7.1",
"xml2js": "0.6.2"
},
"devDependencies": {
"chai": "4.3.10",
"eerawlog": "1.5.1",
"eslint": "8.51.0",
"eslint": "8.52.0",
"eslint-config-nodemailer": "1.2.0",
"eslint-config-prettier": "9.0.0",
"grunt": "1.6.1",
Expand Down
2 changes: 1 addition & 1 deletion sbom.json

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -1429,6 +1429,11 @@ async function onCommand(worker, message) {
requestOpts.gptModel = openAiModel;
}

let openAiAPIUrl = message.data.openAiAPIUrl || (await settings.get('openAiAPIUrl'));
if (openAiAPIUrl) {
requestOpts.baseApiUrl = openAiAPIUrl;
}

let openAiTemperature = message.data.openAiTemperature || (await settings.get('openAiTemperature'));
if (openAiTemperature) {
requestOpts.temperature = openAiTemperature;
Expand All @@ -1446,7 +1451,7 @@ async function onCommand(worker, message) {
case 'gpt-3.5-turbo':
case 'gpt-3.5-turbo-instruct':
default:
requestOpts.maxTokens = 3500;
requestOpts.maxTokens = 3000;
break;
}

Expand All @@ -1472,6 +1477,11 @@ async function onCommand(worker, message) {
throw new Error(`OpenAI API key is not set`);
}

let openAiAPIUrl = message.data.openAiAPIUrl || (await settings.get('openAiAPIUrl'));
if (openAiAPIUrl) {
requestOpts.baseApiUrl = openAiAPIUrl;
}

requestOpts.user = message.data.account;

const embeddings = await generateEmbeddings(message.data.message, openAiAPIKey, requestOpts);
Expand Down Expand Up @@ -1501,6 +1511,11 @@ async function onCommand(worker, message) {
throw new Error(`OpenAI API key is not set`);
}

let openAiAPIUrl = message.data.openAiAPIUrl || (await settings.get('openAiAPIUrl'));
if (openAiAPIUrl) {
requestOpts.baseApiUrl = openAiAPIUrl;
}

let openAiModel = message.data.openAiModel || (await settings.get('documentStoreChatModel')) || (await settings.get('openAiModel'));
if (openAiModel) {
requestOpts.gptModel = openAiModel;
Expand All @@ -1513,7 +1528,7 @@ async function onCommand(worker, message) {
case 'gpt-3.5-turbo':
case 'gpt-3.5-turbo-instruct':
default:
requestOpts.maxTokens = 3500;
requestOpts.maxTokens = 3000;
break;
}

Expand Down Expand Up @@ -1562,6 +1577,11 @@ async function onCommand(worker, message) {
throw new Error(`OpenAI API key is not set`);
}

let openAiAPIUrl = message.data.openAiAPIUrl || (await settings.get('openAiAPIUrl'));
if (openAiAPIUrl) {
requestOpts.baseApiUrl = openAiAPIUrl;
}

let openAiModel = message.data.openAiModel || 'gpt-3.5-turbo-instruct';
if (openAiModel) {
requestOpts.gptModel = openAiModel;
Expand Down Expand Up @@ -1592,6 +1612,11 @@ async function onCommand(worker, message) {
throw new Error(`OpenAI API key is not set`);
}

let openAiAPIUrl = message.data.openAiAPIUrl || (await settings.get('openAiAPIUrl'));
if (openAiAPIUrl) {
requestOpts.baseApiUrl = openAiAPIUrl;
}

requestOpts.user = message.data.account;

const data = await getChunkEmbeddings(message.data.message, openAiAPIKey, requestOpts);
Expand Down
2 changes: 1 addition & 1 deletion static/js/ace/ace.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion static/js/ace/ext-language_tools.js

Large diffs are not rendered by default.

54 changes: 42 additions & 12 deletions static/licenses.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<!doctype html><html><head><meta charset="utf-8"><title>EmailEngine Licenses</title><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous"></head><body>
<div class="container-fluid">
<h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following software packages:</p>
<h1>EmailEngine v2.37.7</h1><p>EmailEngine includes code from the following software packages:</p>
<table class="table table-sm">
<tr><thead class="thead-dark"><th>Package</th><th>Version</th><th>License</th><th>Publisher</th><th>Publisher's Email</th><th>Package URL</th></tr>
<tbody>
Expand Down Expand Up @@ -236,7 +236,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@eslint/js">@eslint/js</a></td>
<td>8.51.0</td>
<td>8.52.0</td>
<td>MIT</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -636,7 +636,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@humanwhocodes/config-array">@humanwhocodes/config-array</a></td>
<td>0.11.12</td>
<td>0.11.13</td>
<td>Apache-2.0</td>
<td>Nicholas C. Zakas</td>
<td></td>
Expand All @@ -656,7 +656,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@humanwhocodes/object-schema">@humanwhocodes/object-schema</a></td>
<td>2.0.0</td>
<td>2.0.1</td>
<td>BSD-3-Clause</td>
<td>Nicholas C. Zakas</td>
<td></td>
Expand Down Expand Up @@ -836,7 +836,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/@postalsys/email-ai-tools">@postalsys/email-ai-tools</a></td>
<td>1.6.3</td>
<td>1.7.0</td>
<td>MIT</td>
<td>Postal Systems O&#xDC;</td>
<td></td>
Expand Down Expand Up @@ -1045,6 +1045,16 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/@ungap/structured-clone">@ungap/structured-clone</a></td>
<td>1.2.0</td>
<td>ISC</td>
<td>Andrea Giammarchi</td>
<td></td>
<td>
<a href="https://github.com/ungap/structured-clone">github.com/ungap/structured-clone</a>
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/abab">abab</a></td>
<td>2.0.6</td>
<td>BSD-3-Clause</td>
Expand Down Expand Up @@ -1096,7 +1106,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/ace-builds">ace-builds</a></td>
<td>1.30.0</td>
<td>1.31.0</td>
<td>BSD-3-Clause</td>
<td></td>
<td></td>
Expand Down Expand Up @@ -2655,7 +2665,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/eslint">eslint</a></td>
<td>8.51.0</td>
<td>8.52.0</td>
<td>MIT</td>
<td>Nicholas C. Zakas</td>
<td>[email protected]</td>
Expand Down Expand Up @@ -3175,7 +3185,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/get-intrinsic">get-intrinsic</a></td>
<td>1.2.1</td>
<td>1.2.2</td>
<td>MIT</td>
<td>Jordan Harband</td>
<td>[email protected]</td>
Expand Down Expand Up @@ -3535,7 +3545,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/has-property-descriptors">has-property-descriptors</a></td>
<td>1.0.0</td>
<td>1.0.1</td>
<td>MIT</td>
<td>Jordan Harband</td>
<td>[email protected]</td>
Expand Down Expand Up @@ -3584,6 +3594,16 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/hasown">hasown</a></td>
<td>2.0.0</td>
<td>MIT</td>
<td>Jordan Harband</td>
<td>[email protected]</td>
<td>
<a href="https://github.com/inspect-js/hasOwn">github.com/inspect-js/hasOwn</a>
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/he">he</a></td>
<td>1.2.0</td>
<td>MIT</td>
Expand Down Expand Up @@ -3965,7 +3985,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/is-core-module">is-core-module</a></td>
<td>2.13.0</td>
<td>2.13.1</td>
<td>MIT</td>
<td>Jordan Harband</td>
<td>[email protected]</td>
Expand Down Expand Up @@ -5405,7 +5425,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/nodemailer">nodemailer</a></td>
<td>6.9.6</td>
<td>6.9.7</td>
<td>MIT-0</td>
<td>Andris Reinman</td>
<td></td>
Expand Down Expand Up @@ -5944,6 +5964,16 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/pino">pino</a></td>
<td>8.16.1</td>
<td>MIT</td>
<td>Matteo Collina</td>
<td>[email protected]</td>
<td>
<a href="https://github.com/pinojs/pino">github.com/pinojs/pino</a>
</td
</tr>
<tr>
<td><a href="https://npmjs.com/package/pkg-fetch">pkg-fetch</a></td>
<td>3.4.2</td>
<td>MIT</td>
Expand Down Expand Up @@ -7355,7 +7385,7 @@ <h1>EmailEngine v2.37.6</h1><p>EmailEngine includes code from the following soft
</tr>
<tr>
<td><a href="https://npmjs.com/package/undici">undici</a></td>
<td>5.26.4</td>
<td>5.26.5</td>
<td>MIT</td>
<td></td>
<td></td>
Expand Down
16 changes: 16 additions & 0 deletions views/config/ai.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,21 @@
the selected model, or analysis requests will fail.</small>
</div>

<div class="form-group">

<div class="text-muted float-right code-link">[<a href="/admin/iframe/docs#/Settings/postV1Settings"
target="_blank">openAiAPIUrl</a>]
</div>

<label for="openAiAPIUrl">OpenAI API URL</label>
<input type="url" class="form-control {{#if errors.openAiAPIUrl}}is-invalid{{/if}}" id="openAiAPIUrl"
name="openAiAPIUrl" value="{{values.openAiAPIUrl}}" placeholder="https://api.openai.com" />
{{#if errors.openAiAPIUrl}}
<span class="invalid-feedback">{{errors.openAiAPIUrl}}</span>
{{/if}}
<small class="form-text text-muted">OpenAI API URL. Leave blank to use the default.</small>
</div>

</div>
</div>

Expand Down Expand Up @@ -563,6 +578,7 @@
emailFile,
openAiPrompt: editorPrompt.getValue(),
openAiModel: document.getElementById('settingsServiceOpenAiModel').value,
openAiAPIUrl: document.getElementById('openAiAPIUrl').value,
openAiAPIKey: document.getElementById('openAiAPIKey').value,
openAiTemperature: document.getElementById('settingsOpenAiTemperature').value,
openAiTopP: document.getElementById('settingsOpenAiTopP').value
Expand Down

0 comments on commit 047647d

Please sign in to comment.