@cpwc/node-red-contrib-ai-intent 3.1.0-alpha

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.
Files changed (70) hide show
  1. package/.eslintrc +49 -0
  2. package/.idea/modules.xml +8 -0
  3. package/.idea/node-red-contrib-ai-intent.iml +12 -0
  4. package/.idea/vcs.xml +6 -0
  5. package/LICENSE +21 -0
  6. package/README.md +233 -0
  7. package/call-intent/icons/promotion-icon.svg +8 -0
  8. package/call-intent/index.html +114 -0
  9. package/call-intent/index.js +110 -0
  10. package/constants.js +31 -0
  11. package/database.js +9 -0
  12. package/examples/home-assistant-automation.json +167 -0
  13. package/examples/llm-chat-node-example.json +208 -0
  14. package/examples/openai-call-registered-intent-example.json +174 -0
  15. package/examples/openai-system-node-example.json +178 -0
  16. package/examples/openai-tool-node-example.json +120 -0
  17. package/examples/openai-user-node-exampe.json +234 -0
  18. package/geminiai-chat/geminiai-configuration/index.html +18 -0
  19. package/geminiai-chat/geminiai-configuration/index.js +7 -0
  20. package/geminiai-chat/icons/diamond.svg +8 -0
  21. package/geminiai-chat/icons/gemini-icon.svg +1 -0
  22. package/geminiai-chat/icons/gemini.svg +8 -0
  23. package/geminiai-chat/index.html +189 -0
  24. package/geminiai-chat/index.js +92 -0
  25. package/globalUtils.js +39 -0
  26. package/images/call_register_intent.jpeg +0 -0
  27. package/images/finally.jpg +0 -0
  28. package/images/set-config-node.gif +0 -0
  29. package/llm-chat/AzureOpenAIHelper.js +204 -0
  30. package/llm-chat/ChatGPTHelper.js +197 -0
  31. package/llm-chat/GeminiHelper.js +260 -0
  32. package/llm-chat/OllamaHelper.js +196 -0
  33. package/llm-chat/icons/bot-message-square.svg +1 -0
  34. package/llm-chat/icons/brain-circuit.svg +1 -0
  35. package/llm-chat/icons/chatgpt-icon.svg +7 -0
  36. package/llm-chat/index.html +205 -0
  37. package/llm-chat/index.js +73 -0
  38. package/llm-chat/platform-configuration/index.html +136 -0
  39. package/llm-chat/platform-configuration/index.js +16 -0
  40. package/localai-chat/icons/gem-icon.svg +1 -0
  41. package/localai-chat/icons/llama.svg +8 -0
  42. package/localai-chat/index.html +244 -0
  43. package/localai-chat/index.js +108 -0
  44. package/localai-chat/localai-configuration/index.html +18 -0
  45. package/localai-chat/localai-configuration/index.js +7 -0
  46. package/openai-chat/icons/chatgpt-icon.svg +7 -0
  47. package/openai-chat/index.html +196 -0
  48. package/openai-chat/index.js +58 -0
  49. package/openai-chat/openai-configuration/index.html +18 -0
  50. package/openai-chat/openai-configuration/index.js +7 -0
  51. package/openai-response/index.html +66 -0
  52. package/openai-response/index.js +154 -0
  53. package/openai-system/index.html +68 -0
  54. package/openai-system/index.js +28 -0
  55. package/openai-tool/index.html +57 -0
  56. package/openai-tool/index.js +50 -0
  57. package/openai-user/index.html +76 -0
  58. package/openai-user/index.js +26 -0
  59. package/package.json +49 -0
  60. package/register-intent/icons/register-icon.svg +8 -0
  61. package/register-intent/index.html +195 -0
  62. package/register-intent/index.js +72 -0
  63. package/register-intent/utils.js +10 -0
  64. package/utilities/chat-controller.js +249 -0
  65. package/utilities/chat-ledger.js +122 -0
  66. package/utilities/conversationHistory.js +68 -0
  67. package/utilities/format.js +94 -0
  68. package/utilities/gemini-controller.js +243 -0
  69. package/utilities/global-context.js +30 -0
  70. package/utilities/validateSchema.js +74 -0
