openloops 0.1.15 → 0.1.18

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.
@@ -3,7 +3,8 @@ import type { KnownProvider, Message, AssistantMessage } from '@mariozechner/pi-
3
3
  import { CurrentUser } from '../../services/app/core/index.js';
4
4
  export declare class LLMClient {
5
5
  private readonly logger;
6
- private readonly langfuse;
6
+ private readonly langfuse?;
7
+ private readonly langfuseEnabled;
7
8
  constructor();
8
9
  complete(params: LLMCompletionParams): Promise<AssistantMessage>;
9
10
  private postResponse;
@@ -41,13 +41,19 @@ var import_create_llmcall = require("../../services/agent/modules/llmcalls/lambd
41
41
  class LLMClient {
42
42
  logger = new import_logger.Logger();
43
43
  langfuse;
44
+ langfuseEnabled;
44
45
  constructor() {
45
46
  process.env.OPENAI_API_KEY = import_secret_manager.secretManager.get("OPENAI_API_KEY");
46
- this.langfuse = new import_langfuse.Langfuse({
47
- publicKey: import_secret_manager.secretManager.get("LANGFUSE_PUBLIC_KEY"),
48
- secretKey: import_secret_manager.secretManager.get("LANGFUSE_SECRET_KEY"),
49
- baseUrl: process.env.LANGFUSE_BASE_URL
50
- });
47
+ const publicKey = import_secret_manager.secretManager.get("LANGFUSE_PUBLIC_KEY");
48
+ const secretKey = import_secret_manager.secretManager.get("LANGFUSE_SECRET_KEY");
49
+ const baseUrl = import_secret_manager.secretManager.get("LANGFUSE_BASE_URL");
50
+ this.langfuseEnabled = Boolean(publicKey && secretKey && baseUrl);
51
+ if (this.langfuseEnabled) {
52
+ this.langfuse = new import_langfuse.Langfuse({ publicKey, secretKey, baseUrl });
53
+ this.logger.debug("[LLM Service] Langfuse enabled");
54
+ } else {
55
+ this.logger.debug("[LLM Service] Langfuse disabled: configuration variables missing");
56
+ }
51
57
  }
52
58
  async complete(params) {
53
59
  const { getModel, complete } = await import("@mariozechner/pi-ai");
@@ -74,7 +80,7 @@ class LLMClient {
74
80
  messages: this.formatMessagesForLog(messages)
75
81
  }
76
82
  }, "[LLM Service] context");
77
- const trace = this.langfuse.trace({
83
+ const trace = this.langfuseEnabled ? this.langfuse.trace({
78
84
  sessionId,
79
85
  name: taskName,
80
86
  userId: currentUser?.userId,
@@ -83,8 +89,8 @@ class LLMClient {
83
89
  email: currentUser?.email,
84
90
  sessionId
85
91
  }
86
- });
87
- const generation = trace.generation({
92
+ }) : void 0;
93
+ const generation = trace?.generation({
88
94
  name: "llm-completion",
89
95
  model: modelName,
90
96
  modelParameters: { temperature, provider },
@@ -94,7 +100,7 @@ class LLMClient {
94
100
  const response = await complete(model, context, {
95
101
  temperature
96
102
  });
97
- generation.end({
103
+ generation?.end({
98
104
  output: response,
99
105
  usage: response.usage ? {
100
106
  promptTokens: response.usage.input,
@@ -102,7 +108,7 @@ class LLMClient {
102
108
  totalTokens: response.usage.totalTokens
103
109
  } : void 0
104
110
  });
105
- await this.langfuse.flushAsync();
111
+ if (this.langfuseEnabled) await this.langfuse.flushAsync();
106
112
  this.logger.debug({
107
113
  taskName,
108
114
  response: {
@@ -113,11 +119,11 @@ class LLMClient {
113
119
  await this.postResponse({ taskName, sessionId, answerId, currentUser, response });
114
120
  return response;
115
121
  } catch (error) {
116
- generation.end({
122
+ generation?.end({
117
123
  level: "ERROR",
118
124
  statusMessage: error.message
119
125
  });
120
- await this.langfuse.flushAsync();
126
+ if (this.langfuseEnabled) await this.langfuse.flushAsync();
121
127
  throw error;
122
128
  }
123
129
  }
@@ -9,13 +9,19 @@ import { CreateLLMCallUseCase } from "../../services/agent/modules/llmcalls/lamb
9
9
  class LLMClient {
10
10
  logger = new Logger();
11
11
  langfuse;
12
+ langfuseEnabled;
12
13
  constructor() {
13
14
  process.env.OPENAI_API_KEY = secretManager.get("OPENAI_API_KEY");
14
- this.langfuse = new Langfuse({
15
- publicKey: secretManager.get("LANGFUSE_PUBLIC_KEY"),
16
- secretKey: secretManager.get("LANGFUSE_SECRET_KEY"),
17
- baseUrl: process.env.LANGFUSE_BASE_URL
18
- });
15
+ const publicKey = secretManager.get("LANGFUSE_PUBLIC_KEY");
16
+ const secretKey = secretManager.get("LANGFUSE_SECRET_KEY");
17
+ const baseUrl = secretManager.get("LANGFUSE_BASE_URL");
18
+ this.langfuseEnabled = Boolean(publicKey && secretKey && baseUrl);
19
+ if (this.langfuseEnabled) {
20
+ this.langfuse = new Langfuse({ publicKey, secretKey, baseUrl });
21
+ this.logger.debug("[LLM Service] Langfuse enabled");
22
+ } else {
23
+ this.logger.debug("[LLM Service] Langfuse disabled: configuration variables missing");
24
+ }
19
25
  }
20
26
  async complete(params) {
21
27
  const { getModel, complete } = await import("@mariozechner/pi-ai");
@@ -42,7 +48,7 @@ class LLMClient {
42
48
  messages: this.formatMessagesForLog(messages)
43
49
  }
44
50
  }, "[LLM Service] context");
45
- const trace = this.langfuse.trace({
51
+ const trace = this.langfuseEnabled ? this.langfuse.trace({
46
52
  sessionId,
47
53
  name: taskName,
48
54
  userId: currentUser?.userId,
@@ -51,8 +57,8 @@ class LLMClient {
51
57
  email: currentUser?.email,
52
58
  sessionId
53
59
  }
54
- });
55
- const generation = trace.generation({
60
+ }) : void 0;
61
+ const generation = trace?.generation({
56
62
  name: "llm-completion",
57
63
  model: modelName,
58
64
  modelParameters: { temperature, provider },
@@ -62,7 +68,7 @@ class LLMClient {
62
68
  const response = await complete(model, context, {
63
69
  temperature
64
70
  });
65
- generation.end({
71
+ generation?.end({
66
72
  output: response,
67
73
  usage: response.usage ? {
68
74
  promptTokens: response.usage.input,
@@ -70,7 +76,7 @@ class LLMClient {
70
76
  totalTokens: response.usage.totalTokens
71
77
  } : void 0
72
78
  });
73
- await this.langfuse.flushAsync();
79
+ if (this.langfuseEnabled) await this.langfuse.flushAsync();
74
80
  this.logger.debug({
75
81
  taskName,
76
82
  response: {
@@ -81,11 +87,11 @@ class LLMClient {
81
87
  await this.postResponse({ taskName, sessionId, answerId, currentUser, response });
82
88
  return response;
83
89
  } catch (error) {
84
- generation.end({
90
+ generation?.end({
85
91
  level: "ERROR",
86
92
  statusMessage: error.message
87
93
  });
88
- await this.langfuse.flushAsync();
94
+ if (this.langfuseEnabled) await this.langfuse.flushAsync();
89
95
  throw error;
90
96
  }
91
97
  }
@@ -35,7 +35,7 @@ const reportError = async (error, details) => {
35
35
  }, "[Report Error] Reporting new error");
36
36
  const isLocal = process.env.IS_LOCAL === "true" || process.env.NODE_ENV === "development";
37
37
  try {
38
- !isLocal && await import_sentry_client.sentryClient.captureError(error, {
38
+ !isLocal && await import_sentry_client.sentryClient?.captureError(error, {
39
39
  statusCode,
40
40
  errorMessage,
41
41
  errorDetails,
@@ -13,7 +13,7 @@ const reportError = async (error, details) => {
13
13
  }, "[Report Error] Reporting new error");
14
14
  const isLocal = process.env.IS_LOCAL === "true" || process.env.NODE_ENV === "development";
15
15
  try {
16
- !isLocal && await sentryClient.captureError(error, {
16
+ !isLocal && await sentryClient?.captureError(error, {
17
17
  statusCode,
18
18
  errorMessage,
19
19
  errorDetails,
@@ -74,11 +74,17 @@ class SecretManager {
74
74
  }
75
75
  getEnvVar(key) {
76
76
  const value = process.env[key];
77
- if (!value) throw new Error(`[Secret manager] Environment variable ${key} is not set`);
77
+ if (!value) {
78
+ import_logger.logger.warn({ key }, "[Secret manager] Environment variable is not set");
79
+ return "";
80
+ }
78
81
  return value;
79
82
  }
80
83
  decryptEnvVar(encryptedValue) {
81
- if (!encryptedValue) throw new Error("[Secret manager] Encrypted value cannot be empty");
84
+ if (!encryptedValue) {
85
+ import_logger.logger.debug("[Secret manager] Encrypted value cannot be empty");
86
+ return "";
87
+ }
82
88
  if (!this.isStringEncrypted(encryptedValue)) {
83
89
  import_logger.logger.debug("[Secret Manager] Value is not encrypted");
84
90
  return encryptedValue;
@@ -41,11 +41,17 @@ class SecretManager {
41
41
  }
42
42
  getEnvVar(key) {
43
43
  const value = process.env[key];
44
- if (!value) throw new Error(`[Secret manager] Environment variable ${key} is not set`);
44
+ if (!value) {
45
+ logger.warn({ key }, "[Secret manager] Environment variable is not set");
46
+ return "";
47
+ }
45
48
  return value;
46
49
  }
47
50
  decryptEnvVar(encryptedValue) {
48
- if (!encryptedValue) throw new Error("[Secret manager] Encrypted value cannot be empty");
51
+ if (!encryptedValue) {
52
+ logger.debug("[Secret manager] Encrypted value cannot be empty");
53
+ return "";
54
+ }
49
55
  if (!this.isStringEncrypted(encryptedValue)) {
50
56
  logger.debug("[Secret Manager] Value is not encrypted");
51
57
  return encryptedValue;
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './services/agent/core/index.js';
1
+ export * from './services/agent/core';
package/dist/index.js CHANGED
@@ -15,8 +15,8 @@ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "defau
15
15
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
16
16
  var index_exports = {};
17
17
  module.exports = __toCommonJS(index_exports);
18
- __reExport(index_exports, require("./services/agent/core/index.js"), module.exports);
18
+ __reExport(index_exports, require("./services/agent/core"), module.exports);
19
19
  // Annotate the CommonJS export names for ESM import in node:
20
20
  0 && (module.exports = {
21
- ...require("./services/agent/core/index.js")
21
+ ...require("./services/agent/core")
22
22
  });
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export * from "./services/agent/core/index.js";
1
+ export * from "./services/agent/core";
@@ -1,4 +1,4 @@
1
- import { User, UserProps } from '../modules/users/entities/user.entity.js';
1
+ import { User, UserProps } from '../modules/users/entities/user.entity';
2
2
  export declare class CurrentUser extends User {
3
3
  private _isPremium;
4
4
  static asyncFromDB(userId: string): Promise<CurrentUser | undefined>;
@@ -26,7 +26,7 @@ var import_countries_and_currencies_utils = require("countries-and-currencies-ut
26
26
  var import_mongo_db = require("../../../common/repositories/mongo-db.client.js");
27
27
  var import_secret_manager = require("../../../common/utils/secret-manager.js");
28
28
  var import_logger = require("../../../common/logger/index.js");
29
- var import_user = require("../modules/users/entities/user.entity.js");
29
+ var import_user = require("../modules/users/entities/user.entity");
30
30
  class CurrentUser extends import_user.User {
31
31
  _isPremium = false;
32
32
  static async asyncFromDB(userId) {
@@ -4,7 +4,7 @@ import { getTimezoneOffset } from "countries-and-currencies-utils";
4
4
  import { getMongoDBClient } from "../../../common/repositories/mongo-db.client.js";
5
5
  import { secretManager } from "../../../common/utils/secret-manager.js";
6
6
  import { logger } from "../../../common/logger/index.js";
7
- import { User, UserRole } from "../modules/users/entities/user.entity.js";
7
+ import { User, UserRole } from "../modules/users/entities/user.entity";
8
8
  class CurrentUser extends User {
9
9
  _isPremium = false;
10
10
  static async asyncFromDB(userId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openloops",
3
- "version": "0.1.15",
3
+ "version": "0.1.18",
4
4
  "description": "Framework to build AI Agents",
5
5
  "author": {
6
6
  "name": "Jose Barcos",
@@ -35,7 +35,7 @@
35
35
  "types": "./dist/services/app/core/index.d.ts",
36
36
  "default": "./dist/services/app/core/index.js"
37
37
  },
38
- "./chat": {
38
+ "./chats": {
39
39
  "types": "./dist/services/agent/modules/chats/index.d.ts",
40
40
  "default": "./dist/services/agent/modules/chats/index.js"
41
41
  }
@@ -51,48 +51,47 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "@mariozechner/pi-ai": "^0.73.1",
54
- "@modelcontextprotocol/sdk": "^1.30.0",
55
- "@sentry/node": "^10.29.0",
56
- "axios": "^1.16.0",
54
+ "@modelcontextprotocol/sdk": "^1.30.1",
55
+ "@sentry/node": "^11.0.0",
56
+ "axios": "^1.20.0",
57
57
  "bcryptjs": "^3.0.3",
58
58
  "countries-and-currencies-utils": "^0.1.9",
59
59
  "cryptr": "^6.4.0",
60
60
  "dotenv": "^18.0.3",
61
- "html-to-text": "^10.0.0",
61
+ "html-to-text": "^10.0.1",
62
62
  "jsonwebtoken": "^9.0.3",
63
- "langfuse": "^3.38.20",
64
- "mongodb": "^6.18.0",
65
- "openai": "^6.10.0",
66
- "p-limit": "^7.2.0",
67
- "pino": "^10.1.0",
63
+ "langfuse": "^3.39.2",
64
+ "mongodb": "^7.6.0",
65
+ "openai": "^7.23.0",
66
+ "p-limit": "^7.3.3",
67
+ "pino": "^10.3.1",
68
68
  "pino-pretty": "^13.1.3",
69
69
  "reflect-metadata": "^0.2.2",
70
- "sanitize-html": "^2.17.0",
71
- "source-map-support": "^0.5.21",
70
+ "sanitize-html": "^2.17.7",
72
71
  "tsyringe": "^4.10.0"
73
72
  },
74
73
  "devDependencies": {
75
74
  "@types/jest": "^30.0.0",
76
- "@types/node": "^24.10.1",
77
- "@types/sanitize-html": "^2.16.0",
78
- "@typescript-eslint/eslint-plugin": "^8.49.0",
79
- "@typescript-eslint/parser": "^8.49.0",
80
- "eslint": "^9.39.1",
75
+ "@types/node": "^26.6.2",
76
+ "@types/sanitize-html": "^2.16.1",
77
+ "@typescript-eslint/eslint-plugin": "^8.70.1",
78
+ "@typescript-eslint/parser": "^8.70.1",
79
+ "eslint": "^10.11.0",
81
80
  "eslint-config-airbnb-base": "^15.0.0",
82
81
  "eslint-config-airbnb-typescript": "^18.0.0",
83
82
  "eslint-config-prettier": "^10.1.8",
84
- "eslint-import-resolver-typescript": "^4.4.4",
83
+ "eslint-import-resolver-typescript": "^4.4.5",
85
84
  "eslint-plugin-import": "^2.32.0",
86
- "eslint-plugin-jest": "^29.2.1",
87
- "eslint-plugin-prettier": "^5.5.4",
88
- "eslint-plugin-promise": "^7.2.1",
89
- "jest": "^30.2.0",
90
- "prettier": "^3.7.4",
91
- "ts-jest": "^29.4.6",
85
+ "eslint-plugin-jest": "^29.16.6",
86
+ "eslint-plugin-prettier": "^5.5.6",
87
+ "eslint-plugin-promise": "^7.3.0",
88
+ "jest": "^30.5.2",
89
+ "prettier": "^3.9.9",
90
+ "ts-jest": "^29.4.13",
92
91
  "tsc-alias": "^1.9.5",
93
92
  "tsconfig-paths": "^4.2.0",
94
93
  "tsup": "^8.5.1",
95
- "typescript": "^5.9.3"
94
+ "typescript": "^6.0.3"
96
95
  },
97
96
  "engines": {
98
97
  "node": ">=22.0.0"