@smythos/sre 1.7.1 → 1.7.7

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 (53) hide show
  1. package/dist/index.js +33 -31
  2. package/dist/index.js.map +1 -1
  3. package/dist/types/Core/ConnectorsService.d.ts +2 -1
  4. package/dist/types/Core/SmythRuntime.class.d.ts +1 -0
  5. package/dist/types/helpers/BinaryInput.helper.d.ts +1 -1
  6. package/dist/types/helpers/LocalCache.helper.d.ts +18 -0
  7. package/dist/types/helpers/TemplateString.helper.d.ts +2 -1
  8. package/dist/types/subsystems/IO/VectorDB.service/VectorDBConnector.d.ts +4 -4
  9. package/dist/types/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.d.ts +2 -2
  10. package/dist/types/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.d.ts +2 -2
  11. package/dist/types/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.d.ts +2 -2
  12. package/dist/types/subsystems/IO/VectorDB.service/embed/BaseEmbedding.d.ts +16 -9
  13. package/dist/types/subsystems/IO/VectorDB.service/embed/index.d.ts +4 -1
  14. package/dist/types/subsystems/LLMManager/LLM.inference.d.ts +36 -2
  15. package/dist/types/types/LLM.types.d.ts +54 -31
  16. package/dist/types/types/VectorDB.types.d.ts +6 -3
  17. package/dist/types/utils/string.utils.d.ts +0 -4
  18. package/package.json +1 -1
  19. package/src/Components/Classifier.class.ts +8 -2
  20. package/src/Components/GenAILLM.class.ts +11 -7
  21. package/src/Components/LLMAssistant.class.ts +12 -3
  22. package/src/Components/ScrapflyWebScrape.class.ts +8 -1
  23. package/src/Components/TavilyWebSearch.class.ts +4 -1
  24. package/src/Core/ConnectorsService.ts +12 -2
  25. package/src/Core/SmythRuntime.class.ts +32 -17
  26. package/src/helpers/BinaryInput.helper.ts +8 -8
  27. package/src/helpers/Conversation.helper.ts +11 -1
  28. package/src/helpers/LocalCache.helper.ts +18 -0
  29. package/src/helpers/TemplateString.helper.ts +20 -9
  30. package/src/index.ts +208 -208
  31. package/src/index.ts.bak +208 -208
  32. package/src/subsystems/AgentManager/Agent.class.ts +2 -0
  33. package/src/subsystems/AgentManager/AgentData.service/AgentDataConnector.ts +6 -5
  34. package/src/subsystems/AgentManager/AgentLogger.class.ts +1 -1
  35. package/src/subsystems/IO/VectorDB.service/VectorDBConnector.ts +15 -4
  36. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +31 -10
  37. package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +27 -10
  38. package/src/subsystems/IO/VectorDB.service/connectors/RAMVecrtorDB.class.ts +25 -9
  39. package/src/subsystems/IO/VectorDB.service/embed/BaseEmbedding.ts +182 -12
  40. package/src/subsystems/IO/VectorDB.service/embed/GoogleEmbedding.ts +1 -1
  41. package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +1 -1
  42. package/src/subsystems/IO/VectorDB.service/embed/index.ts +12 -2
  43. package/src/subsystems/LLMManager/LLM.inference.ts +76 -17
  44. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +3 -2
  45. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +2 -2
  46. package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +2 -2
  47. package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +4 -1
  48. package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +12 -0
  49. package/src/types/LLM.types.ts +66 -38
  50. package/src/types/VectorDB.types.ts +7 -3
  51. package/src/utils/string.utils.ts +193 -191
  52. package/dist/bundle-analysis-lazy.html +0 -4949
  53. package/dist/bundle-analysis.html +0 -4949
@@ -18,7 +18,8 @@ import { CodeConnector } from '@sre/ComputeManager/Code.service/CodeConnector';
18
18
  import { SchedulerConnector } from '@sre/AgentManager/Scheduler.service/SchedulerConnector';
