@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.
Files changed (60) hide show
  1. package/CHANGELOG +136 -64
  2. package/dist/index.js +65 -50
  3. package/dist/index.js.map +1 -1
  4. package/dist/types/Components/Async.class.d.ts +11 -5
  5. package/dist/types/index.d.ts +2 -0
  6. package/dist/types/subsystems/AgentManager/AgentData.service/connectors/SQLiteAgentDataConnector.class.d.ts +45 -0
  7. package/dist/types/subsystems/LLMManager/LLM.helper.d.ts +32 -1
  8. package/dist/types/subsystems/LLMManager/LLM.inference.d.ts +25 -2
  9. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.d.ts +22 -2
  10. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.d.ts +2 -2
  11. package/dist/types/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.d.ts +27 -2
  12. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Groq.class.d.ts +22 -2
  13. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Ollama.class.d.ts +22 -2
  14. package/dist/types/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.d.ts +3 -3
  15. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.d.ts +23 -3
  16. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.d.ts +2 -2
  17. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.d.ts +2 -2
  18. package/dist/types/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.d.ts +2 -2
  19. package/dist/types/subsystems/LLMManager/LLM.service/connectors/xAI.class.d.ts +3 -3
  20. package/dist/types/subsystems/MemoryManager/LLMContext.d.ts +10 -3
  21. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.d.ts +24 -0
  22. package/dist/types/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.redaction.helper.d.ts +49 -0
  23. package/dist/types/types/LLM.types.d.ts +30 -1
  24. package/package.json +4 -3
  25. package/src/Components/APICall/OAuth.helper.ts +16 -1
  26. package/src/Components/APIEndpoint.class.ts +11 -4
  27. package/src/Components/Async.class.ts +38 -5
  28. package/src/Components/GenAILLM.class.ts +13 -7
  29. package/src/Components/LLMAssistant.class.ts +3 -1
  30. package/src/Components/LogicAND.class.ts +13 -0
  31. package/src/Components/LogicAtLeast.class.ts +18 -0
  32. package/src/Components/LogicAtMost.class.ts +19 -0
  33. package/src/Components/LogicOR.class.ts +12 -2
  34. package/src/Components/LogicXOR.class.ts +11 -0
  35. package/src/constants.ts +1 -1
  36. package/src/helpers/Conversation.helper.ts +10 -8
  37. package/src/index.ts +2 -0
  38. package/src/index.ts.bak +2 -0
  39. package/src/subsystems/AgentManager/AgentData.service/connectors/SQLiteAgentDataConnector.class.ts +190 -0
  40. package/src/subsystems/AgentManager/AgentData.service/index.ts +2 -0
  41. package/src/subsystems/LLMManager/LLM.helper.ts +117 -1
  42. package/src/subsystems/LLMManager/LLM.inference.ts +136 -67
  43. package/src/subsystems/LLMManager/LLM.service/LLMConnector.ts +13 -6
  44. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +157 -33
  45. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +9 -8
  46. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +121 -83
  47. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +125 -62
  48. package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +168 -76
  49. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +18 -8
  50. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +8 -4
  51. package/src/subsystems/LLMManager/LLM.service/connectors/openai/OpenAIConnector.class.ts +50 -8
  52. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +30 -16
  53. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/OpenAIApiInterface.ts +2 -2
  54. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +29 -15
  55. package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +10 -8
  56. package/src/subsystems/MemoryManager/LLMContext.ts +27 -8
  57. package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.ts +467 -120
  58. package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.redaction.helper.ts +203 -0
  59. package/src/types/LLM.types.ts +31 -1
  60. 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(body: OpenAI.Responses.ResponseCreateParams, context: ILLMRequestContext): Promise<OpenAI.Responses.Response> {
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
- ...body,
86
- stream: false,
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
- ...body,
97
- stream: true,
98
- })) as Stream<OpenAI.Responses.ResponseStreamEvent>;
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 (finishReason !== 'stop') {
273
- emitter.emit(TLLMEvent.Interrupted, finishReason);
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, finishReason);
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 === 'tool_calls') {
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 = 'stop';
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 !== 'stop') {
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
- private push(...message: any[]) {
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;