@smythos/sre 1.6.1 → 1.6.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 (234) hide show
  1. package/CHANGELOG +111 -111
  2. package/LICENSE +18 -18
  3. package/README.md +135 -135
  4. package/dist/index.js +2 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/types/subsystems/LLMManager/ModelsProvider.service/connectors/SmythModelsProvider.class.d.ts +39 -0
  7. package/package.json +1 -1
  8. package/src/Components/APICall/APICall.class.ts +161 -161
  9. package/src/Components/APICall/AccessTokenManager.ts +166 -166
  10. package/src/Components/APICall/ArrayBufferResponse.helper.ts +58 -58
  11. package/src/Components/APICall/OAuth.helper.ts +447 -447
  12. package/src/Components/APICall/mimeTypeCategories.ts +46 -46
  13. package/src/Components/APICall/parseData.ts +167 -167
  14. package/src/Components/APICall/parseHeaders.ts +41 -41
  15. package/src/Components/APICall/parseProxy.ts +68 -68
  16. package/src/Components/APICall/parseUrl.ts +91 -91
  17. package/src/Components/APIEndpoint.class.ts +234 -234
  18. package/src/Components/APIOutput.class.ts +58 -58
  19. package/src/Components/AgentPlugin.class.ts +102 -102
  20. package/src/Components/Async.class.ts +155 -155
  21. package/src/Components/Await.class.ts +90 -90
  22. package/src/Components/Classifier.class.ts +158 -158
  23. package/src/Components/Component.class.ts +147 -147
  24. package/src/Components/ComponentHost.class.ts +38 -38
  25. package/src/Components/DataSourceCleaner.class.ts +92 -92
  26. package/src/Components/DataSourceIndexer.class.ts +181 -181
  27. package/src/Components/DataSourceLookup.class.ts +161 -161
  28. package/src/Components/ECMASandbox.class.ts +72 -72
  29. package/src/Components/FEncDec.class.ts +29 -29
  30. package/src/Components/FHash.class.ts +33 -33
  31. package/src/Components/FSign.class.ts +80 -80
  32. package/src/Components/FSleep.class.ts +25 -25
  33. package/src/Components/FTimestamp.class.ts +66 -66
  34. package/src/Components/FileStore.class.ts +78 -78
  35. package/src/Components/ForEach.class.ts +97 -97
  36. package/src/Components/GPTPlugin.class.ts +70 -70
  37. package/src/Components/GenAILLM.class.ts +586 -586
  38. package/src/Components/HuggingFace.class.ts +313 -313
  39. package/src/Components/Image/imageSettings.config.ts +70 -70
  40. package/src/Components/ImageGenerator.class.ts +483 -483
  41. package/src/Components/JSONFilter.class.ts +54 -54
  42. package/src/Components/LLMAssistant.class.ts +213 -213
  43. package/src/Components/LogicAND.class.ts +28 -28
  44. package/src/Components/LogicAtLeast.class.ts +85 -85
  45. package/src/Components/LogicAtMost.class.ts +86 -86
  46. package/src/Components/LogicOR.class.ts +29 -29
  47. package/src/Components/LogicXOR.class.ts +34 -34
  48. package/src/Components/MCPClient.class.ts +137 -137
  49. package/src/Components/MemoryDeleteKeyVal.class.ts +70 -70
  50. package/src/Components/MemoryReadKeyVal.class.ts +67 -67
  51. package/src/Components/MemoryWriteKeyVal.class.ts +62 -62
  52. package/src/Components/MemoryWriteObject.class.ts +97 -97
  53. package/src/Components/MultimodalLLM.class.ts +128 -128
  54. package/src/Components/OpenAPI.class.ts +72 -72
  55. package/src/Components/PromptGenerator.class.ts +122 -122
  56. package/src/Components/ScrapflyWebScrape.class.ts +183 -183
  57. package/src/Components/ServerlessCode.class.ts +123 -123
  58. package/src/Components/TavilyWebSearch.class.ts +103 -103
  59. package/src/Components/VisionLLM.class.ts +104 -104
  60. package/src/Components/ZapierAction.class.ts +127 -127
  61. package/src/Components/index.ts +97 -97
  62. package/src/Core/AgentProcess.helper.ts +240 -240
  63. package/src/Core/Connector.class.ts +123 -123
  64. package/src/Core/ConnectorsService.ts +197 -197
  65. package/src/Core/DummyConnector.ts +49 -49
  66. package/src/Core/HookService.ts +105 -105
  67. package/src/Core/SmythRuntime.class.ts +241 -241
  68. package/src/Core/SystemEvents.ts +16 -16
  69. package/src/Core/boot.ts +56 -56
  70. package/src/config.ts +15 -15
  71. package/src/constants.ts +126 -126
  72. package/src/data/hugging-face.params.json +579 -579
  73. package/src/helpers/AWSLambdaCode.helper.ts +624 -599
  74. package/src/helpers/BinaryInput.helper.ts +331 -331
  75. package/src/helpers/Conversation.helper.ts +1157 -1157
  76. package/src/helpers/ECMASandbox.helper.ts +64 -64
  77. package/src/helpers/JsonContent.helper.ts +97 -97
  78. package/src/helpers/LocalCache.helper.ts +97 -97
  79. package/src/helpers/Log.helper.ts +274 -274
  80. package/src/helpers/OpenApiParser.helper.ts +150 -150
  81. package/src/helpers/S3Cache.helper.ts +147 -147
  82. package/src/helpers/SmythURI.helper.ts +5 -5
  83. package/src/helpers/Sysconfig.helper.ts +95 -95
  84. package/src/helpers/TemplateString.helper.ts +243 -243
  85. package/src/helpers/TypeChecker.helper.ts +329 -329
  86. package/src/index.ts +198 -198
  87. package/src/index.ts.bak +198 -198
  88. package/src/subsystems/AgentManager/Agent.class.ts +1114 -1114
  89. package/src/subsystems/AgentManager/Agent.helper.ts +3 -3
  90. package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +230 -230
  91. package/src/subsystems/AgentManager/AgentData.service/connectors/CLIAgentDataConnector.class.ts +66 -66
  92. package/src/subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class.ts +145 -145
  93. package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +39 -39
  94. package/src/subsystems/AgentManager/AgentData.service/index.ts +18 -18
  95. package/src/subsystems/AgentManager/AgentLogger.class.ts +301 -301
  96. package/src/subsystems/AgentManager/AgentRequest.class.ts +51 -51
  97. package/src/subsystems/AgentManager/AgentRuntime.class.ts +557 -557
  98. package/src/subsystems/AgentManager/AgentSSE.class.ts +101 -101
  99. package/src/subsystems/AgentManager/AgentSettings.class.ts +52 -52
  100. package/src/subsystems/AgentManager/Component.service/ComponentConnector.ts +32 -32
  101. package/src/subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class.ts +60 -60
  102. package/src/subsystems/AgentManager/Component.service/index.ts +11 -11
  103. package/src/subsystems/AgentManager/EmbodimentSettings.class.ts +47 -47
  104. package/src/subsystems/AgentManager/ForkedAgent.class.ts +154 -154
  105. package/src/subsystems/AgentManager/OSResourceMonitor.ts +77 -77
  106. package/src/subsystems/ComputeManager/Code.service/CodeConnector.ts +98 -98
  107. package/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts +171 -172
  108. package/src/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.ts +131 -131
  109. package/src/subsystems/ComputeManager/Code.service/index.ts +13 -13
  110. package/src/subsystems/IO/CLI.service/CLIConnector.ts +47 -47
  111. package/src/subsystems/IO/CLI.service/index.ts +9 -9
  112. package/src/subsystems/IO/Log.service/LogConnector.ts +32 -32
  113. package/src/subsystems/IO/Log.service/connectors/ConsoleLog.class.ts +28 -28
  114. package/src/subsystems/IO/Log.service/index.ts +13 -13
  115. package/src/subsystems/IO/NKV.service/NKVConnector.ts +43 -43
  116. package/src/subsystems/IO/NKV.service/connectors/NKVLocalStorage.class.ts +234 -234
  117. package/src/subsystems/IO/NKV.service/connectors/NKVRAM.class.ts +204 -204
  118. package/src/subsystems/IO/NKV.service/connectors/NKVRedis.class.ts +182 -182
  119. package/src/subsystems/IO/NKV.service/index.ts +14 -14
  120. package/src/subsystems/IO/Router.service/RouterConnector.ts +21 -21
  121. package/src/subsystems/IO/Router.service/connectors/ExpressRouter.class.ts +48 -48
  122. package/src/subsystems/IO/Router.service/connectors/NullRouter.class.ts +40 -40
  123. package/src/subsystems/IO/Router.service/index.ts +11 -11
  124. package/src/subsystems/IO/Storage.service/SmythFS.class.ts +488 -488
  125. package/src/subsystems/IO/Storage.service/StorageConnector.ts +66 -66
  126. package/src/subsystems/IO/Storage.service/connectors/LocalStorage.class.ts +327 -327
  127. package/src/subsystems/IO/Storage.service/connectors/S3Storage.class.ts +482 -482
  128. package/src/subsystems/IO/Storage.service/index.ts +13 -13
  129. package/src/subsystems/IO/VectorDB.service/VectorDBConnector.ts +108 -108
  130. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +465 -465
  131. package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +387 -387
  132. package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +408 -408
  133. package/src/subsystems/IO/VectorDB.service/embed/BaseEmbedding.ts +107 -107
  134. package/src/subsystems/IO/VectorDB.service/embed/GoogleEmbedding.ts +118 -118
  135. package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +109 -109
  136. package/src/subsystems/IO/VectorDB.service/embed/index.ts +26 -26
  137. package/src/subsystems/IO/VectorDB.service/index.ts +14 -14
  138. package/src/subsystems/LLMManager/LLM.helper.ts +251 -251
  139. package/src/subsystems/LLMManager/LLM.inference.ts +345 -345
  140. package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +492 -492
  141. package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +171 -171
  142. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +666 -666
  143. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +407 -407
  144. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +92 -92
  145. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +983 -983
  146. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +319 -319
  147. package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +361 -361
  148. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +257 -257
  149. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +430 -430
  150. package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +503 -503
  151. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +524 -524
  152. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +100 -100
  153. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.ts +81 -81
  154. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +1145 -1145
  155. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.ts +13 -13
  156. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.ts +4 -4
  157. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/utils.ts +11 -11
  158. package/src/subsystems/LLMManager/LLM.service/connectors/openai/types.ts +32 -32
  159. package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +478 -478
  160. package/src/subsystems/LLMManager/LLM.service/index.ts +47 -47
  161. package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +303 -303
  162. package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +271 -271
  163. package/src/subsystems/LLMManager/ModelsProvider.service/index.ts +11 -11
  164. package/src/subsystems/LLMManager/custom-models.ts +854 -854
  165. package/src/subsystems/LLMManager/models.ts +2540 -2540
  166. package/src/subsystems/LLMManager/paramMappings.ts +69 -69
  167. package/src/subsystems/MemoryManager/Cache.service/CacheConnector.ts +86 -86
  168. package/src/subsystems/MemoryManager/Cache.service/connectors/LocalStorageCache.class.ts +297 -297
  169. package/src/subsystems/MemoryManager/Cache.service/connectors/RAMCache.class.ts +214 -214
  170. package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +252 -252
  171. package/src/subsystems/MemoryManager/Cache.service/connectors/S3Cache.class.ts +373 -373
  172. package/src/subsystems/MemoryManager/Cache.service/index.ts +15 -15
  173. package/src/subsystems/MemoryManager/LLMCache.ts +72 -72
  174. package/src/subsystems/MemoryManager/LLMContext.ts +124 -124
  175. package/src/subsystems/MemoryManager/LLMMemory.service/LLMMemoryConnector.ts +26 -26
  176. package/src/subsystems/MemoryManager/RuntimeContext.ts +277 -277
  177. package/src/subsystems/Security/AccessControl/ACL.class.ts +208 -208
  178. package/src/subsystems/Security/AccessControl/AccessCandidate.class.ts +82 -82
  179. package/src/subsystems/Security/AccessControl/AccessRequest.class.ts +52 -52
  180. package/src/subsystems/Security/Account.service/AccountConnector.ts +44 -44
  181. package/src/subsystems/Security/Account.service/connectors/DummyAccount.class.ts +130 -130
  182. package/src/subsystems/Security/Account.service/connectors/JSONFileAccount.class.ts +170 -170
  183. package/src/subsystems/Security/Account.service/connectors/MySQLAccount.class.ts +76 -76
  184. package/src/subsystems/Security/Account.service/index.ts +14 -14
  185. package/src/subsystems/Security/Credentials.helper.ts +62 -62
  186. package/src/subsystems/Security/ManagedVault.service/ManagedVaultConnector.ts +38 -38
  187. package/src/subsystems/Security/ManagedVault.service/connectors/NullManagedVault.class.ts +53 -53
  188. package/src/subsystems/Security/ManagedVault.service/connectors/SecretManagerManagedVault.ts +154 -154
  189. package/src/subsystems/Security/ManagedVault.service/index.ts +12 -12
  190. package/src/subsystems/Security/SecureConnector.class.ts +110 -110
  191. package/src/subsystems/Security/Vault.service/Vault.helper.ts +30 -30
  192. package/src/subsystems/Security/Vault.service/VaultConnector.ts +29 -29
  193. package/src/subsystems/Security/Vault.service/connectors/HashicorpVault.class.ts +46 -46
  194. package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +221 -221
  195. package/src/subsystems/Security/Vault.service/connectors/NullVault.class.ts +54 -54
  196. package/src/subsystems/Security/Vault.service/connectors/SecretsManager.class.ts +140 -140
  197. package/src/subsystems/Security/Vault.service/index.ts +12 -12
  198. package/src/types/ACL.types.ts +104 -104
  199. package/src/types/AWS.types.ts +10 -10
  200. package/src/types/Agent.types.ts +61 -61
  201. package/src/types/AgentLogger.types.ts +17 -17
  202. package/src/types/Cache.types.ts +1 -1
  203. package/src/types/Common.types.ts +2 -2
  204. package/src/types/LLM.types.ts +520 -520
  205. package/src/types/Redis.types.ts +8 -8
  206. package/src/types/SRE.types.ts +64 -64
  207. package/src/types/Security.types.ts +14 -14
  208. package/src/types/Storage.types.ts +5 -5
  209. package/src/types/VectorDB.types.ts +86 -86
  210. package/src/utils/base64.utils.ts +275 -275
  211. package/src/utils/cli.utils.ts +68 -68
  212. package/src/utils/data.utils.ts +322 -322
  213. package/src/utils/date-time.utils.ts +22 -22
  214. package/src/utils/general.utils.ts +238 -238
  215. package/src/utils/index.ts +12 -12
  216. package/src/utils/lazy-client.ts +261 -261
  217. package/src/utils/numbers.utils.ts +13 -13
  218. package/src/utils/oauth.utils.ts +35 -35
  219. package/src/utils/string.utils.ts +414 -414
  220. package/src/utils/url.utils.ts +19 -19
  221. package/src/utils/validation.utils.ts +74 -74
  222. package/dist/bundle-analysis-lazy.html +0 -4949
  223. package/dist/bundle-analysis.html +0 -4949
  224. package/dist/types/Components/Triggers/GmailTrigger.class.d.ts +0 -13
  225. package/dist/types/Components/Triggers/Trigger.class.d.ts +0 -3
  226. package/dist/types/helpers/AIPerformanceAnalyzer.helper.d.ts +0 -45
  227. package/dist/types/helpers/AIPerformanceCollector.helper.d.ts +0 -111
  228. package/dist/types/subsystems/IO/Storage.service/connectors/AzureBlobStorage.class.d.ts +0 -211
  229. package/dist/types/subsystems/IO/VectorDB.service/connectors/WeaviateVectorDB.class.d.ts +0 -187
  230. package/dist/types/subsystems/PerformanceManager/Performance.service/PerformanceConnector.d.ts +0 -102
  231. package/dist/types/subsystems/PerformanceManager/Performance.service/connectors/LocalPerformanceConnector.class.d.ts +0 -100
  232. package/dist/types/subsystems/PerformanceManager/Performance.service/index.d.ts +0 -22
  233. package/dist/types/types/Performance.types.d.ts +0 -468
  234. package/dist/types/utils/package-manager.utils.d.ts +0 -26