19
19
  export declare class ConnectorService {
20
20
  static Connectors: {};
21
- static ConnectorInstances: any;
21
+ protected static _instances: any;
22
+ static get ConnectorInstances(): any;
22
23
  static get ready(): boolean;
23
24
  static get service(): TServiceRegistry;
24
25
  /**
@@ -25,5 +25,6 @@ export declare class SmythRuntime {
25
25
  ready(): Promise<boolean>;
26
26
  private _stopping;
27
27
  _stop(): Promise<void>;
28
+ private setupShutdownHandlers;
28
29
  }
29
30
  export declare const SRE: SmythRuntime;
@@ -14,7 +14,7 @@ export declare class BinaryInput {
14
14
  ready(): Promise<any>;
15
15
  private load;
16
16
  private getUrlInfo;
17
- static from(data: any, name?: string, mimetype?: string, candidate?: IAccessCandidate): BinaryInput;
17
+ static from(source: any, name?: string, mimetype?: string, candidate?: IAccessCandidate): BinaryInput;
18
18
  upload(candidate: IAccessCandidate, ttl?: number): Promise<void>;
19
19
  getJsonData(candidate: IAccessCandidate, ttl?: number): Promise<{
20
20
  mimetype: string;
@@ -1,3 +1,10 @@
1
+ /**
2
+ * A local cache helper used to cache data, functions or object instances
3
+ * This is useful when you need to cache an object and refresh the cache if the object is accessed within a certain time period
4
+ *
5
+ * @template K - The type of the key
6
+ * @template V - The type of the value
7
+ */
1
8
  export declare class LocalCache<K, V> {
2
9
  private cache;
3
10
  private expiryMap;
@@ -6,7 +13,18 @@ export declare class LocalCache<K, V> {
6
13
  constructor(defaultTTL?: number);
7
14
  set(key: K, value: V, ttlMs?: number): void;
8
15
  updateTTL(key: K, ttlMs?: number): void;
16
+ /**
17
+ * Get the value from the cache, and update the TTL if provided
18
+ * @param key - The key to get the value from the cache
19
+ * @param ttlMs - The TTL in milliseconds
20
+ * @returns The value from the cache
21
+ */
9
22
  get(key: K, ttlMs?: number): V | undefined;
23
+ /**
24
+ * Check if the key exists in the cache
25
+ * @param key - The key to check if it exists in the cache
26
+ * @returns True if the key exists in the cache, false otherwise
27
+ */
10
28
  has(key: K): boolean;
11
29
  delete(key: K): boolean;
12
30
  clear(): void;
@@ -31,8 +31,9 @@ export declare class TemplateStringHelper {
31
31
  /**
32
32
  * Parses a template string by replacing the placeholders with the values from the provided data object
33
33
  * unmatched placeholders will be left as is
34
+ * Recursively resolves nested template variables until no more variables are found
34
35
  */
35
- parse(data: Record<string, string>, regex?: TemplateStringMatch): this;
36
+ parse(data: Record<string, string>, regex?: TemplateStringMatch, maxDepth?: number): this;
36
37
  /**
37
38
  * Parses a template string by replacing placeholders with values from the provided data object, keeping the original raw values intact. This is particularly important for BinaryInput instances, as they include buffer data.
38
39
  * unmatched placeholders will be left as is
@@ -3,13 +3,13 @@ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.cla
3
3
  import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
4
4
  import { SecureConnector } from '@sre/Security/SecureConnector.class';
5
5
  import { IAccessCandidate } from '@sre/types/ACL.types';
6
- import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorsResultData } from '@sre/types/VectorDB.types';
6
+ import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorDBResult } from '@sre/types/VectorDB.types';
7
7
  export type DeleteFilterOptions = {
8
8
  datasourceId?: string;
9
9
  };
10
10
  export type DeleteTarget = string | string[] | DeleteFilterOptions;
11
11
  export interface IVectorDBRequest {
12
- search(namespace: string, query: string | number[], options?: QueryOptions): Promise<VectorsResultData>;
12
+ search(namespace: string, query: string | number[], options?: QueryOptions): Promise<VectorDBResult[]>;
13
13
  createDatasource(namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource>;
14
14
  deleteDatasource(namespace: string, datasourceId: string): Promise<void>;
15
15
  listDatasources(namespace: string): Promise<IStorageVectorDataSource[]>;
@@ -25,8 +25,8 @@ export declare abstract class VectorDBConnector extends SecureConnector<IVectorD
25
25
  abstract id: string;
26
26
  abstract getResourceACL(resourceId: string, candidate: IAccessCandidate): Promise<ACL>;
27
27
  requester(candidate: AccessCandidate): IVectorDBRequest;
28
- protected abstract search(acRequest: AccessRequest, namespace: string, query: string | number[], options: QueryOptions): Promise<VectorsResultData>;
29
- protected abstract insert(acRequest: AccessRequest, namespace: string, source: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<string[]>;
28
+ protected abstract search(acRequest: AccessRequest, namespace: string, query: string | number[], options: QueryOptions): Promise<VectorDBResult[]>;
29
+ protected abstract insert(acRequest: AccessRequest, namespace: string, source: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<VectorDBResult[]>;
30
30
  protected abstract delete(acRequest: AccessRequest, namespace: string, deleteTarget: DeleteTarget): Promise<void>;
31
31
  protected abstract createDatasource(acRequest: AccessRequest, namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource>;
32
32
  protected abstract deleteDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<void>;
@@ -2,7 +2,7 @@ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.cla
2
2
  import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
3
3
  import { ACL } from '@sre/Security/AccessControl/ACL.class';
4
4
  import { IAccessCandidate } from '@sre/types/ACL.types';
5
- import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorsResultData } from '@sre/types/VectorDB.types';
5
+ import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorDBResult, VectorsResultData } from '@sre/types/VectorDB.types';
6
6
  import { BaseEmbedding, TEmbeddings } from '../embed/BaseEmbedding';
7
7
  import { DeleteTarget, VectorDBConnector } from '../VectorDBConnector';
8
8
  export type IMilvusCredentials = {
@@ -41,7 +41,7 @@ export declare class MilvusVectorDB extends VectorDBConnector {
41
41
  protected namespaceExists(acRequest: AccessRequest, namespace: string): Promise<boolean>;
42
42
  protected deleteNamespace(acRequest: AccessRequest, namespace: string): Promise<void>;
43
43
  protected search(acRequest: AccessRequest, namespace: string, query: string | number[], options?: QueryOptions): Promise<VectorsResultData>;
44
- protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<string[]>;
44
+ protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<VectorDBResult[]>;
45
45
  protected delete(acRequest: AccessRequest, namespace: string, deleteTarget: DeleteTarget): Promise<void>;
46
46
  protected createDatasource(acRequest: AccessRequest, namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource>;
47
47
  protected deleteDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<void>;
@@ -3,7 +3,7 @@ import { IAccessCandidate } from '@sre/types/ACL.types';
3
3
  import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
4
4
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
5
5
  import { VectorDBConnector, DeleteTarget } from '../VectorDBConnector';
6
- import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorsResultData } from '@sre/types/VectorDB.types';
6
+ import { DatasourceDto, IStorageVectorDataSource, IVectorDataSourceDto, QueryOptions, VectorDBResult, VectorsResultData } from '@sre/types/VectorDB.types';
7
7
  import { BaseEmbedding, TEmbeddings } from '../embed/BaseEmbedding';
8
8
  export type PineconeConfig = {
9
9
  /**
@@ -37,7 +37,7 @@ export declare class PineconeVectorDB extends VectorDBConnector {
37
37
  protected namespaceExists(acRequest: AccessRequest, namespace: string): Promise<boolean>;
38
38
  protected deleteNamespace(acRequest: AccessRequest, namespace: string): Promise<void>;
39
39
  protected search(acRequest: AccessRequest, namespace: string, query: string | number[], options?: QueryOptions): Promise<VectorsResultData>;
40
- protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<string[]>;
40
+ protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<VectorDBResult[]>;
41
41
  protected delete(acRequest: AccessRequest, namespace: string, deleteTarget: DeleteTarget): Promise<void>;
42
42
  protected createDatasource(acRequest: AccessRequest, namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource>;
43
43
  protected deleteDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<void>;
@@ -2,7 +2,7 @@ import { ACL } from '@sre/Security/AccessControl/ACL.class';
2
2
  import { IAccessCandidate } from '@sre/types/ACL.types';
3
3
  import { AccessRequest } from '@sre/Security/AccessControl/AccessRequest.class';
4
4
  import { VectorDBConnector, DeleteTarget } from '../VectorDBConnector';
5
- import { DatasourceDto, IStorageVectorDataSource, IStorageVectorNamespace, IVectorDataSourceDto, QueryOptions, VectorsResultData } from '@sre/types/VectorDB.types';
5
+ import { DatasourceDto, IStorageVectorDataSource, IStorageVectorNamespace, IVectorDataSourceDto, QueryOptions, VectorDBResult, VectorsResultData } from '@sre/types/VectorDB.types';
6
6
  import { BaseEmbedding, TEmbeddings } from '../embed/BaseEmbedding';
7
7
  export type RAMVectorDBConfig = {
8
8
  /**
@@ -38,7 +38,7 @@ export declare class RAMVectorDB extends VectorDBConnector {
38
38
  protected listNamespaces(acRequest: AccessRequest): Promise<IStorageVectorNamespace[]>;
39
39
  protected deleteNamespace(acRequest: AccessRequest, namespace: string): Promise<void>;
40
40
  protected search(acRequest: AccessRequest, namespace: string, query: string | number[], options?: QueryOptions): Promise<VectorsResultData>;
41
- protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<string[]>;
41
+ protected insert(acRequest: AccessRequest, namespace: string, sourceWrapper: IVectorDataSourceDto | IVectorDataSourceDto[]): Promise<VectorDBResult[]>;
42
42
  protected delete(acRequest: AccessRequest, namespace: string, deleteTarget: DeleteTarget): Promise<void>;
43
43
  protected createDatasource(acRequest: AccessRequest, namespace: string, datasource: DatasourceDto): Promise<IStorageVectorDataSource>;
44
44
  protected deleteDatasource(acRequest: AccessRequest, namespace: string, datasourceId: string): Promise<void>;
@@ -2,26 +2,29 @@ import { IVectorDataSourceDto, Source } from '@sre/types/VectorDB.types';
2
2
  import { SupportedProviders, SupportedModels } from './index';
3
3
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
4
4
  export type TEmbeddings = {
5
- provider: SupportedProviders;
6
- model: SupportedModels[SupportedProviders];
5
+ provider?: SupportedProviders;
6
+ model?: SupportedModels[SupportedProviders];
7
7
  credentials?: {
8
8
  apiKey: string;
9
9
  };
10
- params?: {
11
- dimensions?: number;
12
- timeout?: number;
13
- chunkSize?: number;
14
- stripNewLines?: boolean;
15
- };
10
+ dimensions?: number;
11
+ timeout?: number;
12
+ chunkSize?: number;
13
+ chunkOverlap?: number;
14
+ batchSize?: number;
15
+ stripNewLines?: boolean;
16
+ params?: any;
16
17
  };
17
18
  type SupportedSources = 'text' | 'vector' | 'url';
18
19
  export declare abstract class BaseEmbedding {
19
20
  model: string;
20
21
  modelName: string;
21
22
  chunkSize: number;
23
+ chunkOverlap: number;
22
24
  stripNewLines: boolean;
23
25
  dimensions?: number;
24
26
  timeout?: number;
27
+ batchSize: number;
25
28
  constructor(fields?: Partial<TEmbeddings>);
26
29
  /**
27
30
  * Embed multiple texts and return their vector representations
@@ -35,6 +38,10 @@ export declare abstract class BaseEmbedding {
35
38
  * Utility method to chunk arrays into smaller batches
36
39
  */
37
40
  protected chunkArr<T>(arr: T[], sizePerChunk: number): T[][];
41
+ chunkText(text: string, { chunkSize, chunkOverlap }: {
42
+ chunkSize?: number;
43
+ chunkOverlap?: number;
44
+ }): string[];
38
45
  /**
39
46
  * Utility method to process multiple texts based on stripNewLines setting
40
47
  */
@@ -48,7 +55,7 @@ export declare abstract class BaseEmbedding {
48
55
  datasourceId: string;
49
56
  datasourceLabel: string;
50
57
  acl: string;
51
- user_metadata?: string;
58
+ user_metadata?: string | Record<string, any>;
52
59
  };
53
60
  id: string;
54
61
  }[]>;
@@ -1,6 +1,7 @@
1
1
  import { OpenAIEmbeds } from './OpenAIEmbedding';
2
2
  import { GoogleEmbeds } from './GoogleEmbedding';
3
3
  import { TEmbeddings } from './BaseEmbedding';
4
+ import { TLLMModel } from '@sre/types/LLM.types';
4
5
  declare const supportedProviders: {
5
6
  readonly OpenAI: {
6
7
  readonly embedder: typeof OpenAIEmbeds;
@@ -16,6 +17,8 @@ export type SupportedModels = {
16
17
  [K in SupportedProviders]: (typeof supportedProviders)[K]['models'][number];
17
18
  };
18
19
  export declare class EmbeddingsFactory {
19
- static create(provider: SupportedProviders, config: TEmbeddings): OpenAIEmbeds | GoogleEmbeds;
20
+ static create(provider?: SupportedProviders, config?: TEmbeddings & {
21
+ model?: SupportedModels[SupportedProviders] | TLLMModel;
22
+ }): OpenAIEmbeds | GoogleEmbeds;
20
23
  }
21
24
  export {};
@@ -7,6 +7,7 @@ type TPromptParams = {
7
7
  contextWindow?: any[];
8
8
  files?: any[];
9
9
  params: TLLMParams;
10
+ onFallback?: (data: any) => void;
10
11
  };
11
12
  export declare class LLMInference {
12
13
  private model;
@@ -16,8 +17,41 @@ export declare class LLMInference {
16
17
  static getInstance(model: string | TLLMModel, candidate: AccessCandidate): Promise<LLMInference>;
17
18
  static user(candidate: AccessCandidate): any;
18
19
  get connector(): LLMConnector;
19
- prompt({ query, contextWindow, files, params }: TPromptParams, isInFallback?: boolean): Promise<any>;
20
- promptStream({ query, contextWindow, files, params }: TPromptParams, isInFallback?: boolean): Promise<any>;
20
+ prompt({ query, contextWindow, files, params, onFallback }: TPromptParams, isInFallback?: boolean): Promise<any>;
21
+ promptStream({ query, contextWindow, files, params, onFallback }: TPromptParams, isInFallback?: boolean): Promise<any>;
22
+ /**
23
+ * Creates a safe, minimal set of parameters when switching to a fallback LLM provider.
24
+ *
25
+ * **Why this exists:**
26
+ * Model settings persist in the component's configuration data, even when you switch models.
27
+ * This can cause issues when fallback models run with settings the user can't see or track.
28
+ *
29
+ * **Real-world scenario:**
30
+ * 1. User configures a GPT-5 model and sets `reasoning_effort: "high"`
31
+ * 2. This setting gets saved to the component's configuration
32
+ * 3. User switches to a custom model (e.g., for cost savings)
33
+ * 4. The UI now shows custom model options - GPT-5 options are hidden
34
+ * 5. **BUT**: `reasoning_effort: "high"` is STILL in the config data!
35
+ * 6. Custom model has GPT-5 as its fallback
36
+ * 7. Primary custom model fails → automatically switches to GPT-5 fallback
37
+ * 8. GPT-5 fallback runs with the hidden `reasoning_effort: "high"` setting
38
+ * 9. `reasoning_effort: "high"` requires a high `max_tokens` value
39
+ * 10. If `max_tokens` is too low → the request fails
40
+ *
41
+ * **The impact:**
42
+ * Users can't track response quality properly because they don't know what configuration
43
+ * the fallback model is using. The UI doesn't show fallback model settings, so users have
44
+ * no visibility into how responses are being generated.
45
+ *
46
+ * **What this function does:**
47
+ * Strips out provider-specific settings when falling back, using only universal parameters.
48
+ * This ensures predictable behavior. (Note: A more robust solution would be showing fallback
49
+ * configuration in the UI, but for now this handles it at the parameter level.)
50
+ *
51
+ * @param params - The full set of LLM parameters from the original request
52
+ * @returns A filtered parameter object with only provider-agnostic, safe parameters
53
+ */
54
+ private getSafeFallbackParams;
21
55
  /**
22
56
  * Executes fallback logic for custom models when the primary model fails.
23
57
  * This method checks if a fallback model is configured and invokes the appropriate LLM method.
@@ -71,7 +71,32 @@ export type TToolsInfo = {
71
71
  xai: TxAIToolsInfo;
72
72
  };
73
73
  export type TSearchContextSize = 'low' | 'medium' | 'high';
74
- export type TLLMParams = {
74
+ type TLLMToolConfig = {
75
+ toolsConfig?: {
76
+ tools?: OpenAI.ChatCompletionTool[] | OpenAI.Responses.Tool[] | OpenAI.Responses.WebSearchTool[];
77
+ tool_choice?: TLLMToolChoice;
78
+ };
79
+ };
80
+ type TLLMThinkingConfig = {
81
+ thinking?: {
82
+ type: 'enabled' | 'disabled';
83
+ budget_tokens: number;
84
+ };
85
+ maxThinkingTokens?: number;
86
+ };
87
+ type TLLMReasoningConfig = {
88
+ useReasoning?: boolean;
89
+ /**
90
+ * Controls the level of effort the model will put into reasoning
91
+ * For GPT-OSS models (20B, 120B): "low" | "medium" | "high"
92
+ * For Qwen 3 32B: "none" | "default"
93
+ */
94
+ reasoningEffort?: 'none' | 'default' | OpenAIReasoningEffort;
95
+ max_output_tokens?: number;
96
+ verbosity?: OpenAI.Responses.ResponseCreateParams['text']['verbosity'];
97
+ abortSignal?: AbortSignal;
98
+ };
99
+ type TLLMTextGenConfig = {
75
100
  model: TLLMModel | string;
76
101
  prompt?: string;
77
102
  messages?: any[];
@@ -83,31 +108,16 @@ export type TLLMParams = {
83
108
  frequencyPenalty?: number;
84
109
  presencePenalty?: number;
85
110
  responseFormat?: any;
86
- modelInfo?: TCustomLLMModel;
87
- files?: BinaryInput[];
88
- toolsConfig?: {
89
- tools?: OpenAI.ChatCompletionTool[] | OpenAI.Responses.Tool[] | OpenAI.Responses.WebSearchTool[];
90
- tool_choice?: TLLMToolChoice;
91
- };
92
- baseURL?: string;
93
- size?: OpenAI.Images.ImageGenerateParams['size'] | OpenAI.Images.ImageEditParams['size'];
94
- quality?: 'standard' | 'hd';
95
- n?: number;
96
- style?: 'vivid' | 'natural';
97
- cache?: boolean;
98
- agentId?: string;
99
- teamId?: string;
100
- thinking?: {
101
- type: 'enabled' | 'disabled';
102
- budget_tokens: number;
103
- };
104
- maxThinkingTokens?: number;
111
+ } & TLLMToolConfig & TLLMThinkingConfig & TLLMReasoningConfig;
112
+ type TLLMWebSearchConfig = {
105
113
  useWebSearch?: boolean;
106
114
  webSearchContextSize?: TSearchContextSize;
107
115
  webSearchCity?: string;
108
116
  webSearchCountry?: string;
109
117
  webSearchRegion?: string;
110
118
  webSearchTimezone?: string;
119
+ };
120
+ type TLLMSearchConfig = {
111
121
  useSearch?: boolean;
112
122
  searchMode?: 'auto' | 'on' | 'off';
113
123
  returnCitations?: boolean;
@@ -124,17 +134,27 @@ export type TLLMParams = {
124
134
  safeSearch?: boolean;
125
135
  fromDate?: string;
126
136
  toDate?: string;
127
- useReasoning?: boolean;
128
- /**
129
- * Controls the level of effort the model will put into reasoning
130
- * For GPT-OSS models (20B, 120B): "low" | "medium" | "high"
131
- * For Qwen 3 32B: "none" | "default"
132
- */
133
- reasoningEffort?: 'none' | 'default' | OpenAIReasoningEffort;
134
- max_output_tokens?: number;
135
- verbosity?: OpenAI.Responses.ResponseCreateParams['text']['verbosity'];
136
- abortSignal?: AbortSignal;
137
+ } & TLLMWebSearchConfig;
138
+ type TLLMMiscConfig = {
139
+ maxContextWindowLength?: number;
140
+ useContextWindow?: boolean;
141
+ passthrough?: boolean;
142
+ };
143
+ type TLLMRuntimeContext = {
144
+ modelInfo?: TCustomLLMModel;
145
+ files?: BinaryInput[];
146
+ baseURL?: string;
147
+ cache?: boolean;
148
+ agentId?: string;
149
+ teamId?: string;
150
+ };
151
+ type TLLMImageGenConfig = {
152
+ size?: OpenAI.Images.ImageGenerateParams['size'] | OpenAI.Images.ImageEditParams['size'];
153
+ quality?: 'standard' | 'hd';
154
+ n?: number;
155
+ style?: 'vivid' | 'natural';
137
156
  };
157
+ export type TLLMParams = TLLMTextGenConfig & TLLMSearchConfig & TLLMImageGenConfig & TLLMMiscConfig & TLLMRuntimeContext;
138
158
  export type TLLMPreparedParams = TLLMParams & {
139
159
  body: any;
140
160
  modelEntryName?: string;
@@ -422,7 +442,9 @@ export declare enum TLLMEvent {
422
442
  /** Tokens usage information */
423
443
  Usage = "usage",
424
444
  /** Interrupted : emitted when the response is interrupted before completion */
425
- Interrupted = "interrupted"
445
+ Interrupted = "interrupted",
446
+ /** Fallback : emitted when the response is using a fallback model */
447
+ Fallback = "fallback"
426
448
  }
427
449
  export interface ILLMRequestContext {
428
450
  modelEntryName: string;
@@ -478,3 +500,4 @@ export interface TGoogleAIRequestBody {
478
500
  toolConfig?: any;
479
501
  }
480
502
  export type TLLMRequestBody = TOpenAIRequestBody | TAnthropicRequestBody | TGoogleAIRequestBody | ConverseCommandInput;
503
+ export {};
@@ -3,16 +3,17 @@ export type VectorDBMetadata = {
3
3
  datasourceId: string;
4
4
  datasourceLabel: string;
5
5
  acl: string;
6
- user_metadata?: string;
6
+ user_metadata?: string | Record<string, any>;
7
7
  text?: string;
8
8
  };
9
- export type VectorsResultData = {
9
+ export type VectorDBResult = {
10
10
  id: string;
11
11
  score?: number;
12
12
  values: number[];
13
13
  text: string;
14
14
  metadata?: Record<string, any>;
15
- }[];
15
+ };
16
+ export type VectorsResultData = VectorDBResult[];
16
17
  export interface NsKnownMetadata {
17
18
  isOnCustomStorage?: boolean;
18
19
  [key: string]: any;
@@ -37,6 +38,7 @@ export interface IStorageVectorDataSource {
37
38
  metadata: string;
38
39
  text?: string;
39
40
  vectorIds: string[];
41
+ vectorInfo?: VectorDBResult[];
40
42
  id: string;
41
43
  candidateId: string;
42
44
  candidateRole: string;
@@ -65,4 +67,5 @@ export interface DatasourceDto {
65
67
  chunkOverlap?: number;
66
68
  label?: string;
67
69
  id?: string;
70
+ returnFullVectorInfo?: boolean;
68
71
  }
@@ -22,7 +22,3 @@ export declare const kebabToCapitalize: (input: any) => any;
22
22
  * @param input
23
23
  */
24
24
  export declare const identifyMimetypeFromString: (input: string) => "application/json" | "text/plain" | "application/xml" | "text/html" | "text/css" | "text/csv" | "text/markdown" | "" | "image/svg+xml" | "application/javascript" | "application/yaml" | "application/sql";
25
- export declare function chunkText(text: string, { chunkSize, chunkOverlap, }?: {
26
- chunkSize?: number;
27
- chunkOverlap?: number;
28
- }): string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@smythos/sre",
3
- "version": "1.7.1",
3
+ "version": "1.7.7",
4
4
  "description": "Smyth Runtime Environment",
5
5
  "author": "Alaa-eddine KADDOURI",
6
6
  "license": "MIT",
@@ -115,7 +115,13 @@ ${JSON.stringify(categories, null, 2)}`;
115
115
 
116
116
  try {
117
117
  let response = await llmInference
118
- .prompt({ query: prompt, params: { ...config, agentId: agent.id } })
118
+ .prompt({
119
+ query: prompt,
120
+ params: { ...config, agentId: agent.id },
121
+ onFallback: (data) => {
122
+ logger.debug(`\n ↩️ Using Fallback Model: ${data.model}`);
123
+ },
124
+ })
119
125
  .catch((error) => ({ error: error }));
120
126
 
121
127
  if (response?.error) {
@@ -146,7 +152,7 @@ ${JSON.stringify(categories, null, 2)}`;
146
152
  delete parsed.error;
147
153
  }
148
154
 
149
- logger.log(' Classifier result\n', parsed);
155
+ logger.debug('\n Classifier result\n', parsed);
150
156
 
151
157
  parsed['_debug'] = logger.output;
152
158
 
@@ -7,6 +7,7 @@ import { getMimeType } from '@sre/utils/data.utils';
7
7
  import { Component } from './Component.class';
8
8
  import { formatDataForDebug } from '@sre/utils/data.utils';
9
9
  import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
10
+ import { TLLMEvent } from '@sre/types/LLM.types';
10
11
 
11
12
  //TODO : better handling of context window exceeding max length
12
13
 
@@ -480,13 +481,16 @@ export class GenAILLM extends Component {
480
481
  ...config.data,
481
482
  agentId: agent.id,
482
483
  },
484
+ onFallback: (fallbackInfo) => {
485
+ logger.debug(`\n ↩️ Using fallback model: ${fallbackInfo.model}`);
486
+ },
483
487
  })
484
488
  .catch((error) => {
485
489
  console.error('Error on promptStream: ', error);
486
490
  reject(error);
487
491
  });
488
492
 
489
- eventEmitter.on('content', (content) => {
493
+ eventEmitter.on(TLLMEvent.Content, (content) => {
490
494
  if (passThrough) {
491
495
  if (typeof agent.callback === 'function') {
492
496
  agent.callback({ content });
@@ -496,7 +500,7 @@ export class GenAILLM extends Component {
496
500
  _content += content;
497
501
  });
498
502
 
499
- eventEmitter.on('thinking', (thinking) => {
503
+ eventEmitter.on(TLLMEvent.Thinking, (thinking) => {
500
504
  if (passThrough) {
501
505
  if (typeof agent.callback === 'function') {
502
506
  agent.callback({ thinking });
@@ -504,7 +508,7 @@ export class GenAILLM extends Component {
504
508
  agent.sse.send('llm/passthrough/thinking', thinking.replace(/\n/g, '\\n'));
505
509
  }
506
510
  });
507
- eventEmitter.on('end', () => {
511
+ eventEmitter.on(TLLMEvent.End, () => {
508
512
  if (passThrough) {
509
513
  if (typeof agent.callback === 'function') {
510
514
  agent.callback({ content: '\n' });
@@ -513,18 +517,18 @@ export class GenAILLM extends Component {
513
517
  }
514
518
  resolve(_content);
515
519
  });
516
- eventEmitter.on('interrupted', (reason) => {
520
+ eventEmitter.on(TLLMEvent.Interrupted, (reason) => {
517
521
  finishReason = reason || 'stop';
518
522
  });
519
523
 
520
- eventEmitter.on('error', (error) => {
524
+ eventEmitter.on(TLLMEvent.Error, (error) => {
521
525
  reject(error);
522
526
  });
523
527
  });
524
528
  response = await contentPromise.catch((error) => {
525
529
  return { error: error.message || error };
526
530
  });
527
- // // If the model stopped before completing the response, this is usually due to output token limit reached.
531
+ // If the model stopped before completing the response, this is usually due to output token limit reached.
528
532
  if (finishReason !== 'stop') {
529
533
  return {
530
534
  Reply: response,
@@ -551,7 +555,7 @@ export class GenAILLM extends Component {
551
555
  return { _error: Reply.error, _debug: logger.output };
552
556
  }
553
557
 
554
- logger.debug(' Reply \n', Reply);
558
+ logger.debug('\n Reply \n', Reply);
555
559
 
556
560
  const result = { Reply };
557
561
 
@@ -113,7 +113,7 @@ export class LLMAssistant extends Component {
113
113
  const conversationId = input.ConversationId;
114
114
 
115
115
  let behavior = TemplateString(config.data.behavior).parse(input).result;
116
- logger.debug(`[Parsed Behavior] \n${behavior}\n\n`);
116
+ logger.debug(`[Parsed Behavior] \n${behavior}`);
117
117
 
118
118
  //#region get max tokens
119
119
  let maxTokens = 2048;
@@ -154,6 +154,9 @@ export class LLMAssistant extends Component {
154
154
  .promptStream({
155
155
  contextWindow: messages,
156
156
  params: { ...config, model, agentId: agent.id },
157
+ onFallback: (fallbackInfo) => {
158
+ logger.debug(`\n ↩️ Using fallback model: ${fallbackInfo.model}`);
159
+ },
157
160
  })
158
161
  .catch((error) => {
159
162
  console.error('Error on promptStream: ', error);
@@ -180,7 +183,13 @@ export class LLMAssistant extends Component {
180
183
  response = await contentPromise;
181
184
  } else {
182
185
  response = await llmInference
183
- .prompt({ contextWindow: messages, params: { ...config, agentId: agent.id } })
186
+ .prompt({
187
+ contextWindow: messages,
188
+ params: { ...config, agentId: agent.id },
189
+ onFallback: (fallbackInfo) => {
190
+ logger.debug(`\n ↩️ Using fallback model: ${fallbackInfo.model}`);
191
+ },
192
+ })
184
193
  .catch((error) => ({ error: error }));
185
194
  }
186
195
 
@@ -199,7 +208,7 @@ export class LLMAssistant extends Component {
199
208
  messages.push({ role: 'assistant', content: response });
200
209
  saveMessagesToSession(agent.id, userId, conversationId, messages, ttl);
201
210
 
202
- logger.debug(' Response \n', response);
211
+ logger.debug('\n Response \n', response);
203
212
 
204
213
  const result = { Response: response };
205
214
 
@@ -53,7 +53,14 @@ export class ScrapflyWebScrape extends Component {
53
53
  logger.debug(`=== Web Scrape Log ===`);
54
54
  let Output: any = {};
55
55
  let _error = undefined;
56
- const scrapeUrls = this.extractUrls(input);
56
+
57
+ // Filter inputs to include only the fields defined in the component's configuration.
58
+ // This prevents URLs from global variables from being scraped.
59
+ const componentInputNames = new Set(config.inputs.map((input) => input.name));
60
+ const filteredInput = Object.fromEntries(Object.entries(input).filter(([key]) => componentInputNames.has(key)));
61
+
62
+ const scrapeUrls = this.extractUrls(filteredInput);
63
+
57
64
  logger.debug('Payload:', JSON.stringify(config.data));
58
65
  logger.debug(`Vaild URLs: ${JSON.stringify(scrapeUrls)}`);
59
66
  const teamId = agent.teamId;
@@ -55,6 +55,9 @@ export class TavilyWebSearch extends Component {
55
55
  const api_key = await getCredentials(AccessCandidate.team(teamId), 'tavily');
56
56
 
57
57
  logger.debug('Payload:', JSON.stringify(config.data));
58
+
59
+ const excludeDomains = config.data.excludeDomains?.length ? config.data.excludeDomains.split(',').map((d) => d.trim()) : [];
60
+
58
61
  const response = await axios({
59
62
  method: 'post',
60
63
  url: 'https://api.tavily.com/search',
@@ -62,7 +65,7 @@ export class TavilyWebSearch extends Component {
62
65
  api_key,
63
66
  query: searchQuery,
64
67
  topic: config.data.searchTopic,
65
- exclude_domains: config.data.excludeDomains?.length ? config.data.excludeDomains.split(',') : [],
68
+ exclude_domains: excludeDomains,
66
69
  max_results: config.data.sourcesLimit,
67
70
  ...(config.data.timeRange !== 'None' ? { time_range: config.data.timeRange } : {}),
68
71
  ...(config.data.includeImages ? { include_images: true } : {}),