@smythos/sre 1.7.18 → 1.7.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.
Files changed (69) hide show
  1. package/dist/index.js +120 -82
  2. package/dist/index.js.map +1 -1
  3. package/dist/types/Components/DataSourceIndexer.class.d.ts +4 -12
  4. package/dist/types/Components/GenAILLM.class.d.ts +5 -5
  5. package/dist/types/Components/RAG/DataSourceCleaner.class.d.ts +37 -0
  6. package/dist/types/Components/RAG/DataSourceComponent.class.d.ts +30 -0
  7. package/dist/types/Components/RAG/DataSourceIndexer.class.d.ts +14 -0
  8. package/dist/types/Components/RAG/DataSourceLookup.class.d.ts +36 -0
  9. package/dist/types/Components/index.d.ts +3 -3
  10. package/dist/types/helpers/Conversation.helper.d.ts +3 -0
  11. package/dist/types/index.d.ts +3 -3
  12. package/dist/types/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.d.ts +1 -0
  13. package/dist/types/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.d.ts +11 -4
  14. package/dist/types/subsystems/IO/VectorDB.service/embed/index.d.ts +5 -0
  15. package/dist/types/subsystems/LLMManager/LLM.inference.d.ts +10 -3
  16. package/dist/types/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.d.ts +4 -2
  17. package/dist/types/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.d.ts +35 -0
  18. package/dist/types/subsystems/Security/Account.service/AccountConnector.d.ts +2 -2
  19. package/dist/types/subsystems/Security/ManagedVault.service/connectors/SecretManagerManagedVault.d.ts +10 -0
  20. package/dist/types/subsystems/Security/Vault.service/connectors/SecretsManager.class.d.ts +6 -2
  21. package/dist/types/types/LLM.types.d.ts +2 -0
  22. package/dist/types/types/VectorDB.types.d.ts +4 -0
  23. package/dist/types/utils/array.utils.d.ts +4 -0
  24. package/dist/types/utils/string.utils.d.ts +1 -0
  25. package/package.json +3 -3
  26. package/src/Components/APIEndpoint.class.ts +1 -6
  27. package/src/Components/Component.class.ts +14 -1
  28. package/src/Components/DataSourceIndexer.class.ts +148 -34
  29. package/src/Components/GenAILLM.class.ts +21 -11
  30. package/src/Components/RAG/DataSourceCleaner.class.ts +178 -0
  31. package/src/Components/RAG/DataSourceComponent.class.ts +111 -0
  32. package/src/Components/RAG/DataSourceIndexer.class.ts +254 -0
  33. package/src/Components/{DataSourceLookup.class.ts → RAG/DataSourceLookup.class.ts} +92 -3
  34. package/src/Components/ServerlessCode.class.ts +1 -4
  35. package/src/Components/index.ts +3 -3
  36. package/src/helpers/AWSLambdaCode.helper.ts +40 -45
  37. package/src/helpers/Conversation.helper.ts +14 -10
  38. package/src/helpers/S3Cache.helper.ts +2 -1
  39. package/src/index.ts +212 -212
  40. package/src/index.ts.bak +212 -212
  41. package/src/subsystems/IO/NKV.service/connectors/NKVRedis.class.ts +3 -1
  42. package/src/subsystems/IO/VectorDB.service/connectors/MilvusVectorDB.class.ts +145 -19
  43. package/src/subsystems/IO/VectorDB.service/connectors/PineconeVectorDB.class.ts +56 -22
  44. package/src/subsystems/IO/VectorDB.service/embed/GoogleEmbedding.ts +1 -0
  45. package/src/subsystems/IO/VectorDB.service/embed/OpenAIEmbedding.ts +2 -1
  46. package/src/subsystems/IO/VectorDB.service/embed/index.ts +18 -0
  47. package/src/subsystems/LLMManager/LLM.inference.ts +63 -47
  48. package/src/subsystems/LLMManager/LLM.service/connectors/Anthropic.class.ts +35 -10
  49. package/src/subsystems/LLMManager/LLM.service/connectors/Bedrock.class.ts +12 -4
  50. package/src/subsystems/LLMManager/LLM.service/connectors/Echo.class.ts +4 -4
  51. package/src/subsystems/LLMManager/LLM.service/connectors/GoogleAI.class.ts +105 -23
  52. package/src/subsystems/LLMManager/LLM.service/connectors/Groq.class.ts +17 -5
  53. package/src/subsystems/LLMManager/LLM.service/connectors/Ollama.class.ts +18 -3
  54. package/src/subsystems/LLMManager/LLM.service/connectors/Perplexity.class.ts +14 -5
  55. package/src/subsystems/LLMManager/LLM.service/connectors/VertexAI.class.ts +6 -4
  56. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ChatCompletionsApiInterface.ts +5 -5
  57. package/src/subsystems/LLMManager/LLM.service/connectors/openai/apiInterfaces/ResponsesApiInterface.ts +8 -3
  58. package/src/subsystems/LLMManager/LLM.service/connectors/xAI.class.ts +9 -8
  59. package/src/subsystems/LLMManager/ModelsProvider.service/connectors/JSONModelsProvider.class.ts +126 -28
  60. package/src/subsystems/ObservabilityManager/Telemetry.service/connectors/OTel/OTel.class.ts +38 -6
  61. package/src/subsystems/Security/Account.service/AccountConnector.ts +3 -3
  62. package/src/subsystems/Security/ManagedVault.service/connectors/SecretManagerManagedVault.ts +111 -48
  63. package/src/subsystems/Security/Vault.service/connectors/SecretsManager.class.ts +41 -66
  64. package/src/types/LLM.types.ts +5 -0
  65. package/src/types/VectorDB.types.ts +4 -0
  66. package/src/utils/array.utils.ts +11 -0
  67. package/src/utils/base64.utils.ts +1 -1
  68. package/src/utils/string.utils.ts +3 -192
  69. package/src/Components/DataSourceCleaner.class.ts +0 -92
