@smythos/sre 1.5.1 → 1.5.4

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 (193) hide show
  1. package/LICENSE +18 -0
  2. package/dist/index.js +22329 -4
  3. package/dist/index.js.map +1 -1
  4. package/dist/types/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.d.ts +2 -2
  5. package/dist/types/subsystems/IO/VectorDB.service/embed/BaseEmbedding.d.ts +11 -7
  6. package/dist/types/types/VectorDB.types.d.ts +13 -11
  7. package/package.json +102 -127
  8. package/src/Components/APICall/APICall.class.ts +155 -0
  9. package/src/Components/APICall/AccessTokenManager.ts +130 -0
  10. package/src/Components/APICall/ArrayBufferResponse.helper.ts +58 -0
  11. package/src/Components/APICall/OAuth.helper.ts +294 -0
  12. package/src/Components/APICall/mimeTypeCategories.ts +46 -0
  13. package/src/Components/APICall/parseData.ts +167 -0
  14. package/src/Components/APICall/parseHeaders.ts +41 -0
  15. package/src/Components/APICall/parseProxy.ts +68 -0
  16. package/src/Components/APICall/parseUrl.ts +91 -0
  17. package/src/Components/APIEndpoint.class.ts +234 -0
  18. package/src/Components/APIOutput.class.ts +58 -0
  19. package/src/Components/AgentPlugin.class.ts +102 -0
  20. package/src/Components/Async.class.ts +155 -0
  21. package/src/Components/Await.class.ts +90 -0
  22. package/src/Components/Classifier.class.ts +158 -0
  23. package/src/Components/Component.class.ts +94 -0
  24. package/src/Components/ComponentHost.class.ts +38 -0
  25. package/src/Components/DataSourceCleaner.class.ts +92 -0
  26. package/src/Components/DataSourceIndexer.class.ts +181 -0
  27. package/src/Components/DataSourceLookup.class.ts +141 -0
  28. package/src/Components/FEncDec.class.ts +29 -0
  29. package/src/Components/FHash.class.ts +33 -0
  30. package/src/Components/FSign.class.ts +80 -0
  31. package/src/Components/FSleep.class.ts +25 -0
  32. package/src/Components/FTimestamp.class.ts +25 -0
  33. package/src/Components/FileStore.class.ts +75 -0
  34. package/src/Components/ForEach.class.ts +97 -0
  35. package/src/Components/GPTPlugin.class.ts +70 -0
  36. package/src/Components/GenAILLM.class.ts +395 -0
  37. package/src/Components/HuggingFace.class.ts +314 -0
  38. package/src/Components/Image/imageSettings.config.ts +70 -0
  39. package/src/Components/ImageGenerator.class.ts +407 -0
  40. package/src/Components/JSONFilter.class.ts +54 -0
  41. package/src/Components/LLMAssistant.class.ts +213 -0
  42. package/src/Components/LogicAND.class.ts +28 -0
  43. package/src/Components/LogicAtLeast.class.ts +85 -0
  44. package/src/Components/LogicAtMost.class.ts +86 -0
  45. package/src/Components/LogicOR.class.ts +29 -0
  46. package/src/Components/LogicXOR.class.ts +34 -0
  47. package/src/Components/MCPClient.class.ts +112 -0
  48. package/src/Components/PromptGenerator.class.ts +122 -0
  49. package/src/Components/ScrapflyWebScrape.class.ts +159 -0
  50. package/src/Components/TavilyWebSearch.class.ts +98 -0
  51. package/src/Components/index.ts +77 -0
  52. package/src/Core/AgentProcess.helper.ts +240 -0
  53. package/src/Core/Connector.class.ts +123 -0
  54. package/src/Core/ConnectorsService.ts +192 -0
  55. package/src/Core/DummyConnector.ts +49 -0
  56. package/src/Core/HookService.ts +105 -0
  57. package/src/Core/SmythRuntime.class.ts +292 -0
  58. package/src/Core/SystemEvents.ts +15 -0
  59. package/src/Core/boot.ts +55 -0
  60. package/src/config.ts +15 -0
  61. package/src/constants.ts +125 -0
  62. package/src/data/hugging-face.params.json +580 -0
  63. package/src/helpers/BinaryInput.helper.ts +324 -0
  64. package/src/helpers/Conversation.helper.ts +1094 -0
  65. package/src/helpers/JsonContent.helper.ts +97 -0
  66. package/src/helpers/LocalCache.helper.ts +97 -0
  67. package/src/helpers/Log.helper.ts +234 -0
  68. package/src/helpers/OpenApiParser.helper.ts +150 -0
  69. package/src/helpers/S3Cache.helper.ts +129 -0
  70. package/src/helpers/SmythURI.helper.ts +5 -0
  71. package/src/helpers/TemplateString.helper.ts +243 -0
  72. package/src/helpers/TypeChecker.helper.ts +329 -0
  73. package/src/index.ts +179 -0
  74. package/src/index.ts.bak +179 -0
  75. package/src/subsystems/AgentManager/Agent.class.ts +1108 -0
  76. package/src/subsystems/AgentManager/Agent.helper.ts +3 -0
  77. package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +230 -0
  78. package/src/subsystems/AgentManager/AgentData.service/connectors/CLIAgentDataConnector.class.ts +66 -0
  79. package/src/subsystems/AgentManager/AgentData.service/connectors/LocalAgentDataConnector.class.ts +142 -0
  80. package/src/subsystems/AgentManager/AgentData.service/connectors/NullAgentData.class.ts +39 -0
  81. package/src/subsystems/AgentManager/AgentData.service/index.ts +18 -0
  82. package/src/subsystems/AgentManager/AgentLogger.class.ts +297 -0
  83. package/src/subsystems/AgentManager/AgentRequest.class.ts +51 -0
  84. package/src/subsystems/AgentManager/AgentRuntime.class.ts +559 -0
  85. package/src/subsystems/AgentManager/AgentSSE.class.ts +101 -0
  86. package/src/subsystems/AgentManager/AgentSettings.class.ts +52 -0
  87. package/src/subsystems/AgentManager/Component.service/ComponentConnector.ts +32 -0
  88. package/src/subsystems/AgentManager/Component.service/connectors/LocalComponentConnector.class.ts +59 -0
  89. package/src/subsystems/AgentManager/Component.service/index.ts +11 -0
  90. package/src/subsystems/AgentManager/EmbodimentSettings.class.ts +47 -0
  91. package/src/subsystems/AgentManager/ForkedAgent.class.ts +153 -0
  92. package/src/subsystems/AgentManager/OSResourceMonitor.ts +77 -0
  93. package/src/subsystems/ComputeManager/Code.service/CodeConnector.ts +99 -0
  94. package/src/subsystems/ComputeManager/Code.service/connectors/AWSLambdaCode.class.ts +63 -0
  95. package/src/subsystems/ComputeManager/Code.service/index.ts +11 -0
  96. package/src/subsystems/IO/CLI.service/CLIConnector.ts +47 -0
  97. package/src/subsystems/IO/CLI.service/index.ts +9 -0
  98. package/src/subsystems/IO/Log.service/LogConnector.ts +32 -0
  99. package/src/subsystems/IO/Log.service/connectors/ConsoleLog.class.ts +28 -0
  100. package/src/subsystems/IO/Log.service/index.ts +13 -0
  101. package/src/subsystems/IO/NKV.service/NKVConnector.ts +41 -0
  102. package/src/subsystems/IO/NKV.service/connectors/NKVRAM.class.ts +204 -0
  103. package/src/subsystems/IO/NKV.service/connectors/NKVRedis.class.ts +182 -0
  104. package/src/subsystems/IO/NKV.service/index.ts +12 -0
  105. package/src/subsystems/IO/Router.service/RouterConnector.ts +21 -0
  106. package/src/subsystems/IO/Router.service/connectors/ExpressRouter.class.ts +48 -0
  107. package/src/subsystems/IO/Router.service/connectors/NullRouter.class.ts +40 -0
  108. package/src/subsystems/IO/Router.service/index.ts +11 -0
  109. package/src/subsystems/IO/Storage.service/SmythFS.class.ts +472 -0
  110. package/src/subsystems/IO/Storage.service/StorageConnector.ts +66 -0
  111. package/src/subsystems/IO/Storage.service/connectors/LocalStorage.class.ts +305 -0
  112. package/src/subsystems/IO/Storage.service/connectors/S3Storage.class.ts +418 -0
  113. package/src/subsystems/IO/Storage.service/index.ts +13 -0
  114. package/src/subsystems/IO/VectorDB.service/VectorDBConnector.ts +108 -0
  115. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +454 -0
  116. package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +384 -0
  117. package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +421 -0
  118. package/src/subsystems/IO/VectorDB.service/embed/BaseEmbedding.ts +107 -0
  119. package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +109 -0
  120. package/src/subsystems/IO/VectorDB.service/embed/index.ts +21 -0
  121. package/src/subsystems/IO/VectorDB.service/index.ts +14 -0
  122. package/src/subsystems/LLMManager/LLM.helper.ts +221 -0
  123. package/src/subsystems/LLMManager/LLM.inference.ts +335 -0
  124. package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +375 -0
  125. package/src/subsystems/LLMManager/LLM.service/LLMCredentials.helper.ts +145 -0
  126. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +632 -0
  127. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +405 -0
  128. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +81 -0
  129. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +689 -0
  130. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +257 -0
  131. package/src/subsystems/LLMManager/LLM.service/connectors/OpenAI.class.ts +848 -0
  132. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +255 -0
  133. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +193 -0
  134. package/src/subsystems/LLMManager/LLM.service/index.ts +43 -0
  135. package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +281 -0
  136. package/src/subsystems/LLMManager/ModelsProvider.service/connectors/SmythModelsProvider.class.ts +229 -0
  137. package/src/subsystems/LLMManager/ModelsProvider.service/index.ts +11 -0
  138. package/src/subsystems/LLMManager/custom-models.ts +854 -0
  139. package/src/subsystems/LLMManager/models.ts +2539 -0
  140. package/src/subsystems/LLMManager/paramMappings.ts +69 -0
  141. package/src/subsystems/MemoryManager/Cache.service/CacheConnector.ts +86 -0
  142. package/src/subsystems/MemoryManager/Cache.service/connectors/LocalStorageCache.class.ts +297 -0
  143. package/src/subsystems/MemoryManager/Cache.service/connectors/RAMCache.class.ts +201 -0
  144. package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +252 -0
  145. package/src/subsystems/MemoryManager/Cache.service/connectors/S3Cache.class.ts +373 -0
  146. package/src/subsystems/MemoryManager/Cache.service/index.ts +15 -0
  147. package/src/subsystems/MemoryManager/LLMCache.ts +72 -0
  148. package/src/subsystems/MemoryManager/LLMContext.ts +125 -0
  149. package/src/subsystems/MemoryManager/RuntimeContext.ts +249 -0
  150. package/src/subsystems/Security/AccessControl/ACL.class.ts +208 -0
  151. package/src/subsystems/Security/AccessControl/AccessCandidate.class.ts +76 -0
  152. package/src/subsystems/Security/AccessControl/AccessRequest.class.ts +52 -0
  153. package/src/subsystems/Security/Account.service/AccountConnector.ts +41 -0
  154. package/src/subsystems/Security/Account.service/connectors/AWSAccount.class.ts +76 -0
  155. package/src/subsystems/Security/Account.service/connectors/DummyAccount.class.ts +130 -0
  156. package/src/subsystems/Security/Account.service/connectors/JSONFileAccount.class.ts +159 -0
  157. package/src/subsystems/Security/Account.service/index.ts +14 -0
  158. package/src/subsystems/Security/Credentials.helper.ts +62 -0
  159. package/src/subsystems/Security/ManagedVault.service/ManagedVaultConnector.ts +34 -0
  160. package/src/subsystems/Security/ManagedVault.service/connectors/NullManagedVault.class.ts +57 -0
  161. package/src/subsystems/Security/ManagedVault.service/connectors/SecretManagerManagedVault.ts +154 -0
  162. package/src/subsystems/Security/ManagedVault.service/index.ts +12 -0
  163. package/src/subsystems/Security/SecureConnector.class.ts +110 -0
  164. package/src/subsystems/Security/Vault.service/Vault.helper.ts +30 -0
  165. package/src/subsystems/Security/Vault.service/VaultConnector.ts +26 -0
  166. package/src/subsystems/Security/Vault.service/connectors/HashicorpVault.class.ts +46 -0
  167. package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +166 -0
  168. package/src/subsystems/Security/Vault.service/connectors/NullVault.class.ts +54 -0
  169. package/src/subsystems/Security/Vault.service/connectors/SecretsManager.class.ts +140 -0
  170. package/src/subsystems/Security/Vault.service/index.ts +12 -0
  171. package/src/types/ACL.types.ts +104 -0
  172. package/src/types/AWS.types.ts +9 -0
  173. package/src/types/Agent.types.ts +61 -0
  174. package/src/types/AgentLogger.types.ts +17 -0
  175. package/src/types/Cache.types.ts +1 -0
  176. package/src/types/Common.types.ts +3 -0
  177. package/src/types/LLM.types.ts +419 -0
  178. package/src/types/Redis.types.ts +8 -0
  179. package/src/types/SRE.types.ts +64 -0
  180. package/src/types/Security.types.ts +18 -0
  181. package/src/types/Storage.types.ts +5 -0
  182. package/src/types/VectorDB.types.ts +86 -0
  183. package/src/utils/base64.utils.ts +275 -0
  184. package/src/utils/cli.utils.ts +68 -0
  185. package/src/utils/data.utils.ts +263 -0
  186. package/src/utils/date-time.utils.ts +22 -0
  187. package/src/utils/general.utils.ts +238 -0
  188. package/src/utils/index.ts +12 -0
  189. package/src/utils/numbers.utils.ts +13 -0
  190. package/src/utils/oauth.utils.ts +35 -0
  191. package/src/utils/string.utils.ts +414 -0
  192. package/src/utils/url.utils.ts +19 -0
  193. package/src/utils/validation.utils.ts +74 -0
