@rubytech/create-maxy 1.0.451 → 1.0.452

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.451",
3
+ "version": "1.0.452",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -9539,6 +9539,42 @@ function extractBoomDetails(err) {
9539
9539
  return { statusCode, error: error48, message };
9540
9540
  }
9541
9541
 
9542
+ // app/lib/whatsapp/reconnect.ts
9543
+ import { DisconnectReason as DisconnectReason2 } from "@whiskeysockets/baileys";
9544
+ function classifyDisconnect(err) {
9545
+ const statusCode = getStatusCode(err);
9546
+ const message = formatError(err);
9547
+ if (statusCode === DisconnectReason2.loggedOut) {
9548
+ return {
9549
+ kind: "loggedOut",
9550
+ statusCode,
9551
+ message: "Session logged out \u2014 re-link required",
9552
+ shouldRetry: false
9553
+ };
9554
+ }
9555
+ if (statusCode === 409 || statusCode === DisconnectReason2.connectionReplaced) {
9556
+ return {
9557
+ kind: "conflict",
9558
+ statusCode,
9559
+ message: "Connection replaced by another client",
9560
+ shouldRetry: false
9561
+ };
9562
+ }
9563
+ return {
9564
+ kind: "transient",
9565
+ statusCode,
9566
+ message,
9567
+ shouldRetry: true
9568
+ };
9569
+ }
9570
+ function computeBackoff(attempt, config2 = {}) {
9571
+ const base = config2.baseDelayMs ?? 2e3;
9572
+ const max = config2.maxDelayMs ?? 12e4;
9573
+ const exponential = Math.min(base * Math.pow(2, attempt), max);
9574
+ const jitter = exponential * (0.75 + Math.random() * 0.5);
9575
+ return Math.round(jitter);
9576
+ }
9577
+
9542
9578
  // app/lib/whatsapp/login.ts
9543
9579
  var TAG3 = "[whatsapp:login]";
9544
9580
  var ACTIVE_LOGIN_TTL_MS = 3 * 6e4;
