ultravisor 1.0.3 → 1.0.8

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 (248) hide show
  1. package/.claude/launch.json +11 -0
  2. package/.claude/ultravisor-dev-config.json +3 -0
  3. package/card-audit.json +1545 -0
  4. package/docs/_sidebar.md +17 -0
  5. package/docs/css/docuserve.css +73 -0
  6. package/docs/features/beacon-authentication.md +209 -0
  7. package/docs/features/beacon-providers.md +1299 -0
  8. package/docs/features/beacons.md +530 -0
  9. package/docs/features/capabilities.md +193 -0
  10. package/docs/features/llm-model-setup.md +505 -0
  11. package/docs/features/llm.md +262 -0
  12. package/docs/features/tasks-content-system.md +110 -0
  13. package/docs/features/tasks-data-transform.md +233 -0
  14. package/docs/features/tasks-extension.md +36 -0
  15. package/docs/features/tasks-file-system.md +203 -0
  16. package/docs/features/tasks-flow-control.md +125 -0
  17. package/docs/features/tasks-http-client.md +119 -0
  18. package/docs/features/tasks-llm.md +118 -0
  19. package/docs/features/tasks-meadow-api.md +163 -0
  20. package/docs/features/tasks-user-interaction.md +49 -0
  21. package/docs/features/tasks.md +14 -0
  22. package/docs/index.html +1 -1
  23. package/docs/retold-catalog.json +1 -1
  24. package/docs/retold-keyword-index.json +17374 -5
  25. package/operation-library/api-data-pipeline.json +143 -0
  26. package/operation-library/beacon-remote-command.json +72 -0
  27. package/operation-library/conditional-file-backup.json +143 -0
  28. package/operation-library/config-processor.json +136 -0
  29. package/operation-library/csv-data-analysis.json +228 -0
  30. package/operation-library/csv-to-json.json +160 -0
  31. package/operation-library/directory-inventory.json +128 -0
  32. package/operation-library/expression-calculator.json +114 -0
  33. package/operation-library/file-search-replace.json +175 -0
  34. package/operation-library/git-status-report.json +368 -0
  35. package/operation-library/health-check-ping.json +329 -0
  36. package/operation-library/json-config-merge.json +313 -0
  37. package/operation-library/llm-embedding-tool-use.json +314 -0
  38. package/operation-library/llm-multi-turn-analysis.json +322 -0
  39. package/operation-library/llm-summarize.json +264 -0
  40. package/operation-library/log-line-counter.json +185 -0
  41. package/operation-library/meadow-crud-lifecycle.json +264 -0
  42. package/operation-library/npm-project-validator.json +193 -0
  43. package/operation-library/rest-api-orchestrator.json +218 -0
  44. package/operation-library/shell-system-info.json +137 -0
  45. package/operation-library/simple-echo.json +95 -0
  46. package/operation-library/template-processor.json +299 -0
  47. package/operation-library/text-sanitizer.json +176 -0
  48. package/package.json +12 -8
  49. package/source/Ultravisor.cjs +30 -3
  50. package/source/beacon/Ultravisor-Beacon-CLI.cjs +143 -0
  51. package/source/beacon/Ultravisor-Beacon-CapabilityProvider.cjs +129 -0
  52. package/source/beacon/Ultravisor-Beacon-Client.cjs +568 -0
  53. package/source/beacon/Ultravisor-Beacon-Executor.cjs +500 -0
  54. package/source/beacon/Ultravisor-Beacon-ProviderRegistry.cjs +330 -0
  55. package/source/beacon/providers/Ultravisor-Beacon-Provider-FileSystem.cjs +331 -0
  56. package/source/beacon/providers/Ultravisor-Beacon-Provider-LLM.cjs +966 -0
  57. package/source/beacon/providers/Ultravisor-Beacon-Provider-Shell.cjs +95 -0
  58. package/source/cli/Ultravisor-CLIProgram.cjs +44 -22
  59. package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
  60. package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
  61. package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
  62. package/source/config/Ultravisor-Default-Command-Configuration.cjs +12 -3
  63. package/source/services/Ultravisor-Beacon-Coordinator.cjs +966 -0
  64. package/source/services/Ultravisor-ExecutionEngine.cjs +1093 -0
  65. package/source/services/Ultravisor-ExecutionManifest.cjs +629 -0
  66. package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
  67. package/source/services/Ultravisor-Hypervisor.cjs +185 -75
  68. package/source/services/Ultravisor-Schedule-Persistence-Base.cjs +45 -0
  69. package/source/services/Ultravisor-StateManager.cjs +253 -0
  70. package/source/services/Ultravisor-TaskTypeRegistry.cjs +213 -0
  71. package/source/services/persistence/Ultravisor-Schedule-Persistence-JSONFile.cjs +140 -0
  72. package/source/services/tasks/Ultravisor-BuiltIn-TaskConfigs.cjs +19 -0
  73. package/source/services/tasks/Ultravisor-TaskHelper-BeaconDispatch.cjs +107 -0
  74. package/source/services/tasks/Ultravisor-TaskType-Base.cjs +125 -0
  75. package/source/services/tasks/content-system/Ultravisor-TaskConfigs-ContentSystem.cjs +90 -0
  76. package/source/services/tasks/content-system/definitions/content-create-folder.json +24 -0
  77. package/source/services/tasks/content-system/definitions/content-list-files.json +27 -0
  78. package/source/services/tasks/content-system/definitions/content-read-file.json +26 -0
  79. package/source/services/tasks/content-system/definitions/content-save-file.json +26 -0
  80. package/source/services/tasks/data-transform/Ultravisor-TaskConfigs-DataTransform.cjs +577 -0
  81. package/source/services/tasks/data-transform/Ultravisor-TaskType-ReplaceString.cjs +80 -0
  82. package/source/services/tasks/data-transform/Ultravisor-TaskType-SetValues.cjs +74 -0
  83. package/source/services/tasks/data-transform/Ultravisor-TaskType-StringAppender.cjs +90 -0
  84. package/source/services/tasks/data-transform/definitions/comprehension-intersect.json +24 -0
  85. package/source/services/tasks/data-transform/definitions/csv-transform.json +24 -0
  86. package/source/services/tasks/data-transform/definitions/expression-solver.json +20 -0
  87. package/source/services/tasks/data-transform/definitions/histogram.json +23 -0
  88. package/source/services/tasks/data-transform/definitions/parse-csv.json +27 -0
  89. package/source/services/tasks/data-transform/definitions/replace-string.json +27 -0
  90. package/source/services/tasks/data-transform/definitions/set-values.json +17 -0
  91. package/source/services/tasks/data-transform/definitions/string-appender.json +22 -0
  92. package/source/services/tasks/data-transform/definitions/template-string.json +20 -0
  93. package/source/services/tasks/extension/Ultravisor-TaskConfigs-Extension.cjs +87 -0
  94. package/source/services/tasks/extension/definitions/beacon-dispatch.json +32 -0
  95. package/source/services/tasks/file-system/Ultravisor-TaskConfigs-FileSystem.cjs +509 -0
  96. package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFile.cjs +96 -0
  97. package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFileBuffered.cjs +123 -0
  98. package/source/services/tasks/file-system/Ultravisor-TaskType-WriteFile.cjs +106 -0
  99. package/source/services/tasks/file-system/definitions/copy-file.json +27 -0
  100. package/source/services/tasks/file-system/definitions/list-files.json +27 -0
  101. package/source/services/tasks/file-system/definitions/read-file-buffered.json +31 -0
  102. package/source/services/tasks/file-system/definitions/read-file.json +26 -0
  103. package/source/services/tasks/file-system/definitions/read-json.json +23 -0
  104. package/source/services/tasks/file-system/definitions/write-file.json +29 -0
  105. package/source/services/tasks/file-system/definitions/write-json.json +30 -0
  106. package/source/services/tasks/flow-control/Ultravisor-TaskConfigs-FlowControl.cjs +353 -0
  107. package/source/services/tasks/flow-control/Ultravisor-TaskType-IfConditional.cjs +125 -0
  108. package/source/services/tasks/flow-control/Ultravisor-TaskType-LaunchOperation.cjs +186 -0
  109. package/source/services/tasks/flow-control/Ultravisor-TaskType-SplitExecute.cjs +164 -0
  110. package/source/services/tasks/flow-control/definitions/if-conditional.json +25 -0
  111. package/source/services/tasks/flow-control/definitions/launch-operation.json +27 -0
  112. package/source/services/tasks/flow-control/definitions/split-execute.json +32 -0
  113. package/source/services/tasks/http-client/Ultravisor-TaskConfigs-HttpClient.cjs +281 -0
  114. package/source/services/tasks/http-client/definitions/get-json.json +26 -0
  115. package/source/services/tasks/http-client/definitions/get-text.json +26 -0
  116. package/source/services/tasks/http-client/definitions/rest-request.json +32 -0
  117. package/source/services/tasks/http-client/definitions/send-json.json +28 -0
  118. package/source/services/tasks/llm/Ultravisor-TaskConfigs-LLM.cjs +605 -0
  119. package/source/services/tasks/llm/definitions/llm-chat-completion.json +46 -0
  120. package/source/services/tasks/llm/definitions/llm-embedding.json +31 -0
  121. package/source/services/tasks/llm/definitions/llm-tool-use.json +42 -0
  122. package/source/services/tasks/meadow-api/Ultravisor-TaskConfigs-MeadowApi.cjs +341 -0
  123. package/source/services/tasks/meadow-api/definitions/meadow-count.json +26 -0
  124. package/source/services/tasks/meadow-api/definitions/meadow-create.json +26 -0
  125. package/source/services/tasks/meadow-api/definitions/meadow-delete.json +23 -0
  126. package/source/services/tasks/meadow-api/definitions/meadow-read.json +26 -0
  127. package/source/services/tasks/meadow-api/definitions/meadow-reads.json +29 -0
  128. package/source/services/tasks/meadow-api/definitions/meadow-update.json +26 -0
  129. package/source/services/tasks/shell/Ultravisor-TaskConfigs-Shell.cjs +63 -0
  130. package/source/services/tasks/shell/definitions/command.json +29 -0
  131. package/source/services/tasks/user-interaction/Ultravisor-TaskConfigs-UserInteraction.cjs +64 -0
  132. package/source/services/tasks/user-interaction/Ultravisor-TaskType-ErrorMessage.cjs +55 -0
  133. package/source/services/tasks/user-interaction/Ultravisor-TaskType-ValueInput.cjs +47 -0
  134. package/source/services/tasks/user-interaction/definitions/error-message.json +18 -0
  135. package/source/services/tasks/user-interaction/definitions/value-input.json +23 -0
  136. package/source/web_server/Ultravisor-API-Server.cjs +849 -124
  137. package/test/Ultravisor_browser_tests.js +2226 -0
  138. package/test/Ultravisor_operation_library_tests.js +894 -0
  139. package/test/Ultravisor_tests.js +4946 -5044
  140. package/test/workflows/test-content-concatenate-all.json +339 -0
  141. package/test/workflows/test-content-full-pipeline.json +159 -0
  142. package/test/workflows/test-content-list-files.json +76 -0
  143. package/test/workflows/test-content-save-and-read.json +106 -0
  144. package/webinterface/css/ultravisor-themes.css +668 -0
  145. package/webinterface/css/ultravisor.css +37 -14
  146. package/webinterface/docs/card-help/beacon-dispatch.md +30 -0
  147. package/webinterface/docs/card-help/command.md +27 -0
  148. package/webinterface/docs/card-help/comprehension-intersect.md +24 -0
  149. package/webinterface/docs/card-help/content-create-folder.md +22 -0
  150. package/webinterface/docs/card-help/content-list-files.md +25 -0
  151. package/webinterface/docs/card-help/content-read-file.md +24 -0
  152. package/webinterface/docs/card-help/content-save-file.md +24 -0
  153. package/webinterface/docs/card-help/copy-file.md +25 -0
  154. package/webinterface/docs/card-help/csv-transform.md +24 -0
  155. package/webinterface/docs/card-help/end.md +11 -0
  156. package/webinterface/docs/card-help/error-message.md +16 -0
  157. package/webinterface/docs/card-help/expression-solver.md +21 -0
  158. package/webinterface/docs/card-help/get-json.md +24 -0
  159. package/webinterface/docs/card-help/get-text.md +24 -0
  160. package/webinterface/docs/card-help/histogram.md +23 -0
  161. package/webinterface/docs/card-help/if-conditional.md +23 -0
  162. package/webinterface/docs/card-help/launch-operation.md +25 -0
  163. package/webinterface/docs/card-help/list-files.md +25 -0
  164. package/webinterface/docs/card-help/llm-chat-completion.md +43 -0
  165. package/webinterface/docs/card-help/llm-embedding.md +24 -0
  166. package/webinterface/docs/card-help/llm-tool-use.md +39 -0
  167. package/webinterface/docs/card-help/meadow-count.md +24 -0
  168. package/webinterface/docs/card-help/meadow-create.md +24 -0
  169. package/webinterface/docs/card-help/meadow-delete.md +19 -0
  170. package/webinterface/docs/card-help/meadow-read.md +24 -0
  171. package/webinterface/docs/card-help/meadow-reads.md +27 -0
  172. package/webinterface/docs/card-help/meadow-update.md +24 -0
  173. package/webinterface/docs/card-help/parse-csv.md +27 -0
  174. package/webinterface/docs/card-help/read-file-buffered.md +29 -0
  175. package/webinterface/docs/card-help/read-file.md +24 -0
  176. package/webinterface/docs/card-help/read-json.md +21 -0
  177. package/webinterface/docs/card-help/replace-string.md +25 -0
  178. package/webinterface/docs/card-help/rest-request.md +30 -0
  179. package/webinterface/docs/card-help/send-json.md +26 -0
  180. package/webinterface/docs/card-help/set-values.md +16 -0
  181. package/webinterface/docs/card-help/split-execute.md +35 -0
  182. package/webinterface/docs/card-help/start.md +11 -0
  183. package/webinterface/docs/card-help/string-appender.md +22 -0
  184. package/webinterface/docs/card-help/template-string.md +21 -0
  185. package/webinterface/docs/card-help/value-input.md +24 -0
  186. package/webinterface/docs/card-help/write-file.md +27 -0
  187. package/webinterface/docs/card-help/write-json.md +28 -0
  188. package/webinterface/html/index.html +5 -0
  189. package/webinterface/package.json +13 -4
  190. package/webinterface/source/Pict-Application-Ultravisor.js +564 -70
  191. package/webinterface/source/Ultravisor-TimingUtils.js +99 -0
  192. package/webinterface/source/card-help-content.js +46 -0
  193. package/webinterface/source/cards/Ultravisor-BuiltIn-CardConfigs.js +174 -0
  194. package/webinterface/source/cards/Ultravisor-CardConfigGenerator.js +431 -0
  195. package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
  196. package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
  197. package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
  198. package/webinterface/source/panels/Ultravisor-CardSettingsPanel.js +902 -0
  199. package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +20 -8
  200. package/webinterface/source/views/PictView-Ultravisor-BeaconList.js +817 -0
  201. package/webinterface/source/views/PictView-Ultravisor-BottomBar.js +5 -5
  202. package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +25 -25
  203. package/webinterface/source/views/PictView-Ultravisor-Documentation.js +856 -0
  204. package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +777 -0
  205. package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +321 -58
  206. package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +36 -91
  207. package/webinterface/source/views/PictView-Ultravisor-OperationList.js +388 -16
  208. package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
  209. package/webinterface/source/views/PictView-Ultravisor-Schedule.js +521 -65
  210. package/webinterface/source/views/PictView-Ultravisor-TimingView.js +333 -71
  211. package/webinterface/source/views/PictView-Ultravisor-TopBar.js +257 -21
  212. package/webinterface/theme-sampler.html +645 -0
  213. package/debug/Harness.js +0 -6
  214. package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
  215. package/source/services/Ultravisor-Operation.cjs +0 -200
  216. package/source/services/Ultravisor-Task.cjs +0 -349
  217. package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
  218. package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
  219. package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
  220. package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
  221. package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
  222. package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
  223. package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
  224. package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
  225. package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
  226. package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
  227. package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
  228. package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
  229. package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
  230. package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
  231. package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
  232. package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
  233. package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
  234. package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
  235. package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
  236. package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
  237. package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
  238. package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
  239. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
  240. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
  241. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
  242. package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
  243. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
  244. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
  245. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
  246. package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
  247. package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
  248. package/webinterface/source/views/PictView-Ultravisor-TaskList.js +0 -248
