@smythos/sre 1.7.41 → 1.8.0
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 +136 -64
- package/dist/index.js +65 -50
- package/dist/index.js.map +1 -1
- package/dist/types/Components/Async.class.d.ts +11 -5
- package/dist/types/index.d.ts +2 -0
- package/dist/types/subsystems/AgentManager/AgentData.service/connectors/SQLiteAgentDataConnector.class.d.ts +45 -0
- package/dist/types/subsystems/LLMManager/LLM.helper.d.ts +32 -1
- package/dist/types/subsystems/LLMManager/LLM.inference.d.ts +25 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.d.ts +22 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.d.ts +2 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.d.ts +27 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Groq.class.d.ts +22 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Ollama.class.d.ts +22 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +3 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +23 -3
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.d.ts +2 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.d.ts +2 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +2 -2
- package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +3 -3
- package/dist/types/subsystems/MemoryManager/LLMContext.d.ts +10 -3
- package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.d.ts +24 -0
- package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.redaction.helper.d.ts +49 -0
- package/dist/types/types/LLM.types.d.ts +30 -1
- package/package.json +4 -3
- package/src/Components/APICall/OAuth.helper.ts +16 -1
- package/src/Components/APIEndpoint.class.ts +11 -4
- package/src/Components/Async.class.ts +38 -5
- package/src/Components/GenAILLM.class.ts +13 -7
- package/src/Components/LLMAssistant.class.ts +3 -1
- package/src/Components/LogicAND.class.ts +13 -0
- package/src/Components/LogicAtLeast.class.ts +18 -0
- package/src/Components/LogicAtMost.class.ts +19 -0
- package/src/Components/LogicOR.class.ts +12 -2
- package/src/Components/LogicXOR.class.ts +11 -0
- package/src/constants.ts +1 -1
- package/src/helpers/Conversation.helper.ts +10 -8
- package/src/index.ts +2 -0
- package/src/index.ts.bak +2 -0
- package/src/subsystems/AgentManager/AgentData.service/connectors/SQLiteAgentDataConnector.class.ts +190 -0
- package/src/subsystems/AgentManager/AgentData.service/index.ts +2 -0
- package/src/subsystems/LLMManager/LLM.helper.ts +117 -1
- package/src/subsystems/LLMManager/LLM.inference.ts +136 -67
- package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +13 -6
- package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +157 -33
- package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +9 -8
- package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +121 -83
- package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +125 -62
- package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +168 -76
- package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +18 -8
- package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +8 -4
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +50 -8
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +30 -16
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +2 -2
- package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +29 -15
- package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +10 -8
- package/src/subsystems/MemoryManager/LLMContext.ts +27 -8
- package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.ts +467 -120
- package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.redaction.helper.ts +203 -0
- package/src/types/LLM.types.ts +31 -1
- package/src/types/node-sqlite.d.ts +45 -0
|
@@ -7,7 +7,8 @@ import fs from 'fs';
|
|
|
7
7
|
|
|
8
8
|
import { BinaryInput } from '@sre/helpers/BinaryInput.helper';
|
|
9
9
|
import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
|
|
10
|
-
import { TLLMParams, TLLMPreparedParams, ILLMRequestContext, ToolData, APIKeySource, TLLMEvent, LLMModelInfo } from '@sre/types/LLM.types';
|
|
10
|
+
import { TLLMParams, TLLMPreparedParams, ILLMRequestContext, ToolData, APIKeySource, TLLMEvent, LLMModelInfo, TLLMFinishReason } from '@sre/types/LLM.types';
|
|
11
|
+
import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
11
12
|
import { OpenAIApiInterface, ToolConfig } from './OpenAIApiInterface';
|
|
12
13
|
import { HandlerDependencies, TToolType } from '../types';
|
|
13
14
|
import { SUPPORTED_MIME_TYPES_MAP } from '@sre/constants';
|
|
@@ -79,23 +80,34 @@ export class ResponsesApiInterface extends OpenAIApiInterface {
|
|
|
79
80
|
this.deps = deps;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
|
-
async createRequest(
|
|
83
|
+
async createRequest(
|
|
84
|
+
body: OpenAI.Responses.ResponseCreateParams,
|
|
85
|
+
context: ILLMRequestContext,
|
|
86
|
+
abortSignal?: AbortSignal
|
|
87
|
+
): Promise<OpenAI.Responses.Response> {
|
|
83
88
|
const openai = await this.deps.getClient(context);
|
|
84
|
-
return await openai.responses.create(
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
89
|
+
return await openai.responses.create(
|
|
90
|
+
{
|
|
91
|
+
...body,
|
|
92
|
+
stream: false,
|
|
93
|
+
},
|
|
94
|
+
{ signal: abortSignal }
|
|
95
|
+
);
|
|
88
96
|
}
|
|
89
97
|
|
|
90
98
|
async createStream(
|
|
91
99
|
body: OpenAI.Responses.ResponseCreateParams,
|
|
92
|
-
context: ILLMRequestContext
|
|
100
|
+
context: ILLMRequestContext,
|
|
101
|
+
abortSignal?: AbortSignal
|
|
93
102
|
): Promise<Stream<OpenAI.Responses.ResponseStreamEvent>> {
|
|
94
103
|
const openai = await this.deps.getClient(context);
|
|
95
|
-
return (await openai.responses.create(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
return (await openai.responses.create(
|
|
105
|
+
{
|
|
106
|
+
...body,
|
|
107
|
+
stream: true,
|
|
108
|
+
},
|
|
109
|
+
{ signal: abortSignal }
|
|
110
|
+
)) as Stream<OpenAI.Responses.ResponseStreamEvent>;
|
|
99
111
|
}
|
|
100
112
|
|
|
101
113
|
public handleStream(stream: Stream<OpenAI.Responses.ResponseStreamEvent>, context: ILLMRequestContext): EventEmitter {
|
|
@@ -262,20 +274,22 @@ export class ResponsesApiInterface extends OpenAIApiInterface {
|
|
|
262
274
|
/**
|
|
263
275
|
* Emit final events
|
|
264
276
|
*/
|
|
265
|
-
private emitFinalEvents(emitter: EventEmitter, toolsData: ToolData[], reportedUsage: any[], finishReason: string): void {
|
|
277
|
+
private emitFinalEvents(emitter: EventEmitter, toolsData: ToolData[], reportedUsage: any[], finishReason: string | TLLMFinishReason): void {
|
|
278
|
+
const normalizedFinishReason = typeof finishReason === 'string' ? LLMHelper.normalizeFinishReason(finishReason) : finishReason;
|
|
279
|
+
|
|
266
280
|
// Emit tool info event if tools were called
|
|
267
281
|
if (toolsData.length > 0) {
|
|
268
282
|
emitter.emit(TLLMEvent.ToolInfo, toolsData);
|
|
269
283
|
}
|
|
270
284
|
|
|
271
285
|
// Emit interrupted event if finishReason is not 'stop'
|
|
272
|
-
if (
|
|
273
|
-
emitter.emit(TLLMEvent.Interrupted,
|
|
286
|
+
if (normalizedFinishReason !== TLLMFinishReason.Stop) {
|
|
287
|
+
emitter.emit(TLLMEvent.Interrupted, normalizedFinishReason);
|
|
274
288
|
}
|
|
275
289
|
|
|
276
290
|
// Emit end event with setImmediate to ensure proper event ordering
|
|
277
291
|
setImmediate(() => {
|
|
278
|
-
emitter.emit(TLLMEvent.End, toolsData, reportedUsage,
|
|
292
|
+
emitter.emit(TLLMEvent.End, toolsData, reportedUsage, normalizedFinishReason);
|
|
279
293
|
});
|
|
280
294
|
}
|
|
281
295
|
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
TLLMChatResponse,
|
|
16
16
|
ILLMRequestContext,
|
|
17
17
|
TLLMEvent,
|
|
18
|
+
TLLMFinishReason,
|
|
18
19
|
} from '@sre/types/LLM.types';
|
|
19
20
|
import { LLMHelper } from '@sre/LLMManager/LLM.helper';
|
|
20
21
|
|
|
@@ -100,21 +101,21 @@ export class xAIConnector extends LLMConnector {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
@hookAsync('LLMConnector.request')
|
|
103
|
-
protected async request({ acRequest, body, context }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
104
|
+
protected async request({ acRequest, body, context, abortSignal }: ILLMRequestFuncParams): Promise<TLLMChatResponse> {
|
|
104
105
|
try {
|
|
105
106
|
logger.debug(`request ${this.name}`, acRequest.candidate);
|
|
106
107
|
const grok = await this.getClient(context);
|
|
107
|
-
const response = await grok.post('/chat/completions', body);
|
|
108
|
+
const response = await grok.post('/chat/completions', body, { signal: abortSignal });
|
|
108
109
|
|
|
109
110
|
const message = response?.data?.choices?.[0]?.message;
|
|
110
|
-
const finishReason = response?.data?.choices?.[0]?.finish_reason;
|
|
111
|
+
const finishReason = LLMHelper.normalizeFinishReason(response?.data?.choices?.[0]?.finish_reason);
|
|
111
112
|
const usage = response?.data?.usage as TUsage;
|
|
112
113
|
const citations = response?.data?.citations;
|
|
113
114
|
|
|
114
115
|
let toolsData: ToolData[] = [];
|
|
115
116
|
let useTool = false;
|
|
116
117
|
|
|
117
|
-
if (finishReason ===
|
|
118
|
+
if (finishReason === TLLMFinishReason.ToolCalls) {
|
|
118
119
|
toolsData =
|
|
119
120
|
message?.tool_calls?.map((tool, index) => ({
|
|
120
121
|
index,
|
|
@@ -157,7 +158,7 @@ export class xAIConnector extends LLMConnector {
|
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
@hookAsync('LLMConnector.streamRequest')
|
|
160
|
-
protected async streamRequest({ acRequest, body, context }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
161
|
+
protected async streamRequest({ acRequest, body, context, abortSignal }: ILLMRequestFuncParams): Promise<EventEmitter> {
|
|
161
162
|
const emitter = new EventEmitter();
|
|
162
163
|
|
|
163
164
|
try {
|
|
@@ -168,11 +169,12 @@ export class xAIConnector extends LLMConnector {
|
|
|
168
169
|
{ ...body, stream: true, stream_options: { include_usage: true } },
|
|
169
170
|
{
|
|
170
171
|
responseType: 'stream',
|
|
172
|
+
signal: abortSignal,
|
|
171
173
|
}
|
|
172
174
|
);
|
|
173
175
|
|
|
174
176
|
const reportedUsage: any[] = [];
|
|
175
|
-
let finishReason =
|
|
177
|
+
let finishReason: TLLMFinishReason = TLLMFinishReason.Stop;
|
|
176
178
|
let toolsData: any[] = [];
|
|
177
179
|
let usage: any = {};
|
|
178
180
|
let citations: any[] = [];
|
|
@@ -225,7 +227,7 @@ export class xAIConnector extends LLMConnector {
|
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
if (parsed.choices?.[0]?.finish_reason) {
|
|
228
|
-
finishReason = parsed.choices[0].finish_reason;
|
|
230
|
+
finishReason = LLMHelper.normalizeFinishReason(parsed.choices[0].finish_reason);
|
|
229
231
|
}
|
|
230
232
|
} catch (e) {
|
|
231
233
|
// Ignore parsing errors for incomplete chunks
|
|
@@ -257,7 +259,7 @@ export class xAIConnector extends LLMConnector {
|
|
|
257
259
|
reportedUsage.push(_reported);
|
|
258
260
|
}
|
|
259
261
|
|
|
260
|
-
if (finishReason !==
|
|
262
|
+
if (finishReason !== TLLMFinishReason.Stop) {
|
|
261
263
|
emitter.emit(TLLMEvent.Interrupted, finishReason);
|
|
262
264
|
}
|
|
263
265
|
|
|
@@ -10,6 +10,9 @@ export class LLMContext {
|
|
|
10
10
|
private _llmContextStore: ILLMContextStore;
|
|
11
11
|
private _llmCache: LLMCache;
|
|
12
12
|
|
|
13
|
+
/** Resolves when the context store has finished loading (if any). Safe to call before using addUserMessage, getContextWindow, or other context operations. */
|
|
14
|
+
private _readyPromise: Promise<void>;
|
|
15
|
+
|
|
13
16
|
public get systemPrompt() {
|
|
14
17
|
return this._systemPrompt;
|
|
15
18
|
}
|
|
@@ -38,19 +41,31 @@ export class LLMContext {
|
|
|
38
41
|
*/
|
|
39
42
|
constructor(private llmInference, _systemPrompt: string = '', llmContextStore?: ILLMContextStore) {
|
|
40
43
|
this._llmCache = new LLMCache(AccessCandidate.team(this.llmInference.teamId));
|
|
44
|
+
|
|
41
45
|
//this._systemPrompt = _systemPrompt;
|
|
42
46
|
this.systemPrompt = _systemPrompt;
|
|
43
47
|
|
|
44
48
|
if (llmContextStore) {
|
|
45
49
|
this._llmContextStore = llmContextStore;
|
|
46
|
-
this._llmContextStore.load().then((messages) => {
|
|
50
|
+
this._readyPromise = this._llmContextStore.load().then((messages) => {
|
|
47
51
|
this._messages = messages;
|
|
48
52
|
this._llmCache.set('messages', this._messages);
|
|
49
53
|
});
|
|
54
|
+
} else {
|
|
55
|
+
this._readyPromise = Promise.resolve();
|
|
50
56
|
}
|
|
51
57
|
}
|
|
52
58
|
|
|
53
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Returns a promise that resolves when the context is ready (store loaded if present).
|
|
61
|
+
* Call before pushing or reading messages to avoid race conditions.
|
|
62
|
+
*/
|
|
63
|
+
public ready(): Promise<void> {
|
|
64
|
+
return this._readyPromise;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async push(...message: any[]) {
|
|
68
|
+
await this.ready();
|
|
54
69
|
this._messages.push(...message);
|
|
55
70
|
|
|
56
71
|
if (this._llmContextStore) {
|
|
@@ -58,7 +73,8 @@ export class LLMContext {
|
|
|
58
73
|
}
|
|
59
74
|
this._llmCache.set('messages', this._messages);
|
|
60
75
|
}
|
|
61
|
-
public addUserMessage(content: string, message_id: string, metadata?: any) {
|
|
76
|
+
public async addUserMessage(content: string, message_id: string, metadata?: any): Promise<void> {
|
|
77
|
+
await this.ready();
|
|
62
78
|
//in the current implementation, we do not support forked conversations
|
|
63
79
|
//we always attatch to the last message in the queue
|
|
64
80
|
|
|
@@ -75,9 +91,10 @@ export class LLMContext {
|
|
|
75
91
|
const prev = lastMessage?.__smyth_data__?.message_id;
|
|
76
92
|
const next = [];
|
|
77
93
|
|
|
78
|
-
this.push({ role: 'user', content, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
94
|
+
await this.push({ role: 'user', content, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
79
95
|
}
|
|
80
|
-
public addAssistantMessage(content: string, message_id: string, metadata?: any) {
|
|
96
|
+
public async addAssistantMessage(content: string, message_id: string, metadata?: any): Promise<void> {
|
|
97
|
+
await this.ready();
|
|
81
98
|
const lastMessage = this._messages[this._messages.length - 1];
|
|
82
99
|
|
|
83
100
|
if (lastMessage) {
|
|
@@ -89,9 +106,10 @@ export class LLMContext {
|
|
|
89
106
|
|
|
90
107
|
const prev = lastMessage?.__smyth_data__?.message_id;
|
|
91
108
|
const next = [];
|
|
92
|
-
this.push({ role: 'assistant', content, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
109
|
+
await this.push({ role: 'assistant', content, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
93
110
|
}
|
|
94
|
-
public addToolMessage(messageBlock: any, toolsData: any, message_id: string, metadata?: any) {
|
|
111
|
+
public async addToolMessage(messageBlock: any, toolsData: any, message_id: string, metadata?: any): Promise<void> {
|
|
112
|
+
await this.ready();
|
|
95
113
|
const lastMessage = this._messages[this._messages.length - 1];
|
|
96
114
|
|
|
97
115
|
if (lastMessage) {
|
|
@@ -103,10 +121,11 @@ export class LLMContext {
|
|
|
103
121
|
|
|
104
122
|
const prev = lastMessage?.__smyth_data__?.message_id;
|
|
105
123
|
const next = [];
|
|
106
|
-
this.push({ messageBlock, toolsData, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
124
|
+
await this.push({ messageBlock, toolsData, __smyth_data__: { message_id, ...metadata, prev, next } });
|
|
107
125
|
}
|
|
108
126
|
|
|
109
127
|
public async getContextWindow(maxTokens: number, maxOutputTokens: number = 1024): Promise<any[]> {
|
|
128
|
+
await this.ready();
|
|
110
129
|
const messages = JSON.parse(JSON.stringify(this._messages));
|
|
111
130
|
// if (messages[0]?.role === 'system') {
|
|
112
131
|
// messages[0].content = this.systemPrompt;
|