@inductiv/node-red-openai-api 0.3.7 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib.js CHANGED
@@ -22,6 +22,11 @@ var OpenaiApi = (function () {
22
22
  setApiBase(apiBase) {
23
23
  this.domain = apiBase;
24
24
  }
25
+
26
+ setOrganizationIdHeader(organizationId) {
27
+ this.organizationId = organizationId;
28
+ }
29
+
25
30
  setAuthHeaders(headerParams) {
26
31
  var headers = headerParams ? headerParams : {};
27
32
  if (!this.apiKey.isQuery && this.apiKey.headerOrQueryName) {
@@ -30,18 +35,22 @@ var OpenaiApi = (function () {
30
35
  return headers;
31
36
  }
32
37
 
33
- setNodeRef(node){
38
+ setNodeRef(node) {
34
39
  this.node = node;
35
40
  }
36
41
 
37
- getFromEndpoint(path, parameters, expectedQueryParams, customHeaders) {
42
+ getFromEndpoint(path, parameters, expectedQueryParams, customHeaders = {}) {
38
43
  return new Promise((resolve, reject) => {
39
44
  var domain = this.domain;
40
- var queryParameters = {},
41
- baseHeaders = {};
45
+ var organizationId = this.organizationId;
46
+ var queryParameters = {};
47
+ var baseHeaders = {};
42
48
 
43
49
  baseHeaders = this.setAuthHeaders(headers);
44
50
  baseHeaders["Accept"] = "application/json";
51
+ if (organizationId) {
52
+ customHeaders["OpenAI-Organization"] = organizationId;
53
+ }
45
54
 
46
55
  var headers = {
47
56
  ...baseHeaders,
@@ -78,26 +87,32 @@ var OpenaiApi = (function () {
78
87
  });
79
88
  });
80
89
  }
90
+
81
91
  postToEndpoint(
82
92
  path,
83
93
  parameters,
84
94
  expectedQueryParams,
85
95
  contentType,
86
96
  filePath,
87
- customHeaders,
97
+ customHeaders = {},
88
98
  ) {
89
99
  return new Promise((resolve, reject) => {
90
100
  const _path = require("path");
91
101
 
92
102
  parameters = parameters || {};
93
103
  var domain = this.domain;
104
+ var organizationId = this.organizationId;
94
105
  var queryParameters = {},
95
106
  baseHeaders = {},
96
107
  data;
97
108
 
98
- baseHeaders = this.setAuthHeaders({});
109
+ baseHeaders = this.setAuthHeaders(baseHeaders);
99
110
  baseHeaders["Accept"] = "application/json";
100
111
 
112
+ if (organizationId) {
113
+ customHeaders["OpenAI-Organization"] = organizationId;
114
+ }
115
+
101
116
  var headers = {
102
117
  ...baseHeaders,
103
118
  ...customHeaders,
@@ -153,26 +168,29 @@ var OpenaiApi = (function () {
153
168
  headers: headers,
154
169
  params: queryParameters,
155
170
  data: data,
156
- responseType: data.stream === true ? "stream" : "json"
171
+ responseType: data.stream === true ? "stream" : "json",
157
172
  };
158
173
 
159
174
  axios(config)
160
175
  .then((response) => {
161
176
  if (config.responseType === "stream") {
162
177
  // Handle the stream response
163
- response.data.on('data', (chunk) => {
164
- // Convert chunk from Uint8Array to string
165
- const chunkAsString = new TextDecoder().decode(chunk);
166
-
167
- // Emit converted data chunks as Node-RED messages
168
- this.node.send({ payload: chunkAsString });
169
- }).on('end', () => {
170
- // Handle the end of the stream
171
- resolve({ payload: "Stream ended" });
172
- }).on('error', (err) => {
173
- // Handle any errors
174
- reject(err);
175
- });
178
+ response.data
179
+ .on("data", (chunk) => {
180
+ // Convert chunk from Uint8Array to string
181
+ const chunkAsString = new TextDecoder().decode(chunk);
182
+
183
+ // Emit converted data chunks as Node-RED messages
184
+ this.node.send({ payload: chunkAsString });
185
+ })
186
+ .on("end", () => {
187
+ // Handle the end of the stream
188
+ resolve({ payload: "Stream ended" });
189
+ })
190
+ .on("error", (err) => {
191
+ // Handle any errors
192
+ reject(err);
193
+ });
176
194
  } else {
177
195
  // Handle non-stream response (e.g., JSON)
178
196
  resolve(response);
@@ -184,16 +202,26 @@ var OpenaiApi = (function () {
184
202
  });
185
203
  }
186
204
 
187
- deleteFromEndpoint(path, parameters, expectedQueryParams, customHeaders) {
205
+ deleteFromEndpoint(
206
+ path,
207
+ parameters,
208
+ expectedQueryParams,
209
+ customHeaders = {},
210
+ ) {
188
211
  return new Promise((resolve, reject) => {
189
212
  parameters = parameters || {};
190
213
  var domain = this.domain;
214
+ var organizationId = this.organizationId;
191
215
  var queryParameters = {},
192
216
  baseHeaders = {};
193
217
 
194
218
  baseHeaders = this.setAuthHeaders(headers);
195
219
  baseHeaders["Accept"] = "application/json";
196
220
 
221
+ if (organizationId) {
222
+ customHeaders["OpenAI-Organization"] = organizationId;
223
+ }
224
+
197
225
  var headers = {
198
226
  ...baseHeaders,
199
227
  ...customHeaders,
@@ -229,6 +257,7 @@ var OpenaiApi = (function () {
229
257
  });
230
258
  });
231
259
  }
260
+
232
261
  createChatCompletion(parameters) {
233
262
  const response = this.postToEndpoint("/chat/completions", parameters);
234
263
  return response;
@@ -6,6 +6,7 @@
6
6
  "method": "Method",
7
7
  "host": "Host",
8
8
  "header": "Auth Header",
9
+ "organizationId": "Org Id",
9
10
  "apiKey": "API Key",
10
11
  "isQuery": "isQuery"
11
12
  },
package/node.html CHANGED
@@ -715,6 +715,7 @@
715
715
  defaults: {
716
716
  apiBase: { value: "https://api.openai.com/v1", required: true },
717
717
  secureApiKeyHeaderOrQueryName: { value: "Authorization" },
718
+ organizationId: { value: "" },
718
719
  secureApiKeyIsQuery: { value: false },
719
720
  name: { value: "" },
720
721
  },
@@ -753,6 +754,10 @@
753
754
  <label id="node-config-input-secureApiKeyValue-label" for="node-config-input-secureApiKeyValue"><i class="fa fa-lock"></i> <span data-i18n="OpenaiApi.label.apiKey"></span></label>
754
755
  <input type="password" id="node-config-input-secureApiKeyValue" placeholder="">
755
756
  </div>
757
+ <div class="form-row">
758
+ <label id="node-config-input-organizationId-label" for="node-config-input-organizationId"><i class="fa fa-list"></i> <span data-i18n="OpenaiApi.label.organizationId"></span></label>
759
+ <input type="text" id="node-config-input-organizationId" placeholder="OpenAI Organization Id">
760
+ </div>
756
761
  <div class="form-row">
757
762
  <label id="node-config-input-secureApiKeyIsQuery-label" for="node-config-input-secureApiKeyIsQuery"><i class="fa fa-dot-circle-o"></i> <span data-i18n="OpenaiApi.label.isQuery"></span></label>
758
763
  <select id="node-config-input-secureApiKeyIsQuery">
package/node.js CHANGED
@@ -15,6 +15,7 @@ module.exports = function (RED) {
15
15
  let client = new lib.OpenaiApi();
16
16
  if (!errorFlag && this.service) {
17
17
  client.setApiBase(this.service.apiBase);
18
+ client.setOrganizationIdHeader(this.service.organizationId);
18
19
  }
19
20
 
20
21
  if (!errorFlag && this.service && this.service.credentials && this.service.credentials.secureApiKeyValue) {
@@ -99,6 +100,7 @@ module.exports = function (RED) {
99
100
  this.apiBase = n.apiBase;
100
101
  this.secureApiKeyHeaderOrQueryName = n.secureApiKeyHeaderOrQueryName;
101
102
  this.secureApiKeyIsQuery = n.secureApiKeyIsQuery;
103
+ this.organizationId = n.organizationId;
102
104
  }
103
105
  }
104
106
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inductiv/node-red-openai-api",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Go beyond ChatGPT and DALL·E 3: this Node-RED node seamlessly integrates a range of OpenAI services, including Assistants, Threads, Vision, and Audio, enabling feature-rich enhancement of your AI workflows with any OpenAI REST API-compatible solution.",
5
5
  "main": "node.js",
6
6
  "engines": {