@@ -16,7 +16,7 @@ import fsSync from 'fs';
16
16
  import path from 'path';
17
17
  import { findSmythPath } from '@sre/helpers/Sysconfig.helper';
18
18
 
19
- const console = Logger('SmythModelsProvider');
19
+ const logger = Logger('SmythModelsProvider');
20
20
 
21
21
  type SmythModelsProviderConfig = {
22
22
  /**
@@ -58,7 +58,7 @@ export class JSONModelsProvider extends ModelsProviderConnector {
58
58
  this._settings.mode = 'merge'; //Force merge mode if using models from .smyth folder
59
59
  this.initDirWatcher(modelsFolder); //this.started will be set to true when the watcher is ready
60
60
  } else {
61
- console.warn('No models folder found ... falling back to built-in models only');
61
+ logger.warn('No models folder found ... falling back to built-in models only');
62
62
  this.started = true;
63
63
  }
64
64
  }
@@ -71,7 +71,7 @@ export class JSONModelsProvider extends ModelsProviderConnector {
71
71
  const _modelsFolder = findSmythPath('models');
72
72
 
73
73
  if (fsSync.existsSync(_modelsFolder)) {
74
- console.warn('Using default models folder : ', _modelsFolder);
74
+ logger.warn('Using default models folder : ', _modelsFolder);
75
75
  return _modelsFolder;
76
76
  }
77
77
 
@@ -106,7 +106,7 @@ export class JSONModelsProvider extends ModelsProviderConnector {
106
106
 
107
107
  private async reindexModels(dir: string) {
108
108
  try {
109
- console.debug(`Reindexing models from directory: ${dir}`);
109
+ logger.debug(`Reindexing models from directory: ${dir}`);
110
110
 
111
111
  // Scan directory for models and get them as an object
112
112
  const scannedModels = await this.scanDirectoryForModels(dir);
@@ -121,9 +121,9 @@ export class JSONModelsProvider extends ModelsProviderConnector {
121
121
 
122
122
  JSONModelsProvider.localCache.clear();
123
123
 
124
- console.debug(`Successfully reindexed models. Total models: ${Object.keys(this.models).length}`);
124
+ logger.debug(`Successfully reindexed models. Total models: ${Object.keys(this.models).length}`);
125
125
  } catch (error) {
126
- console.error(`Error reindexing models from directory "${dir}":`, error);
126
+ logger.error(`Error reindexing models from directory "${dir}":`, error);
127
127
  }
128
128
  }
129
129
 
@@ -141,15 +141,21 @@ export class JSONModelsProvider extends ModelsProviderConnector {
141
141
  const subDirModels = await this.scanDirectoryForModels(fullPath);
142
142
  Object.assign(scannedModels, subDirModels);
143
143
  } else if (entry.isFile() && entry.name.endsWith('.json')) {
144
- // Process JSON files and merge results
145
- const fileContent = await fs.readFile(fullPath, 'utf-8');
146
- const modelData = JSON.parse(fileContent);
147
- const validModels = await this.getValidModels(modelData);
148
- Object.assign(scannedModels, validModels);
144
+ try {
145
+ // Process JSON files and merge results
146
+
147
+ const fileContent = await fs.readFile(fullPath, 'utf-8');
148
+ const modelData = JSON.parse(fileContent);
149
+ const validModels = await this.getValidModels(modelData);
150
+ Object.assign(scannedModels, validModels);
151
+ } catch (error) {
152
+ console.error(`Error parsing model data from file "${fullPath}"`);
153
+ logger.warn(`Error parsing model data from file "${fullPath}":`, error.message);
154
+ }
149
155
  }
150
156
  }
151
157
  } catch (error) {
152
- console.warn(`Error scanning directory "${dir}":`, error);
158
+ logger.warn(`Error scanning directory "${dir}":`, error);
153
159
  }
154
160
 
155
161
  return scannedModels;
@@ -164,9 +170,9 @@ export class JSONModelsProvider extends ModelsProviderConnector {
164
170
  // Single model case
165
171
  if (this.isValidSingleModel(modelData)) {
166
172
  validModels[modelData.modelId] = modelData as TLLMModel;
167
- console.debug(`Loaded model: ${modelData.modelId}`);
173
+ logger.debug(`Loaded model: ${modelData.modelId}`);
168
174
  } else {
169
- console.warn(`Invalid model format`, modelData);
175
+ logger.warn(`Invalid model format`, modelData);
170
176
  }
171
177
  } else if (typeof modelData === 'object' && !Array.isArray(modelData)) {
172
178
  // Object of models case
@@ -178,19 +184,19 @@ export class JSONModelsProvider extends ModelsProviderConnector {
178
184
  //console.debug(`Loaded model: ${modelId}`);
179
185
  models += `${modelId} `;
180
186
  } else {
181
- console.warn(`Invalid model format for model "${modelId}"`);
187
+ logger.warn(`Invalid model format for model "${modelId}"`);
182
188
  }
183
189
  } catch (error) {
184
- console.warn(`Error processing model "${modelId}":`, error);
190
+ logger.warn(`Error processing model "${modelId}":`, error);
185
191
  // Continue processing other models instead of failing the whole file
186
192
  }
187
193
  }
188
- console.debug(`Loaded models: ${models}`);
194
+ logger.debug(`Loaded models: ${models}`);
189
195
  } else {
190
- console.warn(`Invalid format (not a model or object of models)`);
196
+ logger.warn(`Invalid format (not a model or object of models)`);
191
197
  }
192
198
  } catch (error) {
193
- console.warn(`Error loading model:`, error);
199
+ logger.warn(`Error loading model:`, error);
194
200
  }
195
201
 
196
202
  return validModels;
@@ -208,11 +214,98 @@ export class JSONModelsProvider extends ModelsProviderConnector {
208
214
  return this.isValidSingleModel(data);
209
215
  }
210
216
 
217
+ /**
218
+ * Determines whether a file path should be ignored by the directory watcher.
219
+ *
220
+ * This method implements a sophisticated filtering strategy for dot-segment paths
221
+ * (paths containing directories that start with a dot, like .git, .env, .cache).
222
+ *
223
+ * **Filtering Strategy:**
224
+ * 1. Paths WITHOUT dot segments: Never ignored
225
+ * 2. Paths WITH dot segments:
226
+ * - If SMYTH_PATH is not configured: All ignored
227
+ * - If SMYTH_PATH is configured:
228
+ * - Allow the watched directory even if SMYTH_PATH contains dot-segments
229
+ * (e.g., /home/user/.smyth/models/OpenAI/default.json is allowed)
230
+ * - Ignore dot-segments INSIDE the models directory
231
+ * (e.g., /home/user/.smyth/models/.hidden/model.json is ignored)
232
+ * - Paths outside watched directory: Ignored
233
+ *
234
+ * @param filePath - The file path to check
235
+ * @param watchedDir - The absolute path of the directory being watched (models folder)
236
+ * @param smythPath - The resolved SMYTH_PATH, or null if not configured
237
+ * @returns true if the path should be ignored, false if it should be watched
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * // Path without dot-segment (allowed)
242
+ * shouldIgnorePath('/models/OpenAI/default.json', '/models', '/home/.smyth') // => false
243
+ *
244
+ * // Dot-segment inside models directory (ignored)
245
+ * shouldIgnorePath('/models/.git/config', '/models', '/home/.smyth') // => true
246
+ *
247
+ * // Dot-segment in parent path only (allowed)
248
+ * shouldIgnorePath('/home/.smyth/models/OpenAI/default.json', '/home/.smyth/models', '/home/.smyth') // => false
249
+ * ```
250
+ */
251
+ private shouldIgnorePath(filePath: string, watchedDir: string, smythPath: string | null): boolean {
252
+ // Check if the file path contains a dot-segment (e.g., /.git/, /.env/, /.cache/)
253
+ // Regex explanation: [\\/]\. matches a path separator (/ or \) followed by a dot
254
+ const hasDotSegment = /[\\/]\./.test(filePath);
255
+
256
+ // CASE 1: If there is NO dot-segment at all, we never ignore this path
257
+ // Examples: /models/OpenAI/default.json, /models/Anthropic/claude.json
258
+ if (!hasDotSegment) {
259
+ return false;
260
+ }
261
+
262
+ // CASE 2: If there IS a dot-segment and SMYTH_PATH is not configured,
263
+ // we ignore all such paths to prevent watching system/hidden files
264
+ // Examples: /.git/config, /node_modules/.cache/file.json
265
+ if (hasDotSegment && !smythPath) {
266
+ return true;
267
+ }
268
+
269
+ // Resolve the file path to an absolute path for accurate comparison
270
+ // This ensures we can reliably compare against the watched directory path
271
+ const resolvedPath = path.resolve(filePath);
272
+
273
+ // Check if the resolved path is inside the watched directory (models folder)
274
+ // This handles two cases:
275
+ // 1. The path exactly matches the watched directory
276
+ // 2. The path is a child of the watched directory (starts with watchedDir + separator)
277
+ const isInsideWatchedDir = resolvedPath === watchedDir || resolvedPath.startsWith(watchedDir + path.sep);
278
+
279
+ // CASE 3: If the path is outside the watched directory, ignore it
280
+ // This prevents watching unrelated files that happen to have dot-segments
281
+ if (!isInsideWatchedDir) {
282
+ return true;
283
+ }
284
+
285
+ // CASE 4: Path is inside the watched directory
286
+ // Now we need to determine if the dot-segment is in the models directory itself
287
+ // or if it is part of the parent path (e.g., SMYTH_PATH containing .smyth)
288
+
289
+ // Get the relative path from the watched directory to determine where the dot-segment is
290
+ const relativePath = path.relative(watchedDir, resolvedPath);
291
+
292
+ // Check if the dot-segment appears in the relative portion (inside models directory)
293
+ // Regex explanation: (^|[\\/])\. matches a dot at the start OR after a path separator
294
+ // Examples that match: '.git/config', 'subdir/.hidden/file.json'
295
+ const hasDotSegmentInsideWatchedDir = /(^|[\\/])\./.test(relativePath);
296
+
297
+ // FINAL DECISION:
298
+ // - If dot-segment is INSIDE the models directory (e.g., models/.git/config), IGNORE it (return true)
299
+ // - If dot-segment is OUTSIDE the models directory (e.g., /home/user/.smyth/models/OpenAI/default.json), ALLOW it (return false)
300
+ // This allows SMYTH_PATH to contain dot-segments while preventing dot-segments within the models folder
301
+ return hasDotSegmentInsideWatchedDir;
302
+ }
303
+
211
304
  private initDirWatcher(dir) {
212
305
  const stats = fsSync.statSync(dir);
213
306
 
214
307
  if (!stats.isDirectory() && !stats.isFile()) {
215
- console.warn(`Path "${dir}" is neither a file nor a directory ... skipping models watcher and falling back to built-in models only`);
308
+ logger.warn(`Path "${dir}" is neither a file nor a directory ... skipping models watcher and falling back to built-in models only`);
216
309
  this.started = true;
217
310
  return;
218
311
  }
@@ -230,17 +323,18 @@ export class JSONModelsProvider extends ModelsProviderConnector {
230
323
  if (this._settings?.mode === 'merge') this.models = { ...this.models, ...modelData };
231
324
  else this.models = modelData;
232
325
  } catch (error) {
233
- console.error(`Error parsing model data from file "${dir}":`, error);
326
+ console.error(`Error parsing model data from file "${dir}":`);
327
+ logger.warn(`Error parsing model data from file "${dir}":`, error.message);
234
328
  }
235
329
  this.started = true;
236
330
  return;
237
331
  }
238
332
 
239
- console.warn(`Path "${dir}" is neither a file nor a directory`);
333
+ logger.warn(`Path "${dir}" is neither a file nor a directory`);
240
334
  return;
241
335
  }