@@ -1,557 +1,557 @@
1
- import { Component } from '@sre/Components/Component.class';
2
- import { Agent } from './Agent.class';
3
-
4
- import { Logger } from '@sre/helpers/Log.helper';
5
- import { LLMCache } from '@sre/MemoryManager/LLMCache';
6
- import { RuntimeContext } from '@sre/MemoryManager/RuntimeContext';
7
- import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
8
- import { uid } from '@sre/utils';
9
-
10
- const console = Logger('AgentRuntime');
11
- const AgentRuntimeUnavailable = new Proxy(
12
- {},
13
- {
14
- get: function (target, prop, receiver) {
15
- // Check if the property being accessed is a function
16
- if (typeof target[prop] === 'function') {
17
- return target[prop];
18
- } else {
19
- // Return a function that logs "unavailable"
20
- return function () {
21
- console.warn(`AgentRuntime Unavailable tried to call : ${prop.toString()}`);
22
- };
23
- }
24
- },
25
- }
26
- );
27
- export class AgentRuntime {
28
- private static processResults: any = {};
29
- private static tagsData = {};
30
- public static dummy = AgentRuntimeUnavailable;
31
-
32
- private agentContext: RuntimeContext;
33
- public llmCache: LLMCache;
34
- //private ctxFile: string = '';
35
- private xDebugRun: string | undefined = '';
36
- private xDebugInject: string | undefined = '';
37
- private xDebugRead: string | undefined = '';
38
- private xDebugStop: string | undefined = '';
39
- private xDebugPendingInject: any = null;
40
- private xMockDataInject: any = null;
41
- public xDebugId: string | undefined = '';
42
-
43
- private xDebugCmd: string | undefined = '';
44
- private _debugActive = false;
45
- private _runtimeFileReady = false;
46
- public sessionClosed = false;
47
-
48
- private reqTagOwner = false;
49
-
50
- //reqTag is used to identify the current running workflow including nested calls, it allows us to identify circular calls
51
- public reqTag: any;
52
- public processID: any; //this identifies the current processID, a process ID is the full set of runCycles that is executed by the agent.
53
- public workflowReqId: any; //this identifies the current running workflow. a workflow starts when and agent endpoint is called, or a debug session is initiated, and ends when no more steps can be executed.
54
-
55
- public alwaysActiveComponents: any = {};
56
- public exclusiveComponents: any = {};
57
-
58
- private checkRuntimeContext: any = null;
59
-
60
- public get circularLimitReached() {
61
- return this.agentContext?.circularLimitReached || false;
62
- }
63
- public set circularLimitReached(value) {
64
- if (this.agentContext) this.agentContext.circularLimitReached = value;
65
- }
66
-
67
- public get debug() {
68
- return this._debugActive;
69
- }
70
- public get curStep() {
71
- return this.agentContext?.step || 0;
72
- }
73
-
74
- constructor(public agent: Agent) {
75
- this.reqTag = agent.agentRequest.header('X-REQUEST-TAG');
76
- const isNestedProcess: boolean = !!this.reqTag;
77
-
78
- if (!this.reqTag) {
79
- //tagged request should not be run in debug mode, this comes from a parent agent
80
- this.xDebugStop = agent.agentRequest.header('X-DEBUG-STOP');
81
- this.xDebugRun = agent.agentRequest.header('X-DEBUG-RUN'); //send this as header to create a session and attach it
82
- this.xDebugInject = agent.agentRequest.header('X-DEBUG-INJ');
83
- this.xDebugRead = agent.agentRequest.header('X-DEBUG-READ');
84
- this.reqTag = 'xTAG-' + uid(); //if request tag is not set, set a new value, this will be used to tag nested agent calls
85
- this.reqTagOwner = true;
86
- } else {
87
- this.xDebugStop = undefined;
88
- this.xDebugRun = undefined;
89
- this.xDebugInject = undefined;
90
- this.xDebugRead = undefined;
91
- }
92
-
93
- this.xDebugId = this.xDebugStop || this.xDebugRun || this.xDebugRead;
94
-
95
- //if (req.body) {
96
- if (!this.xDebugId && agent.agentRequest.body) {
97
- if (this.xDebugInject != undefined && this.xDebugInject != null) {
98
- this.xDebugPendingInject = agent.agentRequest.body;
99
- this.xDebugRun = this.xDebugInject || 'inj-' + uid();
100
- } else {
101
- if (this.xDebugRun == '') {
102
- this.xDebugRun = 'dbg-' + uid(); //generate a random debug id
103
- }
104
- }
105
- this.xDebugId = this.xDebugRun;
106
- }
107
-
108
- if (agent.agentRequest.header('X-MOCK-DATA-INJ') !== undefined) {
109
- this.xMockDataInject = agent.agentRequest.body;
110
- }
111
-
112
- this.processID = this.xDebugId;
113
-
114
- if (!this.xDebugId) {
115
- //if it's not a debug session, processID is unique per request
116
- this.xDebugId = agent.sessionId;
117
- this.processID = this.reqTag;
118
- }
119
- if (isNestedProcess) {
120
- // Need to make processID unique to run same sub-agents multiple times in parallel
121
- this.processID += `:${Math.floor(1000 + Math.random() * 9000)}`;
122
- }
123
-
124
- //we need a way to identify current running workflow in a unique way
125
- //=> In debug mode, xDebugRun holds the debug sessionID which is unique per workflow run
126
- // if the debug session is stopped, xDebugStop holds the sessionID
127
- // Note : We can't use reqTag in debug mode because it changes every time a new debug step is executed
128
- //
129
- //=> In normal mode, reqTag is unique per workflow run
130
- this.workflowReqId = this.xDebugRun || this.xDebugStop || this.reqTag;
131
-
132
- //tagsData can be updated from external integrations (eg. Chatbot, API Endpoint, etc.)
133
- if (!AgentRuntime.tagsData[this.reqTag]) AgentRuntime.tagsData[this.reqTag] = {};
134
- if (!AgentRuntime.processResults[this.processID])
135
- AgentRuntime.processResults[this.processID] = {
136
- timestamp: Date.now(),
137
- errorResults: [],
138
- sessionResults: [],
139
- };
140
-
141
- this.agentContext = new RuntimeContext(this);
142
- this.agentContext.on('ready', () => {
143
- this.alwaysActiveComponents = {};
144
- this.exclusiveComponents = {};
145
- for (let component of this.agent.data.components) {
146
- const cpt: Component = this.agent.ComponentInstances[component.name];
147
- if (!cpt) {
148
- console.warn(`Component ${component.name} Exists in agent but has no implementation`, AccessCandidate.agent(this.agent.id));
149
- continue;
150
- }
151
-
152
- if (cpt.alwaysActive) {
153
- this.alwaysActiveComponents[component.id] = cpt;
154
- this.updateComponent(component.id, { active: true, alwaysActive: true });
155
- const runtimeData = { ...this.getRuntimeData(component.id) };
156
- this.saveRuntimeComponentData(component.id, runtimeData);
157
- }
158
- if (cpt.exclusive) {
159
- this.exclusiveComponents[component.id] = cpt;
160
- this.updateComponent(component.id, { exclusive: true });
161
- const runtimeData = { ...this.getRuntimeData(component.id) };
162
- this.saveRuntimeComponentData(component.id, runtimeData);
163
- }
164
- }
165
- });
166
-
167
- //if xDebugId is equal to agent session, it means that the debugging features are not active
168
- this._debugActive = this.xDebugId != agent.sessionId;
169
-
170
- const xCacheId = agent.agentRequest.header('X-CACHE-ID') || '';
171
- this.llmCache = new LLMCache(AccessCandidate.agent(this.agent.id), xCacheId);
172
- //this.xCacheId =
173
- }
174
-
175
- public async ready() {
176
- return this.agentContext.ready();
177
- }
178
-
179
- public destroy() {
180
- this.sessionClosed = true;
181
- this.sync();
182
- }
183
-
184
- public incTag(componentId) {
185
- if (!AgentRuntime.tagsData[this.reqTag][componentId]) AgentRuntime.tagsData[this.reqTag][componentId] = 0;
186
- AgentRuntime.tagsData[this.reqTag][componentId]++;
187
-
188
- // console.log(
189
- // `incTag agentId=${this.agent.id} componentId=${componentId} tag=${this.reqTag} ==> ${AgentRuntime.tagsData[this.reqTag][componentId]}`,
190
- // );
191
- //console.log('incTag tagsData', tagsData);
192
- }
193
-
194
- public async sync() {
195
- //if (!this.ctxFile) return;
196
-
197
- const deleteTag = (this.reqTagOwner && this.sessionClosed) || this.circularLimitReached;
198
- if (deleteTag) {
199
- delete AgentRuntime.tagsData[this.reqTag];
200
- }
201
-
202
- this.agentContext.enqueueSync();
203
- }
204
- public getWaitingComponents() {
205
- const ctxData = this.agentContext;
206
- const dbgComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
207
- const waitingComponents: any = dbgComponents.filter((c: any) => c?.ctx?.status && typeof c?.ctx?.output !== undefined);
208
- return waitingComponents;
209
- }
210
- public getExclusiveActiveComponents() {
211
- const ctxData = this.agentContext;
212
- const dbgComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
213
- const exclusiveActiveComponents: any = dbgComponents.filter((c: any) => c?.ctx?.exclusive == true);
214
- return exclusiveActiveComponents;
215
- }
216
- public readState(stateId: string, deltaOnly = false) {
217
- //if (!this._debugActive || !this.xDebugRead) return null;
218
- if (!this._debugActive || !stateId) return null;
219
-
220
- //this.checkRuntimeContext();
221
- const runtime = this;
222
- const agent = this.agent;
223
-
224
- const ctxData = runtime.agentContext;
225
- const dbgAllComponents: any = runtime.xDebugPendingInject || Object.values(ctxData?.components || []);
226
-
227
- //first try to find exclusive active components
228
- let dbgActiveComponents: any;
229
- dbgActiveComponents = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && c?.ctx?.exclusive == true);
230
- //if no exclusive active components, find all active components
231
- if (!dbgActiveComponents || dbgActiveComponents.length == 0)
232
- dbgActiveComponents = dbgAllComponents.filter(
233
- (c: any) =>
234
- c?.ctx?.active == true ||
235
- (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
236
- );
237
- //find waiting components that was not previously run
238
- const dbgActiveWaitingComponents: any = dbgAllComponents.filter(
239
- (c: any) => c?.ctx?.active == true && c?.ctx?.status && typeof c?.ctx?.output !== undefined
240
- );
241
-
242
- const dbgActiveReadyComponents: any = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && !c?.ctx?.status);
243
-
244
- let state = {};
245
- for (let dbgComponent of dbgAllComponents) {
246
- state[dbgComponent.id] = dbgComponent.ctx;
247
- }
248
-
249
- //let dbgSession: any = runtime.xDebugRead;
250
- let dbgSession: any = stateId;
251
-
252
- // let alwaysActiveComponents = 0;
253
- // for (let activeCpt of dbgActiveComponents) {
254
- // if (this.agent.alwaysActiveComponents[activeCpt.id]) alwaysActiveComponents++;
255
- // }
256
-
257
- if (!dbgActiveComponents || dbgActiveComponents.length == 0 /*|| dbgActiveComponents.length == alwaysActiveComponents*/) {
258
- dbgSession = null;
259
- runtime.sessionClosed = true;
260
- }
261
-
262
- const remainingActiveComponents: any = Object.values(ctxData?.components || []).filter(
263
- (c: any) => c?.ctx?.active == true && !c?.ctx?.alwaysActive
264
- );
265
- const activeAsyncComponents: any = Object.values(ctxData?.components || []).filter(
266
- (c: any) => !c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0
267
- );
268
-
269
- if (remainingActiveComponents.length == 0 && activeAsyncComponents.length == 0 /*&& awaitingInputs.length == 0*/) {
270
- runtime.sessionClosed = true;
271
- }
272
-
273
- if (runtime.circularLimitReached) {
274
- const circularLimitData = runtime.checkCircularLimit();
275
- const error = `Circular Calls Limit Reached on ${circularLimitData}. Current agent circular limit is ${agent.circularLimit}`;
276
- runtime.sessionClosed = true;
277
- return { state, dbgSession, sessionClosed: runtime.sessionClosed, error };
278
- }
279
-
280
- const step = this.curStep >= 1 ? this.curStep - 1 : 0; //current state was executed in previous step
281
-
282
- if (deltaOnly) {
283
- const delta = {};
284
- for (let cptId in state) {
285
- const cpt = state[cptId];
286
-
287
- //workaround, here we are supposed to test component steps that are equalt to current step
288
- //but due to an inconsistency, the Async component has sometimes a step greater than the current step
289
- if (cpt.step >= step) delta[cptId] = cpt;
290
- //FIXME : identify the root cause of this issue and replace >= with ==
291
- }
292
- //return { state: delta, dbgSession, sessionClosed: runtime.sessionClosed, step };
293
- state = delta;
294
- }
295
-
296
- return { state, dbgSession, sessionClosed: runtime.sessionClosed, step };
297
- }
298
-
299
- /**
300
- * This method is called by the agent to run a process cycle, it will run all active components and return the results
301
- * The function is called multiple times until all components are executed and no more active components are available
302
- * @returns
303
- */
304
- public async runCycle() {
305
- console.debug(
306
- `runCycle agentId=${this.agent.id} wfReqId=${this.workflowReqId} reqTag=${this.reqTag} session=${this.xDebugRun} cycleId=${this.processID}`,
307
- AccessCandidate.agent(this.agent.id)
308
- );
309
- //this.checkRuntimeContext();
310
-
311
- const runtime = this;
312
- const agent = this.agent;
313
- const ctxData = runtime.agentContext;
314
- const dbgAllComponents: any = runtime.xDebugPendingInject || Object.values(ctxData?.components || []);
315
-
316
- //first try to find exclusive active components
317
- let dbgActiveComponents: any;
318
- dbgActiveComponents = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && c?.ctx?.exclusive == true);
319
- //if no exclusive active components, find all active components
320
- if (!dbgActiveComponents || dbgActiveComponents.length == 0)
321
- dbgActiveComponents = dbgAllComponents.filter(
322
- (c: any) =>
323
- c?.ctx?.active == true ||
324
- (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
325
- );
326
- //find waiting components that was not previously run
327
- const dbgActiveWaitingComponents: any = dbgAllComponents.filter(
328
- (c: any) => c?.ctx?.active == true && c?.ctx?.status && typeof c?.ctx?.output !== undefined
329
- );
330
- const dbgActiveReadyComponents: any = dbgAllComponents.filter(
331
- (c: any) =>
332
- (c?.ctx?.active == true && !c?.ctx?.status) ||
333
- (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
334
- );
335
- //const dbgActiveReadyComponents: any = dbgActiveComponents.filter((c: any) => c?.ctx?.active == true && !c?.ctx?.status);
336
-
337
- let step: any;
338
-
339
- if (!dbgActiveComponents || dbgActiveComponents.length == 0) {
340
- runtime.sessionClosed = true;
341
- step = {
342
- state: { sessionClosed: true },
343
- dbgSession: null,
344
- //expiredDbgSession: runtime.xDebugRun || runtime.xDebugStop,
345
- expiredDbgSession: runtime.xDebugId,
346
- sessionClosed: true,
347
- };
348
- }
349
-
350
- if (!step && dbgActiveComponents.length == dbgActiveWaitingComponents.length && ctxData.sessionResult) {
351
- runtime.sessionClosed = true;
352
- step = {
353
- state: { sessionClosed: true },
354
- dbgSession: null,
355
- //expiredDbgSession: runtime.xDebugRun,
356
- expiredDbgSession: runtime.xDebugId,
357
- sessionClosed: true,
358
- };
359
- }
360
- if (!step && dbgActiveReadyComponents.length > 0) {
361
- const promises: any = [];
362
-
363
- for (let dbgComponent of dbgActiveReadyComponents) {
364
- const injectInput = runtime.xDebugPendingInject ? dbgComponent.ctx.input : undefined;
365
-
366
- promises.push(agent.callComponent(dbgComponent.ctx.sourceId, dbgComponent.id, injectInput));
367
- }
368
- const dbgResults = await Promise.all(promises);
369
- const state = dbgResults.length == 1 ? dbgResults[0] : dbgResults;
370
-
371
- runtime.xDebugPendingInject = null;
372
-
373
- const remainingActiveComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
374
- const activeAsyncComponents: any = Object.values(ctxData?.components || []).filter(
375
- (c: any) => !c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0
376
- );
377
- const dbgActiveWaitingComponents: any = dbgAllComponents.filter((c: any) => c?.ctx?.status && typeof c?.ctx?.output !== undefined);
378
-
379
- if (dbgActiveWaitingComponents.length == remainingActiveComponents.length) {
380
- ctxData.sessionResult = true;
381
- }
382
-
383
- //capture results
384
- let sessionResults = dbgResults.flat().filter(
385
- (e) =>
386
- e.id &&
387
- e.result &&
388
- !e.result._missing_inputs &&
389
- //check if this is the last component in the chain
390
- !agent.connections.find((c) => c.sourceId == e.id)
391
- );
392
-
393
- let errorResults = dbgResults.flat().filter((e) => e.id && (e.error || e.result?._error));
394
-
395
- //also filter out erroneous components that are children of a loop
396
- //otherwise, errors inside a loop will be reported as session results and can lead to wrong results or generated noise in the final agent output
397
- errorResults = errorResults.filter((e) => {
398
- return !ctxData?.components?.[e.id]?.ctx?.runtimeData?._ChildLoopData;
399
- });
400
-
401
- if (ctxData.sessionResult && sessionResults.length == 0 && runtime.sessionClosed) {
402
- //no result ? check if we have errors
403
- sessionResults = errorResults;
404
- }
405
-
406
- ctxData.sessionResults = sessionResults;
407
- step = {
408
- state,
409
- dbgSession: runtime.xDebugRun,
410
- sessionResult: runtime.agentContext.sessionResult,
411
- sessionResults: runtime.agentContext.sessionResults,
412
- errorResults,
413
- sessionClosed: remainingActiveComponents.length == 0 && activeAsyncComponents.length == 0 /*&& awaitingInputs.length == 0*/,
414
- };
415
- } else {
416
- runtime.sessionClosed = true;
417
- //return { sessionClosed: true };
418
- step = {
419
- state: { sessionClosed: true },
420
- dbgSession: null,
421
- //expiredDbgSession: runtime.xDebugRun || runtime.xDebugStop,
422
- expiredDbgSession: runtime.xDebugId,
423
- sessionClosed: true,
424
- };
425
- }
426
-
427
- this.checkCircularLimit();
428
- if (step.sessionResults) {
429
- AgentRuntime.processResults[this.processID].sessionResults.push(step.sessionResults);
430
- }
431
- if (step.errorResults) {
432
- AgentRuntime.processResults[this.processID].errorResults.push(step.errorResults);
433
- }
434
-
435
- if (step?.sessionClosed || this.circularLimitReached) {
436
- const finalResult = this.processResults();
437
- step.finalResult = finalResult;
438
- runtime.sessionClosed = true;
439
- }
440
-
441
- this.incStep();
442
- this.sync();
443
- return step;
444
- }
445
-
446
- private processResults() {
447
- //this.checkCircularLimit();
448
- let result: any = { error: 'Error processing results' };
449
- const sessionResults = AgentRuntime.processResults[this.processID].sessionResults;
450
- const errorResults = AgentRuntime.processResults[this.processID].errorResults;
451
- if (this.circularLimitReached) {
452
- const circularLimitData = this.circularLimitReached;
453
- result = { error: `Circular Calls Limit Reached on ${circularLimitData}. Current circular limit is ${this.agent.circularLimit}` };
454
- } else {
455
- let state = [sessionResults, errorResults].flat(Infinity);
456
- if (!state || state.length == 0) state = errorResults.flat(Infinity);
457
-
458
- //post process run cycle results
459
- //deduplicating redundant entries
460
-
461
- const data = state
462
- .reduce(
463
- (acc, current) => {
464
- if (!acc.seen[current.id]) {
465
- acc.result.push(current);
466
- acc.seen[current.id] = true;
467
- }
468
- return acc;
469
- },
470
- { seen: {}, result: [] }
471
- )
472
- .result.filter((e) => !e.result?._exclude);
473
-
474
- //data.forEach((d: any) => delete d?.result?._debug);
475
-
476
- result = data;
477
- /////////////
478
- }
479
-
480
- //cleanup
481
- delete AgentRuntime.processResults[this.processID];
482
-
483
- this.sync();
484
- return result;
485
- }
486
-
487
- public checkCircularLimit() {
488
- if (this.circularLimitReached) return this.agentContext.circularLimitReached;
489
- for (let componentId in AgentRuntime.tagsData[this.reqTag]) {
490
- if (AgentRuntime.tagsData[this.reqTag][componentId] > this.agent.circularLimit) {
491
- this.sessionClosed = true;
492
- this.agentContext.circularLimitReached = componentId;
493
- return componentId;
494
- }
495
- }
496
- return false;
497
- }
498
-
499
- public async injectDebugOutput(componentId: string) {
500
- let component: {
501
- ctx?: Record<string, any>;
502
- } = {};
503
-
504
- if (this.xDebugPendingInject) {
505
- component = this.xDebugPendingInject?.find((c: any) => c.id == componentId);
506
- } else if (this.xMockDataInject) {
507
- component = this.xMockDataInject?.find((c: any) => c.id == componentId);
508
- }
509
-
510
- if (component?.ctx?.output) {
511
- //if all outputs values are empty, we don't inject
512
- let allEmpty = true;
513
- for (let key in component.ctx.output) {
514
- if (component.ctx.output[key] != '') {
515
- allEmpty = false;
516
- break;
517
- }
518
- }
519
- if (allEmpty) return null;
520
-
521
- return component.ctx.output;
522
- }
523
- }
524
- public getRuntimeData(componentId) {
525
- const componentData = this.getComponentData(componentId);
526
- if (!componentData) return {};
527
- const rData = componentData.runtimeData || {};
528
-
529
- return rData;
530
- }
531
- public updateRuntimeData(componentId, data) {
532
- const componentData = this.getComponentData(componentId);
533
- if (!componentData) return;
534
- componentData.runtimeData = { ...componentData.runtimeData, ...data };
535
-
536
- this.sync();
537
- }
538
-
539
- public saveRuntimeComponentData(componentId, data) {
540
- this.updateComponent(componentId, { runtimeData: data });
541
- }
542
-
543
- public incStep() {
544
- this.agentContext.incStep();
545
- }
546
- public updateComponent(componentId: string, data: any) {
547
- this.agentContext.updateComponent(componentId, data);
548
- }
549
-
550
- public resetComponent(componentId: string) {
551
- this.agentContext.resetComponent(componentId);
552
- }
553
-
554
- public getComponentData(componentId: string) {
555
- return this.agentContext.getComponentData(componentId);
556
- }
557
- }
1
+ import { Component } from '@sre/Components/Component.class';
2
+ import { Agent } from './Agent.class';
3
+
4
+ import { Logger } from '@sre/helpers/Log.helper';
5
+ import { LLMCache } from '@sre/MemoryManager/LLMCache';
6
+ import { RuntimeContext } from '@sre/MemoryManager/RuntimeContext';
7
+ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
8
+ import { uid } from '@sre/utils';
9
+
10
+ const console = Logger('AgentRuntime');
11
+ const AgentRuntimeUnavailable = new Proxy(
12
+ {},
13
+ {
14
+ get: function (target, prop, receiver) {
15
+ // Check if the property being accessed is a function
16
+ if (typeof target[prop] === 'function') {
17
+ return target[prop];
18
+ } else {
19
+ // Return a function that logs "unavailable"
20
+ return function () {
21
+ console.warn(`AgentRuntime Unavailable tried to call : ${prop.toString()}`);
22
+ };
23
+ }
24
+ },
25
+ }
26
+ );
27
+ export class AgentRuntime {
28
+ private static processResults: any = {};
29
+ private static tagsData = {};
30
+ public static dummy = AgentRuntimeUnavailable;
31
+
32
+ private agentContext: RuntimeContext;
33
+ public llmCache: LLMCache;
34
+ //private ctxFile: string = '';
35
+ private xDebugRun: string | undefined = '';
36
+ private xDebugInject: string | undefined = '';
37
+ private xDebugRead: string | undefined = '';
38
+ private xDebugStop: string | undefined = '';
39
+ private xDebugPendingInject: any = null;
40
+ private xMockDataInject: any = null;
41
+ public xDebugId: string | undefined = '';
42
+
43
+ private xDebugCmd: string | undefined = '';
44
+ private _debugActive = false;
45
+ private _runtimeFileReady = false;
46
+ public sessionClosed = false;
47
+
48
+ private reqTagOwner = false;
49
+
50
+ //reqTag is used to identify the current running workflow including nested calls, it allows us to identify circular calls
51
+ public reqTag: any;
52
+ public processID: any; //this identifies the current processID, a process ID is the full set of runCycles that is executed by the agent.
53
+ public workflowReqId: any; //this identifies the current running workflow. a workflow starts when and agent endpoint is called, or a debug session is initiated, and ends when no more steps can be executed.
54
+
55
+ public alwaysActiveComponents: any = {};
56
+ public exclusiveComponents: any = {};
57
+
58
+ private checkRuntimeContext: any = null;
59
+
60
+ public get circularLimitReached() {
61
+ return this.agentContext?.circularLimitReached || false;
62
+ }
63
+ public set circularLimitReached(value) {
64
+ if (this.agentContext) this.agentContext.circularLimitReached = value;
65
+ }
66
+
67
+ public get debug() {
68
+ return this._debugActive;
69
+ }
70
+ public get curStep() {
71
+ return this.agentContext?.step || 0;
72
+ }
73
+
74
+ constructor(public agent: Agent) {
75
+ this.reqTag = agent.agentRequest.header('X-REQUEST-TAG');
76
+ const isNestedProcess: boolean = !!this.reqTag;
77
+
78
+ if (!this.reqTag) {
79
+ //tagged request should not be run in debug mode, this comes from a parent agent
80
+ this.xDebugStop = agent.agentRequest.header('X-DEBUG-STOP');
81
+ this.xDebugRun = agent.agentRequest.header('X-DEBUG-RUN'); //send this as header to create a session and attach it
82
+ this.xDebugInject = agent.agentRequest.header('X-DEBUG-INJ');
83
+ this.xDebugRead = agent.agentRequest.header('X-DEBUG-READ');
84
+ this.reqTag = 'xTAG-' + uid(); //if request tag is not set, set a new value, this will be used to tag nested agent calls
85
+ this.reqTagOwner = true;
86
+ } else {
87
+ this.xDebugStop = undefined;
88
+ this.xDebugRun = undefined;
89
+ this.xDebugInject = undefined;
90
+ this.xDebugRead = undefined;
91
+ }
92
+
93
+ this.xDebugId = this.xDebugStop || this.xDebugRun || this.xDebugRead;
94
+
95
+ //if (req.body) {
96
+ if (!this.xDebugId && agent.agentRequest.body) {
97
+ if (this.xDebugInject != undefined && this.xDebugInject != null) {
98
+ this.xDebugPendingInject = agent.agentRequest.body;
99
+ this.xDebugRun = this.xDebugInject || 'inj-' + uid();
100
+ } else {
101
+ if (this.xDebugRun == '') {
102
+ this.xDebugRun = 'dbg-' + uid(); //generate a random debug id
103
+ }
104
+ }
105
+ this.xDebugId = this.xDebugRun;
106
+ }
107
+
108
+ if (agent.agentRequest.header('X-MOCK-DATA-INJ') !== undefined) {
109
+ this.xMockDataInject = agent.agentRequest.body;
110
+ }
111
+
112
+ this.processID = this.xDebugId;
113
+
114
+ if (!this.xDebugId) {
115
+ //if it's not a debug session, processID is unique per request
116
+ this.xDebugId = agent.sessionId;
117
+ this.processID = this.reqTag;
118
+ }
119
+ if (isNestedProcess) {
120
+ // Need to make processID unique to run same sub-agents multiple times in parallel
121
+ this.processID += `:${Math.floor(1000 + Math.random() * 9000)}`;
122
+ }
123
+
124
+ //we need a way to identify current running workflow in a unique way
125
+ //=> In debug mode, xDebugRun holds the debug sessionID which is unique per workflow run
126
+ // if the debug session is stopped, xDebugStop holds the sessionID
127
+ // Note : We can't use reqTag in debug mode because it changes every time a new debug step is executed
128
+ //
129
+ //=> In normal mode, reqTag is unique per workflow run
130
+ this.workflowReqId = this.xDebugRun || this.xDebugStop || this.reqTag;
131
+
132
+ //tagsData can be updated from external integrations (eg. Chatbot, API Endpoint, etc.)
133
+ if (!AgentRuntime.tagsData[this.reqTag]) AgentRuntime.tagsData[this.reqTag] = {};
134
+ if (!AgentRuntime.processResults[this.processID])
135
+ AgentRuntime.processResults[this.processID] = {
136
+ timestamp: Date.now(),
137
+ errorResults: [],
138
+ sessionResults: [],
139
+ };
140
+
141
+ this.agentContext = new RuntimeContext(this);
142
+ this.agentContext.on('ready', () => {
143
+ this.alwaysActiveComponents = {};
144
+ this.exclusiveComponents = {};
145
+ for (let component of this.agent.data.components) {
146
+ const cpt: Component = this.agent.ComponentInstances[component.name];
147
+ if (!cpt) {
148
+ console.warn(`Component ${component.name} Exists in agent but has no implementation`, AccessCandidate.agent(this.agent.id));
149
+ continue;
150
+ }
151
+
152
+ if (cpt.alwaysActive) {
153
+ this.alwaysActiveComponents[component.id] = cpt;
154
+ this.updateComponent(component.id, { active: true, alwaysActive: true });
155
+ const runtimeData = { ...this.getRuntimeData(component.id) };
156
+ this.saveRuntimeComponentData(component.id, runtimeData);
157
+ }
158
+ if (cpt.exclusive) {
159
+ this.exclusiveComponents[component.id] = cpt;
160
+ this.updateComponent(component.id, { exclusive: true });
161
+ const runtimeData = { ...this.getRuntimeData(component.id) };
162
+ this.saveRuntimeComponentData(component.id, runtimeData);
163
+ }
164
+ }
165
+ });
166
+
167
+ //if xDebugId is equal to agent session, it means that the debugging features are not active
168
+ this._debugActive = this.xDebugId != agent.sessionId;
169
+
170
+ const xCacheId = agent.agentRequest.header('X-CACHE-ID') || '';
171
+ this.llmCache = new LLMCache(AccessCandidate.agent(this.agent.id), xCacheId);
172
+ //this.xCacheId =
173
+ }
174
+
175
+ public async ready() {
176
+ return this.agentContext.ready();
177
+ }
178
+
179
+ public destroy() {
180
+ this.sessionClosed = true;
181
+ this.sync();
182
+ }
183
+
184
+ public incTag(componentId) {
185
+ if (!AgentRuntime.tagsData[this.reqTag][componentId]) AgentRuntime.tagsData[this.reqTag][componentId] = 0;
186
+ AgentRuntime.tagsData[this.reqTag][componentId]++;
187
+
188
+ // console.log(
189
+ // `incTag agentId=${this.agent.id} componentId=${componentId} tag=${this.reqTag} ==> ${AgentRuntime.tagsData[this.reqTag][componentId]}`,
190
+ // );
191
+ //console.log('incTag tagsData', tagsData);
192
+ }
193
+
194
+ public async sync() {
195
+ //if (!this.ctxFile) return;
196
+
197
+ const deleteTag = (this.reqTagOwner && this.sessionClosed) || this.circularLimitReached;
198
+ if (deleteTag) {
199
+ delete AgentRuntime.tagsData[this.reqTag];
200
+ }
201
+
202
+ this.agentContext.enqueueSync();
203
+ }
204
+ public getWaitingComponents() {
205
+ const ctxData = this.agentContext;
206
+ const dbgComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
207
+ const waitingComponents: any = dbgComponents.filter((c: any) => c?.ctx?.status && typeof c?.ctx?.output !== undefined);
208
+ return waitingComponents;
209
+ }
210
+ public getExclusiveActiveComponents() {
211
+ const ctxData = this.agentContext;
212
+ const dbgComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
213
+ const exclusiveActiveComponents: any = dbgComponents.filter((c: any) => c?.ctx?.exclusive == true);
214
+ return exclusiveActiveComponents;
215
+ }
216
+ public readState(stateId: string, deltaOnly = false) {
217
+ //if (!this._debugActive || !this.xDebugRead) return null;
218
+ if (!this._debugActive || !stateId) return null;
219
+
220
+ //this.checkRuntimeContext();
221
+ const runtime = this;
222
+ const agent = this.agent;
223
+
224
+ const ctxData = runtime.agentContext;
225
+ const dbgAllComponents: any = runtime.xDebugPendingInject || Object.values(ctxData?.components || []);
226
+
227
+ //first try to find exclusive active components
228
+ let dbgActiveComponents: any;
229
+ dbgActiveComponents = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && c?.ctx?.exclusive == true);
230
+ //if no exclusive active components, find all active components
231
+ if (!dbgActiveComponents || dbgActiveComponents.length == 0)
232
+ dbgActiveComponents = dbgAllComponents.filter(
233
+ (c: any) =>
234
+ c?.ctx?.active == true ||
235
+ (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
236
+ );
237
+ //find waiting components that was not previously run
238
+ const dbgActiveWaitingComponents: any = dbgAllComponents.filter(
239
+ (c: any) => c?.ctx?.active == true && c?.ctx?.status && typeof c?.ctx?.output !== undefined
240
+ );
241
+
242
+ const dbgActiveReadyComponents: any = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && !c?.ctx?.status);
243
+
244
+ let state = {};
245
+ for (let dbgComponent of dbgAllComponents) {
246
+ state[dbgComponent.id] = dbgComponent.ctx;
247
+ }
248
+
249
+ //let dbgSession: any = runtime.xDebugRead;
250
+ let dbgSession: any = stateId;
251
+
252
+ // let alwaysActiveComponents = 0;
253
+ // for (let activeCpt of dbgActiveComponents) {
254
+ // if (this.agent.alwaysActiveComponents[activeCpt.id]) alwaysActiveComponents++;
255
+ // }
256
+
257
+ if (!dbgActiveComponents || dbgActiveComponents.length == 0 /*|| dbgActiveComponents.length == alwaysActiveComponents*/) {
258
+ dbgSession = null;
259
+ runtime.sessionClosed = true;
260
+ }
261
+
262
+ const remainingActiveComponents: any = Object.values(ctxData?.components || []).filter(
263
+ (c: any) => c?.ctx?.active == true && !c?.ctx?.alwaysActive
264
+ );
265
+ const activeAsyncComponents: any = Object.values(ctxData?.components || []).filter(
266
+ (c: any) => !c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0
267
+ );
268
+
269
+ if (remainingActiveComponents.length == 0 && activeAsyncComponents.length == 0 /*&& awaitingInputs.length == 0*/) {
270
+ runtime.sessionClosed = true;
271
+ }
272
+
273
+ if (runtime.circularLimitReached) {
274
+ const circularLimitData = runtime.checkCircularLimit();
275
+ const error = `Circular Calls Limit Reached on ${circularLimitData}. Current agent circular limit is ${agent.circularLimit}`;
276
+ runtime.sessionClosed = true;
277
+ return { state, dbgSession, sessionClosed: runtime.sessionClosed, error };
278
+ }
279
+
280
+ const step = this.curStep >= 1 ? this.curStep - 1 : 0; //current state was executed in previous step
281
+
282
+ if (deltaOnly) {
283
+ const delta = {};
284
+ for (let cptId in state) {
285
+ const cpt = state[cptId];
286
+
287
+ //workaround, here we are supposed to test component steps that are equalt to current step
288
+ //but due to an inconsistency, the Async component has sometimes a step greater than the current step
289
+ if (cpt.step >= step) delta[cptId] = cpt;
290
+ //FIXME : identify the root cause of this issue and replace >= with ==
291
+ }
292
+ //return { state: delta, dbgSession, sessionClosed: runtime.sessionClosed, step };
293
+ state = delta;
294
+ }
295
+
296
+ return { state, dbgSession, sessionClosed: runtime.sessionClosed, step };
297
+ }
298
+
299
+ /**
300
+ * This method is called by the agent to run a process cycle, it will run all active components and return the results
301
+ * The function is called multiple times until all components are executed and no more active components are available
302
+ * @returns
303
+ */
304
+ public async runCycle() {
305
+ console.debug(
306
+ `runCycle agentId=${this.agent.id} wfReqId=${this.workflowReqId} reqTag=${this.reqTag} session=${this.xDebugRun} cycleId=${this.processID}`,
307
+ AccessCandidate.agent(this.agent.id)
308
+ );
309
+ //this.checkRuntimeContext();
310
+
311
+ const runtime = this;
312
+ const agent = this.agent;
313
+ const ctxData = runtime.agentContext;
314
+ const dbgAllComponents: any = runtime.xDebugPendingInject || Object.values(ctxData?.components || []);
315
+
316
+ //first try to find exclusive active components
317
+ let dbgActiveComponents: any;
318
+ dbgActiveComponents = dbgAllComponents.filter((c: any) => c?.ctx?.active == true && c?.ctx?.exclusive == true);
319
+ //if no exclusive active components, find all active components
320
+ if (!dbgActiveComponents || dbgActiveComponents.length == 0)
321
+ dbgActiveComponents = dbgAllComponents.filter(
322
+ (c: any) =>
323
+ c?.ctx?.active == true ||
324
+ (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
325
+ );
326
+ //find waiting components that was not previously run
327
+ const dbgActiveWaitingComponents: any = dbgAllComponents.filter(
328
+ (c: any) => c?.ctx?.active == true && c?.ctx?.status && typeof c?.ctx?.output !== undefined
329
+ );
330
+ const dbgActiveReadyComponents: any = dbgAllComponents.filter(
331
+ (c: any) =>
332
+ (c?.ctx?.active == true && !c?.ctx?.status) ||
333
+ (!c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0)
334
+ );
335
+ //const dbgActiveReadyComponents: any = dbgActiveComponents.filter((c: any) => c?.ctx?.active == true && !c?.ctx?.status);
336
+
337
+ let step: any;
338
+
339
+ if (!dbgActiveComponents || dbgActiveComponents.length == 0) {
340
+ runtime.sessionClosed = true;
341
+ step = {
342
+ state: { sessionClosed: true },
343
+ dbgSession: null,
344
+ //expiredDbgSession: runtime.xDebugRun || runtime.xDebugStop,
345
+ expiredDbgSession: runtime.xDebugId,
346
+ sessionClosed: true,
347
+ };
348
+ }
349
+
350
+ if (!step && dbgActiveComponents.length == dbgActiveWaitingComponents.length && ctxData.sessionResult) {
351
+ runtime.sessionClosed = true;
352
+ step = {
353
+ state: { sessionClosed: true },
354
+ dbgSession: null,
355
+ //expiredDbgSession: runtime.xDebugRun,
356
+ expiredDbgSession: runtime.xDebugId,
357
+ sessionClosed: true,
358
+ };
359
+ }
360
+ if (!step && dbgActiveReadyComponents.length > 0) {
361
+ const promises: any = [];
362
+
363
+ for (let dbgComponent of dbgActiveReadyComponents) {
364
+ const injectInput = runtime.xDebugPendingInject ? dbgComponent.ctx.input : undefined;
365
+
366
+ promises.push(agent.callComponent(dbgComponent.ctx.sourceId, dbgComponent.id, injectInput));
367
+ }
368
+ const dbgResults = await Promise.all(promises);
369
+ const state = dbgResults.length == 1 ? dbgResults[0] : dbgResults;
370
+
371
+ runtime.xDebugPendingInject = null;
372
+
373
+ const remainingActiveComponents: any = Object.values(ctxData?.components || []).filter((c: any) => c?.ctx?.active == true);
374
+ const activeAsyncComponents: any = Object.values(ctxData?.components || []).filter(
375
+ (c: any) => !c?.ctx?.output?._error && Array.isArray(c?.ctx?._job_components) && c?.ctx?._job_components.length > 0
376
+ );
377
+ const dbgActiveWaitingComponents: any = dbgAllComponents.filter((c: any) => c?.ctx?.status && typeof c?.ctx?.output !== undefined);
378
+
379
+ if (dbgActiveWaitingComponents.length == remainingActiveComponents.length) {
380
+ ctxData.sessionResult = true;
381
+ }
382
+
383
+ //capture results
384
+ let sessionResults = dbgResults.flat().filter(
385
+ (e) =>
386
+ e.id &&
387
+ e.result &&
388
+ !e.result._missing_inputs &&
389
+ //check if this is the last component in the chain
390
+ !agent.connections.find((c) => c.sourceId == e.id)
391
+ );
392
+
393
+ let errorResults = dbgResults.flat().filter((e) => e.id && (e.error || e.result?._error));
394
+
395
+ //also filter out erroneous components that are children of a loop
396
+ //otherwise, errors inside a loop will be reported as session results and can lead to wrong results or generated noise in the final agent output
397
+ errorResults = errorResults.filter((e) => {
398
+ return !ctxData?.components?.[e.id]?.ctx?.runtimeData?._ChildLoopData;
399
+ });
400
+
401
+ if (ctxData.sessionResult && sessionResults.length == 0 && runtime.sessionClosed) {
402
+ //no result ? check if we have errors
403
+ sessionResults = errorResults;
404
+ }
405
+
406
+ ctxData.sessionResults = sessionResults;
407
+ step = {
408
+ state,
409
+ dbgSession: runtime.xDebugRun,
410
+ sessionResult: runtime.agentContext.sessionResult,
411
+ sessionResults: runtime.agentContext.sessionResults,
412
+ errorResults,
413
+ sessionClosed: remainingActiveComponents.length == 0 && activeAsyncComponents.length == 0 /*&& awaitingInputs.length == 0*/,
414
+ };
415
+ } else {
416
+ runtime.sessionClosed = true;
417
+ //return { sessionClosed: true };
418
+ step = {
419
+ state: { sessionClosed: true },
420
+ dbgSession: null,
421
+ //expiredDbgSession: runtime.xDebugRun || runtime.xDebugStop,
422
+ expiredDbgSession: runtime.xDebugId,
423
+ sessionClosed: true,
424
+ };
425
+ }
426
+
427
+ this.checkCircularLimit();
428
+ if (step.sessionResults) {
429
+ AgentRuntime.processResults[this.processID].sessionResults.push(step.sessionResults);
430
+ }
431
+ if (step.errorResults) {
432
+ AgentRuntime.processResults[this.processID].errorResults.push(step.errorResults);
433
+ }
434
+
435
+ if (step?.sessionClosed || this.circularLimitReached) {
436
+ const finalResult = this.processResults();
437
+ step.finalResult = finalResult;
438
+ runtime.sessionClosed = true;
439
+ }
440
+
441
+ this.incStep();
442
+ this.sync();
443
+ return step;
444
+ }
445
+
446
+ private processResults() {
447
+ //this.checkCircularLimit();
448
+ let result: any = { error: 'Error processing results' };
449
+ const sessionResults = AgentRuntime.processResults[this.processID].sessionResults;
450
+ const errorResults = AgentRuntime.processResults[this.processID].errorResults;
451
+ if (this.circularLimitReached) {
452
+ const circularLimitData = this.circularLimitReached;
453
+ result = { error: `Circular Calls Limit Reached on ${circularLimitData}. Current circular limit is ${this.agent.circularLimit}` };
454
+ } else {
455
+ let state = [sessionResults, errorResults].flat(Infinity);
456
+ if (!state || state.length == 0) state = errorResults.flat(Infinity);
457
+
458
+ //post process run cycle results
459
+ //deduplicating redundant entries
460
+
461
+ const data = state
462
+ .reduce(
463
+ (acc, current) => {
464
+ if (!acc.seen[current.id]) {
465
+ acc.result.push(current);
466
+ acc.seen[current.id] = true;
467
+ }
468
+ return acc;
469
+ },
470
+ { seen: {}, result: [] }
471
+ )
472
+ .result.filter((e) => !e.result?._exclude);
473
+
474
+ //data.forEach((d: any) => delete d?.result?._debug);
475
+
476
+ result = data;
477
+ /////////////
478
+ }
479
+
480
+ //cleanup
481
+ delete AgentRuntime.processResults[this.processID];
482
+
483
+ this.sync();
484
+ return result;
485
+ }
486
+
487
+ public checkCircularLimit() {
488
+ if (this.circularLimitReached) return this.agentContext.circularLimitReached;
489
+ for (let componentId in AgentRuntime.tagsData[this.reqTag]) {
490
+ if (AgentRuntime.tagsData[this.reqTag][componentId] > this.agent.circularLimit) {
491
+ this.sessionClosed = true;
492
+ this.agentContext.circularLimitReached = componentId;
493
+ return componentId;
494
+ }
495
+ }
496
+ return false;
497
+ }
498
+
499
+ public async injectDebugOutput(componentId: string) {
500
+ let component: {
501
+ ctx?: Record<string, any>;
502
+ } = {};
503
+
504
+ if (this.xDebugPendingInject) {
505
+ component = this.xDebugPendingInject?.find((c: any) => c.id == componentId);
506
+ } else if (this.xMockDataInject) {
507
+ component = this.xMockDataInject?.find((c: any) => c.id == componentId);
508
+ }
509
+
510
+ if (component?.ctx?.output) {
511
+ //if all outputs values are empty, we don't inject
512
+ let allEmpty = true;
513
+ for (let key in component.ctx.output) {
514
+ if (component.ctx.output[key] != '') {
515
+ allEmpty = false;
516
+ break;
517
+ }
518
+ }
519
+ if (allEmpty) return null;
520
+
521
+ return component.ctx.output;
522
+ }
523
+ }
524
+ public getRuntimeData(componentId) {
525
+ const componentData = this.getComponentData(componentId);
526
+ if (!componentData) return {};
527
+ const rData = componentData.runtimeData || {};
528
+
529
+ return rData;
530
+ }
531
+ public updateRuntimeData(componentId, data) {
532
+ const componentData = this.getComponentData(componentId);
533
+ if (!componentData) return;
534
+ componentData.runtimeData = { ...componentData.runtimeData, ...data };
535
+
536
+ this.sync();
537
+ }
538
+
539
+ public saveRuntimeComponentData(componentId, data) {
540
+ this.updateComponent(componentId, { runtimeData: data });
541
+ }
542
+
543
+ public incStep() {
544
+ this.agentContext.incStep();
545
+ }
546
+ public updateComponent(componentId: string, data: any) {
547
+ this.agentContext.updateComponent(componentId, data);
548
+ }
549
+
550
+ public resetComponent(componentId: string) {
551
+ this.agentContext.resetComponent(componentId);
552
+ }
553
+
554
+ public getComponentData(componentId: string) {
555
+ return this.agentContext.getComponentData(componentId);
556
+ }
557
+ }