@@ -0,0 +1,605 @@
1
+ /**
2
+ * Task configurations for the "LLM" capability.
3
+ *
4
+ * Contains:
5
+ * - llm-chat-completion — Send messages to an LLM with conversation management.
6
+ * - llm-embedding — Generate embeddings for text.
7
+ * - llm-tool-use — Chat completion with tool/function definitions.
8
+ *
9
+ * All three tasks dispatch work to a remote Beacon with LLM capability
10
+ * using the WaitingForInput/resume pattern from beacon-dispatch.
11
+ */
12
+
13
+
14
+ /**
15
+ * Get a named service from the Fable services map.
16
+ */
17
+ function _getService(pTask, pTypeName)
18
+ {
19
+ return pTask.fable.servicesMap[pTypeName]
20
+ ? Object.values(pTask.fable.servicesMap[pTypeName])[0]
21
+ : null;
22
+ }
23
+
24
+ /**
25
+ * Build the Messages array for the LLM from resolved settings,
26
+ * incorporating conversation history if configured.
27
+ *
28
+ * @param {object} pResolvedSettings - The resolved task settings.
29
+ * @param {object} pExecutionContext - The runtime execution context.
30
+ * @param {object} pStateManager - The Ultravisor StateManager service.
31
+ * @param {string} pCurrentNodeHash - Current node hash for state resolution.
32
+ * @returns {Array} The messages array to send to the LLM.
33
+ */
34
+ function _buildMessages(pResolvedSettings, pExecutionContext, pStateManager, pCurrentNodeHash)
35
+ {
36
+ let tmpMessages = [];
37
+
38
+ // 1. Load conversation history if ConversationAddress is set
39
+ let tmpConversationAddress = pResolvedSettings.ConversationAddress || '';
40
+
41
+ if (tmpConversationAddress)
42
+ {
43
+ let tmpHistory = pStateManager.resolveAddress(tmpConversationAddress, pExecutionContext, pCurrentNodeHash);
44
+
45
+ if (Array.isArray(tmpHistory))
46
+ {
47
+ tmpMessages = tmpHistory.slice();
48
+ }
49
+ }
50
+
51
+ // 2. If Messages JSON is provided, use it (overrides history for direct control)
52
+ if (pResolvedSettings.Messages)
53
+ {
54
+ let tmpParsed = _safeParseJSON(pResolvedSettings.Messages, null);
55
+
56
+ if (Array.isArray(tmpParsed))
57
+ {
58
+ // If we have conversation history, append these messages to it
59
+ if (tmpMessages.length > 0)
60
+ {
61
+ tmpMessages = tmpMessages.concat(tmpParsed);
62
+ }
63
+ else
64
+ {
65
+ tmpMessages = tmpParsed;
66
+ }
67
+ }
68
+ }
69
+
70
+ // 3. SystemPrompt convenience — prepend if not already present
71
+ if (pResolvedSettings.SystemPrompt)
72
+ {
73
+ let tmpHasSystem = tmpMessages.some(function (pMsg) { return pMsg.role === 'system'; });
74
+
75
+ if (!tmpHasSystem)
76
+ {
77
+ tmpMessages.unshift({ role: 'system', content: pResolvedSettings.SystemPrompt });
78
+ }
79
+ }
80
+
81
+ // 4. UserPrompt convenience — append as user message
82
+ if (pResolvedSettings.UserPrompt)
83
+ {
84
+ let tmpUserContent = pResolvedSettings.UserPrompt;
85
+
86
+ // If InputAddress is set, read context data and inject it
87
+ if (pResolvedSettings.InputAddress)
88
+ {
89
+ let tmpInputData = pStateManager.resolveAddress(
90
+ pResolvedSettings.InputAddress, pExecutionContext, pCurrentNodeHash);
91
+
92
+ if (tmpInputData !== undefined)
93
+ {
94
+ let tmpInputStr = (typeof tmpInputData === 'string')
95
+ ? tmpInputData
96
+ : JSON.stringify(tmpInputData);
97
+ tmpUserContent = tmpUserContent + '\n\n' + tmpInputStr;
98
+ }
99
+ }
100
+
101
+ tmpMessages.push({ role: 'user', content: tmpUserContent });
102
+ }
103
+ else if (pResolvedSettings.InputAddress && !pResolvedSettings.Messages)
104
+ {
105
+ // InputAddress without UserPrompt — send input data as the user message
106
+ let tmpInputData = pStateManager.resolveAddress(
107
+ pResolvedSettings.InputAddress, pExecutionContext, pCurrentNodeHash);
108
+
109
+ if (tmpInputData !== undefined)
110
+ {
111
+ let tmpInputStr = (typeof tmpInputData === 'string')
112
+ ? tmpInputData
113
+ : JSON.stringify(tmpInputData);
114
+ tmpMessages.push({ role: 'user', content: tmpInputStr });
115
+ }
116
+ }
117
+
118
+ // 5. Apply conversation limits
119
+ tmpMessages = _applyConversationLimits(tmpMessages, pResolvedSettings);
120
+
121
+ return tmpMessages;
122
+ }
123
+
124
+ /**
125
+ * Apply conversation history limits (max messages, max tokens).
126
+ * Preserves system messages and trims from the oldest non-system messages.
127
+ */
128
+ function _applyConversationLimits(pMessages, pSettings)
129
+ {
130
+ let tmpMaxMessages = parseInt(pSettings.ConversationMaxMessages, 10);
131
+ let tmpMaxTokens = parseInt(pSettings.ConversationMaxTokens, 10);
132
+
133
+ if (!tmpMaxMessages && !tmpMaxTokens)
134
+ {
135
+ return pMessages;
136
+ }
137
+
138
+ // Separate system messages from the rest
139
+ let tmpSystemMessages = [];
140
+ let tmpOtherMessages = [];
141
+
142
+ for (let i = 0; i < pMessages.length; i++)
143
+ {
144
+ if (pMessages[i].role === 'system')
145
+ {
146
+ tmpSystemMessages.push(pMessages[i]);
147
+ }
148
+ else
149
+ {
150
+ tmpOtherMessages.push(pMessages[i]);
151
+ }
152
+ }
153
+
154
+ // Apply max messages limit (trim oldest first)
155
+ if (tmpMaxMessages > 0 && tmpOtherMessages.length > tmpMaxMessages)
156
+ {
157
+ tmpOtherMessages = tmpOtherMessages.slice(tmpOtherMessages.length - tmpMaxMessages);
158
+ }
159
+
160
+ // Apply rough token limit (estimate ~4 chars per token)
161
+ if (tmpMaxTokens > 0)
162
+ {
163
+ let tmpCharBudget = tmpMaxTokens * 4;
164
+ let tmpTotalChars = 0;
165
+
166
+ // Count backwards from newest, keep messages that fit
167
+ let tmpKeptMessages = [];
168
+
169
+ for (let i = tmpOtherMessages.length - 1; i >= 0; i--)
170
+ {
171
+ let tmpContentLength = (tmpOtherMessages[i].content || '').length;
172
+ tmpTotalChars += tmpContentLength;
173
+
174
+ if (tmpTotalChars > tmpCharBudget)
175
+ {
176
+ break;
177
+ }
178
+
179
+ tmpKeptMessages.unshift(tmpOtherMessages[i]);
180
+ }
181
+
182
+ tmpOtherMessages = tmpKeptMessages;
183
+ }
184
+
185
+ return tmpSystemMessages.concat(tmpOtherMessages);
186
+ }
187
+
188
+ /**
189
+ * After receiving a response, update conversation history in state.
190
+ */
191
+ function _updateConversationHistory(pResolvedSettings, pExecutionContext, pStateManager, pCurrentNodeHash, pUserMessages, pAssistantContent)
192
+ {
193
+ let tmpConversationAddress = pResolvedSettings.ConversationAddress || '';
194
+
195
+ if (!tmpConversationAddress)
196
+ {
197
+ return;
198
+ }
199
+
200
+ let tmpAppend = pResolvedSettings.AppendToConversation;
201
+
202
+ // Default to true if ConversationAddress is set
203
+ if (tmpAppend === undefined || tmpAppend === '')
204
+ {
205
+ tmpAppend = true;
206
+ }
207
+ else
208
+ {
209
+ tmpAppend = (tmpAppend === true || tmpAppend === 'true');
210
+ }
211
+
212
+ if (!tmpAppend)
213
+ {
214
+ return;
215
+ }
216
+
217
+ // Get current history (may have been modified by _buildMessages limits)
218
+ let tmpHistory = pStateManager.resolveAddress(tmpConversationAddress, pExecutionContext, pCurrentNodeHash);
219
+
220
+ if (!Array.isArray(tmpHistory))
221
+ {
222
+ tmpHistory = [];
223
+ }
224
+
225
+ // Find user messages that were added in this turn (after existing history)
226
+ // We reconstruct by adding the UserPrompt and assistant response
227
+ if (pResolvedSettings.UserPrompt || pResolvedSettings.InputAddress)
228
+ {
229
+ let tmpUserContent = pResolvedSettings.UserPrompt || '';
230
+
231
+ if (pResolvedSettings.InputAddress)
232
+ {
233
+ let tmpInputData = pStateManager.resolveAddress(
234
+ pResolvedSettings.InputAddress, pExecutionContext, pCurrentNodeHash);
235
+ if (tmpInputData !== undefined)
236
+ {
237
+ let tmpInputStr = (typeof tmpInputData === 'string')
238
+ ? tmpInputData
239
+ : JSON.stringify(tmpInputData);
240
+ tmpUserContent = tmpUserContent
241
+ ? (tmpUserContent + '\n\n' + tmpInputStr)
242
+ : tmpInputStr;
243
+ }
244
+ }
245
+
246
+ if (tmpUserContent)
247
+ {
248
+ tmpHistory.push({ role: 'user', content: tmpUserContent });
249
+ }
250
+ }
251
+
252
+ // Add the assistant response
253
+ if (pAssistantContent)
254
+ {
255
+ tmpHistory.push({ role: 'assistant', content: pAssistantContent });
256
+ }
257
+
258
+ // Ensure system prompt is in history if not already
259
+ if (pResolvedSettings.SystemPrompt)
260
+ {
261
+ let tmpHasSystem = tmpHistory.some(function (pMsg) { return pMsg.role === 'system'; });
262
+ if (!tmpHasSystem)
263
+ {
264
+ tmpHistory.unshift({ role: 'system', content: pResolvedSettings.SystemPrompt });
265
+ }
266
+ }
267
+
268
+ // Write updated history back to state
269
+ pStateManager.setAddress(tmpConversationAddress, tmpHistory, pExecutionContext, pCurrentNodeHash);
270
+
271
+ // Persist to GlobalState if configured
272
+ if (pResolvedSettings.PersistConversation === true || pResolvedSettings.PersistConversation === 'true')
273
+ {
274
+ let tmpPersistAddress = pResolvedSettings.ConversationPersistAddress || '';
275
+
276
+ if (tmpPersistAddress)
277
+ {
278
+ pStateManager.setAddress(tmpPersistAddress, tmpHistory, pExecutionContext, pCurrentNodeHash);
279
+ }
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Safely parse JSON, returning fallback on failure.
285
+ */
286
+ function _safeParseJSON(pString, pFallback)
287
+ {
288
+ if (!pString || typeof pString !== 'string')
289
+ {
290
+ return pFallback;
291
+ }
292
+
293
+ try
294
+ {
295
+ return JSON.parse(pString);
296
+ }
297
+ catch (pError)
298
+ {
299
+ return pFallback;
300
+ }
301
+ }
302
+
303
+
304
+ module.exports =
305
+ [
306
+ // ── llm-chat-completion ───────────────────────────────────
307
+ {
308
+ Definition: require('./definitions/llm-chat-completion.json'),
309
+ Execute: function (pTask, pResolvedSettings, pExecutionContext, fCallback)
310
+ {
311
+ let tmpCoordinator = _getService(pTask, 'UltravisorBeaconCoordinator');
312
+
313
+ if (!tmpCoordinator)
314
+ {
315
+ return fCallback(null, {
316
+ EventToFire: 'Error',
317
+ Outputs: { Content: 'BeaconCoordinator service not available.', Model: '', PromptTokens: 0, CompletionTokens: 0, FinishReason: 'error', BeaconID: '' },
318
+ Log: ['LLM Chat Completion: BeaconCoordinator service not found.']
319
+ });
320
+ }
321
+
322
+ let tmpBeacons = tmpCoordinator.listBeacons();
323
+
324
+ if (tmpBeacons.length === 0)
325
+ {
326
+ return fCallback(null, {
327
+ EventToFire: 'Error',
328
+ Outputs: { Content: 'No Beacon workers are registered.', Model: '', PromptTokens: 0, CompletionTokens: 0, FinishReason: 'error', BeaconID: '' },
329
+ Log: ['LLM Chat Completion: no Beacon workers registered.']
330
+ });
331
+ }
332
+
333
+ let tmpStateManager = _getService(pTask, 'UltravisorStateManager');
334
+
335
+ // Build messages with conversation history
336
+ let tmpMessages = tmpStateManager
337
+ ? _buildMessages(pResolvedSettings, pExecutionContext, tmpStateManager, pExecutionContext.NodeHash)
338
+ : _safeParseJSON(pResolvedSettings.Messages, []);
339
+
340
+ if (!tmpMessages || tmpMessages.length === 0)
341
+ {
342
+ return fCallback(null, {
343
+ EventToFire: 'Error',
344
+ Outputs: { Content: 'No messages to send.', Model: '', PromptTokens: 0, CompletionTokens: 0, FinishReason: 'error', BeaconID: '' },
345
+ Log: ['LLM Chat Completion: no messages assembled. Provide UserPrompt, Messages, or ConversationAddress with existing history.']
346
+ });
347
+ }
348
+
349
+ // Build work item for the Beacon
350
+ let tmpWorkItemInfo = {
351
+ RunHash: pExecutionContext.RunHash,
352
+ NodeHash: pExecutionContext.NodeHash,
353
+ OperationHash: pExecutionContext.OperationHash,
354
+ Capability: 'LLM',
355
+ Action: 'ChatCompletion',
356
+ Settings: {
357
+ Messages: JSON.stringify(tmpMessages),
358
+ SystemPrompt: '', // Already incorporated into messages
359
+ Model: pResolvedSettings.Model || '',
360
+ Temperature: pResolvedSettings.Temperature,
361
+ MaxTokens: pResolvedSettings.MaxTokens,
362
+ TopP: pResolvedSettings.TopP,
363
+ StopSequences: pResolvedSettings.StopSequences || '',
364
+ ResponseFormat: pResolvedSettings.ResponseFormat || ''
365
+ },
366
+ AffinityKey: pResolvedSettings.AffinityKey || '',
367
+ TimeoutMs: pResolvedSettings.TimeoutMs || 120000
368
+ };
369
+
370
+ let tmpWorkItem = tmpCoordinator.enqueueWorkItem(tmpWorkItemInfo);
371
+
372
+ pTask.log.info(`LLM Chat Completion: enqueued work item [${tmpWorkItem.WorkItemHash}] with ${tmpMessages.length} messages` +
373
+ (pResolvedSettings.AffinityKey ? ` (affinity: ${pResolvedSettings.AffinityKey})` : ''));
374
+
375
+ // Store settings context for post-completion processing
376
+ // The execution engine will call this task's onResume handler
377
+ pExecutionContext._LLMChatSettings = pExecutionContext._LLMChatSettings || {};
378
+ pExecutionContext._LLMChatSettings[pExecutionContext.NodeHash] = {
379
+ ResolvedSettings: pResolvedSettings,
380
+ MessagesBeforeResponse: tmpMessages
381
+ };
382
+
383
+ return fCallback(null, {
384
+ WaitingForInput: true,
385
+ ResumeEventName: 'Complete',
386
+ PromptMessage: `Waiting for LLM response (${tmpMessages.length} messages)`,
387
+ OutputAddress: '',
388
+ Outputs: {},
389
+ Log: [
390
+ `LLM Chat Completion: dispatched to work queue as [${tmpWorkItem.WorkItemHash}].`,
391
+ `Messages: ${tmpMessages.length}, Model: ${pResolvedSettings.Model || '(default)'}`,
392
+ pResolvedSettings.ConversationAddress ? `Conversation: ${pResolvedSettings.ConversationAddress}` : ''
393
+ ].filter(Boolean),
394
+ // Post-completion handler: update conversation history and write to destination
395
+ OnResumeWithOutputs: function (pOutputs)
396
+ {
397
+ if (tmpStateManager && pResolvedSettings.ConversationAddress)
398
+ {
399
+ _updateConversationHistory(
400
+ pResolvedSettings, pExecutionContext, tmpStateManager,
401
+ pExecutionContext.NodeHash, tmpMessages,
402
+ (pOutputs && pOutputs.Content) ? pOutputs.Content : '');
403
+ }
404
+
405
+ // Write to destination if configured
406
+ if (tmpStateManager && pResolvedSettings.Destination && pOutputs && pOutputs.Content)
407
+ {
408
+ tmpStateManager.setAddress(
409
+ pResolvedSettings.Destination, pOutputs.Content,
410
+ pExecutionContext, pExecutionContext.NodeHash);
411
+ }
412
+ }
413
+ });
414
+ }
415
+ },
416
+
417
+ // ── llm-embedding ─────────────────────────────────────────
418
+ {
419
+ Definition: require('./definitions/llm-embedding.json'),
420
+ Execute: function (pTask, pResolvedSettings, pExecutionContext, fCallback)
421
+ {
422
+ let tmpCoordinator = _getService(pTask, 'UltravisorBeaconCoordinator');
423
+
424
+ if (!tmpCoordinator)
425
+ {
426
+ return fCallback(null, {
427
+ EventToFire: 'Error',
428
+ Outputs: { Embedding: '[]', Dimensions: 0, Model: '', BeaconID: '' },
429
+ Log: ['LLM Embedding: BeaconCoordinator service not found.']
430
+ });
431
+ }
432
+
433
+ let tmpBeacons = tmpCoordinator.listBeacons();
434
+
435
+ if (tmpBeacons.length === 0)
436
+ {
437
+ return fCallback(null, {
438
+ EventToFire: 'Error',
439
+ Outputs: { Embedding: '[]', Dimensions: 0, Model: '', BeaconID: '' },
440
+ Log: ['LLM Embedding: no Beacon workers registered.']
441
+ });
442
+ }
443
+
444
+ // Resolve text from InputAddress or direct Text setting
445
+ let tmpText = pResolvedSettings.Text || '';
446
+ let tmpStateManager = _getService(pTask, 'UltravisorStateManager');
447
+
448
+ if (!tmpText && pResolvedSettings.InputAddress && tmpStateManager)
449
+ {
450
+ let tmpInputData = tmpStateManager.resolveAddress(
451
+ pResolvedSettings.InputAddress, pExecutionContext, pExecutionContext.NodeHash);
452
+
453
+ if (tmpInputData !== undefined)
454
+ {
455
+ tmpText = (typeof tmpInputData === 'string')
456
+ ? tmpInputData
457
+ : JSON.stringify(tmpInputData);
458
+ }
459
+ }
460
+
461
+ if (!tmpText)
462
+ {
463
+ return fCallback(null, {
464
+ EventToFire: 'Error',
465
+ Outputs: { Embedding: '[]', Dimensions: 0, Model: '', BeaconID: '' },
466
+ Log: ['LLM Embedding: no text provided. Set Text or InputAddress.']
467
+ });
468
+ }
469
+
470
+ let tmpWorkItemInfo = {
471
+ RunHash: pExecutionContext.RunHash,
472
+ NodeHash: pExecutionContext.NodeHash,
473
+ OperationHash: pExecutionContext.OperationHash,
474
+ Capability: 'LLM',
475
+ Action: 'Embedding',
476
+ Settings: {
477
+ Text: tmpText,
478
+ Model: pResolvedSettings.Model || '',
479
+ Dimensions: pResolvedSettings.Dimensions || 0
480
+ },
481
+ AffinityKey: pResolvedSettings.AffinityKey || '',
482
+ TimeoutMs: pResolvedSettings.TimeoutMs || 60000
483
+ };
484
+
485
+ let tmpWorkItem = tmpCoordinator.enqueueWorkItem(tmpWorkItemInfo);
486
+
487
+ pTask.log.info(`LLM Embedding: enqueued work item [${tmpWorkItem.WorkItemHash}]`);
488
+
489
+ return fCallback(null, {
490
+ WaitingForInput: true,
491
+ ResumeEventName: 'Complete',
492
+ PromptMessage: 'Waiting for LLM embedding generation',
493
+ OutputAddress: '',
494
+ Outputs: {},
495
+ Log: [`LLM Embedding: dispatched to work queue as [${tmpWorkItem.WorkItemHash}].`],
496
+ OnResumeWithOutputs: function (pOutputs)
497
+ {
498
+ if (tmpStateManager && pResolvedSettings.Destination && pOutputs && pOutputs.Embedding)
499
+ {
500
+ tmpStateManager.setAddress(
501
+ pResolvedSettings.Destination, pOutputs.Embedding,
502
+ pExecutionContext, pExecutionContext.NodeHash);
503
+ }
504
+ }
505
+ });
506
+ }
507
+ },
508
+
509
+ // ── llm-tool-use ──────────────────────────────────────────
510
+ {
511
+ Definition: require('./definitions/llm-tool-use.json'),
512
+ Execute: function (pTask, pResolvedSettings, pExecutionContext, fCallback)
513
+ {
514
+ let tmpCoordinator = _getService(pTask, 'UltravisorBeaconCoordinator');
515
+
516
+ if (!tmpCoordinator)
517
+ {
518
+ return fCallback(null, {
519
+ EventToFire: 'Error',
520
+ Outputs: { Content: 'BeaconCoordinator service not available.', ToolCalls: '[]', Model: '', FinishReason: 'error', PromptTokens: 0, CompletionTokens: 0, BeaconID: '' },
521
+ Log: ['LLM Tool Use: BeaconCoordinator service not found.']
522
+ });
523
+ }
524
+
525
+ let tmpBeacons = tmpCoordinator.listBeacons();
526
+
527
+ if (tmpBeacons.length === 0)
528
+ {
529
+ return fCallback(null, {
530
+ EventToFire: 'Error',
531
+ Outputs: { Content: 'No Beacon workers are registered.', ToolCalls: '[]', Model: '', FinishReason: 'error', PromptTokens: 0, CompletionTokens: 0, BeaconID: '' },
532
+ Log: ['LLM Tool Use: no Beacon workers registered.']
533
+ });
534
+ }
535
+
536
+ let tmpStateManager = _getService(pTask, 'UltravisorStateManager');
537
+
538
+ // Build messages with conversation history
539
+ let tmpMessages = tmpStateManager
540
+ ? _buildMessages(pResolvedSettings, pExecutionContext, tmpStateManager, pExecutionContext.NodeHash)
541
+ : _safeParseJSON(pResolvedSettings.Messages, []);
542
+
543
+ if (!tmpMessages || tmpMessages.length === 0)
544
+ {
545
+ return fCallback(null, {
546
+ EventToFire: 'Error',
547
+ Outputs: { Content: 'No messages to send.', ToolCalls: '[]', Model: '', FinishReason: 'error', PromptTokens: 0, CompletionTokens: 0, BeaconID: '' },
548
+ Log: ['LLM Tool Use: no messages assembled.']
549
+ });
550
+ }
551
+
552
+ let tmpWorkItemInfo = {
553
+ RunHash: pExecutionContext.RunHash,
554
+ NodeHash: pExecutionContext.NodeHash,
555
+ OperationHash: pExecutionContext.OperationHash,
556
+ Capability: 'LLM',
557
+ Action: 'ToolUse',
558
+ Settings: {
559
+ Messages: JSON.stringify(tmpMessages),
560
+ Tools: pResolvedSettings.Tools || '[]',
561
+ Model: pResolvedSettings.Model || '',
562
+ ToolChoice: pResolvedSettings.ToolChoice || 'auto',
563
+ Temperature: pResolvedSettings.Temperature,
564
+ MaxTokens: pResolvedSettings.MaxTokens
565
+ },
566
+ AffinityKey: pResolvedSettings.AffinityKey || '',
567
+ TimeoutMs: pResolvedSettings.TimeoutMs || 120000
568
+ };
569
+
570
+ let tmpWorkItem = tmpCoordinator.enqueueWorkItem(tmpWorkItemInfo);
571
+
572
+ pTask.log.info(`LLM Tool Use: enqueued work item [${tmpWorkItem.WorkItemHash}] with ${tmpMessages.length} messages`);
573
+
574
+ return fCallback(null, {
575
+ WaitingForInput: true,
576
+ ResumeEventName: 'Complete',
577
+ PromptMessage: `Waiting for LLM tool use response (${tmpMessages.length} messages)`,
578
+ OutputAddress: '',
579
+ Outputs: {},
580
+ Log: [
581
+ `LLM Tool Use: dispatched to work queue as [${tmpWorkItem.WorkItemHash}].`,
582
+ `Messages: ${tmpMessages.length}, Model: ${pResolvedSettings.Model || '(default)'}`,
583
+ pResolvedSettings.ConversationAddress ? `Conversation: ${pResolvedSettings.ConversationAddress}` : ''
584
+ ].filter(Boolean),
585
+ OnResumeWithOutputs: function (pOutputs)
586
+ {
587
+ if (tmpStateManager && pResolvedSettings.ConversationAddress)
588
+ {
589
+ _updateConversationHistory(
590
+ pResolvedSettings, pExecutionContext, tmpStateManager,
591
+ pExecutionContext.NodeHash, tmpMessages,
592
+ (pOutputs && pOutputs.Content) ? pOutputs.Content : '');
593
+ }
594
+
595
+ if (tmpStateManager && pResolvedSettings.Destination && pOutputs && pOutputs.Content)
596
+ {
597
+ tmpStateManager.setAddress(
598
+ pResolvedSettings.Destination, pOutputs.Content,
599
+ pExecutionContext, pExecutionContext.NodeHash);
600
+ }
601
+ }
602
+ });
603
+ }
604
+ }
605
+ ];
@@ -0,0 +1,46 @@
1
+ {
2
+ "Hash": "llm-chat-completion",
3
+ "Type": "llm-chat-completion",
4
+ "Name": "LLM Chat Completion",
5
+ "Description": "Sends messages to an LLM and returns the completion. Supports multi-turn conversation history with persistence across operation runs.",
6
+ "Category": "llm",
7
+ "Capability": "LLM",
8
+ "Action": "ChatCompletion",
9
+ "Tier": "Extension",
10
+ "EventInputs": [{ "Name": "Trigger" }],
11
+ "EventOutputs": [
12
+ { "Name": "Complete" },
13
+ { "Name": "Error", "IsError": true }
14
+ ],
15
+ "SettingsInputs": [
16
+ { "Name": "SystemPrompt", "DataType": "String", "Required": false, "Description": "System prompt text" },
17
+ { "Name": "UserPrompt", "DataType": "String", "Required": false, "Description": "User prompt text" },
18
+ { "Name": "Messages", "DataType": "String", "Required": false, "Description": "JSON array of messages [{role, content}] for direct control" },
19
+ { "Name": "Model", "DataType": "String", "Required": false, "Description": "Override model name" },
20
+ { "Name": "Temperature", "DataType": "Number", "Required": false, "Description": "Sampling temperature (0-2)" },
21
+ { "Name": "MaxTokens", "DataType": "Number", "Required": false, "Description": "Maximum tokens to generate" },
22
+ { "Name": "TopP", "DataType": "Number", "Required": false, "Description": "Nucleus sampling parameter" },
23
+ { "Name": "StopSequences", "DataType": "String", "Required": false, "Description": "JSON array of stop sequences" },
24
+ { "Name": "ResponseFormat", "DataType": "String", "Required": false, "Description": "\"text\" or \"json_object\"" },
25
+ { "Name": "ConversationAddress", "DataType": "String", "Required": false, "Description": "State address for message history (e.g. Operation.ChatHistory or Global.ChatSession.MyBot)" },
26
+ { "Name": "AppendToConversation", "DataType": "String", "Required": false, "Description": "Append this exchange to history (default true if ConversationAddress set)" },
27
+ { "Name": "ConversationMaxMessages", "DataType": "Number", "Required": false, "Description": "Sliding window: max non-system messages to keep" },
28
+ { "Name": "ConversationMaxTokens", "DataType": "Number", "Required": false, "Description": "Token budget for history (approximate, trims oldest)" },
29
+ { "Name": "PersistConversation", "DataType": "String", "Required": false, "Description": "Copy conversation history to ConversationPersistAddress on completion" },
30
+ { "Name": "ConversationPersistAddress", "DataType": "String", "Required": false, "Description": "GlobalState address for cross-operation persistence" },
31
+ { "Name": "InputAddress", "DataType": "String", "Required": false, "Description": "State address to read context data from (appended to UserPrompt)" },
32
+ { "Name": "Destination", "DataType": "String", "Required": false, "Description": "State address to write the completion content to" },
33
+ { "Name": "AffinityKey", "DataType": "String", "Required": false, "Description": "Route to a specific Beacon worker" },
34
+ { "Name": "TimeoutMs", "DataType": "Number", "Required": false, "Description": "Work item timeout in milliseconds" }
35
+ ],
36
+ "StateOutputs": [
37
+ { "Name": "Content", "DataType": "String", "Description": "The LLM completion text" },
38
+ { "Name": "Model", "DataType": "String", "Description": "Model that generated the response" },
39
+ { "Name": "PromptTokens", "DataType": "Number", "Description": "Tokens in the prompt" },
40
+ { "Name": "CompletionTokens", "DataType": "Number", "Description": "Tokens in the completion" },
41
+ { "Name": "TotalTokens", "DataType": "Number", "Description": "Total tokens used (prompt + completion)" },
42
+ { "Name": "FinishReason", "DataType": "String", "Description": "Why the completion ended" },
43
+ { "Name": "BeaconID", "DataType": "String", "Description": "ID of the Beacon that executed the work" }
44
+ ],
45
+ "DefaultSettings": { "Temperature": 0.7, "MaxTokens": 4096, "TimeoutMs": 120000 }
46
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "Hash": "llm-embedding",
3
+ "Type": "llm-embedding",
4
+ "Name": "LLM Embedding",
5
+ "Description": "Generates embeddings for text input using an LLM provider. Dispatches to a Beacon with LLM capability.",
6
+ "Category": "llm",
7
+ "Capability": "LLM",
8
+ "Action": "Embedding",
9
+ "Tier": "Extension",
10
+ "EventInputs": [{ "Name": "Trigger" }],
11
+ "EventOutputs": [
12
+ { "Name": "Complete" },
13
+ { "Name": "Error", "IsError": true }
14
+ ],
15
+ "SettingsInputs": [
16
+ { "Name": "Text", "DataType": "String", "Required": false, "Description": "Text to embed" },
17
+ { "Name": "Model", "DataType": "String", "Required": false, "Description": "Override embedding model" },
18
+ { "Name": "Dimensions", "DataType": "Number", "Required": false, "Description": "Requested embedding dimensions (model-dependent)" },
19
+ { "Name": "InputAddress", "DataType": "String", "Required": false, "Description": "State address to read text from" },
20
+ { "Name": "Destination", "DataType": "String", "Required": false, "Description": "State address to write embedding to" },
21
+ { "Name": "AffinityKey", "DataType": "String", "Required": false, "Description": "Route to a specific Beacon worker" },
22
+ { "Name": "TimeoutMs", "DataType": "Number", "Required": false, "Description": "Work item timeout in milliseconds" }
23
+ ],
24
+ "StateOutputs": [
25
+ { "Name": "Embedding", "DataType": "String", "Description": "JSON array of embedding floats" },
26
+ { "Name": "Dimensions", "DataType": "Number", "Description": "Number of dimensions in the embedding" },
27
+ { "Name": "Model", "DataType": "String", "Description": "Model used for embedding" },
28
+ { "Name": "BeaconID", "DataType": "String", "Description": "ID of the Beacon that executed the work" }
29
+ ],
30
+ "DefaultSettings": { "TimeoutMs": 60000 }
31
+ }