@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 +38 -35
- package/lib.js +34 -33
- package/locales/de-DE/node.json +1 -0
- package/locales/en-US/node.json +1 -0
- package/locales/ja/node.json +1 -0
- package/locales/zh-CN/node.json +1 -0
- package/node.html +45 -0
- package/node.js +3 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,14 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
|
|
2
|
+
# @inductiv/node-red-openai-api
|
|
3
|
+
|
|
4
|
+
   
|
|
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/
|
|
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
|
-
|
|
21
|
+
```
|
|
10
22
|
|
|
11
|
-
|
|
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.
|
|
44
|
+
## Release Notes (v1.3.0)
|
|
20
45
|
|
|
21
|
-
-
|
|
22
|
-
-
|
|
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.
|
|
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
|
|
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 } =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
}
|
package/locales/de-DE/node.json
CHANGED
|
@@ -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/locales/en-US/node.json
CHANGED
|
@@ -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/locales/ja/node.json
CHANGED
|
@@ -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/locales/zh-CN/node.json
CHANGED
|
@@ -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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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.
|
|
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": "
|
|
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",
|