@@ -0,0 +1,167 @@
1
+ [
2
+ {
3
+ "id": "17bc360ebf2f52da",
4
+ "type": "api-render-template",
5
+ "z": "b9203c19c137b9ca",
6
+ "name": "",
7
+ "server": "228d3d53.df8e02",
8
+ "version": 0,
9
+ "template": "Available Devices:\n```json\n{\n \"current time\": {{now()}},\n{% set lights = expand(states.light) %}\n{%- for area in areas() %}\n {%- set area_info = namespace(printed=false) %}\n {%- for device in area_devices(area) -%}\n {%- if not device_attr(device, \"disabled_by\") and not device_attr(device, \"entry_type\") and device_attr(device, \"name\") %}\n {%- if not area_info.printed %}\n\n \"{{ area_name(area) }}\": {\n {%- set area_info.printed = true -%}\n \"lights\": [\n {%- for light in lights -%}\n {%- if area_name(light.entity_id) == area_name(area) %}\n {\n \"entity name\": \"{{light.name}}\",\n \"id\": \"{{light.entity_id}}\",\n \"state\": \"{{light.state}}\",\n \"timestamp\": \"{{ as_timestamp(light.last_changed) | timestamp_custom('%m-%d-%y %I:%M %p') }}\"\n },\n {%- endif %}\n {%- endfor %}\n ],\n \n \"doors and windows\": [\n {%- for sensor in expand(states.binary_sensor.ring_contact_sensors) -%}\n {%- if area_name(sensor.entity_id) == area_name(area) %}\n {\n \"entity name\": \"{{sensor.name}}\",\n \"id\": \"{{sensor.entity_id}}\",\n \"state\": \"{% if states(sensor.entity_id) == 'on'%}open {%else%}closed {%endif%}\",\n \"timestamp\": \"{{ as_timestamp(sensor.last_changed) | timestamp_custom('%m-%d-%y %I:%M %p') }}\"\n },\n {%- endif %}\n {%- endfor %}\n ]\n }\n \n {%- endif -%}\n {%- endif %}\n {%- endfor %}\n{%- endfor %}\n}\n```",
10
+ "resultsLocation": "summary",
11
+ "resultsLocationType": "msg",
12
+ "templateLocation": "template",
13
+ "templateLocationType": "msg",
14
+ "x": 360,
15
+ "y": 700,
16
+ "wires": [
17
+ [
18
+ "1b2cb2b75a5a2fe2"
19
+ ]
20
+ ]
21
+ },
22
+ {
23
+ "id": "1b2cb2b75a5a2fe2",
24
+ "type": "OpenAI User",
25
+ "z": "b9203c19c137b9ca",
26
+ "name": "",
27
+ "content": "{prompt}",
28
+ "x": 350,
29
+ "y": 740,
30
+ "wires": [
31
+ [
32
+ "82fe0e2b3fbd6cd2"
33
+ ]
34
+ ]
35
+ },
36
+ {
37
+ "id": "82fe0e2b3fbd6cd2",
38
+ "type": "OpenAI System",
39
+ "z": "b9203c19c137b9ca",
40
+ "name": "",
41
+ "instruction": "You possess the knowledge of all the universe, answer any question given to you truthfully and to your fullest ability. \nYou are also a smart home manager, named Ke, who has been given permission to control my smart home which is powered by Home Assistant.\nI will provide you information about my smart home along, you can truthfully make corrections or respond in polite and concise language.\n\n{summary}\nUser is located in the {location}\n\nThe current state of devices is provided in Available Devices.\nOnly use the execute_services function when smart home actions are requested.\nDo not tell me what you're thinking about doing either, just do it.\nIf I ask you about the current state of the home, or many devices I have, or how many devices are in a specific state, just respond with the accurate information but do not call the execute_services function.\nIf I ask you what time or date it is be sure to respond in a human readable format.\nIf you don't have enough information to execute a smart home command then specify what other information you need.",
42
+ "x": 340,
43
+ "y": 780,
44
+ "wires": [
45
+ [
46
+ "fb67875ebc73a3ff"
47
+ ]
48
+ ]
49
+ },
50
+ {
51
+ "id": "f2aa9233e44a12b4",
52
+ "type": "OpenAI Chat",
53
+ "z": "b9203c19c137b9ca",
54
+ "name": "",
55
+ "model": "gpt-4-1106-preview",
56
+ "temperature": 0.7,
57
+ "max_tokens": 1200,
58
+ "top_p": 1,
59
+ "frequency_penalty": 0,
60
+ "presence_penalty": 0,
61
+ "x": 350,
62
+ "y": 860,
63
+ "wires": [
64
+ [
65
+ "ab9b59dc4a6aadf8"
66
+ ]
67
+ ]
68
+ },
69
+ {
70
+ "id": "ab9b59dc4a6aadf8",
71
+ "type": "OpenAI Response",
72
+ "z": "b9203c19c137b9ca",
73
+ "name": "",
74
+ "x": 330,
75
+ "y": 900,
76
+ "wires": [
77
+ [
78
+ "2c78c52f1c872c2f"
79
+ ]
80
+ ]
81
+ },
82
+ {
83
+ "id": "2c78c52f1c872c2f",
84
+ "type": "debug",
85
+ "z": "b9203c19c137b9ca",
86
+ "name": "debug 142",
87
+ "active": true,
88
+ "tosidebar": true,
89
+ "console": false,
90
+ "tostatus": false,
91
+ "complete": "true",
92
+ "targetType": "full",
93
+ "statusVal": "",
94
+ "statusType": "auto",
95
+ "x": 570,
96
+ "y": 900,
97
+ "wires": []
98
+ },
99
+ {
100
+ "id": "fae6fc0d7ac5c16b",
101
+ "type": "inject",
102
+ "z": "b9203c19c137b9ca",
103
+ "name": "",
104
+ "props": [
105
+ {
106
+ "p": "payload"
107
+ },
108
+ {
109
+ "p": "prompt",
110
+ "v": "How many lights are on?",
111
+ "vt": "str"
112
+ }
113
+ ],
114
+ "repeat": "",
115
+ "crontab": "",
116
+ "once": false,
117
+ "onceDelay": 0.1,
118
+ "topic": "",
119
+ "payload": "",
120
+ "payloadType": "date",
121
+ "x": 160,
122
+ "y": 700,
123
+ "wires": [
124
+ [
125
+ "17bc360ebf2f52da"
126
+ ]
127
+ ]
128
+ },
129
+ {
130
+ "id": "fb67875ebc73a3ff",
131
+ "type": "OpenAI Tool",
132
+ "z": "b9203c19c137b9ca",
133
+ "name": "execute_services",
134
+ "tool": "{\"type\":\"function\",\"function\":{\"name\":\"execute_services\",\"description\":\"Use this function to execute service of devices in Home Assistant.\",\"parameters\":{\"type\":\"object\",\"properties\":{\"list\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"domain\":{\"type\":\"string\",\"description\":\"The service to be called\"},\"service\":{\"type\":\"string\",\"description\":\"The service to be called\"},\"target\":{\"type\":\"object\",\"description\":\"The service data object to indicate what to control.\",\"properties\":{\"entity_id\":{\"type\":\"string\",\"description\":\"The entity_id retrieved from available devices. It must start with domain, followed by dot character.\"}},\"required\":[\"entity_id\"]}},\"required\":[\"domain\",\"service\",\"target\"]}},\"response\":{\"type\":\"string\",\"description\":\"A friendly response to the given command\"}}}}}",
135
+ "x": 330,
136
+ "y": 820,
137
+ "wires": [
138
+ [
139
+ "f2aa9233e44a12b4"
140
+ ]
141
+ ]
142
+ },
143
+ {
144
+ "id": "865aa4b5f2775a4b",
145
+ "type": "comment",
146
+ "z": "b9203c19c137b9ca",
147
+ "name": "Example: Answers questions about the lights in your smart home",
148
+ "info": "This execute_services was adapted from [jekalmin](https://github.com/jekalmin/extended_openai_conversation)\nThe System context was adapted from [FutureProofHomes](https://www.youtube.com/watch?v=pAKqKTkx5X4&t=2s)",
149
+ "x": 330,
150
+ "y": 660,
151
+ "wires": []
152
+ },
153
+ {
154
+ "id": "228d3d53.df8e02",
155
+ "type": "server",
156
+ "name": "Home Assistant",
157
+ "addon": false,
158
+ "rejectUnauthorizedCerts": true,
159
+ "ha_boolean": "",
160
+ "connectionDelay": false,
161
+ "cacheJson": false,
162
+ "heartbeat": false,
163
+ "heartbeatInterval": "",
164
+ "statusSeparator": "",
165
+ "enableGlobalContextStore": false
166
+ }
167
+ ]
@@ -0,0 +1,208 @@
1
+ [
2
+ {
3
+ "id": "26ee7fb33da44441",
4
+ "type": "debug",
5
+ "z": "63287583ae175fca",
6
+ "name": "debug 210",
7
+ "active": true,
8
+ "tosidebar": true,
9
+ "console": false,
10
+ "tostatus": false,
11
+ "complete": "true",
12
+ "targetType": "full",
13
+ "statusVal": "",
14
+ "statusType": "auto",
15
+ "x": 770,
16
+ "y": 1960,
17
+ "wires": []
18
+ },
19
+ {
20
+ "id": "8bdac3a059f6e50a",
21
+ "type": "inject",
22
+ "z": "63287583ae175fca",
23
+ "name": "1. What is your name",
24
+ "props": [],
25
+ "repeat": "",
26
+ "crontab": "",
27
+ "once": false,
28
+ "onceDelay": 0.1,
29
+ "topic": "",
30
+ "x": 220,
31
+ "y": 1880,
32
+ "wires": [
33
+ [
34
+ "2f3c668301d9dd35"
35
+ ]
36
+ ]
37
+ },
38
+ {
39
+ "id": "c2a53eff4506daf9",
40
+ "type": "LLM Chat",
41
+ "z": "63287583ae175fca",
42
+ "name": "",
43
+ "platform": "0144091d53bfe539",
44
+ "tools": "operate_home",
45
+ "tool_choice": "none",
46
+ "conversation_id": "test example",
47
+ "x": 610,
48
+ "y": 1960,
49
+ "wires": [
50
+ [
51
+ "26ee7fb33da44441"
52
+ ]
53
+ ]
54
+ },
55
+ {
56
+ "id": "0d20cfa2bd7a00a0",
57
+ "type": "inject",
58
+ "z": "63287583ae175fca",
59
+ "name": "2. Smart home question",
60
+ "props": [
61
+ {
62
+ "p": "lights",
63
+ "v": "[\"bathroom\", \"kitchen\"]",
64
+ "vt": "json"
65
+ }
66
+ ],
67
+ "repeat": "",
68
+ "crontab": "",
69
+ "once": false,
70
+ "onceDelay": 0.1,
71
+ "topic": "",
72
+ "x": 220,
73
+ "y": 1960,
74
+ "wires": [
75
+ [
76
+ "dd7ca9ae9b5a3e99"
77
+ ]
78
+ ]
79
+ },
80
+ {
81
+ "id": "e80e71a1321731c0",
82
+ "type": "inject",
83
+ "z": "63287583ae175fca",
84
+ "name": "4. Clear Chat History",
85
+ "props": [
86
+ {
87
+ "p": "clearChatHistory",
88
+ "v": "true",
89
+ "vt": "bool"
90
+ }
91
+ ],
92
+ "repeat": "",
93
+ "crontab": "",
94
+ "once": false,
95
+ "onceDelay": 0.1,
96
+ "topic": "",
97
+ "x": 450,
98
+ "y": 2100,
99
+ "wires": [
100
+ [
101
+ "c2a53eff4506daf9"
102
+ ]
103
+ ]
104
+ },
105
+ {
106
+ "id": "2f3c668301d9dd35",
107
+ "type": "template",
108
+ "z": "63287583ae175fca",
109
+ "name": "",
110
+ "field": "payload",
111
+ "fieldType": "msg",
112
+ "format": "json",
113
+ "syntax": "mustache",
114
+ "template": "{\n \"user\": \"What is your name\",\n \"system\": \"your name is ke and you control my smart home\"\n}",
115
+ "output": "json",
116
+ "x": 400,
117
+ "y": 1880,
118
+ "wires": [
119
+ [
120
+ "c2a53eff4506daf9"
121
+ ]
122
+ ]
123
+ },
124
+ {
125
+ "id": "dd7ca9ae9b5a3e99",
126
+ "type": "template",
127
+ "z": "63287583ae175fca",
128
+ "name": "",
129
+ "field": "payload",
130
+ "fieldType": "msg",
131
+ "format": "json",
132
+ "syntax": "mustache",
133
+ "template": "{\n \"user\": \"What lights are on?\",\n \"system\": \"The {{lights}} lights are on in the home\"\n}",
134
+ "output": "json",
135
+ "x": 420,
136
+ "y": 1960,
137
+ "wires": [
138
+ [
139
+ "c2a53eff4506daf9"
140
+ ]
141
+ ]
142
+ },
143
+ {
144
+ "id": "1a95ff1229b2200c",
145
+ "type": "inject",
146
+ "z": "63287583ae175fca",
147
+ "name": "3. Ask last",
148
+ "props": [],
149
+ "repeat": "",
150
+ "crontab": "",
151
+ "once": false,
152
+ "onceDelay": 0.1,
153
+ "topic": "",
154
+ "x": 180,
155
+ "y": 2040,
156
+ "wires": [
157
+ [
158
+ "4996cba3fc79aecf"
159
+ ]
160
+ ]
161
+ },
162
+ {
163
+ "id": "4996cba3fc79aecf",
164
+ "type": "template",
165
+ "z": "63287583ae175fca",
166
+ "name": "",
167
+ "field": "payload",
168
+ "fieldType": "msg",
169
+ "format": "json",
170
+ "syntax": "mustache",
171
+ "template": "{\n \"user\": \"What was the first question i asked?\"\n}",
172
+ "output": "json",
173
+ "x": 420,
174
+ "y": 2040,
175
+ "wires": [
176
+ [
177
+ "c2a53eff4506daf9"
178
+ ]
179
+ ]
180
+ },
181
+ {
182
+ "id": "fb35636977cc1eea",
183
+ "type": "inject",
184
+ "z": "63287583ae175fca",
185
+ "name": "5. Ask last",
186
+ "props": [],
187
+ "repeat": "",
188
+ "crontab": "",
189
+ "once": false,
190
+ "onceDelay": 0.1,
191
+ "topic": "",
192
+ "x": 180,
193
+ "y": 2160,
194
+ "wires": [
195
+ [
196
+ "4996cba3fc79aecf"
197
+ ]
198
+ ]
199
+ },
200
+ {
201
+ "id": "0144091d53bfe539",
202
+ "type": "platform-configuration",
203
+ "name": "GPT 4o Model",
204
+ "platform": "gpt",
205
+ "url": "",
206
+ "model": "gpt-4o"
207
+ }
208
+ ]
@@ -0,0 +1,174 @@
1
+ [
2
+ {
3
+ "id": "05bdf9f147f9ea58",
4
+ "type": "inject",
5
+ "z": "d312f6d5f62126f3",
6
+ "name": "",
7
+ "props": [
8
+ {
9
+ "p": "payload"
10
+ },
11
+ {
12
+ "p": "test",
13
+ "v": "foobar",
14
+ "vt": "str"
15
+ }
16
+ ],
17
+ "repeat": "",
18
+ "crontab": "",
19
+ "once": false,
20
+ "onceDelay": 0.1,
21
+ "topic": "",
22
+ "payload": "",
23
+ "payloadType": "date",
24
+ "x": 240,
25
+ "y": 1160,
26
+ "wires": [
27
+ [
28
+ "937aada85a8bbdf9"
29
+ ]
30
+ ]
31
+ },
32
+ {
33
+ "id": "937aada85a8bbdf9",
34
+ "type": "OpenAI User",
35
+ "z": "d312f6d5f62126f3",
36
+ "name": "",
37
+ "content": "Lock up the house for me.",
38
+ "x": 230,
39
+ "y": 1200,
40
+ "wires": [
41
+ [
42
+ "881af854eea6f26b"
43
+ ]
44
+ ]
45
+ },
46
+ {
47
+ "id": "a55915b38c3e6a75",
48
+ "type": "OpenAI Chat",
49
+ "z": "d312f6d5f62126f3",
50
+ "name": "",
51
+ "token": "",
52
+ "model": "gpt-3.5-turbo",
53
+ "temperature": 0.7,
54
+ "max_tokens": 1200,
55
+ "top_p": 1,
56
+ "frequency_penalty": 0,
57
+ "presence_penalty": 0,
58
+ "x": 230,
59
+ "y": 1280,
60
+ "wires": [
61
+ [
62
+ "8097038c41fd6f2a"
63
+ ]
64
+ ]
65
+ },
66
+ {
67
+ "id": "8097038c41fd6f2a",
68
+ "type": "OpenAI Response",
69
+ "z": "d312f6d5f62126f3",
70
+ "name": "",
71
+ "x": 210,
72
+ "y": 1320,
73
+ "wires": [
74
+ [
75
+ "18324bcf3283205b"
76
+ ]
77
+ ]
78
+ },
79
+ {
80
+ "id": "881af854eea6f26b",
81
+ "type": "OpenAI System",
82
+ "z": "d312f6d5f62126f3",
83
+ "name": "",
84
+ "instruction": "You are a smart home assistant capable of controlling a smart home.\nIf asked a command use the appropriate function to fulfill the request.",
85
+ "x": 220,
86
+ "y": 1240,
87
+ "wires": [
88
+ [
89
+ "a55915b38c3e6a75"
90
+ ]
91
+ ]
92
+ },
93
+ {
94
+ "id": "8c97d656955c94f8",
95
+ "type": "Call Intent",
96
+ "z": "d312f6d5f62126f3",
97
+ "name": "",
98
+ "registeredNodeId": "",
99
+ "x": 540,
100
+ "y": 1320,
101
+ "wires": []
102
+ },
103
+ {
104
+ "id": "18324bcf3283205b",
105
+ "type": "split",
106
+ "z": "d312f6d5f62126f3",
107
+ "name": "",
108
+ "splt": "\\n",
109
+ "spltType": "str",
110
+ "arraySplt": 1,
111
+ "arraySpltType": "len",
112
+ "stream": false,
113
+ "addname": "",
114
+ "x": 390,
115
+ "y": 1320,
116
+ "wires": [
117
+ [
118
+ "8c97d656955c94f8"
119
+ ]
120
+ ]
121
+ },
122
+ {
123
+ "id": "a63ae38cd3768628",
124
+ "type": "debug",
125
+ "z": "d312f6d5f62126f3",
126
+ "name": "debug 45",
127
+ "active": true,
128
+ "tosidebar": true,
129
+ "console": false,
130
+ "tostatus": false,
131
+ "complete": "true",
132
+ "targetType": "full",
133
+ "statusVal": "",
134
+ "statusType": "auto",
135
+ "x": 720,
136
+ "y": 1220,
137
+ "wires": []
138
+ },
139
+ {
140
+ "id": "441f8a05100623f4",
141
+ "type": "Register Intent",
142
+ "z": "d312f6d5f62126f3",
143
+ "name": "armHome",
144
+ "description": "Turn on the alarm for the house",
145
+ "excludeFromOpenAi": false,
146
+ "x": 500,
147
+ "y": 1220,
148
+ "wires": [
149
+ [
150
+ "a63ae38cd3768628"
151
+ ]
152
+ ]
153
+ },
154
+ {
155
+ "id": "a79bdb00f60eb779",
156
+ "type": "comment",
157
+ "z": "d312f6d5f62126f3",
158
+ "name": "Example: Combining Call Intent with Register Intent node",
159
+ "info": "You can add `Call Intent` node to the \nresponse from OpenAI. If OpenAI responds\nusing function call, then the response will\ndynamically call the correct registered node",
160
+ "x": 310,
161
+ "y": 1120,
162
+ "wires": []
163
+ },
164
+ {
165
+ "id": "50803a6c3a41949e",
166
+ "type": "comment",
167
+ "z": "d312f6d5f62126f3",
168
+ "name": "Register Intent nodes automatically are added to OpenAI and can be called",
169
+ "info": "",
170
+ "x": 700,
171
+ "y": 1180,
172
+ "wires": []
173
+ }
174
+ ]