@smythos/sre 1.5.55 → 1.5.60
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/CHANGELOG +7 -0
- package/dist/index.js +7 -7
- package/dist/index.js.map +1 -1
- package/dist/types/Components/ScrapflyWebScrape.class.d.ts +23 -0
- package/dist/types/Core/SmythRuntime.class.d.ts +1 -0
- package/dist/types/subsystems/MemoryManager/RuntimeContext.d.ts +3 -1
- package/dist/types/types/LLM.types.d.ts +2 -0
- package/package.json +2 -2
- package/src/Components/ScrapflyWebScrape.class.ts +24 -0
- package/src/Components/TavilyWebSearch.class.ts +6 -1
- package/src/Core/SmythRuntime.class.ts +6 -0
- package/src/helpers/Conversation.helper.ts +5 -0
- package/src/subsystems/AgentManager/AgentRuntime.class.ts +4 -6
- package/src/subsystems/LLMManager/LLM.inference.ts +3 -0
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +2 -2
- package/src/subsystems/LLMManager/ModelsProvider.service/ModelsProviderConnector.ts +3 -0
- package/src/subsystems/MemoryManager/RuntimeContext.ts +49 -45
- package/src/types/LLM.types.ts +2 -0
|
@@ -2,6 +2,29 @@ import { IAgent as Agent } from '@sre/types/Agent.types';
|
|
|
2
2
|
import { Component } from './Component.class';
|
|
3
3
|
import Joi from 'joi';
|
|
4
4
|
export declare class ScrapflyWebScrape extends Component {
|
|
5
|
+
protected schema: {
|
|
6
|
+
name: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputs: {
|
|
9
|
+
URLs: {
|
|
10
|
+
type: string;
|
|
11
|
+
description: string;
|
|
12
|
+
default: boolean;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
outputs: {
|
|
16
|
+
Results: {
|
|
17
|
+
type: string;
|
|
18
|
+
description: string;
|
|
19
|
+
default: boolean;
|
|
20
|
+
};
|
|
21
|
+
FailedURLs: {
|
|
22
|
+
type: string;
|
|
23
|
+
description: string;
|
|
24
|
+
default: boolean;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
};
|
|
5
28
|
protected configSchema: Joi.ObjectSchema<any>;
|
|
6
29
|
constructor();
|
|
7
30
|
init(): void;
|
|
@@ -41,7 +41,9 @@ export declare class RuntimeContext extends EventEmitter {
|
|
|
41
41
|
private reset;
|
|
42
42
|
private initRuntimeContext;
|
|
43
43
|
ready(): Promise<boolean>;
|
|
44
|
-
sync
|
|
44
|
+
private sync;
|
|
45
|
+
private _syncQueue;
|
|
46
|
+
enqueueSync(): void;
|
|
45
47
|
incStep(): void;
|
|
46
48
|
updateComponent(componentId: string, data: any): void;
|
|
47
49
|
resetComponent(componentId: string): void;
|
|
@@ -384,6 +384,8 @@ export type TLLMModelsList = {
|
|
|
384
384
|
[key: string]: TLLMModel | TCustomLLMModel;
|
|
385
385
|
};
|
|
386
386
|
export declare enum TLLMEvent {
|
|
387
|
+
/** Generated response chunks */
|
|
388
|
+
Data = "data",
|
|
387
389
|
/** Generated response chunks */
|
|
388
390
|
Content = "content",
|
|
389
391
|
/** Thinking blocks/chunks */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smythos/sre",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.60",
|
|
4
4
|
"description": "Smyth Runtime Environment",
|
|
5
5
|
"author": "Alaa-eddine KADDOURI",
|
|
6
6
|
"license": "MIT",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"@google/genai": "^1.10.0",
|
|
57
57
|
"@google/generative-ai": "^0.14.1",
|
|
58
58
|
"@huggingface/inference": "^2.8.0",
|
|
59
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
59
|
+
"@modelcontextprotocol/sdk": "^1.17.4",
|
|
60
60
|
"@pinecone-database/pinecone": "^3.0.0",
|
|
61
61
|
"@runware/sdk-js": "^1.1.36",
|
|
62
62
|
"@smithy/smithy-client": "^4.4.3",
|
|
@@ -9,6 +9,30 @@ import { getCredentials } from '../subsystems/Security/Credentials.helper';
|
|
|
9
9
|
// const CREDITS_PER_URL = 0.2;
|
|
10
10
|
|
|
11
11
|
export class ScrapflyWebScrape extends Component {
|
|
12
|
+
protected schema = {
|
|
13
|
+
name: 'ScrapflyWebScrape',
|
|
14
|
+
description: 'Use this component to scrape web pages',
|
|
15
|
+
inputs: {
|
|
16
|
+
URLs: {
|
|
17
|
+
type: 'Array',
|
|
18
|
+
description: 'The URLs to scrape',
|
|
19
|
+
default: true,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
outputs: {
|
|
23
|
+
Results: {
|
|
24
|
+
type: 'Array',
|
|
25
|
+
description: 'The scraped results',
|
|
26
|
+
default: true,
|
|
27
|
+
},
|
|
28
|
+
FailedURLs: {
|
|
29
|
+
type: 'Array',
|
|
30
|
+
description: 'The URLs that failed to scrape',
|
|
31
|
+
default: true,
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
|
|
12
36
|
protected configSchema = Joi.object({
|
|
13
37
|
// includeImages: Joi.boolean().default(false).label('Include Image Results'),
|
|
14
38
|
antiScrapingProtection: Joi.boolean().default(false).label('Enable Anti-Scraping Protection'),
|
|
@@ -82,7 +82,12 @@ export class TavilyWebSearch extends Component {
|
|
|
82
82
|
return { ...Output, _error, _debug: logger.output };
|
|
83
83
|
} catch (err: any) {
|
|
84
84
|
const _error = err?.message || err?.response?.data || err.toString();
|
|
85
|
-
|
|
85
|
+
|
|
86
|
+
if (err?.status === 401) {
|
|
87
|
+
logger.error(`Tavily Web Search Auth failed, make sure that you have the vault key "tavily" is present and valid`);
|
|
88
|
+
} else {
|
|
89
|
+
logger.error(` Error scraping web \n${JSON.stringify(_error)}\n`);
|
|
90
|
+
}
|
|
86
91
|
return { Output: undefined, _error, _debug: logger.output };
|
|
87
92
|
}
|
|
88
93
|
}
|
|
@@ -5,6 +5,7 @@ import { Logger } from '../helpers/Log.helper';
|
|
|
5
5
|
import { ConnectorService } from './ConnectorsService';
|
|
6
6
|
import { SystemEvents } from './SystemEvents';
|
|
7
7
|
import { findSmythPath } from '../helpers/Sysconfig.helper';
|
|
8
|
+
import pkg from '../../package.json';
|
|
8
9
|
|
|
9
10
|
const logger = Logger('SRE');
|
|
10
11
|
|
|
@@ -18,6 +19,10 @@ export class SmythRuntime {
|
|
|
18
19
|
private _readyPromise: Promise<boolean>;
|
|
19
20
|
private _readyResolve: (value: boolean) => void;
|
|
20
21
|
|
|
22
|
+
public get version() {
|
|
23
|
+
return pkg.version;
|
|
24
|
+
}
|
|
25
|
+
|
|
21
26
|
private defaultConfig: SREConfig = {
|
|
22
27
|
Vault: {
|
|
23
28
|
Connector: 'JSONFileVault',
|
|
@@ -88,6 +93,7 @@ export class SmythRuntime {
|
|
|
88
93
|
private _initialized = false;
|
|
89
94
|
|
|
90
95
|
public init(_config?: SREConfig): SmythRuntime {
|
|
96
|
+
logger.info(`SRE v${this.version} initializing...`);
|
|
91
97
|
if (!_config || JSON.stringify(_config) === '{}') {
|
|
92
98
|
this._smythDir = findSmythPath();
|
|
93
99
|
logger.info('.smyth directory found in:', this._smythDir);
|
|
@@ -342,6 +342,11 @@ export class Conversation extends EventEmitter {
|
|
|
342
342
|
this.emit(TLLMEvent.Thinking, thinking);
|
|
343
343
|
});
|
|
344
344
|
|
|
345
|
+
eventEmitter.on(TLLMEvent.Data, (data) => {
|
|
346
|
+
if (this.stop) return;
|
|
347
|
+
this.emit(TLLMEvent.Data, data);
|
|
348
|
+
});
|
|
349
|
+
|
|
345
350
|
eventEmitter.on(TLLMEvent.Content, (content) => {
|
|
346
351
|
if (this.stop) return;
|
|
347
352
|
// if (toolHeaders['x-passthrough']) {
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { Agent } from './Agent.class';
|
|
4
1
|
import { Component } from '@sre/Components/Component.class';
|
|
2
|
+
import { Agent } from './Agent.class';
|
|
5
3
|
|
|
6
4
|
import { Logger } from '@sre/helpers/Log.helper';
|
|
7
|
-
import { uid } from '@sre/utils';
|
|
8
|
-
import { RuntimeContext } from '@sre/MemoryManager/RuntimeContext';
|
|
9
5
|
import { LLMCache } from '@sre/MemoryManager/LLMCache';
|
|
6
|
+
import { RuntimeContext } from '@sre/MemoryManager/RuntimeContext';
|
|
10
7
|
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
8
|
+
import { uid } from '@sre/utils';
|
|
11
9
|
|
|
12
10
|
const console = Logger('AgentRuntime');
|
|
13
11
|
const AgentRuntimeUnavailable = new Proxy(
|
|
@@ -201,7 +199,7 @@ export class AgentRuntime {
|
|
|
201
199
|
delete AgentRuntime.tagsData[this.reqTag];
|
|
202
200
|
}
|
|
203
201
|
|
|
204
|
-
this.agentContext.
|
|
202
|
+
this.agentContext.enqueueSync();
|
|
205
203
|
}
|
|
206
204
|
public getWaitingComponents() {
|
|
207
205
|
const ctxData = this.agentContext;
|
|
@@ -265,6 +265,9 @@ export class LLMInference {
|
|
|
265
265
|
console.warn('Max input context is 0, returning empty context window, This usually indicates a wrong model configuration');
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
console.debug(
|
|
269
|
+
`Context Window Configuration: Max Input Tokens: ${maxInputContext}, Max Output Tokens: ${maxOutputContext}, Max Model Tokens: ${maxModelContext}`
|
|
270
|
+
);
|
|
268
271
|
const systemMessage = { role: 'system', content: systemPrompt };
|
|
269
272
|
|
|
270
273
|
let smythContextWindow = [];
|
|
@@ -188,7 +188,7 @@ export class ChatCompletionsApiInterface extends OpenAIApiInterface {
|
|
|
188
188
|
// Handle OpenAI tool definition format
|
|
189
189
|
if ('parameters' in tool) {
|
|
190
190
|
return {
|
|
191
|
-
type: 'function',
|
|
191
|
+
type: 'function' as const,
|
|
192
192
|
function: {
|
|
193
193
|
name: tool.name,
|
|
194
194
|
description: tool.description,
|
|
@@ -199,7 +199,7 @@ export class ChatCompletionsApiInterface extends OpenAIApiInterface {
|
|
|
199
199
|
|
|
200
200
|
// Handle legacy format for backward compatibility
|
|
201
201
|
return {
|
|
202
|
-
type: 'function',
|
|
202
|
+
type: 'function' as const,
|
|
203
203
|
function: {
|
|
204
204
|
name: tool.name,
|
|
205
205
|
description: tool.description,
|
|
@@ -132,6 +132,9 @@ export abstract class ModelsProviderConnector extends SecureConnector {
|
|
|
132
132
|
hasAPIKey: boolean;
|
|
133
133
|
}) => {
|
|
134
134
|
//const teamModels = typeof model === 'string' ? await loadTeamModels() : {};
|
|
135
|
+
if (Array.isArray(model?.tags) && model?.tags?.includes('sdk')) {
|
|
136
|
+
return; //skip check for SDK
|
|
137
|
+
}
|
|
135
138
|
const modelInfo = await this.getModelInfo(candidate.readRequest, {}, model, hasAPIKey);
|
|
136
139
|
const allowedContextTokens = modelInfo?.tokens;
|
|
137
140
|
const totalTokens = promptTokens + completionTokens;
|
|
@@ -21,6 +21,7 @@ type TComponentContext = {
|
|
|
21
21
|
input?: { [key: string]: any };
|
|
22
22
|
output?: { [key: string]: any };
|
|
23
23
|
};
|
|
24
|
+
|
|
24
25
|
export class RuntimeContext extends EventEmitter {
|
|
25
26
|
public circularLimitReached: string | boolean = false;
|
|
26
27
|
public step: number = 0;
|
|
@@ -120,10 +121,10 @@ export class RuntimeContext extends EventEmitter {
|
|
|
120
121
|
cpt.ctx.active = true;
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
|
-
|
|
124
|
+
|
|
124
125
|
await this._cacheConnector
|
|
125
126
|
.requester(AccessCandidate.agent(this.runtime.agent.id))
|
|
126
|
-
.set(this.ctxFile, JSON.stringify(ctxData
|
|
127
|
+
.set(this.ctxFile, JSON.stringify(ctxData), null, null, 1 * 60 * 60); //expires in 1 hour
|
|
127
128
|
} else {
|
|
128
129
|
ctxData = JSON.parse(data);
|
|
129
130
|
if (!ctxData.step) ctxData.step = 0;
|
|
@@ -133,46 +134,38 @@ export class RuntimeContext extends EventEmitter {
|
|
|
133
134
|
this._runtimeFileReady = true;
|
|
134
135
|
this.emit('ready');
|
|
135
136
|
});
|
|
136
|
-
|
|
137
|
-
// if (!fs.existsSync(this.ctxFile)) {
|
|
138
|
-
// ctxData = JSON.parse(JSON.stringify({ components: agent.components, connections: agent.connections, timestamp: Date.now() }));
|
|
139
|
-
// if (!ctxData.step) ctxData.step = 0;
|
|
140
|
-
// for (let cptId in ctxData.components) {
|
|
141
|
-
// ctxData.components[cptId] = {
|
|
142
|
-
// id: cptId,
|
|
143
|
-
// name: ctxData.components[cptId].name,
|
|
144
|
-
// //dbg: { active: false, name: ctxData.components[cptId].name },
|
|
145
|
-
// ctx: { active: false, name: ctxData.components[cptId].name },
|
|
146
|
-
// };
|
|
147
|
-
|
|
148
|
-
// const cpt = ctxData.components[cptId];
|
|
149
|
-
// //if this debug session was initiated from an endpoint, we mark the endpoint component as active
|
|
150
|
-
// if (endpoint && endpoint.id != undefined && cpt.id == endpoint.id && endpointDBGCall) {
|
|
151
|
-
// //cpt.dbg.active = true;
|
|
152
|
-
// cpt.ctx.active = true;
|
|
153
|
-
// }
|
|
154
|
-
// }
|
|
155
|
-
// fs.writeFileSync(this.ctxFile, JSON.stringify(ctxData, null, 2));
|
|
156
|
-
// } else {
|
|
157
|
-
// ctxData = JSON.parse(fs.readFileSync(this.ctxFile, 'utf8'));
|
|
158
|
-
// if (!ctxData.step) ctxData.step = 0;
|
|
159
|
-
// }
|
|
160
|
-
|
|
161
|
-
// this.deserialize(ctxData);
|
|
162
|
-
// this._runtimeFileReady = true;
|
|
163
|
-
// this.emit('ready');
|
|
164
137
|
}
|
|
165
138
|
|
|
166
139
|
public async ready() {
|
|
167
140
|
if (this._runtimeFileReady) return true;
|
|
168
141
|
return this._readyPromise;
|
|
169
142
|
}
|
|
170
|
-
|
|
143
|
+
private async sync() {
|
|
171
144
|
if (!this.ctxFile) return;
|
|
145
|
+
|
|
172
146
|
this.emit('syncing');
|
|
173
147
|
|
|
174
148
|
const deleteSession = this.runtime.sessionClosed;
|
|
175
149
|
|
|
150
|
+
//TODO : Do we need to cache the context if not in debug mode ?
|
|
151
|
+
|
|
152
|
+
const data = this.serialize();
|
|
153
|
+
//if (data) fs.writeFileSync(this.ctxFile, JSON.stringify(data, null, 2));
|
|
154
|
+
if (data) {
|
|
155
|
+
let serializedData = JSON.stringify(data);
|
|
156
|
+
console.debug('Agent Context Size', this.ctxFile, serializedData.length, AccessCandidate.agent(this.runtime.agent.id));
|
|
157
|
+
|
|
158
|
+
await this._cacheConnector
|
|
159
|
+
.requester(AccessCandidate.agent(this.runtime.agent.id))
|
|
160
|
+
.set(this.ctxFile, serializedData, null, null, 3 * 60 * 60); //expires in 3 hours max
|
|
161
|
+
|
|
162
|
+
const mb = serializedData.length / 1024 / 1024;
|
|
163
|
+
const cooldown = (mb / 10) * 1000;
|
|
164
|
+
serializedData = null;
|
|
165
|
+
|
|
166
|
+
await delay(cooldown);
|
|
167
|
+
}
|
|
168
|
+
|
|
176
169
|
if (deleteSession) {
|
|
177
170
|
const exists = await this._cacheConnector.requester(AccessCandidate.agent(this.runtime.agent.id)).exists(this.ctxFile);
|
|
178
171
|
|
|
@@ -183,23 +176,24 @@ export class RuntimeContext extends EventEmitter {
|
|
|
183
176
|
else this._cacheConnector.requester(AccessCandidate.agent(this.runtime.agent.id)).delete(this.ctxFile);
|
|
184
177
|
//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
|
|
185
178
|
//if (fs.existsSync(this.ctxFile)) fs.unlinkSync(this.ctxFile);
|
|
186
|
-
|
|
187
|
-
} else {
|
|
188
|
-
const data = this.serialize();
|
|
189
|
-
//if (data) fs.writeFileSync(this.ctxFile, JSON.stringify(data, null, 2));
|
|
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));
|
|
193
|
-
await this._cacheConnector
|
|
194
|
-
.requester(AccessCandidate.agent(this.runtime.agent.id))
|
|
195
|
-
.set(this.ctxFile, serializedData, null, null, 3 * 60 * 60); //expires in 3 hours max
|
|
179
|
+
this.ctxFile = null;
|
|
196
180
|
}
|
|
197
181
|
}
|
|
198
182
|
}
|
|
183
|
+
private _syncQueue = Promise.resolve();
|
|
199
184
|
|
|
185
|
+
public enqueueSync() {
|
|
186
|
+
if (!this.ctxFile) return;
|
|
187
|
+
console.log('ENQUEUE SYNC');
|
|
188
|
+
this._syncQueue = this._syncQueue
|
|
189
|
+
.then(() => this.sync())
|
|
190
|
+
.catch((err) => {
|
|
191
|
+
console.error('Error syncing context', err);
|
|
192
|
+
}); // avoid unhandled rejections
|
|
193
|
+
}
|
|
200
194
|
public incStep() {
|
|
201
195
|
this.step++;
|
|
202
|
-
this.sync();
|
|
196
|
+
//this.sync();
|
|
203
197
|
}
|
|
204
198
|
|
|
205
199
|
public updateComponent(componentId: string, data: any) {
|
|
@@ -217,11 +211,16 @@ export class RuntimeContext extends EventEmitter {
|
|
|
217
211
|
console.debug('>>> ctxFile', this.ctxFile, AccessCandidate.agent(this.runtime.agent.id));
|
|
218
212
|
console.debug('>>> ctxData', ctxData, AccessCandidate.agent(this.runtime.agent.id));
|
|
219
213
|
}
|
|
220
|
-
component.ctx = { ...component.ctx, ...data, step: this.step };
|
|
214
|
+
//component.ctx = { ...component.ctx, ...data, step: this.step };
|
|
215
|
+
// minimal allocations
|
|
216
|
+
|
|
217
|
+
if (!component.ctx) component.ctx = { active: false, name: '', step: 0 };
|
|
218
|
+
Object.assign(component.ctx, data);
|
|
219
|
+
component.ctx.step = this.step;
|
|
221
220
|
|
|
222
221
|
//if (this.debug) component.dbg = { ...component.dbg, ...data };
|
|
223
222
|
|
|
224
|
-
this.
|
|
223
|
+
this.enqueueSync();
|
|
225
224
|
}
|
|
226
225
|
public resetComponent(componentId: string) {
|
|
227
226
|
const ctxData = this;
|
|
@@ -240,8 +239,13 @@ export class RuntimeContext extends EventEmitter {
|
|
|
240
239
|
//component.dbg.runtimeData = {};
|
|
241
240
|
component.ctx.runtimeData = {};
|
|
242
241
|
component.ctx.active = false;
|
|
242
|
+
if (!this.runtime.debug) {
|
|
243
|
+
//console.debug('NOT in debug mode, clearing context input/output');
|
|
244
|
+
component.ctx.input = undefined;
|
|
245
|
+
component.ctx.output = undefined;
|
|
246
|
+
}
|
|
243
247
|
|
|
244
|
-
this.
|
|
248
|
+
this.enqueueSync();
|
|
245
249
|
}
|
|
246
250
|
|
|
247
251
|
public getComponentData(componentId: string) {
|
package/src/types/LLM.types.ts
CHANGED