@smythos/sre 1.5.37 → 1.5.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +65 -45
- package/dist/index.js.map +1 -1
- package/dist/types/Components/ECMASandbox.class.d.ts +14 -0
- package/dist/types/Components/MemoryDeleteKeyVal.class.d.ts +19 -0
- package/dist/types/Components/MemoryReadKeyVal.class.d.ts +17 -0
- package/dist/types/Components/MemoryWriteKeyVal.class.d.ts +17 -0
- package/dist/types/Components/MemoryWriteObject.class.d.ts +19 -0
- package/dist/types/Components/index.d.ts +10 -0
- package/dist/types/Core/ConnectorsService.d.ts +2 -1
- package/dist/types/helpers/ECMASandbox.helper.d.ts +3 -0
- package/dist/types/helpers/Log.helper.d.ts +1 -1
- package/dist/types/index.d.ts +8 -1
- package/dist/types/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.d.ts +19 -0
- package/dist/types/subsystems/LLMManager/LLM.helper.d.ts +21 -10
- package/dist/types/subsystems/LLMManager/LLM.service/LLMConnector.d.ts +5 -5
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Echo.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Groq.class.d.ts +2 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +3 -4
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.d.ts +19 -14
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +95 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.d.ts +87 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.d.ts +85 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.d.ts +49 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +146 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.d.ts +10 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.d.ts +4 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/types.d.ts +38 -0
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +1 -2
- package/dist/types/subsystems/Security/Vault.service/connectors/JSONFileVault.class.d.ts +5 -0
- package/dist/types/types/LLM.types.d.ts +82 -37
- package/dist/types/utils/data.utils.d.ts +2 -1
- package/package.json +4 -3
- package/src/Components/APICall/APICall.class.ts +2 -1
- package/src/Components/Component.class.ts +1 -1
- package/src/Components/ECMASandbox.class.ts +71 -0
- package/src/Components/GenAILLM.class.ts +1 -1
- package/src/Components/MemoryDeleteKeyVal.class.ts +70 -0
- package/src/Components/MemoryReadKeyVal.class.ts +66 -0
- package/src/Components/MemoryWriteKeyVal.class.ts +62 -0
- package/src/Components/MemoryWriteObject.class.ts +97 -0
- package/src/Components/index.ts +10 -0
- package/src/Core/ConnectorsService.ts +3 -3
- package/src/helpers/Conversation.helper.ts +11 -3
- package/src/helpers/ECMASandbox.helper.ts +54 -0
- package/src/helpers/Log.helper.ts +57 -17
- package/src/index.ts +192 -185
- package/src/index.ts.bak +192 -185
- package/src/subsystems/AgentManager/Agent.class.ts +11 -6
- package/src/subsystems/AgentManager/AgentRuntime.class.ts +13 -13
- package/src/subsystems/ComputeManager/Code.service/connectors/ECMASandbox.class.ts +131 -0
- package/src/subsystems/ComputeManager/Code.service/index.ts +2 -0
- package/src/subsystems/LLMManager/LLM.helper.ts +57 -27
- package/src/subsystems/LLMManager/LLM.inference.ts +4 -0
- package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +125 -28
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +18 -17
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +2 -6
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +26 -17
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +2 -7
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +314 -84
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +455 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +528 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +100 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterfaceFactory.ts +81 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +853 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/constants.ts +37 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/index.ts +4 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/types.ts +37 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +0 -5
- package/src/subsystems/LLMManager/LLM.service/index.ts +1 -1
- package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +2 -2
- package/src/subsystems/LLMManager/models.ts +1 -1
- package/src/subsystems/MemoryManager/Cache.service/connectors/RedisCache.class.ts +18 -0
- package/src/subsystems/MemoryManager/RuntimeContext.ts +33 -16
- package/src/subsystems/Security/Vault.service/connectors/JSONFileVault.class.ts +68 -42
- package/src/types/LLM.types.ts +91 -43
- package/src/utils/data.utils.ts +3 -2
- package/src/subsystems/LLMManager/LLM.service/connectors/OpenAI.class.ts +0 -848
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SearchToolCostConfig } from '../types';
|
|
2
|
+
|
|
3
|
+
export const MODELS_WITHOUT_TEMPERATURE_SUPPORT = ['o3-pro', 'o4-mini'];
|
|
4
|
+
export const MODELS_WITHOUT_PRESENCE_PENALTY_SUPPORT = ['o4-mini'];
|
|
5
|
+
export const MODELS_WITHOUT_JSON_RESPONSE_SUPPORT = ['o1-preview'];
|
|
6
|
+
export const MODELS_WITHOUT_SYSTEM_MESSAGE_SUPPORT = ['o1-mini', 'o1-preview'];
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Search tool cost configuration
|
|
10
|
+
* Costs are in dollars per 1000 requests
|
|
11
|
+
*/
|
|
12
|
+
export const SEARCH_TOOL_COSTS: SearchToolCostConfig = {
|
|
13
|
+
normalModels: {
|
|
14
|
+
'gpt-4.1': {
|
|
15
|
+
low: 30 / 1000,
|
|
16
|
+
medium: 35 / 1000,
|
|
17
|
+
high: 50 / 1000,
|
|
18
|
+
},
|
|
19
|
+
'gpt-4o': {
|
|
20
|
+
low: 30 / 1000,
|
|
21
|
+
medium: 35 / 1000,
|
|
22
|
+
high: 50 / 1000,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
miniModels: {
|
|
26
|
+
'gpt-4.1-mini': {
|
|
27
|
+
low: 25 / 1000,
|
|
28
|
+
medium: 27.5 / 1000,
|
|
29
|
+
high: 30 / 1000,
|
|
30
|
+
},
|
|
31
|
+
'gpt-4o-mini': {
|
|
32
|
+
low: 25 / 1000,
|
|
33
|
+
medium: 27.5 / 1000,
|
|
34
|
+
high: 30 / 1000,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { OpenAIApiInterface, ToolConfig } from './OpenAIApiInterface';
|
|
2
|
+
export { ResponsesApiInterface } from './ResponsesApiInterface';
|
|
3
|
+
export { ChatCompletionsApiInterface } from './ChatCompletionsApiInterface';
|
|
4
|
+
export { OpenAIApiInterfaceFactory } from './OpenAIApiInterfaceFactory';
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import EventEmitter from 'events';
|
|
2
|
+
import OpenAI from 'openai';
|
|
3
|
+
import { ILLMRequestContext, APIKeySource } from '@sre/types/LLM.types';
|
|
4
|
+
|
|
5
|
+
export enum TToolType {
|
|
6
|
+
WebSearch = 'web_search_preview',
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IResponseHandler {
|
|
10
|
+
createStream(body: Record<string, unknown>, context: ILLMRequestContext): Promise<unknown>;
|
|
11
|
+
handleStream(stream: unknown, context: ILLMRequestContext): EventEmitter;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type HandlerDependencies = {
|
|
15
|
+
getClient: (context: ILLMRequestContext) => Promise<OpenAI>;
|
|
16
|
+
reportUsage: (
|
|
17
|
+
usage: OpenAI.Completions.CompletionUsage & {
|
|
18
|
+
input_tokens?: number;
|
|
19
|
+
output_tokens?: number;
|
|
20
|
+
input_tokens_details?: { cached_tokens?: number };
|
|
21
|
+
prompt_tokens_details?: { cached_tokens?: number };
|
|
22
|
+
cost?: number;
|
|
23
|
+
},
|
|
24
|
+
metadata: { modelEntryName: string; keySource: APIKeySource; agentId: string; teamId: string }
|
|
25
|
+
) => any;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export interface CostConfig {
|
|
29
|
+
[modelName: string]: {
|
|
30
|
+
[contextSize: string]: number;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface SearchToolCostConfig {
|
|
35
|
+
normalModels: CostConfig;
|
|
36
|
+
miniModels: CostConfig;
|
|
37
|
+
}
|
|
@@ -266,11 +266,6 @@ export class xAIConnector extends LLMConnector {
|
|
|
266
266
|
return emitter;
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
-
// TODO: will be removed when we merge with interface support of OpenAI
|
|
270
|
-
protected async webSearchRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
271
|
-
throw new Error('Not implemented');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
269
|
protected async reqBodyAdapter(params: TLLMParams): Promise<ChatCompletionParams> {
|
|
275
270
|
const messages = params?.messages || [];
|
|
276
271
|
const modelName = params.model as string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { ConnectorService, ConnectorServiceProvider } from '@sre/Core/ConnectorsService';
|
|
4
4
|
import { TConnectorService } from '@sre/types/SRE.types';
|
|
5
5
|
import { EchoConnector } from './connectors/Echo.class';
|
|
6
|
-
import { OpenAIConnector } from './connectors/
|
|
6
|
+
import { OpenAIConnector } from './connectors/openai/OpenAIConnector.class';
|
|
7
7
|
import { GoogleAIConnector } from './connectors/GoogleAI.class';
|
|
8
8
|
import { AnthropicConnector } from './connectors/Anthropic.class';
|
|
9
9
|
import { GroqConnector } from './connectors/Groq.class';
|
|
@@ -43,7 +43,7 @@ export abstract class ModelsProviderConnector extends SecureConnector {
|
|
|
43
43
|
const cacheKey = `ModelsProviderConnector:${candidate.toString()}`;
|
|
44
44
|
if (ModelsProviderConnector.localCache.has(cacheKey)) {
|
|
45
45
|
//update the TTL every time the requester is called
|
|
46
|
-
return ModelsProviderConnector.localCache.get(cacheKey,
|
|
46
|
+
return ModelsProviderConnector.localCache.get(cacheKey, 10 * 60 * 1000) as IModelsProviderRequest;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
let teamModels = null;
|
|
@@ -135,7 +135,7 @@ export abstract class ModelsProviderConnector extends SecureConnector {
|
|
|
135
135
|
}
|
|
136
136
|
},
|
|
137
137
|
};
|
|
138
|
-
ModelsProviderConnector.localCache.set(cacheKey, instance,
|
|
138
|
+
ModelsProviderConnector.localCache.set(cacheKey, instance, 10 * 60 * 1000); // cache for 10 minutes
|
|
139
139
|
return instance;
|
|
140
140
|
}
|
|
141
141
|
|
|
@@ -745,7 +745,7 @@ export const models = {
|
|
|
745
745
|
llm: 'GoogleAI',
|
|
746
746
|
|
|
747
747
|
label: 'Gemini 2.5 Flash Preview',
|
|
748
|
-
modelId: 'gemini-2.5-flash
|
|
748
|
+
modelId: 'gemini-2.5-flash',
|
|
749
749
|
provider: 'GoogleAI',
|
|
750
750
|
features: ['text', 'image', 'audio', 'video', 'document'],
|
|
751
751
|
tags: ['New', 'Personal'],
|
|
@@ -26,9 +26,27 @@ export class RedisCache extends CacheConnector {
|
|
|
26
26
|
let host = sentinels.length === 1 ? sentinels[0].host : null;
|
|
27
27
|
let port = sentinels.length === 1 ? sentinels[0].port : null;
|
|
28
28
|
|
|
29
|
+
const redisConfig = {
|
|
30
|
+
// HEAVILY OPTIMIZED: Aggressive storm prevention parameters
|
|
31
|
+
maxRetriesPerRequest: 1, // VERY LIMITED retries (official)
|
|
32
|
+
retryDelayOnFailover: 50, // Fast failover (official)
|
|
33
|
+
connectTimeout: 3000, // SHORT timeout (official)
|
|
34
|
+
lazyConnect: false,
|
|
35
|
+
enableReadyCheck: false, // Skip ready check for speed (official)
|
|
36
|
+
commandTimeout: 2000, // VERY SHORT command timeout (official)
|
|
37
|
+
keepAlive: 10000, // Shorter keepalive - 10sec (official)
|
|
38
|
+
family: 4, // Force IPv4 (official)
|
|
39
|
+
maxLoadingTimeout: 2000, // Short loading timeout (official)
|
|
40
|
+
// Additional aggressive settings
|
|
41
|
+
enableOfflineQueue: false, // Disable offline queue (official)
|
|
42
|
+
db: 0, // Explicit DB (official)
|
|
43
|
+
stringNumbers: false, // No string conversion (official)
|
|
44
|
+
};
|
|
45
|
+
|
|
29
46
|
this.redis = new IORedis({
|
|
30
47
|
...(host ? { host, port } : { sentinels, name: _settings.name || process.env.REDIS_MASTER_NAME }),
|
|
31
48
|
password: _settings.password || process.env.REDIS_PASSWORD,
|
|
49
|
+
...redisConfig,
|
|
32
50
|
});
|
|
33
51
|
|
|
34
52
|
this.redis.on('error', (error) => {
|
|
@@ -91,7 +91,7 @@ export class RuntimeContext extends EventEmitter {
|
|
|
91
91
|
if (this._runtimeFileReady) return;
|
|
92
92
|
|
|
93
93
|
const endpointDBGCall = this.runtime.xDebugId?.startsWith('dbg-'); //weak check for debug session, we need to improve this
|
|
94
|
-
console.debug('Init
|
|
94
|
+
console.debug('Init Agent Context', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
95
95
|
const agent = this.runtime.agent;
|
|
96
96
|
let method = (agent.agentRequest.method || 'POST').toUpperCase();
|
|
97
97
|
const endpoint = agent.endpoints?.[agent.agentRequest.path]?.[method];
|
|
@@ -177,10 +177,9 @@ export class RuntimeContext extends EventEmitter {
|
|
|
177
177
|
const exists = await this._cacheConnector.requester(AccessCandidate.agent(this.runtime.agent.id)).exists(this.ctxFile);
|
|
178
178
|
|
|
179
179
|
if (exists) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.updateTTL(this.ctxFile, 5 * 60); //expires in 5 minute
|
|
180
|
+
console.debug('Agent Context Delete', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
181
|
+
if (this.runtime.debug) this._cacheConnector.requester(AccessCandidate.agent(this.runtime.agent.id)).updateTTL(this.ctxFile, 5 * 60);
|
|
182
|
+
//expires in 5 minute
|
|
184
183
|
else this._cacheConnector.requester(AccessCandidate.agent(this.runtime.agent.id)).delete(this.ctxFile);
|
|
185
184
|
//if (this.runtime.debug && fs.existsSync(this.ctxFile)) await delay(1000 * 60); //if we're in debug mode, we keep the file for a while to allow final state read
|
|
186
185
|
//if (fs.existsSync(this.ctxFile)) fs.unlinkSync(this.ctxFile);
|
|
@@ -188,10 +187,13 @@ export class RuntimeContext extends EventEmitter {
|
|
|
188
187
|
} else {
|
|
189
188
|
const data = this.serialize();
|
|
190
189
|
//if (data) fs.writeFileSync(this.ctxFile, JSON.stringify(data, null, 2));
|
|
191
|
-
if (data)
|
|
190
|
+
if (data) {
|
|
191
|
+
const serializedData = JSON.stringify(data, null, 2);
|
|
192
|
+
console.debug('Agent Context Size', this.ctxFile, serializedData.length, AccessCandidate.agent(this.runtime.agent.id));
|
|
192
193
|
await this._cacheConnector
|
|
193
194
|
.requester(AccessCandidate.agent(this.runtime.agent.id))
|
|
194
|
-
.set(this.ctxFile,
|
|
195
|
+
.set(this.ctxFile, serializedData, null, null, 3 * 60 * 60); //expires in 3 hours max
|
|
196
|
+
}
|
|
195
197
|
}
|
|
196
198
|
}
|
|
197
199
|
|
|
@@ -206,9 +208,14 @@ export class RuntimeContext extends EventEmitter {
|
|
|
206
208
|
const component = ctxData.components[componentId];
|
|
207
209
|
|
|
208
210
|
if (!component) {
|
|
209
|
-
console.
|
|
210
|
-
|
|
211
|
-
|
|
211
|
+
console.debug(
|
|
212
|
+
'>>>>>>> updateComponent Component debug data not found',
|
|
213
|
+
componentId,
|
|
214
|
+
component,
|
|
215
|
+
AccessCandidate.agent(this.runtime.agent.id)
|
|
216
|
+
);
|
|
217
|
+
console.debug('>>> ctxFile', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
218
|
+
console.debug('>>> ctxData', ctxData, AccessCandidate.agent(this.runtime.agent.id));
|
|
212
219
|
}
|
|
213
220
|
component.ctx = { ...component.ctx, ...data, step: this.step };
|
|
214
221
|
|
|
@@ -220,9 +227,14 @@ export class RuntimeContext extends EventEmitter {
|
|
|
220
227
|
const ctxData = this;
|
|
221
228
|
const component = ctxData.components[componentId];
|
|
222
229
|
if (!component) {
|
|
223
|
-
console.
|
|
224
|
-
|
|
225
|
-
|
|
230
|
+
console.debug(
|
|
231
|
+
'>>>>>>> resetComponent Component debug data not found',
|
|
232
|
+
componentId,
|
|
233
|
+
component,
|
|
234
|
+
AccessCandidate.agent(this.runtime.agent.id)
|
|
235
|
+
);
|
|
236
|
+
console.debug('>>> ctxFile', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
237
|
+
console.debug('>>> ctxData', ctxData, AccessCandidate.agent(this.runtime.agent.id));
|
|
226
238
|
}
|
|
227
239
|
//component.dbg.active = false;
|
|
228
240
|
//component.dbg.runtimeData = {};
|
|
@@ -237,9 +249,14 @@ export class RuntimeContext extends EventEmitter {
|
|
|
237
249
|
if (!ctxData) return null;
|
|
238
250
|
const component = ctxData.components[componentId];
|
|
239
251
|
if (!component) {
|
|
240
|
-
console.
|
|
241
|
-
|
|
242
|
-
|
|
252
|
+
console.debug(
|
|
253
|
+
'>>>>>>> getComponentData Component debug data not found',
|
|
254
|
+
componentId,
|
|
255
|
+
component,
|
|
256
|
+
AccessCandidate.agent(this.runtime.agent.id)
|
|
257
|
+
);
|
|
258
|
+
console.debug('>>> ctxFile', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
259
|
+
console.debug('>>> ctxData', ctxData, AccessCandidate.agent(this.runtime.agent.id));
|
|
243
260
|
}
|
|
244
261
|
//const data = this.debug ? component.dbg : component.ctx;
|
|
245
262
|
const data = component.ctx;
|
|
@@ -13,6 +13,7 @@ import crypto from 'crypto';
|
|
|
13
13
|
import fs from 'fs';
|
|
14
14
|
import * as readlineSync from 'readline-sync';
|
|
15
15
|
import path from 'path';
|
|
16
|
+
import * as chokidar from 'chokidar';
|
|
16
17
|
import { findSmythPath } from '../../../../helpers/Sysconfig.helper';
|
|
17
18
|
|
|
18
19
|
const console = Logger('JSONFileVault');
|
|
@@ -28,6 +29,8 @@ export class JSONFileVault extends VaultConnector {
|
|
|
28
29
|
private vaultData: any;
|
|
29
30
|
private index: any;
|
|
30
31
|
private shared: string;
|
|
32
|
+
private vaultFile: string;
|
|
33
|
+
private watcher: chokidar.FSWatcher | null = null;
|
|
31
34
|
|
|
32
35
|
constructor(protected _settings: JSONFileVaultConfig) {
|
|
33
36
|
super(_settings);
|
|
@@ -35,48 +38,9 @@ export class JSONFileVault extends VaultConnector {
|
|
|
35
38
|
|
|
36
39
|
this.shared = _settings.shared || ''; //if config.shared, all keys are accessible to all teams, and they are set under the 'shared' teamId
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
this.
|
|
40
|
-
|
|
41
|
-
try {
|
|
42
|
-
if (_settings.fileKey && fs.existsSync(_settings.fileKey)) {
|
|
43
|
-
try {
|
|
44
|
-
const privateKey = fs.readFileSync(_settings.fileKey, 'utf8');
|
|
45
|
-
const encryptedVault = fs.readFileSync(vaultFile, 'utf8').toString();
|
|
46
|
-
const decryptedBuffer = crypto.privateDecrypt(
|
|
47
|
-
{
|
|
48
|
-
key: privateKey,
|
|
49
|
-
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
50
|
-
},
|
|
51
|
-
Buffer.from(encryptedVault, 'base64')
|
|
52
|
-
);
|
|
53
|
-
this.vaultData = JSON.parse(decryptedBuffer.toString('utf8'));
|
|
54
|
-
} catch (error) {
|
|
55
|
-
throw new Error('Failed to decrypt vault');
|
|
56
|
-
}
|
|
57
|
-
} else {
|
|
58
|
-
this.vaultData = JSON.parse(fs.readFileSync(vaultFile).toString());
|
|
59
|
-
}
|
|
60
|
-
} catch (e) {
|
|
61
|
-
console.error('Error parsing vault file:', e);
|
|
62
|
-
console.error('!!! Vault features might not work properly !!!');
|
|
63
|
-
this.vaultData = {};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (this.vaultData?.encrypted && this.vaultData?.algorithm && this.vaultData?.data) {
|
|
67
|
-
//this is an encrypted vault we need to request the master key
|
|
68
|
-
this.setInteraction(this.getMasterKeyInteractive.bind(this));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
for (let teamId in this.vaultData) {
|
|
72
|
-
for (let resourceId in this.vaultData[teamId]) {
|
|
73
|
-
if (!this.index) this.index = {};
|
|
74
|
-
if (!this.index[resourceId]) this.index[resourceId] = {};
|
|
75
|
-
const value = this.vaultData[teamId][resourceId];
|
|
76
|
-
this.index[resourceId][teamId] = value;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
41
|
+
this.vaultFile = this.findVaultFile(_settings.file);
|
|
42
|
+
this.fetchVaultData(this.vaultFile, _settings);
|
|
43
|
+
this.initFileWatcher();
|
|
80
44
|
}
|
|
81
45
|
|
|
82
46
|
private findVaultFile(vaultFile) {
|
|
@@ -192,4 +156,66 @@ export class JSONFileVault extends VaultConnector {
|
|
|
192
156
|
|
|
193
157
|
return acl;
|
|
194
158
|
}
|
|
159
|
+
|
|
160
|
+
private fetchVaultData(vaultFile: string, _settings: JSONFileVaultConfig) {
|
|
161
|
+
if (fs.existsSync(vaultFile)) {
|
|
162
|
+
try {
|
|
163
|
+
if (_settings.fileKey && fs.existsSync(_settings.fileKey)) {
|
|
164
|
+
try {
|
|
165
|
+
const privateKey = fs.readFileSync(_settings.fileKey, 'utf8');
|
|
166
|
+
const encryptedVault = fs.readFileSync(vaultFile, 'utf8').toString();
|
|
167
|
+
const decryptedBuffer = crypto.privateDecrypt(
|
|
168
|
+
{
|
|
169
|
+
key: privateKey,
|
|
170
|
+
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
|
|
171
|
+
},
|
|
172
|
+
Buffer.from(encryptedVault, 'base64')
|
|
173
|
+
);
|
|
174
|
+
this.vaultData = JSON.parse(decryptedBuffer.toString('utf8'));
|
|
175
|
+
} catch (error) {
|
|
176
|
+
throw new Error('Failed to decrypt vault');
|
|
177
|
+
}
|
|
178
|
+
} else {
|
|
179
|
+
this.vaultData = JSON.parse(fs.readFileSync(vaultFile).toString());
|
|
180
|
+
}
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.error('Error parsing vault file:', e);
|
|
183
|
+
console.error('!!! Vault features might not work properly !!!');
|
|
184
|
+
this.vaultData = {};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (this.vaultData?.encrypted && this.vaultData?.algorithm && this.vaultData?.data) {
|
|
188
|
+
//this is an encrypted vault we need to request the master key
|
|
189
|
+
this.setInteraction(this.getMasterKeyInteractive.bind(this));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (let teamId in this.vaultData) {
|
|
193
|
+
for (let resourceId in this.vaultData[teamId]) {
|
|
194
|
+
if (!this.index) this.index = {};
|
|
195
|
+
if (!this.index[resourceId]) this.index[resourceId] = {};
|
|
196
|
+
const value = this.vaultData[teamId][resourceId];
|
|
197
|
+
this.index[resourceId][teamId] = value;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private initFileWatcher() {
|
|
204
|
+
this.watcher = chokidar.watch(this.vaultFile, {
|
|
205
|
+
persistent: false, // Don't keep the process running
|
|
206
|
+
ignoreInitial: true,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
this.watcher.on('change', () => {
|
|
210
|
+
this.fetchVaultData(this.vaultFile, this._settings);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public async stop() {
|
|
215
|
+
super.stop();
|
|
216
|
+
if (this.watcher) {
|
|
217
|
+
this.watcher.close();
|
|
218
|
+
this.watcher = null;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
195
221
|
}
|
package/src/types/LLM.types.ts
CHANGED
|
@@ -45,10 +45,47 @@ export type ILLMConnectorCredentials = BasicCredentials | BedrockCredentials | V
|
|
|
45
45
|
export type TOpenAIResponseToolChoice = OpenAI.Responses.ToolChoiceOptions | OpenAI.Responses.ToolChoiceTypes | OpenAI.Responses.ToolChoiceFunction;
|
|
46
46
|
export type TLLMToolChoice = OpenAI.ChatCompletionToolChoiceOption;
|
|
47
47
|
|
|
48
|
+
export type TOpenAIToolsInfo = {
|
|
49
|
+
webSearch: {
|
|
50
|
+
enabled: boolean;
|
|
51
|
+
contextSize: TSearchContextSize;
|
|
52
|
+
city?: string;
|
|
53
|
+
country?: string;
|
|
54
|
+
region?: string;
|
|
55
|
+
timezone?: string;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export type TxAIToolsInfo = {
|
|
60
|
+
search: {
|
|
61
|
+
enabled: boolean;
|
|
62
|
+
mode?: 'auto' | 'on' | 'off';
|
|
63
|
+
returnCitations?: boolean;
|
|
64
|
+
maxResults?: number;
|
|
65
|
+
dataSources?: string[];
|
|
66
|
+
country?: string;
|
|
67
|
+
excludedWebsites?: string[];
|
|
68
|
+
allowedWebsites?: string[];
|
|
69
|
+
includedXHandles?: string[];
|
|
70
|
+
excludedXHandles?: string[];
|
|
71
|
+
postFavoriteCount?: number;
|
|
72
|
+
postViewCount?: number;
|
|
73
|
+
rssLinks?: string;
|
|
74
|
+
safeSearch?: boolean;
|
|
75
|
+
fromDate?: string;
|
|
76
|
+
toDate?: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export type TToolsInfo = {
|
|
81
|
+
openai: TOpenAIToolsInfo;
|
|
82
|
+
xai: TxAIToolsInfo;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export type TSearchContextSize = 'low' | 'medium' | 'high';
|
|
86
|
+
|
|
48
87
|
export type TLLMParams = {
|
|
49
88
|
model: TLLMModel | string;
|
|
50
|
-
modelEntryName?: string; // for usage reporting
|
|
51
|
-
credentials?: ILLMConnectorCredentials;
|
|
52
89
|
|
|
53
90
|
prompt?: string;
|
|
54
91
|
messages?: any[]; // TODO [Forhad]: apply proper typing
|
|
@@ -84,14 +121,15 @@ export type TLLMParams = {
|
|
|
84
121
|
maxThinkingTokens?: number;
|
|
85
122
|
|
|
86
123
|
// #region Search
|
|
124
|
+
// Web search parameters (will be organized into toolsInfo.webSearch internally)
|
|
87
125
|
useWebSearch?: boolean;
|
|
88
|
-
webSearchContextSize?:
|
|
126
|
+
webSearchContextSize?: TSearchContextSize;
|
|
89
127
|
webSearchCity?: string;
|
|
90
128
|
webSearchCountry?: string;
|
|
91
129
|
webSearchRegion?: string;
|
|
92
130
|
webSearchTimezone?: string;
|
|
93
131
|
|
|
94
|
-
// xAI specific search parameters
|
|
132
|
+
// xAI specific search parameters (consider moving to toolsInfo.xaiSearch)
|
|
95
133
|
useSearch?: boolean;
|
|
96
134
|
searchMode?: 'auto' | 'on' | 'off';
|
|
97
135
|
returnCitations?: boolean;
|
|
@@ -111,7 +149,14 @@ export type TLLMParams = {
|
|
|
111
149
|
// #endregion
|
|
112
150
|
|
|
113
151
|
useReasoning?: boolean;
|
|
152
|
+
max_output_tokens?: number;
|
|
153
|
+
abortSignal?: AbortSignal;
|
|
154
|
+
};
|
|
114
155
|
|
|
156
|
+
export type TLLMPreparedParams = TLLMParams & {
|
|
157
|
+
body: any;
|
|
158
|
+
modelEntryName?: string; // for usage reporting
|
|
159
|
+
credentials?: ILLMConnectorCredentials;
|
|
115
160
|
isUserKey?: boolean;
|
|
116
161
|
capabilities?: {
|
|
117
162
|
search?: boolean;
|
|
@@ -119,43 +164,7 @@ export type TLLMParams = {
|
|
|
119
164
|
imageGeneration?: boolean;
|
|
120
165
|
imageEditing?: boolean;
|
|
121
166
|
};
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
abortSignal?: AbortSignal;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export type TLLMParamsV2 = {
|
|
128
|
-
model: string;
|
|
129
|
-
modelEntryName: string;
|
|
130
|
-
messages: any[];
|
|
131
|
-
toolsConfig?: {
|
|
132
|
-
tools?: OpenAI.Responses.Tool[];
|
|
133
|
-
tool_choice?: OpenAI.Responses.ToolChoiceOptions | OpenAI.Responses.ToolChoiceTypes | OpenAI.Responses.ToolChoiceFunction;
|
|
134
|
-
};
|
|
135
|
-
baseURL?: string;
|
|
136
|
-
stream?: boolean;
|
|
137
|
-
responseFormat?: any;
|
|
138
|
-
credentials?: {
|
|
139
|
-
apiKey?: string;
|
|
140
|
-
isUserKey?: boolean;
|
|
141
|
-
};
|
|
142
|
-
max_output_tokens?: number;
|
|
143
|
-
temperature?: number;
|
|
144
|
-
top_p?: number;
|
|
145
|
-
top_k?: number;
|
|
146
|
-
frequency_penalty?: number;
|
|
147
|
-
presence_penalty?: number;
|
|
148
|
-
teamId?: string;
|
|
149
|
-
files?: BinaryInput[];
|
|
150
|
-
|
|
151
|
-
// #region Search
|
|
152
|
-
useWebSearch?: boolean;
|
|
153
|
-
webSearchContextSize?: 'high' | 'medium' | 'low';
|
|
154
|
-
webSearchCity?: string;
|
|
155
|
-
webSearchCountry?: string;
|
|
156
|
-
webSearchRegion?: string;
|
|
157
|
-
webSearchTimezone?: string;
|
|
158
|
-
// #endregion
|
|
167
|
+
toolsInfo?: TToolsInfo;
|
|
159
168
|
};
|
|
160
169
|
|
|
161
170
|
export type TLLMConnectorParams = Omit<TLLMParams, 'model'> & {
|
|
@@ -207,6 +216,12 @@ export type TLLMModel = {
|
|
|
207
216
|
//models can come with predefined params
|
|
208
217
|
//this can also be used to pass a preconfigured model object
|
|
209
218
|
params?: TLLMParams;
|
|
219
|
+
/**
|
|
220
|
+
* Specifies the API interface type to use for this model
|
|
221
|
+
* Examples: 'chat.completions', 'responses'
|
|
222
|
+
* This determines which OpenAI API endpoint and interface implementation to use
|
|
223
|
+
*/
|
|
224
|
+
interface?: 'chat.completions' | 'responses';
|
|
210
225
|
};
|
|
211
226
|
|
|
212
227
|
// #region [ Handle extendable LLM Providers ] ================================================
|
|
@@ -245,6 +260,7 @@ export type TVertexAISettings = {
|
|
|
245
260
|
projectId: string;
|
|
246
261
|
credentialsName: string;
|
|
247
262
|
jsonCredentialsName: string;
|
|
263
|
+
apiEndpoint?: string;
|
|
248
264
|
};
|
|
249
265
|
|
|
250
266
|
export type TCustomLLMModel = TLLMModel & {
|
|
@@ -269,16 +285,47 @@ export type ToolData = {
|
|
|
269
285
|
error?: string; // for Bedrock
|
|
270
286
|
};
|
|
271
287
|
|
|
272
|
-
|
|
288
|
+
/**
|
|
289
|
+
* Base tool definition interface - only truly common properties
|
|
290
|
+
* All provider-specific tool definitions extend from this
|
|
291
|
+
*/
|
|
292
|
+
export interface ToolDefinition {
|
|
273
293
|
name: string;
|
|
274
294
|
description: string;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* OpenAI-specific tool definition
|
|
299
|
+
* Extends base with OpenAI's parameter format
|
|
300
|
+
*/
|
|
301
|
+
export interface OpenAIToolDefinition extends ToolDefinition {
|
|
302
|
+
parameters: {
|
|
303
|
+
type: 'object';
|
|
304
|
+
properties: Record<string, unknown>;
|
|
305
|
+
required?: string[];
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Anthropic-specific tool definition
|
|
311
|
+
* Extends base with Anthropic's input_schema format
|
|
312
|
+
*/
|
|
313
|
+
export interface AnthropicToolDefinition extends ToolDefinition {
|
|
275
314
|
input_schema: {
|
|
276
315
|
type: 'object';
|
|
277
316
|
properties: Record<string, unknown>;
|
|
278
317
|
required: string[];
|
|
279
318
|
};
|
|
280
319
|
}
|
|
281
|
-
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Legacy tool definition for backward compatibility
|
|
323
|
+
* @deprecated Use provider-specific definitions instead
|
|
324
|
+
*/
|
|
325
|
+
export interface LegacyToolDefinition extends ToolDefinition {
|
|
326
|
+
properties?: Record<string, unknown>;
|
|
327
|
+
requiredFields?: string[];
|
|
328
|
+
}
|
|
282
329
|
export type ToolChoice = OpenAI.ChatCompletionToolChoiceOption | FunctionCallingMode;
|
|
283
330
|
|
|
284
331
|
export interface ToolsConfig {
|
|
@@ -397,6 +444,7 @@ export interface ILLMRequestContext {
|
|
|
397
444
|
hasFiles?: boolean;
|
|
398
445
|
modelInfo: TCustomLLMModel | TLLMModel;
|
|
399
446
|
credentials: ILLMConnectorCredentials;
|
|
447
|
+
toolsInfo?: TToolsInfo;
|
|
400
448
|
}
|
|
401
449
|
|
|
402
450
|
// Generic interface that can be extended by specific providers
|
package/src/utils/data.utils.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { isBinaryFileSync } from 'isbinaryfile';
|
|
|
7
7
|
import { fileTypeFromBuffer } from 'file-type';
|
|
8
8
|
import { BinaryInput } from '@sre/helpers/BinaryInput.helper';
|
|
9
9
|
import { identifyMimetypeFromString } from './string.utils';
|
|
10
|
+
import { IAccessCandidate } from '@sre/types/ACL.types';
|
|
10
11
|
|
|
11
12
|
// Helper function to convert stream to buffer
|
|
12
13
|
export async function streamToBuffer(stream: Readable): Promise<Buffer> {
|
|
@@ -250,7 +251,7 @@ export async function getMimeType(data: any): Promise<string> {
|
|
|
250
251
|
|
|
251
252
|
// Mask data like Buffer, FormData, etc. in debug output
|
|
252
253
|
// TODO [Forhad]: Need to get the size of FormData
|
|
253
|
-
export async function formatDataForDebug(data: any) {
|
|
254
|
+
export async function formatDataForDebug(data: any, candidate: IAccessCandidate) {
|
|
254
255
|
let dataForDebug;
|
|
255
256
|
|
|
256
257
|
if (!data) {
|
|
@@ -259,7 +260,7 @@ export async function formatDataForDebug(data: any) {
|
|
|
259
260
|
|
|
260
261
|
try {
|
|
261
262
|
if (data.constructor?.name === 'BinaryInput') {
|
|
262
|
-
const jsonData = await data.getJsonData();
|
|
263
|
+
const jsonData = await data.getJsonData(candidate);
|
|
263
264
|
dataForDebug = `[BinaryInput size=${jsonData?.size}]`;
|
|
264
265
|
} else if (isBuffer(data)) {
|
|
265
266
|
dataForDebug = `[Buffer size=${data.byteLength}]`;
|