@@ -0,0 +1,281 @@
1
+ import { ConnectorService } from '@sre/Core/ConnectorsService';
2
+ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
3
+ import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
4
+ import { ACL } from '@sre/Security/AccessControl/ACL.class';
5
+ import { SecureConnector } from '@sre/Security/SecureConnector.class';
6
+ import { IAccessCandidate } from '@sre/types/ACL.types';
7
+ import { TCustomLLMModel, TLLMCredentials, TLLMModel, TLLMModelsList, TLLMProvider } from '@sre/types/LLM.types';
8
+ import { customModels } from '../custom-models';
9
+ import { LocalCache } from '@sre/helpers/LocalCache.helper';
10
+
11
+ export interface IModelsProviderRequest {
12
+ getModels(): Promise<any>;
13
+ getMaxContextTokens(model: string, hasAPIKey?: boolean): Promise<number>;
14
+ addModels(models: TLLMModelsList): Promise<void>;
15
+ getModelInfo(model: string | TLLMModel | TCustomLLMModel, hasAPIKey?: boolean): Promise<TLLMModel>;
16
+ getModelId(model: string | TLLMModel | TCustomLLMModel): Promise<string>;
17
+ getProvider(model: string | TLLMModel | TCustomLLMModel): Promise<string>;
18
+ isStandardLLM(model: string | TLLMModel | TCustomLLMModel): Promise<boolean>;
19
+ adjustMaxCompletionTokens(model: string | TLLMModel | TCustomLLMModel, maxCompletionTokens: number, hasAPIKey?: boolean): Promise<number>;
20
+ getMaxContextTokens(model: string | TLLMModel | TCustomLLMModel, hasAPIKey?: boolean): Promise<number>;
21
+ getMaxCompletionTokens(model: string | TLLMModel | TCustomLLMModel, hasAPIKey?: boolean): Promise<number>;
22
+ validateTokensLimit({
23
+ model,
24
+ promptTokens,
25
+ completionTokens,
26
+ hasAPIKey,
27
+ }: {
28
+ model: string | TLLMModel | TCustomLLMModel;
29
+ promptTokens: number;
30
+ completionTokens: number;
31
+ hasAPIKey?: boolean;
32
+ }): Promise<void>;
33
+ }
34
+
35
+ export abstract class ModelsProviderConnector extends SecureConnector {
36
+ protected static localCache = new LocalCache();
37
+ public abstract getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL>;
38
+ public abstract getModels(acRequest: AccessRequest): Promise<TLLMModelsList>;
39
+ public abstract addModels(acRequest: AccessRequest, models: TLLMModelsList): Promise<void>;
40
+
41
+ public requester(candidate: AccessCandidate): IModelsProviderRequest {
42
+ const cacheKey = `ModelsProviderConnector:${candidate.toString()}`;
43
+ if (ModelsProviderConnector.localCache.has(cacheKey)) {
44
+ //update the TTL every time the requester is called
45
+ return ModelsProviderConnector.localCache.get(cacheKey, 60 * 60 * 1000) as IModelsProviderRequest;
46
+ }
47
+
48
+ let teamModels = null;
49
+ let customModels = null;
50
+
51
+ const loadTeamModels = async () => {
52
+ if (!teamModels) {
53
+ try {
54
+ const builtinmodels = await this.getModels(candidate.readRequest);
55
+ customModels = await this.getCustomModels(candidate);
56
+ teamModels = { ...builtinmodels, ...customModels };
57
+ } catch (error) {
58
+ return null;
59
+ }
60
+ }
61
+ return teamModels;
62
+ };
63
+ loadTeamModels();
64
+
65
+ const instance: IModelsProviderRequest = {
66
+ getModels: async () => {
67
+ return await loadTeamModels();
68
+ },
69
+ addModels: async (models: TLLMModelsList) => {
70
+ return await this.addModels(candidate.readRequest, models);
71
+ },
72
+ getModelInfo: async (model: string | TLLMModel | TCustomLLMModel, hasAPIKey: boolean = false) => {
73
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
74
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model, hasAPIKey);
75
+ return modelInfo;
76
+ },
77
+
78
+ getModelId: async (model: string | TLLMModel | TCustomLLMModel) => {
79
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
80
+ return this.getModelId(candidate.readRequest, teamModels, model);
81
+ },
82
+ getProvider: async (model: string | TLLMModel | TCustomLLMModel) => {
83
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
84
+ return this.getProvider(candidate.readRequest, teamModels, model);
85
+ },
86
+ isStandardLLM: async (model: string | TLLMModel | TCustomLLMModel) => {
87
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
88
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model);
89
+ return !modelInfo.isCustomLLM;
90
+ },
91
+ adjustMaxCompletionTokens: async (
92
+ model: string | TLLMModel | TCustomLLMModel,
93
+ maxCompletionTokens: number,
94
+ hasAPIKey: boolean = false,
95
+ ) => {
96
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
97
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model, hasAPIKey);
98
+ return Math.min(maxCompletionTokens || 512, modelInfo?.completionTokens || modelInfo?.tokens || maxCompletionTokens || 512);
99
+ },
100
+ getMaxContextTokens: async (model: string | TLLMModel | TCustomLLMModel, hasAPIKey: boolean = false) => {
101
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
102
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model, hasAPIKey);
103
+ return modelInfo?.tokens || 1024;
104
+ },
105
+ getMaxCompletionTokens: async (model: string | TLLMModel | TCustomLLMModel, hasAPIKey: boolean = false) => {
106
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
107
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model, hasAPIKey);
108
+ return modelInfo?.completionTokens || modelInfo?.tokens || 512;
109
+ },
110
+ validateTokensLimit: async ({
111
+ model,
112
+ promptTokens,
113
+ completionTokens,
114
+ hasAPIKey,
115
+ }: {
116
+ model: string | TLLMModel | TCustomLLMModel;
117
+ promptTokens: number;
118
+ completionTokens: number;
119
+ hasAPIKey: boolean;
120
+ }) => {
121
+ const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
122
+ const modelInfo = await this.getModelInfo(candidate.readRequest, teamModels, model, hasAPIKey);
123
+ const allowedContextTokens = modelInfo?.tokens;
124
+ const totalTokens = promptTokens + completionTokens;
125
+
126
+ const teamAPIKeyExceededMessage = `This models' maximum content length is ${allowedContextTokens} tokens. (This is the sum of your prompt with all variables and the maximum output tokens you've set in Advanced Settings) However, you requested approx ${totalTokens} tokens (${promptTokens} in the prompt, ${completionTokens} in the output). Please reduce the length of either the input prompt or the Maximum output tokens.`;
127
+ const noAPIKeyExceededMessage = `Input exceeds max tokens limit of ${allowedContextTokens}. Please add your API key and select Personal tagged models to unlock full length.`;
128
+
129
+ if (totalTokens > allowedContextTokens) {
130
+ throw new Error(hasAPIKey ? teamAPIKeyExceededMessage : noAPIKeyExceededMessage);
131
+ }
132
+ },
133
+ };
134
+ ModelsProviderConnector.localCache.set(cacheKey, instance, 60 * 60 * 1000); // cache for 1 hour
135
+ return instance;
136
+ }
137
+
138
+ protected async getModelInfo(
139
+ acRequest: AccessRequest,
140
+ models: TLLMModelsList,
141
+ model: string | TLLMModel | TCustomLLMModel,
142
+ hasAPIKey: boolean = false,
143
+ ): Promise<TLLMModel> {
144
+ //model can be passed directly, in which case we do not need to look it up in the models list
145
+ if (typeof model === 'object' && model.modelId) {
146
+ return model;
147
+ }
148
+
149
+ //model can be passed as a string, in which case we need to look it up in the models list
150
+
151
+ const modelId = await this.getModelId(acRequest, models, model);
152
+ const alias = models?.[model as string]?.alias;
153
+ const aliasModelInfo = models?.[alias];
154
+
155
+ const modelInfo = models?.[model as string];
156
+
157
+ const aliasKeyOptions = aliasModelInfo && hasAPIKey ? aliasModelInfo?.keyOptions : null;
158
+
159
+ const modelKeyOptions = modelInfo?.keyOptions || aliasKeyOptions;
160
+
161
+ return { ...aliasModelInfo, ...modelInfo, ...aliasKeyOptions, ...modelKeyOptions, modelId };
162
+ }
163
+
164
+ protected async getModelId(acRequest: AccessRequest, models: TLLMModelsList, model: string | TLLMModel | TCustomLLMModel): Promise<string> {
165
+ //model can be passed directly, in which case we do not need to look it up in the models list
166
+ if (typeof model === 'object' && model.modelId) {
167
+ return model.modelId;
168
+ }
169
+
170
+ //model can be passed as a string, in which case we need to look it up in the models list
171
+ const modelId = models?.[model as string]?.modelId || (model as string);
172
+ const alias = models?.[model as string]?.alias;
173
+ if (alias) {
174
+ const aliasModelId = models?.[alias]?.modelId || alias || (model as string);
175
+ return aliasModelId;
176
+ }
177
+
178
+ return modelId;
179
+ }
180
+
181
+ // public static async validateTokensLimit({
182
+ // model,
183
+ // promptTokens,
184
+ // completionTokens,
185
+ // hasAPIKey = false,
186
+ // }: {
187
+ // model: string;
188
+ // promptTokens: number;
189
+ // completionTokens: number;
190
+ // hasAPIKey?: boolean;
191
+ // }): Promise<void> {
192
+
193
+ // const allowedContextTokens = this.getMaxContextTokens(model, hasAPIKey);
194
+ // const totalTokens = promptTokens + completionTokens;
195
+
196
+ // const teamAPIKeyExceededMessage = `This models' maximum content length is ${allowedContextTokens} tokens. (This is the sum of your prompt with all variables and the maximum output tokens you've set in Advanced Settings) However, you requested approx ${totalTokens} tokens (${promptTokens} in the prompt, ${completionTokens} in the output). Please reduce the length of either the input prompt or the Maximum output tokens.`;
197
+ // const noAPIKeyExceededMessage = `Input exceeds max tokens limit of ${allowedContextTokens}. Please add your API key to unlock full length.`;
198
+
199
+ // if (totalTokens > allowedContextTokens) {
200
+ // throw new Error(hasAPIKey ? teamAPIKeyExceededMessage : noAPIKeyExceededMessage);
201
+ // }
202
+ // }
203
+
204
+ protected async getProvider(acRequest: AccessRequest, models: TLLMModelsList, model: string | TLLMModel | TCustomLLMModel): Promise<string> {
205
+ //model can be passed directly, in which case we do not need to look it up in the models list
206
+ if (typeof model === 'object' && model.provider) {
207
+ return model.provider;
208
+ }
209
+
210
+ //model can be passed as a string, in which case we need to look it up in the models list
211
+
212
+ const modelId = await this.getModelId(acRequest, models, model);
213
+
214
+ return models?.[modelId]?.provider || models?.[model as string]?.provider || models?.[modelId]?.llm || models?.[model as string]?.llm;
215
+ }
216
+ protected async getCustomModels(candidate: IAccessCandidate): Promise<Record<string, any>> {
217
+ const models = {};
218
+ const settingsKey = 'custom-llm';
219
+
220
+ try {
221
+ const accountConnector = ConnectorService.getAccountConnector();
222
+ const team = await accountConnector.requester(candidate as AccessCandidate).getTeam();
223
+
224
+ const teamSettings = await accountConnector.team(team).getTeamSetting(settingsKey);
225
+ const savedCustomModelsData = JSON.parse(teamSettings || '{}') as Record<string, any>;
226
+
227
+ for (const [entryId, entry] of Object.entries(savedCustomModelsData)) {
228
+ const foundationModel = entry.settings.foundationModel;
229
+ const customModel = entry.settings.customModel;
230
+ const supportsSystemPrompt = customModels[foundationModel]?.supportsSystemPrompt || entry.settings.supportsSystemPrompt;
231
+ const customModelData = customModels[foundationModel] || {};
232
+
233
+ let credentials = null;
234
+ switch (entry.provider) {
235
+ case TLLMProvider.Bedrock:
236
+ credentials = TLLMCredentials.BedrockVault;
237
+ break;
238
+ case TLLMProvider.VertexAI:
239
+ credentials = TLLMCredentials.VertexAIVault;
240
+ break;
241
+ default:
242
+ credentials = TLLMCredentials.Internal;
243
+ break;
244
+ }
245
+ models[entry.name] = {
246
+ label: entry.name,
247
+ modelId: customModel || foundationModel,
248
+ provider: entry.provider,
249
+ features: entry.features?.map((feature) => {
250
+ switch (feature) {
251
+ case 'text-completion':
252
+ return 'text';
253
+ case 'tool-use':
254
+ return 'tools';
255
+ default:
256
+ return feature;
257
+ }
258
+ }),
259
+ tags: Array.isArray(entry?.tags) ? ['Enterprise', ...entry?.tags] : ['Enterprise'],
260
+ tokens: customModelData?.tokens ?? 100000,
261
+ completionTokens: customModelData?.completionTokens ?? 4096,
262
+ enabled: true,
263
+
264
+ id: entryId,
265
+ name: entry.name,
266
+ alias: foundationModel,
267
+ llm: entry.provider,
268
+ components: customModelData?.components ?? [],
269
+ isCustomLLM: true,
270
+ supportsSystemPrompt,
271
+ settings: entry.settings,
272
+ credentials,
273
+ };
274
+ }
275
+
276
+ return models;
277
+ } catch (error) {
278
+ return {};
279
+ }
280
+ }
281
+ }
@@ -0,0 +1,229 @@
1
+ import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
2
+ import { models } from '@sre/LLMManager/models';
3
+ import { ModelsProviderConnector } from '../ModelsProviderConnector';
4
+ import { IAccessCandidate } from '@sre/types/ACL.types';
5
+ import { TAccessLevel } from '@sre/types/ACL.types';
6
+ import { TAccessRole } from '@sre/types/ACL.types';
7
+ import { ConnectorService } from '@sre/Core/ConnectorsService';
8
+ import { ACL } from '@sre/Security/AccessControl/ACL.class';
9
+ import { SecureConnector } from '@sre/Security/SecureConnector.class';
10
+ import { TLLMModel, TLLMModelsList } from '@sre/types/LLM.types';
11
+ import { Logger } from '@sre/helpers/Log.helper';
12
+ import { debounce } from '@sre/utils/general.utils';
13
+ import chokidar from 'chokidar';
14
+ import fs from 'fs/promises';
15
+ import path from 'path';
16
+
17
+ const console = Logger('SmythModelsProvider');
18
+
19
+ type SmythModelsProviderConfig = {
20
+ /**
21
+ * The models to be used.
22
+ *
23
+ * If a string is provided, it will be used as the directory name to load the models from.
24
+ * If a TLLMModelsList is provided, it will be used as the models to be used.
25
+ *
26
+ */
27
+ models?: string | TLLMModelsList;
28
+
29
+ /**
30
+ * The mode to be used.
31
+ *
32
+ * If 'append' is used, the models will be appended to the existing models.
33
+ * If 'replace' is used, the existing models will be replaced with the new models.
34
+ */
35
+ mode?: 'merge' | 'replace';
36
+ };
37
+
38
+ export class SmythModelsProvider extends ModelsProviderConnector {
39
+ public name = 'SmythModelsProvider';
40
+
41
+ private models: TLLMModelsList;
42
+
43
+ constructor(protected _settings?: SmythModelsProviderConfig) {
44
+ super(_settings);
45
+
46
+ this.models = JSON.parse(JSON.stringify(models));
47
+ if (typeof this._settings.models === 'string') {
48
+ this.initDirWatcher(this._settings.models);
49
+ } else if (typeof this._settings.models === 'object') {
50
+ if (this._settings.mode === 'merge') this.models = { ...this.models, ...(this._settings.models as TLLMModelsList) };
51
+ else this.models = this._settings.models as TLLMModelsList;
52
+ this.started = true;
53
+ } else {
54
+ this.started = true;
55
+ }
56
+ }
57
+ public async start() {
58
+ super.start();
59
+ }
60
+
61
+ @SecureConnector.AccessControl
62
+ public async addModels(acRequest: AccessRequest, models: TLLMModelsList): Promise<void> {
63
+ await this.ready();
64
+ const validModels = (await this.getValidModels(models)) || {};
65
+ if (Object.keys(validModels).length > 0) {
66
+ this.models = { ...this.models, ...validModels };
67
+ }
68
+ }
69
+
70
+ @SecureConnector.AccessControl
71
+ public async getModels(acRequest: AccessRequest): Promise<any> {
72
+ await this.ready();
73
+
74
+ return this.models;
75
+ }
76
+
77
+ public async getResourceACL(resourceId: string, candidate: IAccessCandidate) {
78
+ const accountConnector = ConnectorService.getAccountConnector();
79
+
80
+ const acl = new ACL();
81
+ //give read access to the candidate by default
82
+ acl.addAccess(candidate.role, candidate.id, TAccessLevel.Read);
83
+
84
+ return acl;
85
+ }
86
+
87
+ private async reindexModels(dir: string) {
88
+ try {
89
+ console.debug(`Reindexing models from directory: ${dir}`);
90
+
91
+ // Scan directory for models and get them as an object
92
+ const scannedModels = await this.scanDirectoryForModels(dir);
93
+
94
+ // Apply models based on settings mode or default behavior
95
+ if (this._settings?.mode === 'merge') {
96
+ this.models = { ...this.models, ...scannedModels };
97
+ } else {
98
+ // Default behavior: reset to base models first, then add scanned models
99
+ this.models = scannedModels;
100
+ }
101
+
102
+ SmythModelsProvider.localCache.clear();
103
+
104
+ console.debug(`Successfully reindexed models. Total models: ${Object.keys(this.models).length}`);
105
+ } catch (error) {
106
+ console.error(`Error reindexing models from directory "${dir}":`, error);
107
+ }
108
+ }
109
+
110
+ private async scanDirectoryForModels(dir: string): Promise<TLLMModelsList> {
111
+ const scannedModels: TLLMModelsList = {};
112
+
113
+ try {
114
+ const entries = await fs.readdir(dir, { withFileTypes: true });
115
+
116
+ for (const entry of entries) {
117
+ const fullPath = path.join(dir, entry.name);
118
+
119
+ if (entry.isDirectory()) {
120
+ // Recursively scan subdirectories and merge results
121
+ const subDirModels = await this.scanDirectoryForModels(fullPath);
122
+ Object.assign(scannedModels, subDirModels);
123
+ } else if (entry.isFile() && entry.name.endsWith('.json')) {
124
+ // Process JSON files and merge results
125
+ const fileContent = await fs.readFile(fullPath, 'utf-8');
126
+ const modelData = JSON.parse(fileContent);
127
+ const validModels = await this.getValidModels(modelData);
128
+ Object.assign(scannedModels, validModels);
129
+ }
130
+ }
131
+ } catch (error) {
132
+ console.warn(`Error scanning directory "${dir}":`, error);
133
+ }
134
+
135
+ return scannedModels;
136
+ }
137
+
138
+ private async getValidModels(modelData: any): Promise<TLLMModelsList> {
139
+ const validModels: TLLMModelsList = {};
140
+
141
+ try {
142
+ // Check if it's a single model or an object of models
143
+ if (modelData.modelId) {
144
+ // Single model case
145
+ if (this.isValidSingleModel(modelData)) {
146
+ validModels[modelData.modelId] = modelData as TLLMModel;
147
+ console.debug(`Loaded model: ${modelData.modelId}`);
148
+ } else {
149
+ console.warn(`Invalid model format`, modelData);
150
+ }
151
+ } else if (typeof modelData === 'object' && !Array.isArray(modelData)) {
152
+ // Object of models case
153
+ for (const [modelId, model] of Object.entries(modelData)) {
154
+ try {
155
+ if (this.isValidSingleModel(model)) {
156
+ validModels[modelId] = model as TLLMModel;
157
+ console.debug(`Loaded model: ${modelId}`);
158
+ } else {
159
+ console.warn(`Invalid model format for model "${modelId}"`);
160
+ }
161
+ } catch (error) {
162
+ console.warn(`Error processing model "${modelId}":`, error);
163
+ // Continue processing other models instead of failing the whole file
164
+ }
165
+ }
166
+ } else {
167
+ console.warn(`Invalid format (not a model or object of models)`);
168
+ }
169
+ } catch (error) {
170
+ console.warn(`Error loading model:`, error);
171
+ }
172
+
173
+ return validModels;
174
+ }
175
+
176
+ private isValidSingleModel(data: any): boolean {
177
+ // Basic validation for single model structure
178
+ return (
179
+ data && typeof data === 'object' && typeof data.modelId === 'string' && (data.provider === undefined || typeof data.provider === 'string')
180
+ );
181
+ }
182
+
183
+ private isValidModel(data: any): boolean {
184
+ // Keep for backward compatibility, but delegate to simpler function
185
+ return this.isValidSingleModel(data);
186
+ }
187
+
188
+ private async initDirWatcher(dir) {
189
+ if (!(await fs.stat(dir)).isDirectory()) {
190
+ console.warn(`Directory "${dir}" does not exist`);
191
+ return;
192
+ }
193
+
194
+ const debouncedReindex = debounce(this.reindexModels.bind(this, dir), 1000, {
195
+ leading: false,
196
+ trailing: true,
197
+ maxWait: 5000,
198
+ });
199
+
200
+ const watcher = chokidar.watch(dir, {
201
+ ignored: /(^|[\/\\])\../, // ignore dotfiles
202
+ persistent: true,
203
+ ignoreInitial: true, // Don't fire events for files that already exist
204
+ awaitWriteFinish: {
205
+ stabilityThreshold: 2000,
206
+ pollInterval: 100,
207
+ },
208
+ });
209
+
210
+ watcher
211
+ .on('add', (path) => {
212
+ console.debug(`File ${path} has been added`);
213
+ debouncedReindex();
214
+ })
215
+ .on('change', (path) => {
216
+ console.debug(`File ${path} has been changed`);
217
+ debouncedReindex();
218
+ })
219
+ .on('unlink', (path) => {
220
+ console.debug(`File ${path} has been removed`);
221
+ debouncedReindex();
222
+ })
223
+ .on('ready', () => {
224
+ console.debug(`Watcher ready. Performing initial scan of ${dir}`);
225
+ // Do initial scan once when watcher is ready
226
+ this.reindexModels(dir);
227
+ });
228
+ }
229
+ }
@@ -0,0 +1,11 @@
1
+ //==[ SRE: ModelsProvider ]======================
2
+
3
+ import { ConnectorService, ConnectorServiceProvider } from '@sre/Core/ConnectorsService';
4
+ import { TConnectorService } from '@sre/types/SRE.types';
5
+ import { SmythModelsProvider } from './connectors/SmythModelsProvider.class';
6
+
7
+ export class ModelsProviderService extends ConnectorServiceProvider {
8
+ public register() {
9
+ ConnectorService.register(TConnectorService.ModelsProvider, 'SmythModelsProvider', SmythModelsProvider);
10
+ }
11
+ }