node-red-contrib-ollama 0.2.5 → 0.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.
@@ -3,22 +3,52 @@ module.exports = function( RED ) {
3
3
 
4
4
  function OllamaCopyNode( config ) {
5
5
  RED.nodes.createNode( this, config )
6
- const node = this
7
6
 
8
- node.on( 'input', async function( msg ) {
9
- const {
10
- host: payloadHost,
11
- source,
12
- destination
13
- } = msg.payload
7
+ this.sourceType = config.sourceType || 'str'
8
+ this.destinationType = config.destinationType || 'str'
14
9
 
10
+ const node = this
11
+ node.on( 'input', async function( msg ) {
15
12
  const server = RED.nodes.getNode( config.server )
16
13
 
17
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
14
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
18
15
 
19
16
  const ollama = new Ollama( { host } )
20
17
 
21
- const response = await ollama.copy( { source, destination } )
18
+ let source = null
19
+ if( msg?.payload?.source ) {
20
+ source = msg?.payload?.source
21
+ } else if( !!config.source ) {
22
+ if( node.sourceType === 'str' ) {
23
+ source = config.source
24
+ } else if( node.sourceType === 'msg' ) {
25
+ source = msg[ config.source ]
26
+ } else if( node.sourceType === 'flow' ) {
27
+ source = node.context().flow.get( config.source )
28
+ } else if( node.sourceType === 'global' ) {
29
+ source = node.context().global.get( config.source )
30
+ }
31
+ }
32
+
33
+ let destination = null
34
+ if( msg?.payload?.destination ) {
35
+ destination = msg?.payload?.destination
36
+ } else if( !!config.destination ) {
37
+ if( node.destinationType === 'str' ) {
38
+ destination = config.destination
39
+ } else if( node.destinationType === 'msg' ) {
40
+ destination = msg[ config.destination ]
41
+ } else if( node.destinationType === 'flow' ) {
42
+ destination = node.context().flow.get( config.destination )
43
+ } else if( node.destinationType === 'global' ) {
44
+ destination = node.context().global.get( config.destination )
45
+ }
46
+ }
47
+
48
+ const response = await ollama.copy( {
49
+ source,
50
+ destination
51
+ } )
22
52
  .catch( error => {
23
53
  node.error( error )
24
54
  } )
@@ -5,7 +5,12 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Create' },
7
7
  server: { value: '', type: 'ollama-config-server', required: false },
8
- model: { value: '', type: 'ollama-config-model', required: false },
8
+ model: { value: '', required: false },
9
+ modelType: { value: 'str', required: false },
10
+ modelfile: { value: '', required: false },
11
+ stream: { value: false },
12
+ path: { value: '', required: false },
13
+ pathType: { value: 'str', required: false },
9
14
  },
10
15
  inputs: 1,
11
16
  outputs: 1,
@@ -13,6 +18,43 @@
13
18
  label: function() {
14
19
  return this.name || 'ollama-create';
15
20
  },
21
+ oneditprepare: function() {
22
+ if( !this.modelType ) {
23
+ this.modelType = 'str'
24
+ }
25
+
26
+ $( '#node-input-model' ).typedInput( {
27
+ type: 'str',
28
+ types: [ 'str', 'msg', 'flow', 'global' ],
29
+ typeField: '#node-input-modelType'
30
+ } )
31
+
32
+ this.editor = RED.editor.createEditor( {
33
+ id: 'node-input-modelfile-editor',
34
+ mode: 'yaml',
35
+ value: this.modelfile,
36
+ mode: 'ace/mode/text'
37
+ } )
38
+
39
+ if( !this.pathType ) {
40
+ this.pathType = 'str'
41
+ }
42
+
43
+ $( '#node-input-path' ).typedInput( {
44
+ type: 'str',
45
+ types: [ 'str', 'msg', 'flow', 'global' ],
46
+ typeField: '#node-input-pathType'
47
+ } )
48
+ },
49
+ oneditsave: function() {
50
+ this.modelfile = this.editor.getValue()
51
+ this.editor.destroy()
52
+ delete this.editor
53
+ },
54
+ oneditcancel: function() {
55
+ this.editor.destroy()
56
+ delete this.editor
57
+ }
16
58
  } )
17
59
  </script>
18
60
 
@@ -28,9 +70,24 @@
28
70
  </div>
29
71
 
30
72
  <div class="form-row">
31
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
73
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
32
74
  <input type="text" id="node-input-model" />
75
+ <input type="hidden" id="node-input-modelType" />
33
76
  </div>
77
+
78
+ <div class="form-row">
79
+ <label for="node-input-stream"><i class="fa fa-cog"></i> Stream</label>
80
+ <input type="checkbox" id="node-input-stream" />
81
+ </div>
82
+
83
+ <div class="form-row">
84
+ <label for="node-input-path"><i class="fa fa-comment"></i> Path</label>
85
+ <input type="text" id="node-input-path" />
86
+ <input type="hidden" id="node-input-pathType" />
87
+ </div>
88
+
89
+ <label>Modelfile</label>
90
+ <div style="height: 250px; min-height:150px;" class="node-text-editor" id="node-input-modelfile-editor" />
34
91
  </script>
35
92
 
36
93
  <script type="text/html" data-help-name="ollama-create">
@@ -44,24 +101,19 @@
44
101
  </dt>
45
102
 
46
103
  <dd>
47
- The payload object.
104
+ The payload object is an alternative way to configure the node.<br />
105
+ Any properties in the payload object will override the node configuration.
48
106
 
49
107
  <dl class="message-properties">
50
108
  <dt class="optional">
51
109
  payload.host <span class="property-type">string</span>
52
110
  </dt>
53
- <dd>
54
- The host of the Ollama instance.<br />
55
- <em>Alternative to the <code>Server</code> field.</em>
56
- </dd>
111
+ <dd>The host of the Ollama instance.</dd>
57
112
 
58
113
  <dt class="optional">
59
114
  payload.model <span class="property-type">string</span>
60
115
  </dt>
61
- <dd>
62
- The name of the model to create.<br />
63
- <em>Alternative to the <code>Model</code> field.</em>
64
- </dd>
116
+ <dd>The name of the model to create.</dd>
65
117
 
66
118
  <dt class="optional">
67
119
  payload.path <span class="property-type">string</span>
@@ -3,34 +3,61 @@ module.exports = function( RED ) {
3
3
 
4
4
  function OllamaCreateNode( config ) {
5
5
  RED.nodes.createNode( this, config )
6
- const node = this
7
6
 
8
- node.on( 'input', async function( msg ) {
9
- const {
10
- host: payloadHost,
11
- model: payloadModel,
12
- modelfile,
13
- stream,
14
- path
15
- } = msg.payload
7
+ this.modelType = config.modelType || 'str'
8
+ this.stream = config.stream || false
9
+ this.pathType = config.pathType || 'str'
16
10
 
11
+ const node = this
12
+ node.on( 'input', async function( msg ) {
17
13
  const server = RED.nodes.getNode( config.server )
18
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
14
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
19
15
 
20
16
  const ollama = new Ollama( { host } )
21
17
 
22
- const modelConfig = RED.nodes.getNode( config.model )
23
- const model = ( modelConfig ) ? modelConfig.name : payloadModel
18
+ let model = null
19
+ if( msg?.payload?.model ) {
20
+ model = msg?.payload?.model
21
+ } else if( !!config.model ) {
22
+ if( node.modelType === 'str' ) {
23
+ model = config.model
24
+ } else if( node.modelType === 'msg' ) {
25
+ model = msg[ config.model ]
26
+ } else if( node.modelType === 'flow' ) {
27
+ model = node.context().flow.get( config.model )
28
+ } else if( node.modelType === 'global' ) {
29
+ model = node.context().global.get( config.model )
30
+ }
31
+ }
32
+
33
+ const modelfile = msg?.payload?.modelfile || config.modelfile
34
+
35
+ const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
36
+
37
+ let path = null
38
+ if( msg?.payload?.path ) {
39
+ path = msg?.payload?.path
40
+ } else if( !!config.path ) {
41
+ if( node.pathType === 'str' ) {
42
+ path = config.path
43
+ } else if( node.pathType === 'msg' ) {
44
+ path = msg[ config.path ]
45
+ } else if( node.pathType === 'flow' ) {
46
+ path = node.context().flow.get( config.path )
47
+ } else if( node.pathType === 'global' ) {
48
+ path = node.context().global.get( config.path )
49
+ }
50
+ }
24
51
 
25
52
  const response = await ollama.create( {
26
- model,
27
- modelfile,
28
- stream,
29
- path
30
- } )
31
- .catch( error => {
32
- node.error( error )
33
- } )
53
+ model,
54
+ modelfile,
55
+ stream,
56
+ path
57
+ } )
58
+ .catch( error => {
59
+ node.error( error )
60
+ } )
34
61
 
35
62
  msg.payload = response
36
63
  node.send( msg )
@@ -5,7 +5,8 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Delete' },
7
7
  server: { value: '', type: 'ollama-config-server', required: false },
8
- model: { value: '', type: 'ollama-config-model', required: false },
8
+ model: { value: '', required: false },
9
+ modelType: { value: 'str', required: false },
9
10
  },
10
11
  inputs: 1,
11
12
  outputs: 1,
@@ -13,6 +14,17 @@
13
14
  label: function() {
14
15
  return this.name || 'ollama-delete';
15
16
  },
17
+ oneditprepare: function() {
18
+ if( !this.modelType ) {
19
+ this.modelType = 'str'
20
+ }
21
+
22
+ $( '#node-input-model' ).typedInput( {
23
+ type: 'str',
24
+ types: [ 'str', 'msg', 'flow', 'global' ],
25
+ typeField: '#node-input-modelType'
26
+ } )
27
+ }
16
28
  } )
17
29
  </script>
18
30
 
@@ -28,8 +40,9 @@
28
40
  </div>
29
41
 
30
42
  <div class="form-row">
31
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
43
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
32
44
  <input type="text" id="node-input-model" />
45
+ <input type="hidden" id="node-input-modelType" />
33
46
  </div>
34
47
  </script>
35
48
 
@@ -44,24 +57,19 @@
44
57
  </dt>
45
58
 
46
59
  <dd>
47
- The payload object.
60
+ The payload object is an alternative way to configure the node.<br />
61
+ Any properties in the payload object will override the node configuration.
48
62
 
49
63
  <dl class="message-properties">
50
64
  <dt class="optional">
51
65
  payload.host <span class="property-type">string</span>
52
66
  </dt>
53
- <dd>
54
- The host of the Ollama instance.<br />
55
- <em>Alternative to the <code>Server</code> field.</em>
56
- </dd>
67
+ <dd>The host of the Ollama instance.</dd>
57
68
 
58
69
  <dt class="optional">
59
70
  payload.model <span class="property-type">string</span>
60
71
  </dt>
61
- <dd>
62
- The name of the model to delete.<br />
63
- <em>Alternative to the <code>Model</code> field.</em>
64
- </dd>
72
+ <dd>The name of the model to delete.</dd>
65
73
  </dl>
66
74
  </dd>
67
75
  </dl>
@@ -3,21 +3,30 @@ module.exports = function( RED ) {
3
3
 
4
4
  function OllamaDeleteNode( config ) {
5
5
  RED.nodes.createNode( this, config )
6
- const node = this
7
6
 
8
- node.on( 'input', async function( msg ) {
9
- const {
10
- host: payloadHost,
11
- model: payloadModel
12
- } = msg.payload
7
+ this.modelType = config.modelType || 'str'
13
8
 
9
+ const node = this
10
+ node.on( 'input', async function( msg ) {
14
11
  const server = RED.nodes.getNode( config.server )
15
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
12
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
16
13
 
17
14
  const ollama = new Ollama( { host } )
18
15
 
19
- const modelConfig = RED.nodes.getNode( config.model )
20
- const model = ( modelConfig ) ? modelConfig.name : payloadModel
16
+ let model = null
17
+ if( msg?.payload?.model ) {
18
+ model = msg?.payload?.model
19
+ } else if( !!config.model ) {
20
+ if( node.modelType === 'str' ) {
21
+ model = config.model
22
+ } else if( node.modelType === 'msg' ) {
23
+ model = msg[ config.model ]
24
+ } else if( node.modelType === 'flow' ) {
25
+ model = node.context().flow.get( config.model )
26
+ } else if( node.modelType === 'global' ) {
27
+ model = node.context().global.get( config.model )
28
+ }
29
+ }
21
30
 
22
31
  const response = await ollama.delete( { model } )
23
32
  .catch( error => {
@@ -5,7 +5,14 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Embed' },
7
7
  server: { value: '', type: 'ollama-config-server', required: false },
8
- model: { value: '', type: 'ollama-config-model', required: false },
8
+ model: { value: '', required: false },
9
+ modelType: { value: 'str', required: false },
10
+ input: { value: '', required: false },
11
+ inputType: { value: 'str', required: false },
12
+ truncate: { value: false, required: false },
13
+ keepAlive: { value: '5m', required: false },
14
+ keepAliveType: { value: 'str', required: false },
15
+ options: { value: '', type: 'ollama-config-options', required: false },
9
16
  },
10
17
  inputs: 1,
11
18
  outputs: 1,
@@ -13,6 +20,37 @@
13
20
  label: function() {
14
21
  return this.name || 'ollama-embed';
15
22
  },
23
+ oneditprepare: function() {
24
+ if( !this.modelType ) {
25
+ this.modelType = 'str'
26
+ }
27
+
28
+ $( '#node-input-model' ).typedInput( {
29
+ type: 'str',
30
+ types: [ 'str', 'msg', 'flow', 'global' ],
31
+ typeField: '#node-input-modelType'
32
+ } )
33
+
34
+ if( !this.inputType ) {
35
+ this.inputType = 'str'
36
+ }
37
+
38
+ $( '#node-input-input' ).typedInput( {
39
+ type: 'str',
40
+ types: [ 'str', 'json', 'msg', 'flow', 'global' ],
41
+ typeField: '#node-input-inputType'
42
+ } )
43
+
44
+ if( !this.keepAliveType ) {
45
+ this.keepAliveType = 'str'
46
+ }
47
+
48
+ $( '#node-input-keepAlive' ).typedInput( {
49
+ type: 'str',
50
+ types: [ 'str', 'num' ],
51
+ typeField: '#node-input-keepAliveType'
52
+ } )
53
+ }
16
54
  } )
17
55
  </script>
18
56
 
@@ -28,8 +66,31 @@
28
66
  </div>
29
67
 
30
68
  <div class="form-row">
31
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
69
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
32
70
  <input type="text" id="node-input-model" />
71
+ <input type="hidden" id="node-input-modelType" />
72
+ </div>
73
+
74
+ <div class="form-row">
75
+ <label for="node-input-input"><i class="fa fa-comment"></i> Input</label>
76
+ <input type="text" id="node-input-input" />
77
+ <input type="hidden" id="node-input-inputType" />
78
+ </div>
79
+
80
+ <div class="form-row">
81
+ <label for="node-input-truncate"><i class="fa fa-cog"></i> Truncate</label>
82
+ <input type="checkbox" id="node-input-truncate" />
83
+ </div>
84
+
85
+ <div class="form-row">
86
+ <label for="node-input-keepAlive"><i class="fa fa-cog"></i> Keep Alive</label>
87
+ <input type="text" id="node-input-keepAlive" />
88
+ <input type="hidden" id="node-input-keepAliveType" />
89
+ </div>
90
+
91
+ <div class="form-row">
92
+ <label for="node-input-options"><i class="fa fa-cog"></i> Options</label>
93
+ <input type="text" id="node-input-options" />
33
94
  </div>
34
95
  </script>
35
96
 
@@ -44,28 +105,23 @@
44
105
  </dt>
45
106
 
46
107
  <dd>
47
- The payload object.
108
+ The payload object is an alternative way to configure the node.<br />
109
+ Any properties in the payload object will override the node configuration.
48
110
 
49
111
  <dl class="message-properties">
50
112
  <dt class="optional">
51
113
  payload.host <span class="property-type">string</span>
52
114
  </dt>
53
- <dd>
54
- The host of the Ollama instance.<br />
55
- <em>Alternative to the <code>Server</code> field.</em>
56
- </dd>
115
+ <dd>The host of the Ollama instance.</dd>
57
116
 
58
117
  <dt class="optional">
59
118
  payload.model <span class="property-type">string</span>
60
119
  </dt>
61
- <dd>
62
- The name of the model used to generate the embeddings.<br />
63
- <em>Alternative to the <code>Model</code> field.</em>
64
- </dd>
120
+ <dd>The name of the model used to generate the embeddings.</dd>
65
121
 
66
- <dt>
122
+ <dt class="optional">
67
123
  payload.input <span class="property-type">string | array[string]</span>
68
- </dt>
124
+ </d>
69
125
  <dd>The input used to generate the embeddings.</dd>
70
126
 
71
127
  <dt class="optional">
@@ -83,143 +139,144 @@
83
139
  </dt>
84
140
  <dd>
85
141
  Options to configure the runtime.<br />
142
+ <em>Alternative to the <code>Options</code> field.</em>
86
143
 
87
144
  <h4>Options</h4>
88
145
  <dl class="message-properties">
89
- <dt>
146
+ <dt class="optional">
90
147
  numa <span class="property-type">boolean</span>
91
148
  </dt>
92
149
  <dd>Use NUMA for the runtime.</dd>
93
150
 
94
- <dt>
151
+ <dt class="optional">
95
152
  num_ctx <span class="property-type">number</span>
96
153
  </dt>
97
154
  <dd>The number of contexts to use.</dd>
98
155
 
99
- <dt>
156
+ <dt class="optional">
100
157
  num_batch <span class="property-type">number</span>
101
158
  </dt>
102
159
  <dd>The number of batches to use.</dd>
103
160
 
104
- <dt>
161
+ <dt class="optional">
105
162
  main_gpu <span class="property-type">number</span>
106
163
  </dt>
107
164
  <dd>The main GPU to use.</dd>
108
165
 
109
- <dt>
166
+ <dt class="optional">
110
167
  low_vram <span class="property-type">boolean</span>
111
168
  </dt>
112
169
  <dd>Use low VRAM.</dd>
113
170
 
114
- <dt>
171
+ <dt class="optional">
115
172
  f16_kv <span class="property-type">boolean</span>
116
173
  </dt>
117
174
  <dd>Use f16 key-value.</dd>
118
175
 
119
- <dt>
176
+ <dt class="optional">
120
177
  logits_all <span class="property-type">boolean</span>
121
178
  </dt>
122
179
  <dd>Return all logits.</dd>
123
180
 
124
- <dt>
181
+ <dt class="optional">
125
182
  vocab_only <span class="property-type">boolean</span>
126
183
  </dt>
127
184
  <dd>Return only the vocabulary.</dd>
128
185
 
129
- <dt>
186
+ <dt class="optional">
130
187
  use_nmap <span class="property-type">boolean</span>
131
188
  </dt>
132
189
  <dd>Use NMAP.</dd>
133
190
 
134
- <dt>
191
+ <dt class="optional">
135
192
  use_mlock <span class="property-type">boolean</span>
136
193
  </dt>
137
194
  <dd>Use mlock.</dd>
138
195
 
139
- <dt>
196
+ <dt class="optional">
140
197
  embedding_only <span class="property-type">boolean</span>
141
198
  </dt>
142
199
  <dd>Return only the embeddings.</dd>
143
200
 
144
- <dt>
201
+ <dt class="optional">
145
202
  num_thread <span class="property-type">number</span>
146
203
  </dt>
147
204
  <dd>The number of threads to use.</dd>
148
205
 
149
- <dt>
206
+ <dt class="optional">
150
207
  num_keep <span class="property-type">number</span>
151
208
  </dt>
152
209
  <dd>The number of models to keep.</dd>
153
210
 
154
- <dt>
211
+ <dt class="optional">
155
212
  seed <span class="property-type">number</span>
156
213
  </dt>
157
214
  <dd>The seed to use.</dd>
158
215
 
159
- <dt>
216
+ <dt class="optional">
160
217
  num_predict <span class="property-type">number</span>
161
218
  </dt>
162
219
  <dd>The number of predictions to use.</dd>
163
220
 
164
- <dt>
221
+ <dt class="optional">
165
222
  top_k <span class="property-type">number</span>
166
223
  </dt>
167
224
  <dd>The top k to use.</dd>
168
225
 
169
- <dt>
226
+ <dt class="optional">
170
227
  top_p <span class="property-type">number</span>
171
228
  </dt>
172
229
  <dd>The top p to use.</dd>
173
230
 
174
- <dt>
231
+ <dt class="optional">
175
232
  typical_p <span class="property-type">number</span>
176
233
  </dt>
177
234
  <dd>The typical p to use.</dd>
178
235
 
179
- <dt>
236
+ <dt class="optional">
180
237
  repeat_last_n <span class="property-type">number</span>
181
238
  </dt>
182
239
  <dd>The repeat last n to use.</dd>
183
240
 
184
- <dt>
241
+ <dt class="optional">
185
242
  temperature <span class="property-type">number</span>
186
243
  </dt>
187
244
  <dd>The temperature to use.</dd>
188
245
 
189
- <dt>
246
+ <dt class="optional">
190
247
  repeat_pentalty <span class="property-type">number</span>
191
248
  </dt>
192
249
  <dd>The repeat pentalty to use.</dd>
193
250
 
194
- <dt>
251
+ <dt class="optional">
195
252
  presence_penalty <span class="property-type">number</span>
196
253
  </dt>
197
254
  <dd>The presence penalty to use.</dd>
198
255
 
199
- <dt>
256
+ <dt class="optional">
200
257
  frequency_penalty <span class="property-type">number</span>
201
258
  </dt>
202
259
  <dd>The frequency penalty to use.</dd>
203
260
 
204
- <dt>
261
+ <dt class="optional">
205
262
  mirostat <span class="property-type">boolean</span>
206
263
  </dt>
207
264
  <dd>Use mirostat.</dd>
208
265
 
209
- <dt>
266
+ <dt class="optional">
210
267
  mirostat_tau <span class="property-type">number</span>
211
268
  </dt>
212
269
 
213
- <dt>
270
+ <dt class="optional">
214
271
  mirostat_eta <span class="property-type">number</span>
215
272
  </dt>
216
273
 
217
- <dt>
274
+ <dt class="optional">
218
275
  penalize_newline <span class="property-type">boolean</span>
219
276
  </dt>
220
277
  <dd>Penalize newline.</dd>
221
278
 
222
- <dt>
279
+ <dt class="optional">
223
280
  stop <span class="property-type">array</span>
224
281
  </dt>
225
282
  <dd>The stop to use.</dd>