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.
- package/.claude/launch.json +11 -0
- package/.claude/ultravisor-dev-config.json +3 -0
- package/card-audit.json +1545 -0
- package/docs/_sidebar.md +17 -0
- package/docs/css/docuserve.css +73 -0
- package/docs/features/beacon-authentication.md +209 -0
- package/docs/features/beacon-providers.md +1299 -0
- package/docs/features/beacons.md +530 -0
- package/docs/features/capabilities.md +193 -0
- package/docs/features/llm-model-setup.md +505 -0
- package/docs/features/llm.md +262 -0
- package/docs/features/tasks-content-system.md +110 -0
- package/docs/features/tasks-data-transform.md +233 -0
- package/docs/features/tasks-extension.md +36 -0
- package/docs/features/tasks-file-system.md +203 -0
- package/docs/features/tasks-flow-control.md +125 -0
- package/docs/features/tasks-http-client.md +119 -0
- package/docs/features/tasks-llm.md +118 -0
- package/docs/features/tasks-meadow-api.md +163 -0
- package/docs/features/tasks-user-interaction.md +49 -0
- package/docs/features/tasks.md +14 -0
- package/docs/index.html +1 -1
- package/docs/retold-catalog.json +1 -1
- package/docs/retold-keyword-index.json +17374 -5
- package/operation-library/api-data-pipeline.json +143 -0
- package/operation-library/beacon-remote-command.json +72 -0
- package/operation-library/conditional-file-backup.json +143 -0
- package/operation-library/config-processor.json +136 -0
- package/operation-library/csv-data-analysis.json +228 -0
- package/operation-library/csv-to-json.json +160 -0
- package/operation-library/directory-inventory.json +128 -0
- package/operation-library/expression-calculator.json +114 -0
- package/operation-library/file-search-replace.json +175 -0
- package/operation-library/git-status-report.json +368 -0
- package/operation-library/health-check-ping.json +329 -0
- package/operation-library/json-config-merge.json +313 -0
- package/operation-library/llm-embedding-tool-use.json +314 -0
- package/operation-library/llm-multi-turn-analysis.json +322 -0
- package/operation-library/llm-summarize.json +264 -0
- package/operation-library/log-line-counter.json +185 -0
- package/operation-library/meadow-crud-lifecycle.json +264 -0
- package/operation-library/npm-project-validator.json +193 -0
- package/operation-library/rest-api-orchestrator.json +218 -0
- package/operation-library/shell-system-info.json +137 -0
- package/operation-library/simple-echo.json +95 -0
- package/operation-library/template-processor.json +299 -0
- package/operation-library/text-sanitizer.json +176 -0
- package/package.json +12 -8
- package/source/Ultravisor.cjs +30 -3
- package/source/beacon/Ultravisor-Beacon-CLI.cjs +143 -0
- package/source/beacon/Ultravisor-Beacon-CapabilityProvider.cjs +129 -0
- package/source/beacon/Ultravisor-Beacon-Client.cjs +568 -0
- package/source/beacon/Ultravisor-Beacon-Executor.cjs +500 -0
- package/source/beacon/Ultravisor-Beacon-ProviderRegistry.cjs +330 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-FileSystem.cjs +331 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-LLM.cjs +966 -0
- package/source/beacon/providers/Ultravisor-Beacon-Provider-Shell.cjs +95 -0
- package/source/cli/Ultravisor-CLIProgram.cjs +44 -22
- package/source/cli/commands/Ultravisor-Command-SingleOperation.cjs +29 -18
- package/source/cli/commands/Ultravisor-Command-SingleTask.cjs +62 -19
- package/source/cli/commands/Ultravisor-Command-UpdateTask.cjs +27 -15
- package/source/config/Ultravisor-Default-Command-Configuration.cjs +12 -3
- package/source/services/Ultravisor-Beacon-Coordinator.cjs +966 -0
- package/source/services/Ultravisor-ExecutionEngine.cjs +1093 -0
- package/source/services/Ultravisor-ExecutionManifest.cjs +629 -0
- package/source/services/Ultravisor-Hypervisor-State.cjs +270 -97
- package/source/services/Ultravisor-Hypervisor.cjs +185 -75
- package/source/services/Ultravisor-Schedule-Persistence-Base.cjs +45 -0
- package/source/services/Ultravisor-StateManager.cjs +253 -0
- package/source/services/Ultravisor-TaskTypeRegistry.cjs +213 -0
- package/source/services/persistence/Ultravisor-Schedule-Persistence-JSONFile.cjs +140 -0
- package/source/services/tasks/Ultravisor-BuiltIn-TaskConfigs.cjs +19 -0
- package/source/services/tasks/Ultravisor-TaskHelper-BeaconDispatch.cjs +107 -0
- package/source/services/tasks/Ultravisor-TaskType-Base.cjs +125 -0
- package/source/services/tasks/content-system/Ultravisor-TaskConfigs-ContentSystem.cjs +90 -0
- package/source/services/tasks/content-system/definitions/content-create-folder.json +24 -0
- package/source/services/tasks/content-system/definitions/content-list-files.json +27 -0
- package/source/services/tasks/content-system/definitions/content-read-file.json +26 -0
- package/source/services/tasks/content-system/definitions/content-save-file.json +26 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskConfigs-DataTransform.cjs +577 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-ReplaceString.cjs +80 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-SetValues.cjs +74 -0
- package/source/services/tasks/data-transform/Ultravisor-TaskType-StringAppender.cjs +90 -0
- package/source/services/tasks/data-transform/definitions/comprehension-intersect.json +24 -0
- package/source/services/tasks/data-transform/definitions/csv-transform.json +24 -0
- package/source/services/tasks/data-transform/definitions/expression-solver.json +20 -0
- package/source/services/tasks/data-transform/definitions/histogram.json +23 -0
- package/source/services/tasks/data-transform/definitions/parse-csv.json +27 -0
- package/source/services/tasks/data-transform/definitions/replace-string.json +27 -0
- package/source/services/tasks/data-transform/definitions/set-values.json +17 -0
- package/source/services/tasks/data-transform/definitions/string-appender.json +22 -0
- package/source/services/tasks/data-transform/definitions/template-string.json +20 -0
- package/source/services/tasks/extension/Ultravisor-TaskConfigs-Extension.cjs +87 -0
- package/source/services/tasks/extension/definitions/beacon-dispatch.json +32 -0
- package/source/services/tasks/file-system/Ultravisor-TaskConfigs-FileSystem.cjs +509 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFile.cjs +96 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-ReadFileBuffered.cjs +123 -0
- package/source/services/tasks/file-system/Ultravisor-TaskType-WriteFile.cjs +106 -0
- package/source/services/tasks/file-system/definitions/copy-file.json +27 -0
- package/source/services/tasks/file-system/definitions/list-files.json +27 -0
- package/source/services/tasks/file-system/definitions/read-file-buffered.json +31 -0
- package/source/services/tasks/file-system/definitions/read-file.json +26 -0
- package/source/services/tasks/file-system/definitions/read-json.json +23 -0
- package/source/services/tasks/file-system/definitions/write-file.json +29 -0
- package/source/services/tasks/file-system/definitions/write-json.json +30 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskConfigs-FlowControl.cjs +353 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-IfConditional.cjs +125 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-LaunchOperation.cjs +186 -0
- package/source/services/tasks/flow-control/Ultravisor-TaskType-SplitExecute.cjs +164 -0
- package/source/services/tasks/flow-control/definitions/if-conditional.json +25 -0
- package/source/services/tasks/flow-control/definitions/launch-operation.json +27 -0
- package/source/services/tasks/flow-control/definitions/split-execute.json +32 -0
- package/source/services/tasks/http-client/Ultravisor-TaskConfigs-HttpClient.cjs +281 -0
- package/source/services/tasks/http-client/definitions/get-json.json +26 -0
- package/source/services/tasks/http-client/definitions/get-text.json +26 -0
- package/source/services/tasks/http-client/definitions/rest-request.json +32 -0
- package/source/services/tasks/http-client/definitions/send-json.json +28 -0
- package/source/services/tasks/llm/Ultravisor-TaskConfigs-LLM.cjs +605 -0
- package/source/services/tasks/llm/definitions/llm-chat-completion.json +46 -0
- package/source/services/tasks/llm/definitions/llm-embedding.json +31 -0
- package/source/services/tasks/llm/definitions/llm-tool-use.json +42 -0
- package/source/services/tasks/meadow-api/Ultravisor-TaskConfigs-MeadowApi.cjs +341 -0
- package/source/services/tasks/meadow-api/definitions/meadow-count.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-create.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-delete.json +23 -0
- package/source/services/tasks/meadow-api/definitions/meadow-read.json +26 -0
- package/source/services/tasks/meadow-api/definitions/meadow-reads.json +29 -0
- package/source/services/tasks/meadow-api/definitions/meadow-update.json +26 -0
- package/source/services/tasks/shell/Ultravisor-TaskConfigs-Shell.cjs +63 -0
- package/source/services/tasks/shell/definitions/command.json +29 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskConfigs-UserInteraction.cjs +64 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ErrorMessage.cjs +55 -0
- package/source/services/tasks/user-interaction/Ultravisor-TaskType-ValueInput.cjs +47 -0
- package/source/services/tasks/user-interaction/definitions/error-message.json +18 -0
- package/source/services/tasks/user-interaction/definitions/value-input.json +23 -0
- package/source/web_server/Ultravisor-API-Server.cjs +849 -124
- package/test/Ultravisor_browser_tests.js +2226 -0
- package/test/Ultravisor_operation_library_tests.js +894 -0
- package/test/Ultravisor_tests.js +4946 -5044
- package/test/workflows/test-content-concatenate-all.json +339 -0
- package/test/workflows/test-content-full-pipeline.json +159 -0
- package/test/workflows/test-content-list-files.json +76 -0
- package/test/workflows/test-content-save-and-read.json +106 -0
- package/webinterface/css/ultravisor-themes.css +668 -0
- package/webinterface/css/ultravisor.css +37 -14
- package/webinterface/docs/card-help/beacon-dispatch.md +30 -0
- package/webinterface/docs/card-help/command.md +27 -0
- package/webinterface/docs/card-help/comprehension-intersect.md +24 -0
- package/webinterface/docs/card-help/content-create-folder.md +22 -0
- package/webinterface/docs/card-help/content-list-files.md +25 -0
- package/webinterface/docs/card-help/content-read-file.md +24 -0
- package/webinterface/docs/card-help/content-save-file.md +24 -0
- package/webinterface/docs/card-help/copy-file.md +25 -0
- package/webinterface/docs/card-help/csv-transform.md +24 -0
- package/webinterface/docs/card-help/end.md +11 -0
- package/webinterface/docs/card-help/error-message.md +16 -0
- package/webinterface/docs/card-help/expression-solver.md +21 -0
- package/webinterface/docs/card-help/get-json.md +24 -0
- package/webinterface/docs/card-help/get-text.md +24 -0
- package/webinterface/docs/card-help/histogram.md +23 -0
- package/webinterface/docs/card-help/if-conditional.md +23 -0
- package/webinterface/docs/card-help/launch-operation.md +25 -0
- package/webinterface/docs/card-help/list-files.md +25 -0
- package/webinterface/docs/card-help/llm-chat-completion.md +43 -0
- package/webinterface/docs/card-help/llm-embedding.md +24 -0
- package/webinterface/docs/card-help/llm-tool-use.md +39 -0
- package/webinterface/docs/card-help/meadow-count.md +24 -0
- package/webinterface/docs/card-help/meadow-create.md +24 -0
- package/webinterface/docs/card-help/meadow-delete.md +19 -0
- package/webinterface/docs/card-help/meadow-read.md +24 -0
- package/webinterface/docs/card-help/meadow-reads.md +27 -0
- package/webinterface/docs/card-help/meadow-update.md +24 -0
- package/webinterface/docs/card-help/parse-csv.md +27 -0
- package/webinterface/docs/card-help/read-file-buffered.md +29 -0
- package/webinterface/docs/card-help/read-file.md +24 -0
- package/webinterface/docs/card-help/read-json.md +21 -0
- package/webinterface/docs/card-help/replace-string.md +25 -0
- package/webinterface/docs/card-help/rest-request.md +30 -0
- package/webinterface/docs/card-help/send-json.md +26 -0
- package/webinterface/docs/card-help/set-values.md +16 -0
- package/webinterface/docs/card-help/split-execute.md +35 -0
- package/webinterface/docs/card-help/start.md +11 -0
- package/webinterface/docs/card-help/string-appender.md +22 -0
- package/webinterface/docs/card-help/template-string.md +21 -0
- package/webinterface/docs/card-help/value-input.md +24 -0
- package/webinterface/docs/card-help/write-file.md +27 -0
- package/webinterface/docs/card-help/write-json.md +28 -0
- package/webinterface/html/index.html +5 -0
- package/webinterface/package.json +13 -4
- package/webinterface/source/Pict-Application-Ultravisor.js +564 -70
- package/webinterface/source/Ultravisor-TimingUtils.js +99 -0
- package/webinterface/source/card-help-content.js +46 -0
- package/webinterface/source/cards/Ultravisor-BuiltIn-CardConfigs.js +174 -0
- package/webinterface/source/cards/Ultravisor-CardConfigGenerator.js +431 -0
- package/webinterface/source/data/ExampleFlow-CSVPipeline.js +231 -0
- package/webinterface/source/data/ExampleFlow-FileProcessor.js +315 -0
- package/webinterface/source/data/ExampleFlow-MeadowPipeline.js +328 -0
- package/webinterface/source/panels/Ultravisor-CardSettingsPanel.js +902 -0
- package/webinterface/source/providers/PictRouter-Ultravisor-Configuration.json +20 -8
- package/webinterface/source/views/PictView-Ultravisor-BeaconList.js +817 -0
- package/webinterface/source/views/PictView-Ultravisor-BottomBar.js +5 -5
- package/webinterface/source/views/PictView-Ultravisor-Dashboard.js +25 -25
- package/webinterface/source/views/PictView-Ultravisor-Documentation.js +856 -0
- package/webinterface/source/views/PictView-Ultravisor-FlowEditor.js +777 -0
- package/webinterface/source/views/PictView-Ultravisor-ManifestList.js +321 -58
- package/webinterface/source/views/PictView-Ultravisor-OperationEdit.js +36 -91
- package/webinterface/source/views/PictView-Ultravisor-OperationList.js +388 -16
- package/webinterface/source/views/PictView-Ultravisor-PendingInput.js +314 -0
- package/webinterface/source/views/PictView-Ultravisor-Schedule.js +521 -65
- package/webinterface/source/views/PictView-Ultravisor-TimingView.js +333 -71
- package/webinterface/source/views/PictView-Ultravisor-TopBar.js +257 -21
- package/webinterface/theme-sampler.html +645 -0
- package/debug/Harness.js +0 -6
- package/source/services/Ultravisor-Operation-Manifest.cjs +0 -160
- package/source/services/Ultravisor-Operation.cjs +0 -200
- package/source/services/Ultravisor-Task.cjs +0 -349
- package/source/services/events/Ultravisor-Hypervisor-Event-Solver.cjs +0 -11
- package/source/services/tasks/Ultravisor-Task-Base.cjs +0 -264
- package/source/services/tasks/Ultravisor-Task-CollectValues.cjs +0 -188
- package/source/services/tasks/Ultravisor-Task-Command.cjs +0 -65
- package/source/services/tasks/Ultravisor-Task-CommandEach.cjs +0 -190
- package/source/services/tasks/Ultravisor-Task-Conditional.cjs +0 -104
- package/source/services/tasks/Ultravisor-Task-DateWindow.cjs +0 -72
- package/source/services/tasks/Ultravisor-Task-GeneratePagedOperation.cjs +0 -336
- package/source/services/tasks/Ultravisor-Task-LaunchOperation.cjs +0 -143
- package/source/services/tasks/Ultravisor-Task-LaunchTask.cjs +0 -146
- package/source/services/tasks/Ultravisor-Task-LineMatch.cjs +0 -158
- package/source/services/tasks/Ultravisor-Task-Request.cjs +0 -56
- package/source/services/tasks/Ultravisor-Task-Solver.cjs +0 -89
- package/source/services/tasks/Ultravisor-Task-TemplateString.cjs +0 -93
- package/source/services/tasks/rest/Ultravisor-Task-GetBinary.cjs +0 -127
- package/source/services/tasks/rest/Ultravisor-Task-GetJSON.cjs +0 -119
- package/source/services/tasks/rest/Ultravisor-Task-GetText.cjs +0 -109
- package/source/services/tasks/rest/Ultravisor-Task-GetXML.cjs +0 -112
- package/source/services/tasks/rest/Ultravisor-Task-RestRequest.cjs +0 -499
- package/source/services/tasks/rest/Ultravisor-Task-SendJSON.cjs +0 -150
- package/source/services/tasks/stagingfiles/Ultravisor-Task-CopyFile.cjs +0 -110
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ListFiles.cjs +0 -89
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadBinary.cjs +0 -87
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadJSON.cjs +0 -67
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadText.cjs +0 -66
- package/source/services/tasks/stagingfiles/Ultravisor-Task-ReadXML.cjs +0 -69
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteBinary.cjs +0 -95
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteJSON.cjs +0 -96
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteText.cjs +0 -99
- package/source/services/tasks/stagingfiles/Ultravisor-Task-WriteXML.cjs +0 -102
- package/webinterface/source/views/PictView-Ultravisor-TaskEdit.js +0 -220
- 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
|
+
}
|