@@ -9559,6 +9595,56 @@ function resetActiveLogin(accountId) {
9559
9595
  function isLoginFresh(login) {
9560
9596
  return Date.now() - login.startedAt < ACTIVE_LOGIN_TTL_MS;
9561
9597
  }
9598
+ var LOGIN_MAX_RECONNECTS = 3;
9599
+ var LOGIN_RECONNECT_DELAYS = [2e3, 4e3, 8e3];
9600
+ async function loginConnectionLoop(accountId, login) {
9601
+ let attempt = 0;
9602
+ while (true) {
9603
+ try {
9604
+ await waitForConnection(login.sock);
9605
+ const current = activeLogins.get(accountId);
9606
+ if (current?.id === login.id) {
9607
+ current.connected = true;
9608
+ }
9609
+ return;
9610
+ } catch (err) {
9611
+ const current = activeLogins.get(accountId);
9612
+ if (current?.id !== login.id) return;
9613
+ const classification = classifyDisconnect(err);
9614
+ if (!classification.shouldRetry || attempt >= LOGIN_MAX_RECONNECTS) {
9615
+ if (attempt >= LOGIN_MAX_RECONNECTS) {
9616
+ console.error(
9617
+ `${TAG3} login reconnect attempts exhausted (${attempt}/${LOGIN_MAX_RECONNECTS}) \u2014 surfacing error to agent`
9618
+ );
9619
+ current.error = `Login failed after ${attempt} reconnect attempts: ${formatError(err)}`;
9620
+ } else {
9621
+ current.error = formatError(err);
9622
+ }
9623
+ current.errorStatus = getStatusCode(err);
9624
+ return;
9625
+ }
9626
+ attempt++;
9627
+ const delay = LOGIN_RECONNECT_DELAYS[attempt - 1] ?? 8e3;
9628
+ console.error(
9629
+ `${TAG3} status=${classification.statusCode ?? "unknown"} restart required \u2014 reconnecting with saved creds (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}) delay=${delay}ms`
9630
+ );
9631
+ closeSocket(current.sock);
9632
+ await new Promise((r) => setTimeout(r, delay));
9633
+ const afterDelay = activeLogins.get(accountId);
9634
+ if (afterDelay?.id !== login.id) return;
9635
+ try {
9636
+ const newSock = await createWaSocket({ authDir: login.authDir });
9637
+ current.sock = newSock;
9638
+ } catch (sockErr) {
9639
+ console.error(
9640
+ `${TAG3} reconnect socket creation failed (attempt ${attempt}/${LOGIN_MAX_RECONNECTS}): ${String(sockErr)}`
9641
+ );
9642
+ current.error = `Reconnection failed: ${String(sockErr)}`;
9643
+ return;
9644
+ }
9645
+ }
9646
+ }
9647
+ }
9562
9648
  async function startLogin(opts) {
9563
9649
  const { accountId, authDir, force, timeoutMs = 3e4 } = opts;
9564
9650
  const existing0 = activeLogins.get(accountId);
@@ -9633,14 +9719,12 @@ async function startLogin(opts) {
9633
9719
  };
9634
9720
  activeLogins.set(accountId, login);
9635
9721
  if (pendingQr && !login.qr) login.qr = pendingQr;
9636
- waitForConnection(sock).then(() => {
9637
- const current = activeLogins.get(accountId);
9638
- if (current?.id === login.id) current.connected = true;
9639
- }).catch((err) => {
9722
+ loginConnectionLoop(accountId, login).catch((err) => {
9723
+ console.error(`${TAG3} loginConnectionLoop unexpected error: ${String(err)}`);
9640
9724
  const current = activeLogins.get(accountId);
9641
- if (current?.id !== login.id) return;
9642
- current.error = formatError(err);
9643
- current.errorStatus = getStatusCode(err);
9725
+ if (current?.id === login.id) {
9726
+ current.error = `Unexpected login error: ${String(err)}`;
9727
+ }
9644
9728
  });
9645
9729
  let qr;
9646
9730
  try {
@@ -23548,42 +23632,6 @@ var WhatsAppConfigSchema = external_exports.object({
23548
23632
  });
23549
23633
  });
23550
23634
 
23551
- // app/lib/whatsapp/reconnect.ts
23552
- import { DisconnectReason as DisconnectReason2 } from "@whiskeysockets/baileys";
23553
- function classifyDisconnect(err) {
23554
- const statusCode = getStatusCode(err);
23555
- const message = formatError(err);
23556
- if (statusCode === DisconnectReason2.loggedOut) {
23557
- return {
23558
- kind: "loggedOut",
23559
- statusCode,
23560
- message: "Session logged out \u2014 re-link required",
23561
- shouldRetry: false
23562
- };
23563
- }
23564
- if (statusCode === 409 || statusCode === DisconnectReason2.connectionReplaced) {
23565
- return {
23566
- kind: "conflict",
23567
- statusCode,
23568
- message: "Connection replaced by another client",
23569
- shouldRetry: false
23570
- };
23571
- }
23572
- return {
23573
- kind: "transient",
23574
- statusCode,
23575
- message,
23576
- shouldRetry: true
23577
- };
23578
- }
23579
- function computeBackoff(attempt, config2 = {}) {
23580
- const base = config2.baseDelayMs ?? 2e3;
23581
- const max = config2.maxDelayMs ?? 12e4;
23582
- const exponential = Math.min(base * Math.pow(2, attempt), max);
23583
- const jitter = exponential * (0.75 + Math.random() * 0.5);
23584
- return Math.round(jitter);
23585
- }
23586
-
23587
23635
  // app/lib/whatsapp/normalize.ts
23588
23636
  var WHATSAPP_USER_JID_RE = /^(\d+)(?::\d+)?@s\.whatsapp\.net$/i;
23589
23637
  var WHATSAPP_LID_RE = /^(\d+)@lid$/i;
@@ -9,6 +9,10 @@ You are a public-facing agent for a business. Your personality, tone, and busine
9
9
  - Never describe your own capabilities or limitations unprompted. Visitors care about the business, not your architecture.
10
10
  - British English unless your business context specifies otherwise.
11
11
 
12
+ ## Visual content
13
+
14
+ Images may be available at `/brand/` — these are visual assets the business has prepared. When your knowledge lists an image and a visitor's question is relevant to it, embed it inline using standard markdown: `![description](/brand/filename)`. The visitor sees the image directly in the conversation. Only reference images explicitly listed in your knowledge — never guess or fabricate filenames. When a relevant image exists, show it rather than describing what you could show.
15
+
12
16
  ## Boundaries
13
17
 
14
18
  - You are an AI assistant. State this clearly if asked. Never impersonate a human.