@exulu/backend 1.6.0 → 1.6.2

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.md CHANGED
@@ -1,10 +1,9 @@
1
- # [1.6.0](https://github.com/Qventu/exulu-backend/compare/v1.5.0...v1.6.0) (2025-08-04)
1
+ ## [1.6.2](https://github.com/Qventu/exulu-backend/compare/v1.6.1...v1.6.2) (2025-08-05)
2
2
 
3
3
 
4
- ### Features
4
+ ### Bug Fixes
5
5
 
6
- * add init db function to script ([77fa08c](https://github.com/Qventu/exulu-backend/commit/77fa08c073c2073ca969a6fde76a998d3e7d7f35))
7
- * make email provider in next auth optional ([d38e790](https://github.com/Qventu/exulu-backend/commit/d38e7900e973007596f66391dae3d4ca643432c4))
6
+ * remove browserbase from core repo ([371031b](https://github.com/Qventu/exulu-backend/commit/371031ba330b89d619b0b4cfe935521e249d6b29))
8
7
 
9
8
  # [1.1.0](https://github.com/Qventu/exulu-backend/compare/v1.0.1...v1.1.0) (2025-07-30)
10
9
 
package/dist/index.cjs CHANGED
@@ -143,6 +143,36 @@ var import_knex = __toESM(require("knex"), 1);
143
143
  var import_knex2 = require("knex");
144
144
  var import_knex3 = require("pgvector/knex");
145
145
  var db = {};
146
+ var databaseExistsChecked = false;
147
+ async function ensureDatabaseExists() {
148
+ console.log("[EXULU] Ensuring exulu database exists...");
149
+ const defaultKnex = (0, import_knex.default)({
150
+ client: "pg",
151
+ connection: {
152
+ host: process.env.POSTGRES_DB_HOST,
153
+ port: parseInt(process.env.POSTGRES_DB_PORT || "5432"),
154
+ user: process.env.POSTGRES_DB_USER,
155
+ database: "postgres",
156
+ // Connect to default database
157
+ password: process.env.POSTGRES_DB_PASSWORD,
158
+ ssl: process.env.POSTGRES_DB_SSL === "true" ? { rejectUnauthorized: false } : false
159
+ }
160
+ });
161
+ try {
162
+ const result = await defaultKnex.raw(`
163
+ SELECT 1 FROM pg_database WHERE datname = 'exulu'
164
+ `);
165
+ if (result.rows.length === 0) {
166
+ console.log("[EXULU] Database 'exulu' does not exist. Creating it...");
167
+ await defaultKnex.raw(`CREATE DATABASE exulu`);
168
+ console.log("[EXULU] Database 'exulu' created successfully.");
169
+ } else {
170
+ console.log("[EXULU] Database 'exulu' already exists.");
171
+ }
172
+ } finally {
173
+ await defaultKnex.destroy();
174
+ }
175
+ }
146
176
  async function postgresClient() {
147
177
  if (!db["exulu"]) {
148
178
  try {
@@ -152,6 +182,12 @@ async function postgresClient() {
152
182
  console.log("[EXULU] POSTGRES_DB_USER:", process.env.POSTGRES_DB_USER);
153
183
  console.log("[EXULU] POSTGRES_DB_PASSWORD:", process.env.POSTGRES_DB_PASSWORD);
154
184
  console.log("[EXULU] POSTGRES_DB_SSL:", process.env.POSTGRES_DB_SSL);
185
+ console.log("[EXULU] Database exists checked:", databaseExistsChecked);
186
+ if (!databaseExistsChecked) {
187
+ console.log("[EXULU] Ensuring exulu database exists...");
188
+ await ensureDatabaseExists();
189
+ databaseExistsChecked = true;
190
+ }
155
191
  const knex = (0, import_knex.default)({
156
192
  client: "pg",
157
193
  connection: {
@@ -2993,6 +3029,7 @@ var global_queues = {
2993
3029
  logs_cleaner: "logs-cleaner"
2994
3030
  };
2995
3031
  var createRecurringJobs = async () => {
3032
+ console.log("[EXULU] creating recurring jobs.");
2996
3033
  const recurringJobSchedulersLogs = [];
2997
3034
  const queue = queues.use(global_queues.logs_cleaner);
2998
3035
  recurringJobSchedulersLogs.push({
@@ -3020,7 +3057,7 @@ var createRecurringJobs = async () => {
3020
3057
  }
3021
3058
  }
3022
3059
  );
3023
- console.log("Recurring job schedulers:");
3060
+ console.log("[EXULU] recurring job schedulers:");
3024
3061
  console.table(recurringJobSchedulersLogs);
3025
3062
  return queue;
3026
3063
  };
@@ -4568,129 +4605,6 @@ var defaultAgent = new ExuluAgent({
4568
4605
  }
4569
4606
  });
4570
4607
 
4571
- // src/templates/tools/browserbase.ts
4572
- var import_zod5 = require("zod");
4573
- var import_stagehand = require("@browserbasehq/stagehand");
4574
- var import_sdk = require("@browserbasehq/sdk");
4575
- var PROJECT_ID = "811444dd-6e6d-40b5-bd90-541c93e44be6";
4576
- process.env.BROWSERBASE_PROJECT_ID = PROJECT_ID;
4577
- var BB_API_KEY = "bb_live_LwMwNgZB5cIEKcBwMuAugrgNkFM";
4578
- async function createContext() {
4579
- const bb = new import_sdk.Browserbase({ apiKey: BB_API_KEY });
4580
- const context = await bb.contexts.create({
4581
- projectId: PROJECT_ID
4582
- });
4583
- return context;
4584
- }
4585
- async function createAuthSession(contextId) {
4586
- const bb = new import_sdk.Browserbase({ apiKey: BB_API_KEY });
4587
- const session = await bb.sessions.create({
4588
- projectId: PROJECT_ID,
4589
- browserSettings: {
4590
- context: {
4591
- id: contextId,
4592
- persist: true
4593
- }
4594
- }
4595
- /* proxies: [{ // not included in the free tier
4596
- type: "browserbase",
4597
- geolocation: {
4598
- city: CITY,
4599
- country: COUNTRY
4600
- }
4601
- }] */
4602
- });
4603
- const liveViewLinks = await bb.sessions.debug(session.id);
4604
- const liveViewLink = liveViewLinks.debuggerFullscreenUrl;
4605
- console.log(`\u{1F50D} Live View Link: ${liveViewLink}`);
4606
- console.log("Session URL: https://browserbase.com/sessions/" + session.id);
4607
- return {
4608
- url: liveViewLink,
4609
- id: session.id
4610
- };
4611
- }
4612
- var createSession = new ExuluTool({
4613
- id: `1234-5178-9423-4267`,
4614
- type: "function",
4615
- name: "Create a browserbase session.",
4616
- description: `
4617
- Creates a browserbase session and returns the live view url as well as
4618
- the session id as a JSON object. A browserbase session is a headless browser
4619
- that can be used to to visit websites and perform actions.
4620
- `,
4621
- execute: async () => {
4622
- const { id } = await createContext();
4623
- return await createAuthSession(id);
4624
- }
4625
- });
4626
- var askChatgpt = new ExuluTool({
4627
- id: `1234-5178-9423-4268`,
4628
- type: "function",
4629
- name: "ChatGPT browserbase operation.",
4630
- inputSchema: import_zod5.z.object({
4631
- session: import_zod5.z.string().describe("The session id of the browserbase session."),
4632
- question: import_zod5.z.string().describe("The question to ask ChatGPT.")
4633
- }),
4634
- description: `Uses an existing, authenticated browserbase session to visit ChatGPT and perform actions such as asking questions.`,
4635
- execute: async ({ session, question }) => {
4636
- const stagehand = new import_stagehand.Stagehand({
4637
- // With npx create-browser-app, this config is found
4638
- // in a separate stagehand.config.ts file
4639
- env: "BROWSERBASE",
4640
- // set to "LOCAL" for local development
4641
- apiKey: BB_API_KEY,
4642
- // todo make this a config variable the admin can set in the UI
4643
- modelName: "openai/gpt-4.1-mini",
4644
- // todo change to claude || optionally make configurable?
4645
- browserbaseSessionID: session,
4646
- modelClientOptions: {
4647
- apiKey: process.env.OPENAI_API_KEY
4648
- // todo make this a config variable the admin can set in the UI
4649
- }
4650
- });
4651
- await stagehand.init();
4652
- const page = stagehand.page;
4653
- await page.goto("https://chatgpt.com");
4654
- await page.act(`Type in '${question}' into the search bar`);
4655
- const { answer } = await page.extract({
4656
- instruction: "The answer to the question generated by ChatGPT.",
4657
- schema: import_zod5.z.object({
4658
- answer: import_zod5.z.string()
4659
- })
4660
- });
4661
- console.log(answer);
4662
- await stagehand.close();
4663
- return {
4664
- answer
4665
- };
4666
- }
4667
- });
4668
-
4669
- // src/templates/tools/jira.ts
4670
- var import_zod6 = require("zod");
4671
- var getTicket = new ExuluTool({
4672
- id: `1414-5179-1423-1269`,
4673
- name: "JIRA ticket retrieval.",
4674
- type: "function",
4675
- inputSchema: import_zod6.z.object({
4676
- ticketId: import_zod6.z.string().describe("The id of the ticket to retrieve.")
4677
- }),
4678
- description: `Retrieves a ticket from Jira.`,
4679
- execute: async ({ session, question }) => {
4680
- return {
4681
- name: "BYD-1234",
4682
- id: "12345678",
4683
- status: "Open",
4684
- description: "This is a test ticket",
4685
- assignee: "John Doe",
4686
- createdAt: "2021-01-01",
4687
- updatedAt: "2021-01-01",
4688
- dueDate: "2021-01-01",
4689
- priority: "High"
4690
- };
4691
- }
4692
- });
4693
-
4694
4608
  // src/registry/index.ts
4695
4609
  var ExuluApp = class {
4696
4610
  _agents = [];
@@ -4718,12 +4632,7 @@ var ExuluApp = class {
4718
4632
  // Add contexts as tools
4719
4633
  ...Object.values(contexts || {}).map((context) => context.tool()),
4720
4634
  // Add agents as tools
4721
- ...(agents || []).map((agent) => agent.tool()),
4722
- ...[
4723
- createSession,
4724
- askChatgpt,
4725
- getTicket
4726
- ]
4635
+ ...(agents || []).map((agent) => agent.tool())
4727
4636
  ];
4728
4637
  const contextsArray = Object.values(contexts || {});
4729
4638
  const queues2 = [
package/dist/index.js CHANGED
@@ -100,6 +100,36 @@ import Knex from "knex";
100
100
  import "knex";
101
101
  import "pgvector/knex";
102
102
  var db = {};
103
+ var databaseExistsChecked = false;
104
+ async function ensureDatabaseExists() {
105
+ console.log("[EXULU] Ensuring exulu database exists...");
106
+ const defaultKnex = Knex({
107
+ client: "pg",
108
+ connection: {
109
+ host: process.env.POSTGRES_DB_HOST,
110
+ port: parseInt(process.env.POSTGRES_DB_PORT || "5432"),
111
+ user: process.env.POSTGRES_DB_USER,
112
+ database: "postgres",
113
+ // Connect to default database
114
+ password: process.env.POSTGRES_DB_PASSWORD,
115
+ ssl: process.env.POSTGRES_DB_SSL === "true" ? { rejectUnauthorized: false } : false
116
+ }
117
+ });
118
+ try {
119
+ const result = await defaultKnex.raw(`
120
+ SELECT 1 FROM pg_database WHERE datname = 'exulu'
121
+ `);
122
+ if (result.rows.length === 0) {
123
+ console.log("[EXULU] Database 'exulu' does not exist. Creating it...");
124
+ await defaultKnex.raw(`CREATE DATABASE exulu`);
125
+ console.log("[EXULU] Database 'exulu' created successfully.");
126
+ } else {
127
+ console.log("[EXULU] Database 'exulu' already exists.");
128
+ }
129
+ } finally {
130
+ await defaultKnex.destroy();
131
+ }
132
+ }
103
133
  async function postgresClient() {
104
134
  if (!db["exulu"]) {
105
135
  try {
@@ -109,6 +139,12 @@ async function postgresClient() {
109
139
  console.log("[EXULU] POSTGRES_DB_USER:", process.env.POSTGRES_DB_USER);
110
140
  console.log("[EXULU] POSTGRES_DB_PASSWORD:", process.env.POSTGRES_DB_PASSWORD);
111
141
  console.log("[EXULU] POSTGRES_DB_SSL:", process.env.POSTGRES_DB_SSL);
142
+ console.log("[EXULU] Database exists checked:", databaseExistsChecked);
143
+ if (!databaseExistsChecked) {
144
+ console.log("[EXULU] Ensuring exulu database exists...");
145
+ await ensureDatabaseExists();
146
+ databaseExistsChecked = true;
147
+ }
112
148
  const knex = Knex({
113
149
  client: "pg",
114
150
  connection: {
@@ -2950,6 +2986,7 @@ var global_queues = {
2950
2986
  logs_cleaner: "logs-cleaner"
2951
2987
  };
2952
2988
  var createRecurringJobs = async () => {
2989
+ console.log("[EXULU] creating recurring jobs.");
2953
2990
  const recurringJobSchedulersLogs = [];
2954
2991
  const queue = queues.use(global_queues.logs_cleaner);
2955
2992
  recurringJobSchedulersLogs.push({
@@ -2977,7 +3014,7 @@ var createRecurringJobs = async () => {
2977
3014
  }
2978
3015
  }
2979
3016
  );
2980
- console.log("Recurring job schedulers:");
3017
+ console.log("[EXULU] recurring job schedulers:");
2981
3018
  console.table(recurringJobSchedulersLogs);
2982
3019
  return queue;
2983
3020
  };
@@ -4525,129 +4562,6 @@ var defaultAgent = new ExuluAgent({
4525
4562
  }
4526
4563
  });
4527
4564
 
4528
- // src/templates/tools/browserbase.ts
4529
- import { z as z4 } from "zod";
4530
- import { Stagehand } from "@browserbasehq/stagehand";
4531
- import { Browserbase } from "@browserbasehq/sdk";
4532
- var PROJECT_ID = "811444dd-6e6d-40b5-bd90-541c93e44be6";
4533
- process.env.BROWSERBASE_PROJECT_ID = PROJECT_ID;
4534
- var BB_API_KEY = "bb_live_LwMwNgZB5cIEKcBwMuAugrgNkFM";
4535
- async function createContext() {
4536
- const bb = new Browserbase({ apiKey: BB_API_KEY });
4537
- const context = await bb.contexts.create({
4538
- projectId: PROJECT_ID
4539
- });
4540
- return context;
4541
- }
4542
- async function createAuthSession(contextId) {
4543
- const bb = new Browserbase({ apiKey: BB_API_KEY });
4544
- const session = await bb.sessions.create({
4545
- projectId: PROJECT_ID,
4546
- browserSettings: {
4547
- context: {
4548
- id: contextId,
4549
- persist: true
4550
- }
4551
- }
4552
- /* proxies: [{ // not included in the free tier
4553
- type: "browserbase",
4554
- geolocation: {
4555
- city: CITY,
4556
- country: COUNTRY
4557
- }
4558
- }] */
4559
- });
4560
- const liveViewLinks = await bb.sessions.debug(session.id);
4561
- const liveViewLink = liveViewLinks.debuggerFullscreenUrl;
4562
- console.log(`\u{1F50D} Live View Link: ${liveViewLink}`);
4563
- console.log("Session URL: https://browserbase.com/sessions/" + session.id);
4564
- return {
4565
- url: liveViewLink,
4566
- id: session.id
4567
- };
4568
- }
4569
- var createSession = new ExuluTool({
4570
- id: `1234-5178-9423-4267`,
4571
- type: "function",
4572
- name: "Create a browserbase session.",
4573
- description: `
4574
- Creates a browserbase session and returns the live view url as well as
4575
- the session id as a JSON object. A browserbase session is a headless browser
4576
- that can be used to to visit websites and perform actions.
4577
- `,
4578
- execute: async () => {
4579
- const { id } = await createContext();
4580
- return await createAuthSession(id);
4581
- }
4582
- });
4583
- var askChatgpt = new ExuluTool({
4584
- id: `1234-5178-9423-4268`,
4585
- type: "function",
4586
- name: "ChatGPT browserbase operation.",
4587
- inputSchema: z4.object({
4588
- session: z4.string().describe("The session id of the browserbase session."),
4589
- question: z4.string().describe("The question to ask ChatGPT.")
4590
- }),
4591
- description: `Uses an existing, authenticated browserbase session to visit ChatGPT and perform actions such as asking questions.`,
4592
- execute: async ({ session, question }) => {
4593
- const stagehand = new Stagehand({
4594
- // With npx create-browser-app, this config is found
4595
- // in a separate stagehand.config.ts file
4596
- env: "BROWSERBASE",
4597
- // set to "LOCAL" for local development
4598
- apiKey: BB_API_KEY,
4599
- // todo make this a config variable the admin can set in the UI
4600
- modelName: "openai/gpt-4.1-mini",
4601
- // todo change to claude || optionally make configurable?
4602
- browserbaseSessionID: session,
4603
- modelClientOptions: {
4604
- apiKey: process.env.OPENAI_API_KEY
4605
- // todo make this a config variable the admin can set in the UI
4606
- }
4607
- });
4608
- await stagehand.init();
4609
- const page = stagehand.page;
4610
- await page.goto("https://chatgpt.com");
4611
- await page.act(`Type in '${question}' into the search bar`);
4612
- const { answer } = await page.extract({
4613
- instruction: "The answer to the question generated by ChatGPT.",
4614
- schema: z4.object({
4615
- answer: z4.string()
4616
- })
4617
- });
4618
- console.log(answer);
4619
- await stagehand.close();
4620
- return {
4621
- answer
4622
- };
4623
- }
4624
- });
4625
-
4626
- // src/templates/tools/jira.ts
4627
- import { z as z5 } from "zod";
4628
- var getTicket = new ExuluTool({
4629
- id: `1414-5179-1423-1269`,
4630
- name: "JIRA ticket retrieval.",
4631
- type: "function",
4632
- inputSchema: z5.object({
4633
- ticketId: z5.string().describe("The id of the ticket to retrieve.")
4634
- }),
4635
- description: `Retrieves a ticket from Jira.`,
4636
- execute: async ({ session, question }) => {
4637
- return {
4638
- name: "BYD-1234",
4639
- id: "12345678",
4640
- status: "Open",
4641
- description: "This is a test ticket",
4642
- assignee: "John Doe",
4643
- createdAt: "2021-01-01",
4644
- updatedAt: "2021-01-01",
4645
- dueDate: "2021-01-01",
4646
- priority: "High"
4647
- };
4648
- }
4649
- });
4650
-
4651
4565
  // src/registry/index.ts
4652
4566
  var ExuluApp = class {
4653
4567
  _agents = [];
@@ -4675,12 +4589,7 @@ var ExuluApp = class {
4675
4589
  // Add contexts as tools
4676
4590
  ...Object.values(contexts || {}).map((context) => context.tool()),
4677
4591
  // Add agents as tools
4678
- ...(agents || []).map((agent) => agent.tool()),
4679
- ...[
4680
- createSession,
4681
- askChatgpt,
4682
- getTicket
4683
- ]
4592
+ ...(agents || []).map((agent) => agent.tool())
4684
4593
  ];
4685
4594
  const contextsArray = Object.values(contexts || {});
4686
4595
  const queues2 = [
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "1.6.0",
4
+ "version": "1.6.2",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {
@@ -31,12 +31,12 @@
31
31
  "@commitlint/cli": "^19.8.1",
32
32
  "@commitlint/config-conventional": "^19.8.1",
33
33
  "@semantic-release/changelog": "^6.0.3",
34
- "semantic-release": "^24.2.7",
35
34
  "@types/bun": "latest",
36
35
  "@types/node": "^22.14.0",
37
36
  "@types/pg": "^8.15.1",
38
37
  "conventional-changelog-atom": "^5.0.0",
39
38
  "husky": "^9.1.7",
39
+ "semantic-release": "^24.2.7",
40
40
  "tsup": "^8.5.0",
41
41
  "tsx": "^4.19.3"
42
42
  },
@@ -50,8 +50,6 @@
50
50
  "@aws-sdk/client-s3": "^3.338.0",
51
51
  "@aws-sdk/client-sts": "^3.338.0",
52
52
  "@aws-sdk/s3-request-presigner": "^3.338.0",
53
- "@browserbasehq/sdk": "^2.6.0",
54
- "@browserbasehq/stagehand": "^2.4.1",
55
53
  "@inkjs/ui": "^2.0.0",
56
54
  "@modelcontextprotocol/sdk": "^1.14.0",
57
55
  "@types/bcrypt": "^5.0.2",