242
336
  } catch (error) {
243
- console.warn(`Path "${dir}" does not exist or cannot be accessed:`, error.message);
337
+ logger.warn(`Path "${dir}" does not exist or cannot be accessed:`, error.message);
244
338
  return;
245
339
  }
246
340
 
@@ -250,8 +344,12 @@ export class JSONModelsProvider extends ModelsProviderConnector {
250
344
  maxWait: 5000,
251
345
  });
252
346
 
347
+ const smythPath = process.env.SMYTH_PATH ? path.resolve(process.env.SMYTH_PATH) : null;
348
+ const watchedDir = path.resolve(dir);
349
+
253
350
  const watcher = chokidar.watch(dir, {
254
- ignored: /(^|[\/\\])\../, // ignore dotfiles
351
+ // Use the extracted method for path filtering
352
+ ignored: (filePath: string) => this.shouldIgnorePath(filePath, watchedDir, smythPath),
255
353
  persistent: true,
256
354
  ignoreInitial: true, // Don't fire events for files that already exist
257
355
  awaitWriteFinish: {
@@ -262,19 +360,19 @@ export class JSONModelsProvider extends ModelsProviderConnector {
262
360
 
263
361
  watcher
264
362
  .on('add', (path) => {
265
- console.debug(`File ${path} has been added`);
363
+ logger.debug(`File ${path} has been added`);
266
364
  debouncedReindex();
267
365
  })
268
366
  .on('change', (path) => {
269
- console.debug(`File ${path} has been changed`);
367
+ logger.debug(`File ${path} has been changed`);
270
368
  debouncedReindex();
271
369
  })
272
370
  .on('unlink', (path) => {
273
- console.debug(`File ${path} has been removed`);
371
+ logger.debug(`File ${path} has been removed`);
274
372
  debouncedReindex();
275
373
  })
276
374
  .on('ready', async () => {
277
- console.debug(`Watcher ready. Performing initial scan of ${dir}`);
375
+ logger.debug(`Watcher ready. Performing initial scan of ${dir}`);
278
376
  // Do initial scan once when watcher is ready
279
377
  await this.reindexModels(dir);
280
378
  this.started = true;
@@ -20,8 +20,9 @@ import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http';
20
20
  import { IAgent } from '@sre/types/Agent.types';
21
21
  import { Conversation } from '@sre/helpers/Conversation.helper';
22
22
  import { TLLMEvent } from '@sre/types/LLM.types';
23
+ import { AccessCandidate } from '@sre/Security/AccessControl/AccessCandidate.class';
23
24
 
24
- const outputLogger = Logger('OTelLog');
25
+ const outputLogger = Logger('OTel');
25
26
 
26
27
  export type OTelLogConfig = {
27
28
  endpoint: string;
@@ -50,7 +51,7 @@ export type OTelLogConfig = {
50
51
  */
51
52
  redactFields?: string[];
52
53
  };
53
-
54
+ const OTEL_DEBUG_LOGS = true;
54
55
  export class OTel extends TelemetryConnector {
55
56
  public name: string = 'OTel';
56
57
  public id: string;
@@ -208,6 +209,8 @@ export class OTel extends TelemetryConnector {
208
209
 
209
210
  const createToolInfoHandler = function (hookContext) {
210
211
  return function (toolInfo: any) {
212
+ const accessCandidate = AccessCandidate.agent(hookContext?.agentId);
213
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createToolInfoHandler started', accessCandidate);
211
214
  if (!hookContext.curLLMGenSpan || !hookContext.convSpan) return;
212
215
 
213
216
  const modelId = toolInfo.model;
@@ -238,6 +241,7 @@ export class OTel extends TelemetryConnector {
238
241
 
239
242
  hookContext.curLLMGenSpan.end();
240
243
  delete hookContext.curLLMGenSpan;
244
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createToolInfoHandler completed', accessCandidate);
241
245
  };
242
246
  };
243
247
 
@@ -245,6 +249,8 @@ export class OTel extends TelemetryConnector {
245
249
  return function (data: any, reqInfo: any) {
246
250
  if (!hookContext.convSpan) return;
247
251
  if (hookContext.curLLMGenSpan) return;
252
+ const accessCandidate = AccessCandidate.agent(hookContext?.agentId);
253
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createDataHandler started', reqInfo?.requestId, accessCandidate);
248
254
 
249
255
  const modelId = reqInfo.model;
250
256
  const contextWindow = reqInfo.contextWindow;
@@ -285,13 +291,15 @@ export class OTel extends TelemetryConnector {
285
291
  'context.preview': JSON.stringify(lastContext).substring(0, 200),
286
292
  });
287
293
  hookContext.curLLMGenSpan = llmGenSpan;
294
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createDataHandler completed', reqInfo?.requestId, accessCandidate);
288
295
  };
289
296
  };
290
297
 
291
298
  const createRequestedHandler = function (hookContext) {
292
299
  return function (reqInfo: any) {
293
300
  if (!hookContext.convSpan) return;
294
-
301
+ const accessCandidate = AccessCandidate.agent(hookContext?.agentId);
302
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createRequestedHandler started', reqInfo?.requestId, accessCandidate);
295
303
  if (!hookContext.latencySpans) hookContext.latencySpans = {};
296
304
  const contextWindow = reqInfo.contextWindow;
297
305
 
@@ -317,6 +325,7 @@ export class OTel extends TelemetryConnector {
317
325
  'context.preview': JSON.stringify(lastContext).substring(0, 200),
318
326
  });
319
327
  hookContext.latencySpans[reqInfo.requestId] = llmGenLatencySpan;
328
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('createRequestedHandler completed', reqInfo?.requestId, accessCandidate);
320
329
  };
321
330
  };
322
331
  HookService.register(
@@ -332,26 +341,35 @@ export class OTel extends TelemetryConnector {
332
341
 
333
342
  return;
334
343
  }
344
+ const accessCandidate = AccessCandidate.agent(agentId);
345
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('Conversation.streamPrompt started', { processId, message }, accessCandidate);
335
346
 
336
347
  const modelId = typeof conversation?.model === 'string' ? conversation?.model : conversation?.model?.modelId;
337
348
 
338
349
  const convSpan = tracer.startSpan('Agent.Conv', {
339
350
  attributes: {
351
+ // OTel standard attributes
352
+ 'gen_ai.operation.name': 'chat',
353
+ 'gen_ai.provider.name': conversation?.llmInference?.llmProviderName || 'unknown',
354
+ 'gen_ai.conversation.id': processId,
355
+ 'gen_ai.request.model': modelId || 'unknown',
356
+ ////////////////////////////////
340
357
  'agent.id': agentId,
341
358
  'conv.id': processId,
342
359
  'llm.model': modelId || 'unknown',
343
360
  },
344
361
  });
345
362
  hookContext.convSpan = convSpan;
363
+ hookContext.agentId = agentId;
364
+ hookContext.processId = processId;
346
365
 
347
366
  hookContext.dataHandler = createDataHandler(hookContext);
348
367
  conversation.on(TLLMEvent.Data, hookContext.dataHandler);
368
+
349
369
  hookContext.requestedHandler = createRequestedHandler(hookContext);
350
370
  conversation.on(TLLMEvent.Requested, hookContext.requestedHandler);
351
- hookContext.agentId = agentId;
352
- hookContext.processId = processId;
353
- hookContext.toolInfoHandler = createToolInfoHandler(hookContext);
354
371
 
372
+ hookContext.toolInfoHandler = createToolInfoHandler(hookContext);
355
373
  conversation.on(TLLMEvent.ToolInfo, hookContext.toolInfoHandler);
356
374
 
357
375
  // Add start event
@@ -403,6 +421,9 @@ export class OTel extends TelemetryConnector {
403
421
  const ctx = OTelContextRegistry.get(agentId, processId);
404
422
  if (!ctx) return;
405
423
 
424
+ const accessCandidate = AccessCandidate.agent(agentId);
425
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('Conversation.streamPrompt completed', { processId }, accessCandidate);
426
+
406
427
  if (hookContext.curLLMGenSpan) {
407
428
  hookContext.curLLMGenSpan.addEvent('llm.gen.content', {
408
429
  'content.size': JSON.stringify(result || {}).length,
@@ -455,6 +476,9 @@ export class OTel extends TelemetryConnector {
455
476
  const teamId = agent.teamId;
456
477
  const _hookContext: any = this.context;
457
478
 
479
+ const accessCandidate = AccessCandidate.agent(agentId);
480
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('SREAgent.process started', { processId, agentProcessId, endpointPath }, accessCandidate);
481
+
458
482
  const body = oTelInstance.prepareComponentData(agentRequest.body || {});
459
483
  const query = oTelInstance.prepareComponentData(agentRequest.query || {});
460
484
  const headers = oTelInstance.prepareComponentData(agentRequest.headers || {});
@@ -531,6 +555,9 @@ export class OTel extends TelemetryConnector {
531
555
 
532
556
  if (!agentSpan) return;
533
557
 
558
+ const accessCandidate = AccessCandidate.agent(agentId);
559
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('SREAgent.process completed', { agentProcessId }, accessCandidate);
560
+
534
561
  if (error) {
535
562
  agentSpan.recordException(error);
536
563
  agentSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
@@ -597,6 +624,8 @@ export class OTel extends TelemetryConnector {
597
624
  const componentType = settings.name;
598
625
  const componentName = settings.displayName || settings.name;
599
626
  const eventId = settings.eventId; // specific event id attached to this component execution
627
+ const accessCandidate = AccessCandidate.agent(agentId);
628
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('Component.process started', { componentId }, accessCandidate);
600
629
 
601
630
  const ctx = OTelContextRegistry.get(agentId, processId);
602
631
  const parentSpan = ctx?.rootSpan;
@@ -671,6 +700,9 @@ export class OTel extends TelemetryConnector {
671
700
  const componentType = settings.name;
672
701
  const componentName = settings.displayName || settings.name;
673
702
 
703
+ const accessCandidate = AccessCandidate.agent(agentId);
704
+ if (OTEL_DEBUG_LOGS) outputLogger.debug('Component.process completed', { componentId }, accessCandidate);
705
+
674
706
  if (error) {
675
707
  // Capture error details
676
708
  span.recordException(error);
@@ -10,7 +10,7 @@ export interface ISmythAccountRequest {
10
10
  getCandidateTeam(): Promise<string | undefined>;
11
11
  getAllTeamSettings(): Promise<KeyValueObject>;
12
12
  getAllUserSettings(): Promise<KeyValueObject>;
13
- getTeamSetting(settingKey: string): Promise<string>;
13
+ getTeamSetting(settingKey: string, group?: string): Promise<string>;
14
14
  getUserSetting(settingKey: string): Promise<string>;
15
15
  getAgentSetting(settingKey: string): Promise<string>;
16
16
  getTeam(): Promise<string>;
@@ -25,7 +25,7 @@ export abstract class AccountConnector extends Connector {
25
25
  getAllUserSettings: async () => this.getAllUserSettings(candidate.readRequest, candidate.id),
26
26
  getUserSetting: async (settingKey: string) => this.getUserSetting(candidate.readRequest, candidate.id, settingKey),
27
27
  getAllTeamSettings: async () => this.getAllTeamSettings(candidate.readRequest, candidate.id),
28
- getTeamSetting: async (settingKey: string) => this.getTeamSetting(candidate.readRequest, candidate.id, settingKey),
28
+ getTeamSetting: async (settingKey: string, group?: string) => this.getTeamSetting(candidate.readRequest, candidate.id, settingKey, group),
29
29
  isTeamMember: async (teamId: string) => this.isTeamMember(teamId, candidate),
30
30
  getCandidateTeam: async () => this.getCandidateTeam(candidate),
31
31
  getTeam: async () => this.getCandidateTeam(candidate),
@@ -38,7 +38,7 @@ export abstract class AccountConnector extends Connector {
38
38
  public abstract getCandidateTeam(candidate: IAccessCandidate): Promise<string | undefined>;
39
39
  public abstract getAllTeamSettings(acRequest: AccessRequest, teamId: string): Promise<KeyValueObject>;
40
40
  public abstract getAllUserSettings(acRequest: AccessRequest, accountId: string): Promise<KeyValueObject>;
41
- public abstract getTeamSetting(acRequest: AccessRequest, teamId: string, settingKey: string): Promise<string>;
41
+ public abstract getTeamSetting(acRequest: AccessRequest, teamId: string, settingKey: string, group?: string): Promise<string>;
42
42
  public abstract getUserSetting(acRequest: AccessRequest, accountId: string, settingKey: string): Promise<string>;
43
43
  public abstract getAgentSetting(acRequest: AccessRequest, agentId: string, settingKey: string): Promise<string>;
44
44
  }