@inductiv/node-red-openai-api 1.1.0 → 1.3.0

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/README.md CHANGED
@@ -1,14 +1,39 @@
1
- <h1 align="center">
2
- Node-RED OpenAI API: Unleashing AIoT Innovation
3
- <br>
1
+
2
+ # @inductiv/node-red-openai-api
3
+
4
+ ![NPM Version](https://img.shields.io/npm/v/%40inductiv%2Fnode-red-openai-api) ![GitHub Release Date](https://img.shields.io/github/release-date/allanbunch/node-red-openai-api) ![GitHub Issues or Pull Requests](https://img.shields.io/github/issues/allanbunch/node-red-openai-api) ![GitHub Repo stars](https://img.shields.io/github/stars/allanbunch/node-red-openai-api)
5
+
6
+ This library provides convenient access to the OpenAI Node API Library from Node-RED.
7
+
4
8
  <a href="https://github.com/allanbunch/node-red-openai-api">
5
- <img width="265" alt="node-red-openai-api-node" src="https://github.com/allanbunch/node-red-openai-api/assets/4503640/9588aba4-0a97-4cbe-a446-58e06d5dd016">
9
+ <img width="265" alt="node-red-openai-api-node" src="https://github.com/allanbunch/node-red-openai-api/assets/4503640/ee954c8e-fbf4-4812-a38a-f047cecd1982">
6
10
  </a>
7
11
  <br>
12
+
13
+ Node-RED OpenAI API is a versatile and configurable Node-RED node designed for seamless integration with any OpenAI API compatible platform. This node empowers innovators and developers to effortlessly connect and orchestrate complex AI and IoT workflows, leveraging Node-RED's sophisticated ecosystem. Ideal for enhancing IoT operations with advanced AI capabilities, this node serves as your gateway to applying the latest AI technology in an IoT context, facilitating innovative applications across diverse environments.
14
+
15
+ ## Installation
16
+
17
+ ### Via Node-RED Palette Manager
18
+
19
+ ```text
8
20
  @inductiv/node-red-openai-api
9
- </h1>
21
+ ```
10
22
 
11
- Welcome to _@inductiv/node-red-openai-api_, a versatile and configurable Node-RED node designed for seamless integration with any OpenAI API compatible platform. This node empowers innovators and developers to effortlessly connect and orchestrate complex AI and IoT workflows, leveraging Node-RED's sophisticated ecosystem. Ideal for enhancing IoT operations with advanced AI capabilities, this node serves as your gateway to applying the latest AI technology in an IoT context, facilitating innovative applications across diverse environments.
23
+ ### Via NPM
24
+
25
+ ```bash
26
+ cd $HOME/.node-red # or the location of your Node-RED configuration directory.
27
+ npm i @inductiv/node-red-openai-api
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ After installation, find your node in the **AI** palette category labeled "OpenAI API". Here's how you can start integrating AI into your IoT projects:
33
+
34
+ 1. Configure the node with your AI platform's API key (if required).
35
+ 2. Send [OpenAI documented](https://platform.openai.com/docs/api-reference/) API service configuration paramaters to the node using the default `msg.payload` property, or confiure your desired incoming object property reference on the node itself.
36
+ 3. Explore the [examples](./examples/) directory for sample implementations.
12
37
 
13
38
  ## Core Features
14
39
 
@@ -16,13 +41,14 @@ Welcome to _@inductiv/node-red-openai-api_, a versatile and configurable Node-RE
16
41
  - **Configurable and Flexible**: Adapt to a wide range of project requirements, making it easy to integrate AI into your IoT solutions.
17
42
  - **Powerful Combinations**: Utilize Node-RED's diverse nodes to build complex, AI-driven IoT workflows with ease.
18
43
 
19
- ## Release Notes (v1.1.0)
44
+ ## Release Notes (v1.3.0)
20
45
 
21
- - **Fixed a bug** that prevented custom property paths not honored. [#22](https://github.com/allanbunch/node-red-openai-api/issues/22)
22
- - Added the ```vectorStores.fileBatches.uploadAndPoll``` endpoint to the **Vector Store File Batches** endpoint group.
23
- - Updated the node's documentation panel.
46
+ - Streamed responses now share the same `msg._msgid` value
47
+ - Upgraded to OpenAI Node API Library v4.42.0
48
+ - Updated the node's documentation panel
49
+ - Code stability & formatting updates
24
50
 
25
- ## What's New in Version 1.0
51
+ ## What's New in Version 1.x
26
52
 
27
53
  Version 1.0 of the **node-red-openai-api** node brings significant enhancements and new possibilities, including:
28
54
 
@@ -34,36 +60,13 @@ Version 1.0 of the **node-red-openai-api** node brings significant enhancements
34
60
 
35
61
  ### Important Notice Regarding Compatibility
36
62
 
37
- - **Backward Incompatible Changes**: Please be aware that this version includes breaking changes that may affect existing implementations due to the updated OpenAI NodeJS package:
63
+ - **Backward Incompatible Changes**: Please be aware that v1.0 includes breaking changes that may affect existing implementations (v0.x.x instllations) due to the updated OpenAI NodeJS package:
38
64
  - The API call structure and parameters have been refined to align with the latest OpenAI specifications.
39
65
  - Some functions and settings from previous versions may no longer be compatible with this update.
40
66
  - List responses now exist at the top level of the `msg.payload` object; previously `msg.payload.data`.
41
67
 
42
68
  I recommend reviewing current setups and testing them with this new version in a development environment before updating to ensure a smooth transition. This will help you take full advantage of the enhanced features while managing any necessary adjustments in your existing applications.
43
69
 
44
- ## Installation
45
-
46
- ### Via Node-RED Palette Manager
47
-
48
- ```text
49
- @inductiv/node-red-openai-api
50
- ```
51
-
52
- ### Via NPM
53
-
54
- ```bash
55
- cd $HOME/.node-red
56
- npm i @inductiv/node-red-openai-api
57
- ```
58
-
59
- ## Usage
60
-
61
- After installation, find your node in the **AI** palette category labeled "OpenAI API". Here's how you can start integrating AI into your IoT projects:
62
-
63
- 1. Configure the node with your AI platform's API key (if required).
64
- 2. Send [OpenAI documented](https://platform.openai.com/docs/api-reference/) API service configuration paramaters to the node using the default `msg.payload` property, or confiure your desired incoming object property reference on the node itself.
65
- 3. Explore the [examples](./examples/) directory for sample implementations.
66
-
67
70
  ## Contribute
68
71
 
69
72
  I value community contributions that help enhance this Node-RED node and expand its capabilities in AIoT applications. Whether you're fixing bugs, adding new features, or improving documentation, your help is welcome!
package/lib.js CHANGED
@@ -1,5 +1,3 @@
1
- const { response } = require("express");
2
-
3
1
  let OpenaiApi = (function () {
4
2
  "use strict";
5
3
 
@@ -121,31 +119,31 @@ let OpenaiApi = (function () {
121
119
 
122
120
  async uploadAndPollVectorStoreFileBatch(parameters) {
123
121
  const openai = new OpenAI(this.clientParams);
124
- const { vector_store_id, files, file_ids, ...params } = parameters.payload;
125
-
122
+ const { vector_store_id, files, file_ids, ...params } =
123
+ parameters.payload;
124
+
126
125
  if (!files || !Array.isArray(files)) {
127
126
  throw new Error("Files is not defined or not an array");
128
127
  }
129
-
128
+
130
129
  // Validate file paths
131
- files.forEach(path => {
130
+ files.forEach((path) => {
132
131
  if (!fs.existsSync(path)) {
133
132
  throw new Error(`File does not exist: ${path}`);
134
133
  }
135
134
  });
136
-
137
- const fileStreams = files.map(path => fs.createReadStream(path));
138
-
135
+
136
+ const fileStreams = files.map((path) => fs.createReadStream(path));
137
+
139
138
  const response = await openai.beta.vectorStores.fileBatches.uploadAndPoll(
140
139
  vector_store_id,
141
- {files: fileStreams, fileIds: file_ids},
142
- params
140
+ { files: fileStreams, fileIds: file_ids },
141
+ params,
143
142
  );
144
-
143
+
145
144
  return response;
146
145
  }
147
-
148
-
146
+
149
147
  // <<< End File Batch Functions
150
148
 
151
149
  async createVectorStore(parameters) {
@@ -242,9 +240,7 @@ let OpenaiApi = (function () {
242
240
  });
243
241
  for await (const chunk of response) {
244
242
  if (typeof chunk === "object") {
245
- let { _msgid, ...newMsg } = parameters.msg;
246
- newMsg.payload = chunk;
247
-
243
+ const newMsg = { ...parameters.msg, payload: chunk };
248
244
  _node.send(newMsg);
249
245
  }
250
246
  }
@@ -365,9 +361,7 @@ let OpenaiApi = (function () {
365
361
 
366
362
  async createFineTuningJob(parameters) {
367
363
  const openai = new OpenAI(this.clientParams);
368
- const response = await openai.fineTuning.jobs.create(
369
- parameters.payload,
370
- );
364
+ const response = await openai.fineTuning.jobs.create(parameters.payload);
371
365
 
372
366
  return response;
373
367
  }
@@ -401,6 +395,17 @@ let OpenaiApi = (function () {
401
395
  return [...list.data];
402
396
  }
403
397
 
398
+ async listFineTuningCheckpoints(parameters) {
399
+ const openai = new OpenAI(this.clientParams);
400
+ const { fine_tuning_job_id, ...params } = parameters.payload;
401
+ const list = await openai.fineTuning.jobs.checkpoints.list(
402
+ fine_tuning_job_id,
403
+ params,
404
+ );
405
+
406
+ return [...list.data];
407
+ }
408
+
404
409
  async cancelFineTuningJob(parameters) {
405
410
  const openai = new OpenAI(this.clientParams);
406
411
  const { fine_tuning_job_id, ...params } = parameters.payload;
@@ -450,9 +455,7 @@ let OpenaiApi = (function () {
450
455
 
451
456
  async createAssistant(parameters) {
452
457
  const openai = new OpenAI(this.clientParams);
453
- const response = await openai.beta.assistants.create(
454
- parameters.payload,
455
- );
458
+ const response = await openai.beta.assistants.create(parameters.payload);
456
459
 
457
460
  return response;
458
461
  }
@@ -574,9 +577,7 @@ let OpenaiApi = (function () {
574
577
  });
575
578
  for await (const chunk of response) {
576
579
  if (typeof chunk === "object") {
577
- let { _msgid, ...newMsg } = parameters.msg;
578
- newMsg.payload = chunk.data;
579
-
580
+ const newMsg = { ...parameters.msg, payload: chunk.data };
580
581
  _node.send(newMsg);
581
582
  }
582
583
  }
@@ -608,9 +609,7 @@ let OpenaiApi = (function () {
608
609
  });
609
610
  for await (const chunk of response) {
610
611
  if (typeof chunk === "object") {
611
- let { _msgid, ...newMsg } = parameters.msg;
612
- newMsg.payload = chunk.data;
613
-
612
+ const newMsg = { ...parameters.msg, payload: chunk.data };
614
613
  _node.send(newMsg);
615
614
  }
616
615
  }
@@ -662,9 +661,7 @@ let OpenaiApi = (function () {
662
661
  });
663
662
  for await (const chunk of response) {
664
663
  if (typeof chunk === "object") {
665
- let { _msgid, ...newMsg } = parameters.msg;
666
- newMsg.payload = chunk.data;
667
-
664
+ const newMsg = { ...parameters.msg, payload: chunk.data };
668
665
  _node.send(newMsg);
669
666
  }
670
667
  }
@@ -689,7 +686,11 @@ let OpenaiApi = (function () {
689
686
  async listRunSteps(parameters) {
690
687
  const openai = new OpenAI(this.clientParams);
691
688
  const { thread_id, run_id, ...params } = parameters.payload;
692
- const list = await openai.beta.threads.runs.steps.list(thread_id, run_id, params);
689
+ const list = await openai.beta.threads.runs.steps.list(
690
+ thread_id,
691
+ run_id,
692
+ params,
693
+ );
693
694
 
694
695
  return [...list.data];
695
696
  }
@@ -81,6 +81,7 @@
81
81
  "retrieveFineTuningJob": "retrieve fine-tuning job",
82
82
  "fine_tuning_job_id": "fine-tuning job id",
83
83
  "listFineTuningEvents": "list fine-tuning events",
84
+ "listFineTuningCheckpoints": "list fine-tuning checkpoints",
84
85
  "cancelFineTuningJob": "cancel fine-tuning",
85
86
  "createFineTune": "POST /fine-tunes",
86
87
  "listFineTunes": "GET /fine-tunes",
@@ -81,6 +81,7 @@
81
81
  "retrieveFineTuningJob": "retrieve fine-tuning job",
82
82
  "fine_tuning_job_id": "fine-tuning job id",
83
83
  "listFineTuningEvents": "list fine-tuning events",
84
+ "listFineTuningCheckpoints": "list fine-tuning checkpoints",
84
85
  "cancelFineTuningJob": "cancel fine-tuning",
85
86
  "createFineTune": "POST /fine-tunes",
86
87
  "listFineTunes": "GET /fine-tunes",
@@ -81,6 +81,7 @@
81
81
  "retrieveFineTuningJob": "retrieve fine-tuning job",
82
82
  "fine_tuning_job_id": "fine-tuning job id",
83
83
  "listFineTuningEvents": "list fine-tuning events",
84
+ "listFineTuningCheckpoints": "list fine-tuning checkpoints",
84
85
  "cancelFineTuningJob": "cancel fine-tuning",
85
86
  "createFineTune": "POST /fine-tunes",
86
87
  "listFineTunes": "GET /fine-tunes",
@@ -81,6 +81,7 @@
81
81
  "retrieveFineTuningJob": "retrieve fine-tuning job",
82
82
  "fine_tuning_job_id": "fine-tuning job id",
83
83
  "listFineTuningEvents": "list fine-tuning events",
84
+ "listFineTuningCheckpoints": "list fine-tuning checkpoints",
84
85
  "cancelFineTuningJob": "cancel fine-tuning",
85
86
  "createFineTune": "POST /fine-tunes",
86
87
  "listFineTunes": "GET /fine-tunes",
package/node.html CHANGED
@@ -182,6 +182,10 @@
182
182
  value="listFineTuningEvents"
183
183
  data-i18n="OpenaiApi.parameters.listFineTuningEvents"
184
184
  ></option>
185
+ <option
186
+ value="listFineTuningCheckpoints"
187
+ data-i18n="OpenaiApi.parameters.listFineTuningCheckpoints"
188
+ ></option>
185
189
  <option
186
190
  value="cancelFineTuningJob"
187
191
  data-i18n="OpenaiApi.parameters.cancelFineTuningJob"
@@ -1799,6 +1803,47 @@
1799
1803
  <dd>Number of events to retrieve.</dd>
1800
1804
  </dl>
1801
1805
 
1806
+ <!-- >>> Begin List Fine-tuning Checkpoints -->
1807
+ <h4 style="font-weight: bolder;"> ⋙ List Fine-tuning Checkpoints</h4>
1808
+ <p>List checkpoints for a fine-tuning job.</p>
1809
+ <dl class="message-properties">
1810
+ <h4>msg.payload Properties</h4>
1811
+
1812
+ <dt>
1813
+ fine_tuning_job_id
1814
+ <a
1815
+ href="https://platform.openai.com/docs/api-reference/fine-tuning/list-checkpoints#fine-tuning-list-checkpoints-fine_tuning_job_id"
1816
+ target="_blank"
1817
+ ><i class="fa fa-external-link fa-sm" aria-hidden="true"></i
1818
+ ></a>
1819
+ <span class="property-type">string</span>
1820
+ </dt>
1821
+ <dd>The ID of the fine-tuning job to get checkpoints for.</dd>
1822
+ <dt class="optional">
1823
+ after
1824
+ <a
1825
+ href="https://platform.openai.com/docs/api-reference/fine-tuning/list-checkpoints#fine-tuning-list-checkpoints-after"
1826
+ target="_blank"
1827
+ ><i class="fa fa-external-link fa-sm" aria-hidden="true"></i
1828
+ ></a>
1829
+ <span class="property-type">string</span>
1830
+ </dt>
1831
+ <dd>
1832
+ Identifier for the last checkpoint ID from the previous pagination request.
1833
+ </dd>
1834
+ <dt class="optional">
1835
+ limit
1836
+ <a
1837
+ href="https://platform.openai.com/docs/api-reference/fine-tuning/list-checkpoints#fine-tuning-list-checkpoints-limit"
1838
+ target="_blank"
1839
+ ><i class="fa fa-external-link fa-sm" aria-hidden="true"></i
1840
+ ></a>
1841
+ <span class="property-type">integer</span>
1842
+ </dt>
1843
+ <dd>Number of events to retrieve.</dd>
1844
+ </dl>
1845
+ <!-- <<< End List Fine-tuning Checkpoints -->
1846
+
1802
1847
  <h4 style="font-weight: bolder;"> ⋙ Cancel Fine-tuning Job</h4>
1803
1848
  <p>Immediately cancel a fine-tune job.</p>
1804
1849
  <dl class="message-properties">
package/node.js CHANGED
@@ -35,9 +35,9 @@ module.exports = function (RED) {
35
35
  const serviceName = node.config.method; // Set the service name to call.
36
36
 
37
37
  let serviceParametersObject = {
38
- "_node": node,
39
- "payload": payload,
40
- "msg": msg
38
+ _node: node,
39
+ payload: payload,
40
+ msg: msg,
41
41
  };
42
42
 
43
43
  // Dynamically call the function based on the service name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inductiv/node-red-openai-api",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "description": "Enhance your Node-RED flows with advanced AI capabilities.",
5
5
  "main": "node.js",
6
6
  "engines": {
@@ -34,10 +34,11 @@
34
34
  "low-code"
35
35
  ],
36
36
  "dependencies": {
37
- "openai": "^4.38.5"
37
+ "openai": "~4.42.0"
38
38
  },
39
39
  "devDependencies": {
40
40
  "eslint": "^8.54.0",
41
+ "eslint-plugin-jest": "^28.5.0",
41
42
  "prettier": "^3.1.0"
42
43
  },
43
44
  "author": "Allan Bunch",