@exulu/backend 2.0.0 → 2.0.1

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/dist/index.cjs CHANGED
@@ -15830,7 +15830,7 @@ var durationFromSegments = (segments) => {
15830
15830
 
15831
15831
  // src/exulu/recall/service.ts
15832
15832
  var TABLE3 = "transcription_jobs";
15833
- var DEFAULT_BOT_NAME = "Exulu Notetaker";
15833
+ var DEFAULT_BOT_NAME = "Company Notetaker";
15834
15834
  var log4 = (msg) => console.log(`[EXULU-RECALL] ${msg}`);
15835
15835
  var parseJson = (v) => {
15836
15836
  if (v == null) return null;
@@ -18281,10 +18281,74 @@ function resolveMaxStepsFromToolConfigs(toolConfigs) {
18281
18281
  const n = typeof raw === "number" ? raw : parseInt(String(raw ?? ""), 10);
18282
18282
  return Number.isFinite(n) && n > 0 ? Math.floor(n) : void 0;
18283
18283
  }
18284
+ function flattenPart(part) {
18285
+ const p = part;
18286
+ if (p?.type === "text") return p.text ?? "";
18287
+ if (p?.type === "tool-call") {
18288
+ return `[searched ${p.toolName}: ${JSON.stringify(p.input ?? {}).slice(0, 300)}]`;
18289
+ }
18290
+ if (p?.type === "tool-result") {
18291
+ const out = p.output?.value ?? p.output;
18292
+ return `[results from ${p.toolName}]: ${typeof out === "string" ? out : JSON.stringify(out ?? "")}`;
18293
+ }
18294
+ return "";
18295
+ }
18296
+ function flattenToolHistory(messages) {
18297
+ return messages.map((m) => {
18298
+ const msg = m;
18299
+ if (msg.role === "tool") {
18300
+ const text = (Array.isArray(msg.content) ? msg.content : []).map(flattenPart).filter(Boolean).join("\n");
18301
+ return { role: "user", content: text || "(tool results)" };
18302
+ }
18303
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
18304
+ const text = msg.content.map(flattenPart).filter(Boolean).join("\n");
18305
+ return { role: "assistant", content: text || "(searching)" };
18306
+ }
18307
+ return m;
18308
+ });
18309
+ }
18310
+ var FINAL_ANSWER_INSTRUCTION = "Answer the user's original question now, in plain text, using only the material already retrieved above. Do not attempt any further tool calls.";
18284
18311
  function finalAnswerGuard(maxSteps) {
18285
- return ({ stepNumber }) => stepNumber >= maxSteps - 1 ? { toolChoice: "none" } : void 0;
18312
+ return ({ stepNumber, messages }) => stepNumber >= maxSteps - 1 ? {
18313
+ toolChoice: "none",
18314
+ activeTools: [],
18315
+ ...Array.isArray(messages) ? {
18316
+ messages: [
18317
+ ...flattenToolHistory(messages),
18318
+ { role: "user", content: FINAL_ANSWER_INSTRUCTION }
18319
+ ]
18320
+ } : {}
18321
+ } : void 0;
18286
18322
  }
18287
18323
 
18324
+ // src/exulu/auto-decline-stale-approvals.ts
18325
+ init_cjs_shims();
18326
+ var AUTO_DECLINE_REASON = "Automatically declined because the user sent a new message instead of responding to the approval request.";
18327
+ var isPendingApprovalToolPart = (part) => {
18328
+ const candidate = part;
18329
+ return (candidate?.type === "dynamic-tool" || typeof candidate?.type === "string" && candidate.type.startsWith("tool-")) && candidate?.state === "approval-requested" && typeof candidate?.approval?.id === "string";
18330
+ };
18331
+ var autoDeclineStaleApprovals = (messages) => {
18332
+ const declined = [];
18333
+ const reconciled = messages.map((message, index) => {
18334
+ if (index === messages.length - 1 || message.role !== "assistant") return message;
18335
+ if (!message.parts?.some(isPendingApprovalToolPart)) return message;
18336
+ const updated = {
18337
+ ...message,
18338
+ parts: message.parts.map(
18339
+ (part) => isPendingApprovalToolPart(part) ? {
18340
+ ...part,
18341
+ state: "output-denied",
18342
+ approval: { id: part.approval.id, approved: false, reason: AUTO_DECLINE_REASON }
18343
+ } : part
18344
+ )
18345
+ };
18346
+ declined.push(updated);
18347
+ return updated;
18348
+ });
18349
+ return { messages: reconciled, declined };
18350
+ };
18351
+
18288
18352
  // src/exulu/provider.ts
18289
18353
  var import_zod12 = require("zod");
18290
18354
  init_tool();
@@ -19026,6 +19090,11 @@ ${extractedText}
19026
19090
  messages = messages.filter(
19027
19091
  (message2, index, self) => index === self.findLastIndex((t) => t.id === message2.id)
19028
19092
  );
19093
+ const { messages: reconciledMessages, declined } = autoDeclineStaleApprovals(messages);
19094
+ messages = reconciledMessages;
19095
+ if (declined.length && session && user) {
19096
+ await saveChat({ session, user: user.id, messages: declined });
19097
+ }
19029
19098
  messages = await this.processFilePartsInMessages(messages);
19030
19099
  const genericContext = "IMPORTANT: \n\n The current date is " + (/* @__PURE__ */ new Date()).toLocaleDateString() + " and the current time is " + (/* @__PURE__ */ new Date()).toLocaleTimeString() + ". If the user does not explicitly provide the current date, for examle when saying ' this weekend', you should assume they are talking with the current date in mind as a reference.";
19031
19100
  let system = instructions || "You are a helpful assistant. When you use a tool to answer a question do not explicitly comment on the result of the tool call unless the user has explicitly you to do something with the result.";
package/dist/index.js CHANGED
@@ -8852,7 +8852,7 @@ var durationFromSegments = (segments) => {
8852
8852
 
8853
8853
  // src/exulu/recall/service.ts
8854
8854
  var TABLE2 = "transcription_jobs";
8855
- var DEFAULT_BOT_NAME = "Exulu Notetaker";
8855
+ var DEFAULT_BOT_NAME = "Company Notetaker";
8856
8856
  var log3 = (msg) => console.log(`[EXULU-RECALL] ${msg}`);
8857
8857
  var parseJson = (v) => {
8858
8858
  if (v == null) return null;
@@ -11291,10 +11291,73 @@ function resolveMaxStepsFromToolConfigs(toolConfigs) {
11291
11291
  const n = typeof raw === "number" ? raw : parseInt(String(raw ?? ""), 10);
11292
11292
  return Number.isFinite(n) && n > 0 ? Math.floor(n) : void 0;
11293
11293
  }
11294
+ function flattenPart(part) {
11295
+ const p = part;
11296
+ if (p?.type === "text") return p.text ?? "";
11297
+ if (p?.type === "tool-call") {
11298
+ return `[searched ${p.toolName}: ${JSON.stringify(p.input ?? {}).slice(0, 300)}]`;
11299
+ }
11300
+ if (p?.type === "tool-result") {
11301
+ const out = p.output?.value ?? p.output;
11302
+ return `[results from ${p.toolName}]: ${typeof out === "string" ? out : JSON.stringify(out ?? "")}`;
11303
+ }
11304
+ return "";
11305
+ }
11306
+ function flattenToolHistory(messages) {
11307
+ return messages.map((m) => {
11308
+ const msg = m;
11309
+ if (msg.role === "tool") {
11310
+ const text = (Array.isArray(msg.content) ? msg.content : []).map(flattenPart).filter(Boolean).join("\n");
11311
+ return { role: "user", content: text || "(tool results)" };
11312
+ }
11313
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
11314
+ const text = msg.content.map(flattenPart).filter(Boolean).join("\n");
11315
+ return { role: "assistant", content: text || "(searching)" };
11316
+ }
11317
+ return m;
11318
+ });
11319
+ }
11320
+ var FINAL_ANSWER_INSTRUCTION = "Answer the user's original question now, in plain text, using only the material already retrieved above. Do not attempt any further tool calls.";
11294
11321
  function finalAnswerGuard(maxSteps) {
11295
- return ({ stepNumber }) => stepNumber >= maxSteps - 1 ? { toolChoice: "none" } : void 0;
11322
+ return ({ stepNumber, messages }) => stepNumber >= maxSteps - 1 ? {
11323
+ toolChoice: "none",
11324
+ activeTools: [],
11325
+ ...Array.isArray(messages) ? {
11326
+ messages: [
11327
+ ...flattenToolHistory(messages),
11328
+ { role: "user", content: FINAL_ANSWER_INSTRUCTION }
11329
+ ]
11330
+ } : {}
11331
+ } : void 0;
11296
11332
  }
11297
11333
 
11334
+ // src/exulu/auto-decline-stale-approvals.ts
11335
+ var AUTO_DECLINE_REASON = "Automatically declined because the user sent a new message instead of responding to the approval request.";
11336
+ var isPendingApprovalToolPart = (part) => {
11337
+ const candidate = part;
11338
+ return (candidate?.type === "dynamic-tool" || typeof candidate?.type === "string" && candidate.type.startsWith("tool-")) && candidate?.state === "approval-requested" && typeof candidate?.approval?.id === "string";
11339
+ };
11340
+ var autoDeclineStaleApprovals = (messages) => {
11341
+ const declined = [];
11342
+ const reconciled = messages.map((message, index) => {
11343
+ if (index === messages.length - 1 || message.role !== "assistant") return message;
11344
+ if (!message.parts?.some(isPendingApprovalToolPart)) return message;
11345
+ const updated = {
11346
+ ...message,
11347
+ parts: message.parts.map(
11348
+ (part) => isPendingApprovalToolPart(part) ? {
11349
+ ...part,
11350
+ state: "output-denied",
11351
+ approval: { id: part.approval.id, approved: false, reason: AUTO_DECLINE_REASON }
11352
+ } : part
11353
+ )
11354
+ };
11355
+ declined.push(updated);
11356
+ return updated;
11357
+ });
11358
+ return { messages: reconciled, declined };
11359
+ };
11360
+
11298
11361
  // src/exulu/provider.ts
11299
11362
  import { z as z2 } from "zod";
11300
11363
  import {
@@ -12031,6 +12094,11 @@ ${extractedText}
12031
12094
  messages = messages.filter(
12032
12095
  (message2, index, self) => index === self.findLastIndex((t) => t.id === message2.id)
12033
12096
  );
12097
+ const { messages: reconciledMessages, declined } = autoDeclineStaleApprovals(messages);
12098
+ messages = reconciledMessages;
12099
+ if (declined.length && session && user) {
12100
+ await saveChat({ session, user: user.id, messages: declined });
12101
+ }
12034
12102
  messages = await this.processFilePartsInMessages(messages);
12035
12103
  const genericContext = "IMPORTANT: \n\n The current date is " + (/* @__PURE__ */ new Date()).toLocaleDateString() + " and the current time is " + (/* @__PURE__ */ new Date()).toLocaleTimeString() + ". If the user does not explicitly provide the current date, for examle when saying ' this weekend', you should assume they are talking with the current date in mind as a reference.";
12036
12104
  let system = instructions || "You are a helpful assistant. When you use a tool to answer a question do not explicitly comment on the result of the tool call unless the user has explicitly you to do something with the result.";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@exulu/backend",
3
3
  "author": "Qventu Bv.",
4
- "version": "2.0.0",
4
+ "version": "2.0.1",
5
5
  "main": "./dist/index.js",
6
6
  "private": false,
7
7
  "publishConfig": {