node-red-contrib-ollama 0.4.0 → 0.5.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
@@ -14,7 +14,9 @@ This module requires Node.js version 18 or higher.
14
14
 
15
15
  To use it, you need to have Node-RED installed on your system. For more information on how to install Node-RED, refer to the official [Node-RED documentation](https://nodered.org/docs/getting-started/).
16
16
 
17
- You also need Ollama running on the same or a different system. For detailed instructions on how to install Ollama, please refer to the official [Ollama site](https://ollama.com/).
17
+ You also need either:
18
+ - Ollama running on the same or a different system (local installation). For detailed instructions on how to install Ollama, please refer to the official [Ollama site](https://ollama.com/).
19
+ - An Ollama Cloud account with an API key. Get your API key from [Ollama Cloud Settings](https://ollama.com/settings/keys).
18
20
 
19
21
  ## Installation
20
22
 
@@ -40,6 +42,29 @@ npm install node-red-contrib-ollama
40
42
 
41
43
  After installing the module, you need to restart Node-RED to apply the changes.
42
44
 
45
+ ## Configuration
46
+
47
+ ### Server Configuration
48
+
49
+ Before using any Ollama nodes, you need to configure the Ollama server connection:
50
+
51
+ 1. Add any Ollama node to your flow
52
+ 2. Open the node configuration
53
+ 3. Create a new Ollama server configuration
54
+
55
+ #### Local Ollama Server
56
+
57
+ For a local Ollama installation:
58
+ - **Host**: localhost (or the IP address of your Ollama server)
59
+ - **Port**: 11434 (default Ollama port)
60
+
61
+ #### Ollama Cloud
62
+
63
+ For Ollama Cloud:
64
+ 1. Check the "Use Ollama Cloud" checkbox
65
+ 2. Enter your API Key (get it from [Ollama Cloud Settings](https://ollama.com/settings/keys))
66
+ 3. The host will automatically be set to `ollama.com` and port to `443`
67
+
43
68
  ## Usage
44
69
 
45
70
  The module provides a set of nodes that can be used to interact with the ollama.js library. The nodes are:
@@ -50,7 +75,7 @@ The module provides a set of nodes that can be used to interact with the ollama.
50
75
  - **Delete**: Delete a model and its data.
51
76
  - **Embed**: Generate embeddings from a model.
52
77
  - **Generate**: Generate a response for a given prompt with a provided model.
53
- - **List**: List models that are available locally.
78
+ - **List**: List models that are available.
54
79
  - **Pull**: Download a model from the [ollama library](https://ollama.com/library).
55
80
  - **Push**: Upload a model to a model library. Requires registering for ollama.ai and adding a public key first.
56
81
  - **Show**: Show information about a model including details, modelfile, template, parameters, license, and system prompt.
@@ -8,9 +8,39 @@ module.exports = function( RED ) {
8
8
  node.on( 'input', async function( msg ) {
9
9
  const server = RED.nodes.getNode( config.server )
10
10
 
11
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
11
+ // Construct host URL
12
+ let host = null
13
+ if ( !host && server ) {
14
+ if ( server.useCloud ) {
15
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
16
+ // NEVER allow msg.payload.host override when using API key authentication
17
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
18
+ host = server.host
19
+ } else {
20
+ host = `https://${server.host}:${server.port}`
21
+ }
22
+ } else {
23
+ // For local Ollama servers, allow host override from message
24
+ host = msg?.payload?.host
25
+ if ( !host ) {
26
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
27
+ host = server.host
28
+ } else {
29
+ host = `http://${server.host}:${server.port}`
30
+ }
31
+ }
32
+ }
33
+ }
12
34
 
13
- const ollama = new Ollama( { host } )
35
+ // Ollama Cloud configuration
36
+ const ollamaConfig = { host }
37
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
38
+ ollamaConfig.headers = {
39
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
40
+ }
41
+ }
42
+
43
+ const ollama = new Ollama( ollamaConfig )
14
44
 
15
45
  const response = await ollama.abort()
16
46
  .catch( error => {
@@ -172,13 +172,6 @@
172
172
  </dt>
173
173
  <dd>The format of the response (only <code>json</code> for now).</dd>
174
174
 
175
- <dt class="optional">
176
- payload.stream <span class="property-type">boolean</span>
177
- </dt>
178
- <dd>
179
- When true an <code>AsyncGenerator</code> is returned.
180
- </dd>
181
-
182
175
  <dt class="optional">
183
176
  payload.think <span class="property-type">boolean</span>
184
177
  </dt>
@@ -12,9 +12,40 @@ module.exports = function( RED ) {
12
12
  const node = this
13
13
  node.on( 'input', async function( msg ) {
14
14
  const server = RED.nodes.getNode( config.server )
15
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
16
15
 
17
- const ollama = new Ollama( { host } )
16
+ // Construct host URL
17
+ let host = null
18
+ if ( !host && server ) {
19
+ if ( server.useCloud ) {
20
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
21
+ // NEVER allow msg.payload.host override when using API key authentication
22
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
23
+ host = server.host
24
+ } else {
25
+ host = `https://${server.host}:${server.port}`
26
+ }
27
+ } else {
28
+ // For local Ollama servers, allow host override from message
29
+ host = msg?.payload?.host
30
+ if ( !host ) {
31
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
32
+ host = server.host
33
+ } else {
34
+ host = `http://${server.host}:${server.port}`
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ // Ollama Cloud configuration
41
+ const ollamaConfig = { host }
42
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
43
+ ollamaConfig.headers = {
44
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
45
+ }
46
+ }
47
+
48
+ const ollama = new Ollama( ollamaConfig )
18
49
 
19
50
  let model = null
20
51
  if( msg?.payload?.model ) {
@@ -47,7 +78,10 @@ module.exports = function( RED ) {
47
78
  }
48
79
 
49
80
  const formatConfig = RED.nodes.getNode( config.format )
50
- const format = msg?.payload?.format || ( formatConfig ) ? formatConfig.json : null
81
+ const format = msg?.payload?.format
82
+ ? JSON.parse( msg?.payload?.format )
83
+ : ( formatConfig ) ? JSON.parse( formatConfig.json )
84
+ : null
51
85
 
52
86
  const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
53
87
 
@@ -3,22 +3,66 @@
3
3
  category: 'config',
4
4
  defaults: {
5
5
  host: { value: 'localhost', required: true },
6
- port: { value: 11434, required: true, validate: RED.validators.number() }
6
+ port: { value: 11434, required: true, validate: RED.validators.number() },
7
+ useCloud: { value: false }
8
+ },
9
+ credentials: {
10
+ apiKey: { type: "password" }
7
11
  },
8
12
  label: function() {
13
+ if (this.useCloud) {
14
+ return 'Ollama Cloud';
15
+ }
9
16
  return this.host + ':' + this.port;
17
+ },
18
+ oneditprepare: function() {
19
+ const node = this;
20
+
21
+ function toggleCloudFields() {
22
+ const useCloud = $('#node-config-input-useCloud').is(':checked');
23
+ if (useCloud) {
24
+ $('.local-server-row').hide();
25
+ $('.cloud-server-row').show();
26
+ $('#node-config-input-host').val('https://ollama.com');
27
+ $('#node-config-input-port').val('443');
28
+ } else {
29
+ $('.local-server-row').show();
30
+ $('.cloud-server-row').hide();
31
+ if ($('#node-config-input-host').val() === 'https://ollama.com') {
32
+ $('#node-config-input-host').val('localhost');
33
+ $('#node-config-input-port').val('11434');
34
+ }
35
+ }
36
+ }
37
+
38
+ $('#node-config-input-useCloud').on('change', toggleCloudFields);
39
+ toggleCloudFields();
10
40
  }
11
41
  } )
12
42
  </script>
13
43
 
14
44
  <script type="text/html" data-template-name="ollama-config-server">
15
45
  <div class="form-row">
46
+ <label for="node-config-input-useCloud"><i class="fa fa-cloud"></i> Use Ollama Cloud</label>
47
+ <input type="checkbox" id="node-config-input-useCloud" style="display: inline-block; width: auto; vertical-align: top;">
48
+ </div>
49
+
50
+ <div class="form-row local-server-row">
16
51
  <label for="node-config-input-host"><i class="fa fa-server"></i> Host</label>
17
52
  <input type="text" id="node-config-input-host" placeholder="localhost" />
18
53
  </div>
19
54
 
20
- <div class="form-row">
21
- <label for="node-config-input-port"><i class="fa fa-port"></i> Port</label>
55
+ <div class="form-row local-server-row">
56
+ <label for="node-config-input-port"><i class="fa fa-plug"></i> Port</label>
22
57
  <input type="text" id="node-config-input-port" placeholder="11434" />
23
58
  </div>
59
+
60
+ <div class="form-row cloud-server-row" style="display:none;">
61
+ <label for="node-config-input-apiKey"><i class="fa fa-key"></i> API Key</label>
62
+ <input type="password" id="node-config-input-apiKey" placeholder="Enter your Ollama Cloud API key" />
63
+ </div>
64
+
65
+ <div class="form-tips cloud-server-row" style="display:none;">
66
+ <strong>Note:</strong> Get your API key from <a href="https://ollama.com/settings/keys" target="_blank">Ollama Cloud Settings</a>
67
+ </div>
24
68
  </script>
@@ -4,7 +4,12 @@ module.exports = function( RED ) {
4
4
 
5
5
  this.host = config.host
6
6
  this.port = config.port
7
+ this.useCloud = config.useCloud || false
7
8
  }
8
9
 
9
- RED.nodes.registerType( 'ollama-config-server', OllamaConfigServerNode )
10
+ RED.nodes.registerType( 'ollama-config-server', OllamaConfigServerNode, {
11
+ credentials: {
12
+ apiKey: { type: "password" }
13
+ }
14
+ } )
10
15
  }
@@ -11,9 +11,39 @@ module.exports = function( RED ) {
11
11
  node.on( 'input', async function( msg ) {
12
12
  const server = RED.nodes.getNode( config.server )
13
13
 
14
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
14
+ // Construct host URL
15
+ let host = null
16
+ if ( !host && server ) {
17
+ if ( server.useCloud ) {
18
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
19
+ // NEVER allow msg.payload.host override when using API key authentication
20
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
21
+ host = server.host
22
+ } else {
23
+ host = `https://${server.host}:${server.port}`
24
+ }
25
+ } else {
26
+ // For local Ollama servers, allow host override from message
27
+ host = msg?.payload?.host
28
+ if ( !host ) {
29
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
30
+ host = server.host
31
+ } else {
32
+ host = `http://${server.host}:${server.port}`
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ // Ollama Cloud configuration
39
+ const ollamaConfig = { host }
40
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
41
+ ollamaConfig.headers = {
42
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
43
+ }
44
+ }
15
45
 
16
- const ollama = new Ollama( { host } )
46
+ const ollama = new Ollama( ollamaConfig )
17
47
 
18
48
  let source = null
19
49
  if( msg?.payload?.source ) {
@@ -19,9 +19,40 @@ module.exports = function( RED ) {
19
19
  const node = this
20
20
  node.on( 'input', async function( msg ) {
21
21
  const server = RED.nodes.getNode( config.server )
22
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
23
22
 
24
- const ollama = new Ollama( { host } )
23
+ // Construct host URL
24
+ let host = null
25
+ if ( !host && server ) {
26
+ if ( server.useCloud ) {
27
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
28
+ // NEVER allow msg.payload.host override when using API key authentication
29
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
30
+ host = server.host
31
+ } else {
32
+ host = `https://${server.host}:${server.port}`
33
+ }
34
+ } else {
35
+ // For local Ollama servers, allow host override from message
36
+ host = msg?.payload?.host
37
+ if ( !host ) {
38
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
39
+ host = server.host
40
+ } else {
41
+ host = `http://${server.host}:${server.port}`
42
+ }
43
+ }
44
+ }
45
+ }
46
+
47
+ // Ollama Cloud configuration
48
+ const ollamaConfig = { host }
49
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
50
+ ollamaConfig.headers = {
51
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
52
+ }
53
+ }
54
+
55
+ const ollama = new Ollama( ollamaConfig )
25
56
 
26
57
  let model = null
27
58
  if( msg?.payload?.model ) {
@@ -9,9 +9,40 @@ module.exports = function( RED ) {
9
9
  const node = this
10
10
  node.on( 'input', async function( msg ) {
11
11
  const server = RED.nodes.getNode( config.server )
12
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
13
12
 
14
- const ollama = new Ollama( { host } )
13
+ // Construct host URL
14
+ let host = null
15
+ if ( !host && server ) {
16
+ if ( server.useCloud ) {
17
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
18
+ // NEVER allow msg.payload.host override when using API key authentication
19
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
20
+ host = server.host
21
+ } else {
22
+ host = `https://${server.host}:${server.port}`
23
+ }
24
+ } else {
25
+ // For local Ollama servers, allow host override from message
26
+ host = msg?.payload?.host
27
+ if ( !host ) {
28
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
29
+ host = server.host
30
+ } else {
31
+ host = `http://${server.host}:${server.port}`
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ // Ollama Cloud configuration
38
+ const ollamaConfig = { host }
39
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
40
+ ollamaConfig.headers = {
41
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
42
+ }
43
+ }
44
+
45
+ const ollama = new Ollama( ollamaConfig )
15
46
 
16
47
  let model = null
17
48
  if( msg?.payload?.model ) {
@@ -12,9 +12,40 @@ module.exports = function( RED ) {
12
12
  const node = this
13
13
  node.on( 'input', async function( msg ) {
14
14
  const server = RED.nodes.getNode( config.server )
15
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
16
15
 
17
- const ollama = new Ollama( { host } )
16
+ // Construct host URL
17
+ let host = null
18
+ if ( !host && server ) {
19
+ if ( server.useCloud ) {
20
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
21
+ // NEVER allow msg.payload.host override when using API key authentication
22
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
23
+ host = server.host
24
+ } else {
25
+ host = `https://${server.host}:${server.port}`
26
+ }
27
+ } else {
28
+ // For local Ollama servers, allow host override from message
29
+ host = msg?.payload?.host
30
+ if ( !host ) {
31
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
32
+ host = server.host
33
+ } else {
34
+ host = `http://${server.host}:${server.port}`
35
+ }
36
+ }
37
+ }
38
+ }
39
+
40
+ // Ollama Cloud configuration
41
+ const ollamaConfig = { host }
42
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
43
+ ollamaConfig.headers = {
44
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
45
+ }
46
+ }
47
+
48
+ const ollama = new Ollama( ollamaConfig )
18
49
 
19
50
  let model = null
20
51
  if( msg?.payload?.model ) {
@@ -18,9 +18,40 @@ module.exports = function( RED ) {
18
18
  const node = this
19
19
  node.on( 'input', async function( msg ) {
20
20
  const server = RED.nodes.getNode( config.server )
21
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
22
21
 
23
- const ollama = new Ollama( { host } )
22
+ // Construct host URL
23
+ let host = null
24
+ if ( !host && server ) {
25
+ if ( server.useCloud ) {
26
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
27
+ // NEVER allow msg.payload.host override when using API key authentication
28
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
29
+ host = server.host
30
+ } else {
31
+ host = `https://${server.host}:${server.port}`
32
+ }
33
+ } else {
34
+ // For local Ollama servers, allow host override from message
35
+ host = msg?.payload?.host
36
+ if ( !host ) {
37
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
38
+ host = server.host
39
+ } else {
40
+ host = `http://${server.host}:${server.port}`
41
+ }
42
+ }
43
+ }
44
+ }
45
+
46
+ // Ollama Cloud configuration
47
+ const ollamaConfig = { host }
48
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
49
+ ollamaConfig.headers = {
50
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
51
+ }
52
+ }
53
+
54
+ const ollama = new Ollama( ollamaConfig )
24
55
 
25
56
  let model = null
26
57
  if( msg?.payload?.model ) {
@@ -115,7 +146,10 @@ module.exports = function( RED ) {
115
146
  }
116
147
 
117
148
  const formatConfig = RED.nodes.getNode( config.format )
118
- const format = msg?.payload?.format || ( formatConfig ) ? formatConfig.json : null
149
+ const format = msg?.payload?.format
150
+ ? JSON.parse( msg?.payload?.format )
151
+ : ( formatConfig ) ? JSON.parse( formatConfig.json )
152
+ : null
119
153
 
120
154
  const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
121
155
 
@@ -3,7 +3,7 @@
3
3
  category: 'AI',
4
4
  color: 'rgb(186 230 253)',
5
5
  defaults: {
6
- name: { value: 'Ollama List Local Models' },
6
+ name: { value: 'Ollama List Models' },
7
7
  server: { value: '', type: 'ollama-config-server', required: false }
8
8
  },
9
9
  inputs: 1,
@@ -28,7 +28,7 @@
28
28
  </script>
29
29
 
30
30
  <script type="text/html" data-help-name="ollama-list">
31
- <p>List models that are available locally.</p>
31
+ <p>List models that are available.</p>
32
32
 
33
33
  <h3>Inputs</h3>
34
34
 
@@ -59,7 +59,7 @@
59
59
  <span class="property-type">array</span>
60
60
  </dt>
61
61
  <dd>
62
- The list of models that are available locally.<br />
62
+ The list of models that are available.<br />
63
63
 
64
64
  <h4>Model</h4>
65
65
  <dl class="message-properties">
@@ -8,9 +8,39 @@ module.exports = function( RED ) {
8
8
  node.on( 'input', async function( msg ) {
9
9
  const server = RED.nodes.getNode( config.server )
10
10
 
11
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
11
+ // Construct host URL
12
+ let host = null
13
+ if ( !host && server ) {
14
+ if ( server.useCloud ) {
15
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
16
+ // NEVER allow msg.payload.host override when using API key authentication
17
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
18
+ host = server.host
19
+ } else {
20
+ host = `https://${server.host}:${server.port}`
21
+ }
22
+ } else {
23
+ // For local Ollama servers, allow host override from message
24
+ host = msg?.payload?.host
25
+ if ( !host ) {
26
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
27
+ host = server.host
28
+ } else {
29
+ host = `http://${server.host}:${server.port}`
30
+ }
31
+ }
32
+ }
33
+ }
12
34
 
13
- const ollama = new Ollama( { host } )
35
+ // Ollama Cloud configuration
36
+ const ollamaConfig = { host }
37
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
38
+ ollamaConfig.headers = {
39
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
40
+ }
41
+ }
42
+
43
+ const ollama = new Ollama( ollamaConfig )
14
44
 
15
45
  const response = await ollama.list()
16
46
  .catch( error => {
@@ -59,7 +59,7 @@
59
59
  <span class="property-type">array</span>
60
60
  </dt>
61
61
  <dd>
62
- The list of models that are available locally.<br />
62
+ The list of models that are currently loaded into memory.<br />
63
63
 
64
64
  <h4>Model</h4>
65
65
  <dl class="message-properties">
@@ -8,9 +8,39 @@ module.exports = function( RED ) {
8
8
  node.on( 'input', async function( msg ) {
9
9
  const server = RED.nodes.getNode( config.server )
10
10
 
11
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
11
+ // Construct host URL
12
+ let host = null
13
+ if ( !host && server ) {
14
+ if ( server.useCloud ) {
15
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
16
+ // NEVER allow msg.payload.host override when using API key authentication
17
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
18
+ host = server.host
19
+ } else {
20
+ host = `https://${server.host}:${server.port}`
21
+ }
22
+ } else {
23
+ // For local Ollama servers, allow host override from message
24
+ host = msg?.payload?.host
25
+ if ( !host ) {
26
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
27
+ host = server.host
28
+ } else {
29
+ host = `http://${server.host}:${server.port}`
30
+ }
31
+ }
32
+ }
33
+ }
12
34
 
13
- const ollama = new Ollama( { host } )
35
+ // Ollama Cloud configuration
36
+ const ollamaConfig = { host }
37
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
38
+ ollamaConfig.headers = {
39
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
40
+ }
41
+ }
42
+
43
+ const ollama = new Ollama( ollamaConfig )
14
44
 
15
45
  const response = await ollama.ps()
16
46
  .catch( error => {
@@ -1,7 +1,7 @@
1
1
  module.exports = function( RED ) {
2
2
  const { Ollama } = require( 'ollama' )
3
3
 
4
- function OllamaPullNode( config ) {
4
+ function OllamaPulltNode( config ) {
5
5
  RED.nodes.createNode( this, config )
6
6
 
7
7
  this.modelType = config.modelType || 'str'
@@ -11,9 +11,40 @@ module.exports = function( RED ) {
11
11
  const node = this
12
12
  node.on( 'input', async function( msg ) {
13
13
  const server = RED.nodes.getNode( config.server )
14
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
15
14
 
16
- const ollama = new Ollama( { host } )
15
+ // Construct host URL
16
+ let host = null
17
+ if ( !host && server ) {
18
+ if ( server.useCloud ) {
19
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
20
+ // NEVER allow msg.payload.host override when using API key authentication
21
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
22
+ host = server.host
23
+ } else {
24
+ host = `https://${server.host}:${server.port}`
25
+ }
26
+ } else {
27
+ // For local Ollama servers, allow host override from message
28
+ host = msg?.payload?.host
29
+ if ( !host ) {
30
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
31
+ host = server.host
32
+ } else {
33
+ host = `http://${server.host}:${server.port}`
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ // Ollama Cloud configuration
40
+ const ollamaConfig = { host }
41
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
42
+ ollamaConfig.headers = {
43
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
44
+ }
45
+ }
46
+
47
+ const ollama = new Ollama( ollamaConfig )
17
48
 
18
49
  let model = null
19
50
  if( msg?.payload?.model ) {
@@ -48,5 +79,5 @@ module.exports = function( RED ) {
48
79
  } )
49
80
  }
50
81
 
51
- RED.nodes.registerType( 'ollama-pull', OllamaPullNode )
82
+ RED.nodes.registerType( 'ollama-pull', OllamaPulltNode )
52
83
  }
@@ -11,9 +11,40 @@ module.exports = function( RED ) {
11
11
  const node = this
12
12
  node.on( 'input', async function( msg ) {
13
13
  const server = RED.nodes.getNode( config.server )
14
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
15
14
 
16
- const ollama = new Ollama( { host } )
15
+ // Construct host URL
16
+ let host = null
17
+ if ( !host && server ) {
18
+ if ( server.useCloud ) {
19
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
20
+ // NEVER allow msg.payload.host override when using API key authentication
21
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
22
+ host = server.host
23
+ } else {
24
+ host = `https://${server.host}:${server.port}`
25
+ }
26
+ } else {
27
+ // For local Ollama servers, allow host override from message
28
+ host = msg?.payload?.host
29
+ if ( !host ) {
30
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
31
+ host = server.host
32
+ } else {
33
+ host = `http://${server.host}:${server.port}`
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ // Ollama Cloud configuration
40
+ const ollamaConfig = { host }
41
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
42
+ ollamaConfig.headers = {
43
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
44
+ }
45
+ }
46
+
47
+ const ollama = new Ollama( ollamaConfig )
17
48
 
18
49
  let model = null
19
50
  if( msg?.payload?.model ) {
@@ -11,9 +11,40 @@ module.exports = function( RED ) {
11
11
  const node = this
12
12
  node.on( 'input', async function( msg ) {
13
13
  const server = RED.nodes.getNode( config.server )
14
- const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
15
14
 
16
- const ollama = new Ollama( { host } )
15
+ // Construct host URL
16
+ let host = null
17
+ if ( !host && server ) {
18
+ if ( server.useCloud ) {
19
+ // For Ollama Cloud, always use the configured host (https://ollama.com)
20
+ // NEVER allow msg.payload.host override when using API key authentication
21
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
22
+ host = server.host
23
+ } else {
24
+ host = `https://${server.host}:${server.port}`
25
+ }
26
+ } else {
27
+ // For local Ollama servers, allow host override from message
28
+ host = msg?.payload?.host
29
+ if ( !host ) {
30
+ if ( server.host.startsWith('http://') || server.host.startsWith('https://') ) {
31
+ host = server.host
32
+ } else {
33
+ host = `http://${server.host}:${server.port}`
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ // Ollama Cloud configuration
40
+ const ollamaConfig = { host }
41
+ if ( server && server.useCloud && server.credentials && server.credentials.apiKey ) {
42
+ ollamaConfig.headers = {
43
+ 'Authorization': `Bearer ${server.credentials.apiKey}`
44
+ }
45
+ }
46
+
47
+ const ollama = new Ollama( ollamaConfig )
17
48
 
18
49
  let model = null
19
50
  if( msg?.payload?.model ) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-ollama",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Add AI functionality to your flows! This module includes a set of nodes that enable easy communication with Ollama, enriching your projects with intelligent solutions.",
5
5
  "keywords": [
6
6
  "ai",
@@ -39,7 +39,7 @@
39
39
  "node": ">=18.0.0"
40
40
  },
41
41
  "dependencies": {
42
- "ollama": "^0.5.16"
42
+ "ollama": "^0.6.3"
43
43
  },
44
44
  "bugs": {
45
45
  "url": "https://github.com/jakubburkiewicz/node-red-contrib-ollama/issues"