node-red-contrib-ollama 0.2.6 → 0.4.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,37 +3,137 @@ module.exports = function( RED ) {
3
3
 
4
4
  function OllamaGenerateNode( 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
- prompt,
13
- suffix,
14
- system,
15
- template,
16
- raw,
17
- images,
18
- format: payloadFormat,
19
- stream,
20
- keep_alive,
21
- options: payloadOptions
22
- } = msg.payload
7
+ this.modelType = config.modelType || 'str'
8
+ this.promptType = config.promptType || 'str'
9
+ this.suffixType = config.suffixType || 'str'
10
+ this.systemType = config.systemType || 'str'
11
+ this.templateType = config.templateType || 'str'
12
+ this.raw = config.raw || false
13
+ this.imagesType = config.imagesType || 'json'
14
+ this.stream = config.stream || false
15
+ this.think = config.think || false
16
+ this.keepAliveType = config.keepAliveType || 'str'
23
17
 
18
+ const node = this
19
+ node.on( 'input', async function( msg ) {
24
20
  const server = RED.nodes.getNode( config.server )
25
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
21
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
26
22
 
27
23
  const ollama = new Ollama( { host } )
28
24
 
29
- const modelConfig = RED.nodes.getNode( config.model )
30
- const model = ( modelConfig ) ? modelConfig.name : payloadModel
25
+ let model = null
26
+ if( msg?.payload?.model ) {
27
+ model = msg?.payload?.model
28
+ } else if( !!config.model ) {
29
+ if( node.modelType === 'str' ) {
30
+ model = config.model
31
+ } else if( node.modelType === 'msg' ) {
32
+ model = msg[ config.model ]
33
+ } else if( node.modelType === 'flow' ) {
34
+ model = node.context().flow.get( config.model )
35
+ } else if( node.modelType === 'global' ) {
36
+ model = node.context().global.get( config.model )
37
+ }
38
+ }
39
+
40
+ let prompt = null
41
+ if( msg?.payload?.prompt ) {
42
+ prompt = msg?.payload?.prompt
43
+ } else if( !!config.prompt ) {
44
+ if( node.promptType === 'str' ) {
45
+ prompt = config.prompt
46
+ } else if( node.promptType === 'msg' ) {
47
+ prompt = msg[ config.prompt ]
48
+ } else if( node.promptType === 'flow' ) {
49
+ prompt = node.context().flow.get( config.prompt )
50
+ } else if( node.promptType === 'global' ) {
51
+ prompt = node.context().global.get( config.prompt )
52
+ }
53
+ }
54
+
55
+ let suffix = null
56
+ if( msg?.payload?.suffix ) {
57
+ suffix = msg?.payload?.suffix
58
+ } else if( !!config.suffix ) {
59
+ if( node.suffixType === 'str' ) {
60
+ suffix = config.suffix
61
+ } else if( node.suffixType === 'msg' ) {
62
+ suffix = msg[ config.suffix ]
63
+ } else if( node.suffixType === 'flow' ) {
64
+ suffix = node.context().flow.get( config.suffix )
65
+ } else if( node.suffixType === 'global' ) {
66
+ suffix = node.context().global.get( config.suffix )
67
+ }
68
+ }
69
+
70
+ let system = null
71
+ if( msg?.payload?.system ) {
72
+ system = msg?.payload?.system
73
+ } else if( !!config.system ) {
74
+ if( node.systemType === 'str' ) {
75
+ system = config.system
76
+ } else if( node.systemType === 'msg' ) {
77
+ system = msg[ config.system ]
78
+ } else if( node.systemType === 'flow' ) {
79
+ system = node.context().flow.get( config.system )
80
+ } else if( node.systemType === 'global' ) {
81
+ system = node.context().global.get( config.system )
82
+ }
83
+ }
84
+
85
+ let template = null
86
+ if( msg?.payload?.template ) {
87
+ template = msg?.payload?.template
88
+ } else if( !!config.template ) {
89
+ if( node.templateType === 'str' ) {
90
+ template = config.template
91
+ } else if( node.templateType === 'msg' ) {
92
+ template = msg[ config.template ]
93
+ } else if( node.templateType === 'flow' ) {
94
+ template = node.context().flow.get( config.template )
95
+ } else if( node.templateType === 'global' ) {
96
+ template = node.context().global.get( config.template )
97
+ }
98
+ }
99
+
100
+ const raw = ( msg?.payload?.raw !== undefined ) ? msg?.payload?.raw : node.raw
101
+
102
+ let images = null
103
+ if( msg?.payload?.images ) {
104
+ images = msg?.payload?.images
105
+ } else if( !!config.images ) {
106
+ if( node.imagesType === 'json' ) {
107
+ images = JSON.parse( config.images )
108
+ } else if( node.imagesType === 'msg' ) {
109
+ images = msg[ config.images ]
110
+ } else if( node.imagesType === 'flow' ) {
111
+ images = node.context().flow.get( config.images )
112
+ } else if( node.imagesType === 'global' ) {
113
+ images = node.context().global.get( config.images )
114
+ }
115
+ }
31
116
 
32
117
  const formatConfig = RED.nodes.getNode( config.format )
33
- const format = ( formatConfig ) ? formatConfig.json : payloadFormat
118
+ const format = msg?.payload?.format || ( formatConfig ) ? formatConfig.json : null
119
+
120
+ const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
121
+
122
+ const think = ( msg?.payload?.think !== undefined ) ? msg?.payload?.think : node.think || false
123
+
124
+ let keep_alive = null
125
+ if( msg?.payload?.keep_alive ) {
126
+ keep_alive = msg?.payload?.keep_alive
127
+ } else if( !!config.keepAlive ) {
128
+ if( node.keepAliveType === 'str' ) {
129
+ keep_alive = config.keepAlive
130
+ } else if( node.keepAliveType === 'num' ) {
131
+ keep_alive = Number( config.keepAlive )
132
+ }
133
+ }
34
134
 
35
135
  const optionsConfig = RED.nodes.getNode( config.options )
36
- const options = ( optionsConfig ) ? optionsConfig.json : payloadOptions
136
+ const options = msg?.payload?.options || ( optionsConfig ) ? JSON.parse( optionsConfig.json ) : null
37
137
 
38
138
  const response = await ollama.generate( {
39
139
  model,
@@ -45,6 +145,7 @@ module.exports = function( RED ) {
45
145
  images,
46
146
  format,
47
147
  stream,
148
+ think,
48
149
  keep_alive,
49
150
  options
50
151
  } )
@@ -38,16 +38,14 @@
38
38
  </dt>
39
39
 
40
40
  <dd>
41
- The payload object.
41
+ The payload object is an alternative way to configure the node.<br />
42
+ Any properties in the payload object will override the node configuration.
42
43
 
43
44
  <dl class="message-properties">
44
45
  <dt class="optional">
45
46
  payload.host <span class="property-type">string</span>
46
47
  </dt>
47
- <dd>
48
- The host of the Ollama instance.<br />
49
- <em>Alternative to the <code>Server</code> field.</em>
50
- </dd>
48
+ <dd>The host of the Ollama instance.</dd>
51
49
  </dl>
52
50
  </dd>
53
51
  </dl>
@@ -6,13 +6,9 @@ module.exports = function( RED ) {
6
6
  const node = this
7
7
 
8
8
  node.on( 'input', async function( msg ) {
9
- const {
10
- host: payloadHost
11
- } = msg.payload
12
-
13
9
  const server = RED.nodes.getNode( config.server )
14
10
 
15
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
11
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
16
12
 
17
13
  const ollama = new Ollama( { host } )
18
14
 
@@ -38,16 +38,14 @@
38
38
  </dt>
39
39
 
40
40
  <dd>
41
- The payload object.
41
+ The payload object is an alternative way to configure the node.<br />
42
+ Any properties in the payload object will override the node configuration.
42
43
 
43
44
  <dl class="message-properties">
44
45
  <dt class="optional">
45
46
  payload.host <span class="property-type">string</span>
46
47
  </dt>
47
- <dd>
48
- The host of the Ollama instance.<br />
49
- <em>Alternative to the <code>Server</code> field.</em>
50
- </dd>
48
+ <dd>The host of the Ollama instance.</dd>
51
49
  </dl>
52
50
  </dd>
53
51
  </dl>
@@ -6,13 +6,9 @@ module.exports = function( RED ) {
6
6
  const node = this
7
7
 
8
8
  node.on( 'input', async function( msg ) {
9
- const {
10
- host: payloadHost
11
- } = msg.payload
12
-
13
9
  const server = RED.nodes.getNode( config.server )
14
10
 
15
- const host = ( server ) ? server.host + ':' + server.port : payloadHost
11
+ const host = msg?.payload?.host || ( server ) ? server.host + ':' + server.port : null
16
12
 
17
13
  const ollama = new Ollama( { host } )
18
14
 
@@ -5,7 +5,10 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Pull' },
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
+ insecure: { value: false },
11
+ stream: { value: false },
9
12
  },
10
13
  inputs: 1,
11
14
  outputs: 1,
@@ -13,6 +16,17 @@
13
16
  label: function() {
14
17
  return this.name || 'ollama-pull';
15
18
  },
19
+ oneditprepare: function() {
20
+ if( !this.modelType ) {
21
+ this.modelType = 'str'
22
+ }
23
+
24
+ $( '#node-input-model' ).typedInput( {
25
+ type: 'str',
26
+ types: [ 'str', 'msg', 'flow', 'global' ],
27
+ typeField: '#node-input-modelType'
28
+ } )
29
+ }
16
30
  } )
17
31
  </script>
18
32
 
@@ -28,8 +42,19 @@
28
42
  </div>
29
43
 
30
44
  <div class="form-row">
31
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
45
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
32
46
  <input type="text" id="node-input-model" />
47
+ <input type="hidden" id="node-input-modelType" />
48
+ </div>
49
+
50
+ <div class="form-row">
51
+ <label for="node-input-insecure"><i class="fa fa-lock"></i> Insecure</label>
52
+ <input type="checkbox" id="node-input-insecure" />
53
+ </div>
54
+
55
+ <div class="form-row">
56
+ <label for="node-input-stream"><i class="fa fa-cog"></i> Stream</label>
57
+ <input type="checkbox" id="node-input-stream" />
33
58
  </div>
34
59
  </script>
35
60
 
@@ -44,31 +69,26 @@
44
69
  </dt>
45
70
 
46
71
  <dd>
47
- The payload object.
72
+ The payload object is an alternative way to configure the node.<br />
73
+ Any properties in the payload object will override the node configuration.
48
74
 
49
75
  <dl class="message-properties">
50
76
  <dt class="optional">
51
77
  payload.host <span class="property-type">string</span>
52
78
  </dt>
53
- <dd>
54
- The host of the Ollama instance.<br />
55
- <em>Alternative to the <code>Server</code> field.</em>
56
- </dd>
79
+ <dd>The host of the Ollama instance.</dd>
57
80
 
58
81
  <dt class="optional">
59
82
  payload.model <span class="property-type">string</span>
60
83
  </dt>
61
- <dd>
62
- The name of the model to download.<br />
63
- <em>Alternative to the <code>Model</code> field.</em>
64
- </dd>
84
+ <dd>The name of the model to download.</dd>
65
85
 
66
- <dt>
86
+ <dt class="optional">
67
87
  payload.insecure <span class="property-type">boolean</span>
68
88
  </dt>
69
89
  <dd>Pull from servers whose identity cannot be verified.</dd>
70
90
 
71
- <dt>
91
+ <dt class="optional">
72
92
  payload.stream <span class="property-type">boolean</span>
73
93
  </dt>
74
94
  <dd>When true an AsyncGenerator is returned.</dd>
@@ -1,25 +1,38 @@
1
1
  module.exports = function( RED ) {
2
2
  const { Ollama } = require( 'ollama' )
3
3
 
4
- function OllamaPulltNode( config ) {
4
+ function OllamaPullNode( 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
- insecure,
13
- stream
14
- } = msg.payload
7
+ this.modelType = config.modelType || 'str'
8
+ this.insecure = config.insecure || false
9
+ this.stream = config.stream || false
15
10
 
11
+ const node = this
12
+ node.on( 'input', async function( msg ) {
16
13
  const server = RED.nodes.getNode( config.server )
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 modelConfig = RED.nodes.getNode( config.model )
22
- 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 insecure = ( msg?.payload?.insecure !== undefined ) ? msg?.payload?.insecure : node.insecure
34
+
35
+ const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
23
36
 
24
37
  const response = await ollama.pull( {
25
38
  model,
@@ -35,5 +48,5 @@ module.exports = function( RED ) {
35
48
  } )
36
49
  }
37
50
 
38
- RED.nodes.registerType( 'ollama-pull', OllamaPulltNode )
51
+ RED.nodes.registerType( 'ollama-pull', OllamaPullNode )
39
52
  }
@@ -5,7 +5,10 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Push' },
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
+ insecure: { value: false },
11
+ stream: { value: false },
9
12
  },
10
13
  inputs: 1,
11
14
  outputs: 1,
@@ -13,6 +16,17 @@
13
16
  label: function() {
14
17
  return this.name || 'ollama-push';
15
18
  },
19
+ oneditprepare: function() {
20
+ if( !this.modelType ) {
21
+ this.modelType = 'str'
22
+ }
23
+
24
+ $( '#node-input-model' ).typedInput( {
25
+ type: 'str',
26
+ types: [ 'str', 'msg', 'flow', 'global' ],
27
+ typeField: '#node-input-modelType'
28
+ } )
29
+ }
16
30
  } )
17
31
  </script>
18
32
 
@@ -28,8 +42,19 @@
28
42
  </div>
29
43
 
30
44
  <div class="form-row">
31
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
45
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
32
46
  <input type="text" id="node-input-model" />
47
+ <input type="hidden" id="node-input-modelType" />
48
+ </div>
49
+
50
+ <div class="form-row">
51
+ <label for="node-input-insecure"><i class="fa fa-lock"></i> Insecure</label>
52
+ <input type="checkbox" id="node-input-insecure" />
53
+ </div>
54
+
55
+ <div class="form-row">
56
+ <label for="node-input-stream"><i class="fa fa-cog"></i> Stream</label>
57
+ <input type="checkbox" id="node-input-stream" />
33
58
  </div>
34
59
  </script>
35
60
 
@@ -44,31 +69,26 @@
44
69
  </dt>
45
70
 
46
71
  <dd>
47
- The payload object.
72
+ The payload object is an alternative way to configure the node.<br />
73
+ Any properties in the payload object will override the node configuration.
48
74
 
49
75
  <dl class="message-properties">
50
76
  <dt class="optional">
51
77
  payload.host <span class="property-type">string</span>
52
78
  </dt>
53
- <dd>
54
- The host of the Ollama instance.<br />
55
- <em>Alternative to the <code>Server</code> field.</em>
56
- </dd>
79
+ <dd>The host of the Ollama instance.</dd>
57
80
 
58
81
  <dt class="optional">
59
82
  payload.model <span class="property-type">string</span>
60
83
  </dt>
61
- <dd>
62
- The name of the model to upload.<br />
63
- <em>Alternative to the <code>Model</code> field.</em>
64
- </dd>
84
+ <dd>The name of the model to upload.</dd>
65
85
 
66
- <dt>
86
+ <dt class="optional">
67
87
  payload.insecure <span class="property-type">boolean</span>
68
88
  </dt>
69
89
  <dd>Push to servers whose identity cannot be verified.</dd>
70
90
 
71
- <dt>
91
+ <dt class="optional">
72
92
  payload.stream <span class="property-type">boolean</span>
73
93
  </dt>
74
94
  <dd>When true an AsyncGenerator is returned.</dd>
@@ -3,23 +3,36 @@ module.exports = function( RED ) {
3
3
 
4
4
  function OllamaPushNode( 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
- insecure,
13
- stream
14
- } = msg.payload
7
+ this.modelType = config.modelType || 'str'
8
+ this.insecure = config.insecure || false
9
+ this.stream = config.stream || false
15
10
 
11
+ const node = this
12
+ node.on( 'input', async function( msg ) {
16
13
  const server = RED.nodes.getNode( config.server )
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 modelConfig = RED.nodes.getNode( config.model )
22
- 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 insecure = ( msg?.payload?.insecure !== undefined ) ? msg?.payload?.insecure : node.insecure
34
+
35
+ const stream = ( msg?.payload?.stream !== undefined ) ? msg?.payload?.stream : node.stream
23
36
 
24
37
  const response = await ollama.push( {
25
38
  model,
@@ -5,7 +5,12 @@
5
5
  defaults: {
6
6
  name: { value: 'Ollama Show' },
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
+ system: { value: '', required: false },
11
+ systemType: { value: 'str', required: false },
12
+ template: { value: '', required: false },
13
+ templateType: { value: 'str', required: false },
9
14
  options: { value: '', type: 'ollama-config-options', required: false },
10
15
  },
11
16
  inputs: 1,
@@ -14,6 +19,37 @@
14
19
  label: function() {
15
20
  return this.name || 'ollama-show';
16
21
  },
22
+ oneditprepare: function() {
23
+ if( !this.modelType ) {
24
+ this.modelType = 'str'
25
+ }
26
+
27
+ $( '#node-input-model' ).typedInput( {
28
+ type: 'str',
29
+ types: [ 'str', 'msg', 'flow', 'global' ],
30
+ typeField: '#node-input-modelType'
31
+ } )
32
+
33
+ if( !this.systemType ) {
34
+ this.systemType = 'str'
35
+ }
36
+
37
+ $( '#node-input-system' ).typedInput( {
38
+ type: 'str',
39
+ types: [ 'str', 'msg', 'flow', 'global' ],
40
+ typeField: '#node-input-systemType'
41
+ } )
42
+
43
+ if( !this.templateType ) {
44
+ this.templateType = 'str'
45
+ }
46
+
47
+ $( '#node-input-template' ).typedInput( {
48
+ type: 'str',
49
+ types: [ 'str', 'msg', 'flow', 'global' ],
50
+ typeField: '#node-input-templateType'
51
+ } )
52
+ }
17
53
  } )
18
54
  </script>
19
55
 
@@ -29,8 +65,21 @@
29
65
  </div>
30
66
 
31
67
  <div class="form-row">
32
- <label for="node-input-model"><i class="fa fa-bookmark"></i> Model</label>
68
+ <label for="node-input-model"><i class="fa fa-comment"></i> Model</label>
33
69
  <input type="text" id="node-input-model" />
70
+ <input type="hidden" id="node-input-modelType" />
71
+ </div>
72
+
73
+ <div class="form-row">
74
+ <label for="node-input-system"><i class="fa fa-comment"></i> System</label>
75
+ <input type="text" id="node-input-system" />
76
+ <input type="hidden" id="node-input-systemType" />
77
+ </div>
78
+
79
+ <div class="form-row">
80
+ <label for="node-input-template"><i class="fa fa-comment"></i> Template</label>
81
+ <input type="text" id="node-input-template" />
82
+ <input type="hidden" id="node-input-templateType" />
34
83
  </div>
35
84
 
36
85
  <div class="form-row">
@@ -50,24 +99,19 @@
50
99
  </dt>
51
100
 
52
101
  <dd>
53
- The payload object.
102
+ The payload object is an alternative way to configure the node.<br />
103
+ Any properties in the payload object will override the node configuration.
54
104
 
55
105
  <dl class="message-properties">
56
106
  <dt class="optional">
57
107
  payload.host <span class="property-type">string</span>
58
108
  </dt>
59
- <dd>
60
- The host of the Ollama instance.<br />
61
- <em>Alternative to the <code>Server</code> field.</em>
62
- </dd>
109
+ <dd>The host of the Ollama instance.</dd>
63
110
 
64
111
  <dt class="optional">
65
112
  payload.model <span class="property-type">string</span>
66
113
  </dt>
67
- <dd>
68
- The model to show information for.<br />
69
- <em>Alternative to the <code>Model</code> field.</em>
70
- </dd>
114
+ <dd>The model to show information for.</dd>
71
115
 
72
116
  <dt class="optional">
73
117
  payload.system <span class="property-type">string</span>
@@ -81,10 +125,7 @@
81
125
  <dt class="optional">
82
126
  payload.options <span class="property-type">object</span>
83
127
  </dt>
84
- <dd>
85
- Options to configure the runtime.<br />
86
- <em>Alternative to the <code>Server</code> field.</em>
87
- </dd>
128
+ <dd>Options to configure the runtime.</dd>
88
129
  </dl>
89
130
  </dd>
90
131
  </dl>