@diegoaltoworks/chatter 0.60.0 → 0.62.0

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 (125) hide show
  1. package/README.md +56 -17
  2. package/dist/auth/secretStrength.d.ts +1 -1
  3. package/dist/auth/secretStrength.d.ts.map +1 -1
  4. package/dist/bin/create-apikey.js +45 -28
  5. package/dist/bin/wa-pair.js +113 -46
  6. package/dist/channels/backoff.d.ts +10 -0
  7. package/dist/channels/backoff.d.ts.map +1 -0
  8. package/dist/channels/gates.d.ts +15 -8
  9. package/dist/channels/gates.d.ts.map +1 -1
  10. package/dist/channels/index.d.ts +1 -1
  11. package/dist/channels/index.d.ts.map +1 -1
  12. package/dist/channels/index.js +38 -5
  13. package/dist/channels/index.mjs +37 -5
  14. package/dist/channels/matrix/api.d.ts +152 -0
  15. package/dist/channels/matrix/api.d.ts.map +1 -0
  16. package/dist/channels/matrix/channel.d.ts +46 -0
  17. package/dist/channels/matrix/channel.d.ts.map +1 -0
  18. package/dist/channels/matrix/handler.d.ts +58 -0
  19. package/dist/channels/matrix/handler.d.ts.map +1 -0
  20. package/dist/channels/matrix/index.d.ts +37 -0
  21. package/dist/channels/matrix/index.d.ts.map +1 -0
  22. package/dist/channels/matrix/index.js +1128 -0
  23. package/dist/channels/matrix/index.mjs +1079 -0
  24. package/dist/channels/matrix/sync.d.ts +53 -0
  25. package/dist/channels/matrix/sync.d.ts.map +1 -0
  26. package/dist/channels/matrix/updates.d.ts +104 -0
  27. package/dist/channels/matrix/updates.d.ts.map +1 -0
  28. package/dist/channels/pipeline.d.ts +14 -14
  29. package/dist/channels/pipeline.d.ts.map +1 -1
  30. package/dist/channels/polling.d.ts +67 -0
  31. package/dist/channels/polling.d.ts.map +1 -0
  32. package/dist/channels/telegram/channel.d.ts +2 -56
  33. package/dist/channels/telegram/channel.d.ts.map +1 -1
  34. package/dist/channels/telegram/index.js +53 -23
  35. package/dist/channels/telegram/index.mjs +53 -23
  36. package/dist/channels/telegram/poll.d.ts +5 -1
  37. package/dist/channels/telegram/poll.d.ts.map +1 -1
  38. package/dist/channels/telegram/webhook.d.ts +2 -10
  39. package/dist/channels/telegram/webhook.d.ts.map +1 -1
  40. package/dist/channels/whatsapp/authState.d.ts +40 -9
  41. package/dist/channels/whatsapp/authState.d.ts.map +1 -1
  42. package/dist/channels/whatsapp/channel.d.ts +25 -4
  43. package/dist/channels/whatsapp/channel.d.ts.map +1 -1
  44. package/dist/channels/whatsapp/inbound.d.ts +23 -25
  45. package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
  46. package/dist/channels/whatsapp/index.d.ts +3 -3
  47. package/dist/channels/whatsapp/index.d.ts.map +1 -1
  48. package/dist/channels/whatsapp/index.js +123 -41
  49. package/dist/channels/whatsapp/index.mjs +120 -41
  50. package/dist/channels/whatsapp/pairing.d.ts.map +1 -1
  51. package/dist/client/src/Chat.d.ts.map +1 -1
  52. package/dist/client/src/ChatButton.d.ts.map +1 -1
  53. package/dist/client/src/browser.d.ts.map +1 -1
  54. package/dist/core/answer.d.ts +8 -0
  55. package/dist/core/answer.d.ts.map +1 -1
  56. package/dist/core/buildLock.d.ts +52 -0
  57. package/dist/core/buildLock.d.ts.map +1 -0
  58. package/dist/core/pipeline.d.ts +42 -5
  59. package/dist/core/pipeline.d.ts.map +1 -1
  60. package/dist/core/prompts.d.ts +2 -0
  61. package/dist/core/prompts.d.ts.map +1 -1
  62. package/dist/core/retrieval.d.ts +100 -25
  63. package/dist/core/retrieval.d.ts.map +1 -1
  64. package/dist/core/session.d.ts +8 -0
  65. package/dist/core/session.d.ts.map +1 -1
  66. package/dist/flows/index.d.ts +1 -1
  67. package/dist/flows/index.d.ts.map +1 -1
  68. package/dist/flows/index.js +8 -6
  69. package/dist/flows/index.mjs +7 -6
  70. package/dist/flows/intent.d.ts +1 -1
  71. package/dist/flows/intent.d.ts.map +1 -1
  72. package/dist/flows/loader.d.ts +1 -2
  73. package/dist/flows/loader.d.ts.map +1 -1
  74. package/dist/flows/params.d.ts +1 -1
  75. package/dist/flows/params.d.ts.map +1 -1
  76. package/dist/flows/session.d.ts +4 -2
  77. package/dist/flows/session.d.ts.map +1 -1
  78. package/dist/flows/types.d.ts +2 -3
  79. package/dist/flows/types.d.ts.map +1 -1
  80. package/dist/history/index.d.ts +1 -1
  81. package/dist/history/index.d.ts.map +1 -1
  82. package/dist/history/index.js +6 -3
  83. package/dist/history/index.mjs +5 -3
  84. package/dist/history/tursoStore.d.ts +6 -4
  85. package/dist/history/tursoStore.d.ts.map +1 -1
  86. package/dist/images/index.js +2 -2
  87. package/dist/images/index.mjs +2 -2
  88. package/dist/index.d.ts +7 -5
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +596 -295
  91. package/dist/index.mjs +595 -295
  92. package/dist/mcp-server/index.d.ts +5 -5
  93. package/dist/mcp-server/index.d.ts.map +1 -1
  94. package/dist/mcp-server/logger.d.ts +12 -2
  95. package/dist/mcp-server/logger.d.ts.map +1 -1
  96. package/dist/mcp-server/rate-limiter.d.ts +10 -3
  97. package/dist/mcp-server/rate-limiter.d.ts.map +1 -1
  98. package/dist/mcp-server/types.d.ts +20 -5
  99. package/dist/mcp-server/types.d.ts.map +1 -1
  100. package/dist/mcp-server.js +479 -244
  101. package/dist/mcp-server.mjs +485 -244
  102. package/dist/middleware/apiKey.d.ts +10 -0
  103. package/dist/middleware/apiKey.d.ts.map +1 -0
  104. package/dist/middleware/auth.d.ts.map +1 -1
  105. package/dist/middleware/cors.d.ts.map +1 -1
  106. package/dist/middleware/ratelimit.d.ts.map +1 -1
  107. package/dist/middleware/referrer.d.ts.map +1 -1
  108. package/dist/middleware/session.d.ts +1 -1
  109. package/dist/middleware/session.d.ts.map +1 -1
  110. package/dist/routes/demo.d.ts.map +1 -1
  111. package/dist/routes/openai.d.ts.map +1 -1
  112. package/dist/routes/private.d.ts.map +1 -1
  113. package/dist/routes/public.d.ts.map +1 -1
  114. package/dist/scheduler/index.js +1 -1
  115. package/dist/scheduler/index.mjs +1 -1
  116. package/dist/scheduler/scheduler.d.ts +9 -1
  117. package/dist/scheduler/scheduler.d.ts.map +1 -1
  118. package/dist/server.d.ts.map +1 -1
  119. package/dist/server.js +491 -268
  120. package/dist/server.mjs +497 -268
  121. package/dist/shortener.d.ts +5 -4
  122. package/dist/shortener.d.ts.map +1 -1
  123. package/dist/types.d.ts +129 -75
  124. package/dist/types.d.ts.map +1 -1
  125. package/package.json +11 -2
@@ -35,6 +35,7 @@ __export(index_exports, {
35
35
  LEASE_WAIT_MS: () => LEASE_WAIT_MS,
36
36
  acquireSessionLease: () => acquireSessionLease,
37
37
  canAcquireLease: () => canAcquireLease,
38
+ createTursoWaAuthKV: () => createTursoWaAuthKV,
38
39
  createTursoWaLeaseStore: () => createTursoWaLeaseStore,
39
40
  createWhatsAppChannel: () => createWhatsAppChannel,
40
41
  createWhatsAppImageHandler: () => createWhatsAppImageHandler,
@@ -50,12 +51,14 @@ __export(index_exports, {
50
51
  jidsMatch: () => jidsMatch,
51
52
  loadBaileys: () => loadBaileys,
52
53
  messageContext: () => messageContext,
54
+ normalizeWaMediaPayload: () => normalizeWaMediaPayload,
53
55
  reconnectDelayMs: () => reconnectDelayMs,
54
56
  resolveWaMessage: () => resolveWaMessage,
55
57
  senderNameFor: () => senderNameFor,
56
58
  senderPhoneFor: () => senderPhoneFor,
57
59
  shutdownWaSessions: () => shutdownWaSessions,
58
60
  stripOwnMentions: () => stripOwnMentions,
61
+ useAuthState: () => useAuthState,
59
62
  useTursoAuthState: () => useTursoAuthState
60
63
  });
61
64
  module.exports = __toCommonJS(index_exports);
@@ -129,27 +132,55 @@ function ensureAuthSchema(client) {
129
132
  }
130
133
  return ready;
131
134
  }
132
- async function useTursoAuthState(db, secret, sessionId, runtime) {
133
- await ensureAuthSchema(db);
135
+ function createTursoWaAuthKV(db) {
136
+ return {
137
+ async read(id) {
138
+ await ensureAuthSchema(db);
139
+ const result = await db.execute({
140
+ sql: "SELECT value FROM wa_auth WHERE id = ?",
141
+ args: [id]
142
+ });
143
+ const row = result.rows[0];
144
+ return row ? row.value : null;
145
+ },
146
+ async write(id, value) {
147
+ await ensureAuthSchema(db);
148
+ await db.execute({
149
+ sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
150
+ args: [id, value]
151
+ });
152
+ },
153
+ async remove(id) {
154
+ await ensureAuthSchema(db);
155
+ await db.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [id] });
156
+ },
157
+ // Mirrors isAuthRowForSession - keep the two in sync.
158
+ async clear(sessionId) {
159
+ await ensureAuthSchema(db);
160
+ if (sessionId === "default") {
161
+ await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
162
+ } else {
163
+ await db.execute({
164
+ sql: "DELETE FROM wa_auth WHERE id LIKE ?",
165
+ args: [`s:${sessionId}/%`]
166
+ });
167
+ }
168
+ }
169
+ };
170
+ }
171
+ async function useAuthState(store, secret, sessionId, runtime) {
134
172
  const rowId = (id) => sessionId === "default" ? id : `s:${sessionId}/${id}`;
135
173
  async function read(id) {
136
- const result = await db.execute({
137
- sql: "SELECT value FROM wa_auth WHERE id = ?",
138
- args: [rowId(id)]
139
- });
140
- const row = result.rows[0];
141
- if (!row) return null;
142
- return JSON.parse(await decrypt(row.value, secret), runtime.bufferJSON.reviver);
174
+ const value = await store.read(rowId(id));
175
+ if (value === null) return null;
176
+ return JSON.parse(await decrypt(value, secret), runtime.bufferJSON.reviver);
143
177
  }
144
178
  async function write(id, value) {
145
179
  const payload = await encrypt(JSON.stringify(value, runtime.bufferJSON.replacer), secret);
146
- await db.execute({
147
- sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
148
- args: [rowId(id), payload]
149
- });
180
+ await store.write(rowId(id), payload);
150
181
  }
151
182
  async function remove(id) {
152
- await db.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [rowId(id)] });
183
+ await store.remove(rowId(id));
153
184
  }
154
185
  const creds = await read("creds") ?? runtime.initAuthCreds();
155
186
  return {
@@ -186,18 +217,13 @@ async function useTursoAuthState(db, secret, sessionId, runtime) {
186
217
  }
187
218
  },
188
219
  saveCreds: () => write("creds", creds),
189
- clear: async () => {
190
- if (sessionId === "default") {
191
- await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
192
- } else {
193
- await db.execute({
194
- sql: "DELETE FROM wa_auth WHERE id LIKE ?",
195
- args: [`s:${sessionId}/%`]
196
- });
197
- }
198
- }
220
+ // Scoped to THIS session - never nuke a sibling number's pairing.
221
+ clear: () => store.clear(sessionId)
199
222
  };
200
223
  }
224
+ async function useTursoAuthState(db, secret, sessionId, runtime) {
225
+ return useAuthState(createTursoWaAuthKV(db), secret, sessionId, runtime);
226
+ }
201
227
 
202
228
  // src/channels/whatsapp/baileys.ts
203
229
  function wrapMissingBaileysError(cause) {
@@ -260,6 +286,11 @@ function createConsoleLogger(level = "info") {
260
286
  };
261
287
  }
262
288
 
289
+ // src/channels/backoff.ts
290
+ function exponentialBackoffMs(baseMs, maxMs, n) {
291
+ return Math.min(baseMs * 2 ** Math.max(0, Math.min(n, 20)), maxMs);
292
+ }
293
+
263
294
  // src/channels/whatsapp/lease.ts
264
295
  var LEASE_STALE_MS = 9e4;
265
296
  var LEASE_HEARTBEAT_MS = 3e4;
@@ -318,7 +349,7 @@ function createTursoWaLeaseStore(client) {
318
349
  var RECONNECT_DELAY_MS = 5e3;
319
350
  var RECONNECT_MAX_DELAY_MS = 10 * 60 * 1e3;
320
351
  function reconnectDelayMs(failures) {
321
- return Math.min(RECONNECT_DELAY_MS * 2 ** Math.min(failures, 20), RECONNECT_MAX_DELAY_MS);
352
+ return exponentialBackoffMs(RECONNECT_DELAY_MS, RECONNECT_MAX_DELAY_MS, failures);
322
353
  }
323
354
  async function shutdownWaSessions(sessions) {
324
355
  await Promise.all(
@@ -389,9 +420,18 @@ async function acquireSessionLease(sessionId, deps) {
389
420
  function senderNameFor(channelName, sessionId) {
390
421
  return sessionId === "default" ? channelName : `${channelName}:${sessionId}`;
391
422
  }
423
+ function normalizeWaMediaPayload(payload) {
424
+ const media = typeof payload === "string" ? { url: payload } : payload;
425
+ if (!media || typeof media !== "object" || typeof media.url !== "string" || !media.url) {
426
+ throw new TypeError(
427
+ `WhatsApp sendMedia payload must be a URL string or { url, caption? }, got: ${typeof payload}`
428
+ );
429
+ }
430
+ return media;
431
+ }
392
432
  function createWhatsAppChannel(config) {
393
433
  assertStrongSecret(config.sessionSecret, "WhatsApp sessionSecret (e.g. WA_SESSION_SECRET)");
394
- const channelName = "whatsapp";
434
+ const channelName = config.name ?? "whatsapp";
395
435
  const sessionIds = config.sessionIds && config.sessionIds.length > 0 ? config.sessionIds : ["default"];
396
436
  const now = config.now ?? Date.now;
397
437
  const schedule = config.schedule ?? ((fn, ms) => void setTimeout(fn, ms));
@@ -409,8 +449,13 @@ function createWhatsAppChannel(config) {
409
449
  name: channelName,
410
450
  async start(deps) {
411
451
  const log = config.logger ?? deps.logger ?? createConsoleLogger();
412
- const db = deps.db;
413
- const leaseStore = createTursoWaLeaseStore(db);
452
+ if ((!config.leaseStore || !config.authStore) && !deps.db) {
453
+ throw new Error(
454
+ "The WhatsApp channel needs a libsql client for auth state and the session lease: set config.database (config.retriever alone does not open one), or supply both config.leaseStore and config.authStore."
455
+ );
456
+ }
457
+ const leaseStore = config.leaseStore ?? createTursoWaLeaseStore(deps.db);
458
+ const authStore = config.authStore ?? createTursoWaAuthKV(deps.db);
414
459
  senders = deps.senders;
415
460
  await loadBaileys2();
416
461
  async function connect(sessionId) {
@@ -421,8 +466,8 @@ function createWhatsAppChannel(config) {
421
466
  initAuthCreds: baileys.initAuthCreds,
422
467
  appStateSyncKeyFromObject: (value) => baileys.proto.Message.AppStateSyncKeyData.fromObject(value)
423
468
  };
424
- const { state, saveCreds } = await useTursoAuthState(
425
- db,
469
+ const { state, saveCreds } = await useAuthState(
470
+ authStore,
426
471
  config.sessionSecret,
427
472
  sessionId,
428
473
  runtime
@@ -466,6 +511,13 @@ function createWhatsAppChannel(config) {
466
511
  sendText: async (chatId, text) => {
467
512
  await sock.sendMessage(chatId, { text });
468
513
  },
514
+ sendMedia: async (chatId, payload) => {
515
+ const { url, caption } = normalizeWaMediaPayload(payload);
516
+ await sock.sendMessage(
517
+ chatId,
518
+ caption !== void 0 ? { image: { url }, caption } : { image: { url } }
519
+ );
520
+ },
469
521
  sendReaction: async (chatId, messageRef, emoji) => {
470
522
  await sock.sendMessage(chatId, {
471
523
  react: { text: emoji, key: messageRef }
@@ -741,7 +793,8 @@ async function answerOnce({
741
793
  async function applyTransformReply(transformReply, input, logger) {
742
794
  if (!transformReply) return input.text;
743
795
  try {
744
- return await transformReply(input);
796
+ const result = await transformReply(input);
797
+ return typeof result === "string" ? result : null;
745
798
  } catch (error) {
746
799
  logger?.error(
747
800
  `transformReply threw for channel "${input.channel}"; sending the original reply`,
@@ -803,6 +856,7 @@ async function prepareChat({
803
856
  sender,
804
857
  rewriteQuery,
805
858
  rerankContext,
859
+ fallbackFn,
806
860
  logger
807
861
  }) {
808
862
  const lastUserMsg = lastUserMessage(messages);
@@ -819,21 +873,39 @@ async function prepareChat({
819
873
  logger?.error("rewriteQuery threw; falling back to the original query", error);
820
874
  }
821
875
  }
822
- let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
876
+ const resolvedBuckets = buckets ?? defaultBuckets(mode);
877
+ const retrievedChunks = await store.query(query, topK, resolvedBuckets);
878
+ let ctx = retrievedChunks;
823
879
  if (rerankContext) {
824
880
  try {
825
- const reranked = await rerankContext({ query, chunks: ctx });
881
+ const reranked = await rerankContext({ query, chunks: [...ctx] });
826
882
  if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
827
883
  } catch (error) {
828
884
  logger?.error("rerankContext threw; falling back to the original chunks", error);
829
885
  }
830
886
  }
887
+ let fallback;
888
+ if (ctx.length === 0 && fallbackFn) {
889
+ try {
890
+ const guidance = await fallbackFn({
891
+ query,
892
+ mode,
893
+ buckets: resolvedBuckets,
894
+ sender,
895
+ retrievedChunks
896
+ });
897
+ if (typeof guidance === "string" && guidance.trim()) fallback = guidance.trim();
898
+ } catch (error) {
899
+ logger?.error("fallbackFn threw; proceeding without fallback guidance", error);
900
+ }
901
+ }
831
902
  const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
832
903
  const hint = channelHint?.trim();
833
904
  const system = [
834
905
  prompts.baseSystemRules,
835
906
  persona,
836
907
  ...hint ? [hint] : [],
908
+ ...fallback ? [fallback] : [],
837
909
  `${label}:
838
910
  ${ctx.join("\n\n")}`
839
911
  ].join("\n\n");
@@ -841,7 +913,7 @@ ${ctx.join("\n\n")}`
841
913
  }
842
914
 
843
915
  // src/history/compaction.ts
844
- var DEFAULT_TIMEOUT_MS = 8e3;
916
+ var COMPACTION_TIMEOUT_MS = 8e3;
845
917
  var LOAD_ALL = Number.MAX_SAFE_INTEGER;
846
918
  var SUMMARY_PREFIX = "Summary of earlier conversation: ";
847
919
  function defaultSummarize(client, model) {
@@ -869,7 +941,7 @@ function createHistoryCompactor(deps, options) {
869
941
  throw new Error(`Invalid history compaction keep: ${keep}`);
870
942
  }
871
943
  const summarize = options.summarize ?? defaultSummarize(deps.client, options.model);
872
- const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
944
+ const timeoutMs = options.timeoutMs ?? COMPACTION_TIMEOUT_MS;
873
945
  return {
874
946
  async maybeCompact(store, conversationId) {
875
947
  const turns = await store.load(conversationId, LOAD_ALL);
@@ -910,6 +982,16 @@ function createHistoryCompactor(deps, options) {
910
982
  }
911
983
 
912
984
  // src/channels/pipeline.ts
985
+ function resolveBrainHooks(config, fallback) {
986
+ return {
987
+ answerFn: config.answerFn ?? fallback?.answerFn,
988
+ bucketsFor: config.bucketsFor ?? fallback?.bucketsFor,
989
+ rewriteQuery: config.rewriteQuery ?? fallback?.rewriteQuery,
990
+ rerankContext: config.rerankContext ?? fallback?.rerankContext,
991
+ fallbackFn: config.fallbackFn ?? fallback?.fallbackFn,
992
+ transformReply: config.transformReply ?? fallback?.transformReply
993
+ };
994
+ }
913
995
  var DEFAULT_HISTORY_LIMIT = 20;
914
996
  var DEFAULT_GROUP_RATE_LIMIT = { max: 30, windowMs: 60 * 60 * 1e3 };
915
997
  var DEFAULT_DM_RATE_LIMIT = { max: 20, windowMs: 60 * 60 * 1e3 };
@@ -994,6 +1076,7 @@ function createInboundPipeline(deps, config) {
994
1076
  sender,
995
1077
  rewriteQuery: config.rewriteQuery,
996
1078
  rerankContext: config.rerankContext,
1079
+ fallbackFn: config.fallbackFn,
997
1080
  logger: config.logger
998
1081
  });
999
1082
  const { content: produced } = await answerOnce({
@@ -1129,13 +1212,9 @@ function createWhatsAppInboundHandler(config) {
1129
1212
  { client: config.client, store: config.store, prompts: config.prompts },
1130
1213
  {
1131
1214
  channel: "whatsapp",
1132
- answerFn: config.answerFn,
1133
- bucketsFor: config.bucketsFor,
1134
- rewriteQuery: config.rewriteQuery,
1135
- rerankContext: config.rerankContext,
1136
- transformReply: config.transformReply,
1215
+ ...resolveBrainHooks(config, config.serverConfig),
1137
1216
  model: config.model,
1138
- channelHint: config.channelHint,
1217
+ channelHint: config.channelHint ?? "Channel: WhatsApp.",
1139
1218
  personaResolver: personaResolver ? ({ sender, text }) => personaResolver({ senderPhone: sender, text }) : void 0,
1140
1219
  history: config.history,
1141
1220
  allowedChats,
@@ -1296,6 +1375,7 @@ function createWhatsAppMessageRouter(config) {
1296
1375
  LEASE_WAIT_MS,
1297
1376
  acquireSessionLease,
1298
1377
  canAcquireLease,
1378
+ createTursoWaAuthKV,
1299
1379
  createTursoWaLeaseStore,
1300
1380
  createWhatsAppChannel,
1301
1381
  createWhatsAppImageHandler,
@@ -1311,11 +1391,13 @@ function createWhatsAppMessageRouter(config) {
1311
1391
  jidsMatch,
1312
1392
  loadBaileys,
1313
1393
  messageContext,
1394
+ normalizeWaMediaPayload,
1314
1395
  reconnectDelayMs,
1315
1396
  resolveWaMessage,
1316
1397
  senderNameFor,
1317
1398
  senderPhoneFor,
1318
1399
  shutdownWaSessions,
1319
1400
  stripOwnMentions,
1401
+ useAuthState,
1320
1402
  useTursoAuthState
1321
1403
  });
@@ -67,27 +67,55 @@ function ensureAuthSchema(client) {
67
67
  }
68
68
  return ready;
69
69
  }
70
- async function useTursoAuthState(db, secret, sessionId, runtime) {
71
- await ensureAuthSchema(db);
70
+ function createTursoWaAuthKV(db) {
71
+ return {
72
+ async read(id) {
73
+ await ensureAuthSchema(db);
74
+ const result = await db.execute({
75
+ sql: "SELECT value FROM wa_auth WHERE id = ?",
76
+ args: [id]
77
+ });
78
+ const row = result.rows[0];
79
+ return row ? row.value : null;
80
+ },
81
+ async write(id, value) {
82
+ await ensureAuthSchema(db);
83
+ await db.execute({
84
+ sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
85
+ args: [id, value]
86
+ });
87
+ },
88
+ async remove(id) {
89
+ await ensureAuthSchema(db);
90
+ await db.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [id] });
91
+ },
92
+ // Mirrors isAuthRowForSession - keep the two in sync.
93
+ async clear(sessionId) {
94
+ await ensureAuthSchema(db);
95
+ if (sessionId === "default") {
96
+ await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
97
+ } else {
98
+ await db.execute({
99
+ sql: "DELETE FROM wa_auth WHERE id LIKE ?",
100
+ args: [`s:${sessionId}/%`]
101
+ });
102
+ }
103
+ }
104
+ };
105
+ }
106
+ async function useAuthState(store, secret, sessionId, runtime) {
72
107
  const rowId = (id) => sessionId === "default" ? id : `s:${sessionId}/${id}`;
73
108
  async function read(id) {
74
- const result = await db.execute({
75
- sql: "SELECT value FROM wa_auth WHERE id = ?",
76
- args: [rowId(id)]
77
- });
78
- const row = result.rows[0];
79
- if (!row) return null;
80
- return JSON.parse(await decrypt(row.value, secret), runtime.bufferJSON.reviver);
109
+ const value = await store.read(rowId(id));
110
+ if (value === null) return null;
111
+ return JSON.parse(await decrypt(value, secret), runtime.bufferJSON.reviver);
81
112
  }
82
113
  async function write(id, value) {
83
114
  const payload = await encrypt(JSON.stringify(value, runtime.bufferJSON.replacer), secret);
84
- await db.execute({
85
- sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
86
- args: [rowId(id), payload]
87
- });
115
+ await store.write(rowId(id), payload);
88
116
  }
89
117
  async function remove(id) {
90
- await db.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [rowId(id)] });
118
+ await store.remove(rowId(id));
91
119
  }
92
120
  const creds = await read("creds") ?? runtime.initAuthCreds();
93
121
  return {
@@ -124,18 +152,13 @@ async function useTursoAuthState(db, secret, sessionId, runtime) {
124
152
  }
125
153
  },
126
154
  saveCreds: () => write("creds", creds),
127
- clear: async () => {
128
- if (sessionId === "default") {
129
- await db.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
130
- } else {
131
- await db.execute({
132
- sql: "DELETE FROM wa_auth WHERE id LIKE ?",
133
- args: [`s:${sessionId}/%`]
134
- });
135
- }
136
- }
155
+ // Scoped to THIS session - never nuke a sibling number's pairing.
156
+ clear: () => store.clear(sessionId)
137
157
  };
138
158
  }
159
+ async function useTursoAuthState(db, secret, sessionId, runtime) {
160
+ return useAuthState(createTursoWaAuthKV(db), secret, sessionId, runtime);
161
+ }
139
162
 
140
163
  // src/channels/whatsapp/baileys.ts
141
164
  function wrapMissingBaileysError(cause) {
@@ -198,6 +221,11 @@ function createConsoleLogger(level = "info") {
198
221
  };
199
222
  }
200
223
 
224
+ // src/channels/backoff.ts
225
+ function exponentialBackoffMs(baseMs, maxMs, n) {
226
+ return Math.min(baseMs * 2 ** Math.max(0, Math.min(n, 20)), maxMs);
227
+ }
228
+
201
229
  // src/channels/whatsapp/lease.ts
202
230
  var LEASE_STALE_MS = 9e4;
203
231
  var LEASE_HEARTBEAT_MS = 3e4;
@@ -256,7 +284,7 @@ function createTursoWaLeaseStore(client) {
256
284
  var RECONNECT_DELAY_MS = 5e3;
257
285
  var RECONNECT_MAX_DELAY_MS = 10 * 60 * 1e3;
258
286
  function reconnectDelayMs(failures) {
259
- return Math.min(RECONNECT_DELAY_MS * 2 ** Math.min(failures, 20), RECONNECT_MAX_DELAY_MS);
287
+ return exponentialBackoffMs(RECONNECT_DELAY_MS, RECONNECT_MAX_DELAY_MS, failures);
260
288
  }
261
289
  async function shutdownWaSessions(sessions) {
262
290
  await Promise.all(
@@ -327,9 +355,18 @@ async function acquireSessionLease(sessionId, deps) {
327
355
  function senderNameFor(channelName, sessionId) {
328
356
  return sessionId === "default" ? channelName : `${channelName}:${sessionId}`;
329
357
  }
358
+ function normalizeWaMediaPayload(payload) {
359
+ const media = typeof payload === "string" ? { url: payload } : payload;
360
+ if (!media || typeof media !== "object" || typeof media.url !== "string" || !media.url) {
361
+ throw new TypeError(
362
+ `WhatsApp sendMedia payload must be a URL string or { url, caption? }, got: ${typeof payload}`
363
+ );
364
+ }
365
+ return media;
366
+ }
330
367
  function createWhatsAppChannel(config) {
331
368
  assertStrongSecret(config.sessionSecret, "WhatsApp sessionSecret (e.g. WA_SESSION_SECRET)");
332
- const channelName = "whatsapp";
369
+ const channelName = config.name ?? "whatsapp";
333
370
  const sessionIds = config.sessionIds && config.sessionIds.length > 0 ? config.sessionIds : ["default"];
334
371
  const now = config.now ?? Date.now;
335
372
  const schedule = config.schedule ?? ((fn, ms) => void setTimeout(fn, ms));
@@ -347,8 +384,13 @@ function createWhatsAppChannel(config) {
347
384
  name: channelName,
348
385
  async start(deps) {
349
386
  const log = config.logger ?? deps.logger ?? createConsoleLogger();
350
- const db = deps.db;
351
- const leaseStore = createTursoWaLeaseStore(db);
387
+ if ((!config.leaseStore || !config.authStore) && !deps.db) {
388
+ throw new Error(
389
+ "The WhatsApp channel needs a libsql client for auth state and the session lease: set config.database (config.retriever alone does not open one), or supply both config.leaseStore and config.authStore."
390
+ );
391
+ }
392
+ const leaseStore = config.leaseStore ?? createTursoWaLeaseStore(deps.db);
393
+ const authStore = config.authStore ?? createTursoWaAuthKV(deps.db);
352
394
  senders = deps.senders;
353
395
  await loadBaileys2();
354
396
  async function connect(sessionId) {
@@ -359,8 +401,8 @@ function createWhatsAppChannel(config) {
359
401
  initAuthCreds: baileys.initAuthCreds,
360
402
  appStateSyncKeyFromObject: (value) => baileys.proto.Message.AppStateSyncKeyData.fromObject(value)
361
403
  };
362
- const { state, saveCreds } = await useTursoAuthState(
363
- db,
404
+ const { state, saveCreds } = await useAuthState(
405
+ authStore,
364
406
  config.sessionSecret,
365
407
  sessionId,
366
408
  runtime
@@ -404,6 +446,13 @@ function createWhatsAppChannel(config) {
404
446
  sendText: async (chatId, text) => {
405
447
  await sock.sendMessage(chatId, { text });
406
448
  },
449
+ sendMedia: async (chatId, payload) => {
450
+ const { url, caption } = normalizeWaMediaPayload(payload);
451
+ await sock.sendMessage(
452
+ chatId,
453
+ caption !== void 0 ? { image: { url }, caption } : { image: { url } }
454
+ );
455
+ },
407
456
  sendReaction: async (chatId, messageRef, emoji) => {
408
457
  await sock.sendMessage(chatId, {
409
458
  react: { text: emoji, key: messageRef }
@@ -679,7 +728,8 @@ async function answerOnce({
679
728
  async function applyTransformReply(transformReply, input, logger) {
680
729
  if (!transformReply) return input.text;
681
730
  try {
682
- return await transformReply(input);
731
+ const result = await transformReply(input);
732
+ return typeof result === "string" ? result : null;
683
733
  } catch (error) {
684
734
  logger?.error(
685
735
  `transformReply threw for channel "${input.channel}"; sending the original reply`,
@@ -741,6 +791,7 @@ async function prepareChat({
741
791
  sender,
742
792
  rewriteQuery,
743
793
  rerankContext,
794
+ fallbackFn,
744
795
  logger
745
796
  }) {
746
797
  const lastUserMsg = lastUserMessage(messages);
@@ -757,21 +808,39 @@ async function prepareChat({
757
808
  logger?.error("rewriteQuery threw; falling back to the original query", error);
758
809
  }
759
810
  }
760
- let ctx = await store.query(query, topK, buckets ?? defaultBuckets(mode));
811
+ const resolvedBuckets = buckets ?? defaultBuckets(mode);
812
+ const retrievedChunks = await store.query(query, topK, resolvedBuckets);
813
+ let ctx = retrievedChunks;
761
814
  if (rerankContext) {
762
815
  try {
763
- const reranked = await rerankContext({ query, chunks: ctx });
816
+ const reranked = await rerankContext({ query, chunks: [...ctx] });
764
817
  if (Array.isArray(reranked) && reranked.every((c) => typeof c === "string")) ctx = reranked;
765
818
  } catch (error) {
766
819
  logger?.error("rerankContext threw; falling back to the original chunks", error);
767
820
  }
768
821
  }
822
+ let fallback;
823
+ if (ctx.length === 0 && fallbackFn) {
824
+ try {
825
+ const guidance = await fallbackFn({
826
+ query,
827
+ mode,
828
+ buckets: resolvedBuckets,
829
+ sender,
830
+ retrievedChunks
831
+ });
832
+ if (typeof guidance === "string" && guidance.trim()) fallback = guidance.trim();
833
+ } catch (error) {
834
+ logger?.error("fallbackFn threw; proceeding without fallback guidance", error);
835
+ }
836
+ }
769
837
  const persona = personaLayer?.trim() || (mode === "private" ? prompts.privatePersona : prompts.publicPersona);
770
838
  const hint = channelHint?.trim();
771
839
  const system = [
772
840
  prompts.baseSystemRules,
773
841
  persona,
774
842
  ...hint ? [hint] : [],
843
+ ...fallback ? [fallback] : [],
775
844
  `${label}:
776
845
  ${ctx.join("\n\n")}`
777
846
  ].join("\n\n");
@@ -779,7 +848,7 @@ ${ctx.join("\n\n")}`
779
848
  }
780
849
 
781
850
  // src/history/compaction.ts
782
- var DEFAULT_TIMEOUT_MS = 8e3;
851
+ var COMPACTION_TIMEOUT_MS = 8e3;
783
852
  var LOAD_ALL = Number.MAX_SAFE_INTEGER;
784
853
  var SUMMARY_PREFIX = "Summary of earlier conversation: ";
785
854
  function defaultSummarize(client, model) {
@@ -807,7 +876,7 @@ function createHistoryCompactor(deps, options) {
807
876
  throw new Error(`Invalid history compaction keep: ${keep}`);
808
877
  }
809
878
  const summarize = options.summarize ?? defaultSummarize(deps.client, options.model);
810
- const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
879
+ const timeoutMs = options.timeoutMs ?? COMPACTION_TIMEOUT_MS;
811
880
  return {
812
881
  async maybeCompact(store, conversationId) {
813
882
  const turns = await store.load(conversationId, LOAD_ALL);
@@ -848,6 +917,16 @@ function createHistoryCompactor(deps, options) {
848
917
  }
849
918
 
850
919
  // src/channels/pipeline.ts
920
+ function resolveBrainHooks(config, fallback) {
921
+ return {
922
+ answerFn: config.answerFn ?? fallback?.answerFn,
923
+ bucketsFor: config.bucketsFor ?? fallback?.bucketsFor,
924
+ rewriteQuery: config.rewriteQuery ?? fallback?.rewriteQuery,
925
+ rerankContext: config.rerankContext ?? fallback?.rerankContext,
926
+ fallbackFn: config.fallbackFn ?? fallback?.fallbackFn,
927
+ transformReply: config.transformReply ?? fallback?.transformReply
928
+ };
929
+ }
851
930
  var DEFAULT_HISTORY_LIMIT = 20;
852
931
  var DEFAULT_GROUP_RATE_LIMIT = { max: 30, windowMs: 60 * 60 * 1e3 };
853
932
  var DEFAULT_DM_RATE_LIMIT = { max: 20, windowMs: 60 * 60 * 1e3 };
@@ -932,6 +1011,7 @@ function createInboundPipeline(deps, config) {
932
1011
  sender,
933
1012
  rewriteQuery: config.rewriteQuery,
934
1013
  rerankContext: config.rerankContext,
1014
+ fallbackFn: config.fallbackFn,
935
1015
  logger: config.logger
936
1016
  });
937
1017
  const { content: produced } = await answerOnce({
@@ -1067,13 +1147,9 @@ function createWhatsAppInboundHandler(config) {
1067
1147
  { client: config.client, store: config.store, prompts: config.prompts },
1068
1148
  {
1069
1149
  channel: "whatsapp",
1070
- answerFn: config.answerFn,
1071
- bucketsFor: config.bucketsFor,
1072
- rewriteQuery: config.rewriteQuery,
1073
- rerankContext: config.rerankContext,
1074
- transformReply: config.transformReply,
1150
+ ...resolveBrainHooks(config, config.serverConfig),
1075
1151
  model: config.model,
1076
- channelHint: config.channelHint,
1152
+ channelHint: config.channelHint ?? "Channel: WhatsApp.",
1077
1153
  personaResolver: personaResolver ? ({ sender, text }) => personaResolver({ senderPhone: sender, text }) : void 0,
1078
1154
  history: config.history,
1079
1155
  allowedChats,
@@ -1233,6 +1309,7 @@ export {
1233
1309
  LEASE_WAIT_MS,
1234
1310
  acquireSessionLease,
1235
1311
  canAcquireLease,
1312
+ createTursoWaAuthKV,
1236
1313
  createTursoWaLeaseStore,
1237
1314
  createWhatsAppChannel,
1238
1315
  createWhatsAppImageHandler,
@@ -1248,11 +1325,13 @@ export {
1248
1325
  jidsMatch,
1249
1326
  loadBaileys,
1250
1327
  messageContext,
1328
+ normalizeWaMediaPayload,
1251
1329
  reconnectDelayMs,
1252
1330
  resolveWaMessage,
1253
1331
  senderNameFor,
1254
1332
  senderPhoneFor,
1255
1333
  shutdownWaSessions,
1256
1334
  stripOwnMentions,
1335
+ useAuthState,
1257
1336
  useTursoAuthState
1258
1337
  };
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/pairing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/pairing.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/client/src/Chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,IAAI;IACf,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,MAAM,EAAE,UAAU,EA4B7B;IAED,OAAO,CAAC,MAAM;IAqBd,OAAO,CAAC,oBAAoB;YA+Cd,UAAU;IAkExB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,KAAK,IAAI,IAAI,CAGZ;IAED;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE,CAE3B;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAEd;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;CAGjB"}
1
+ {"version":3,"file":"Chat.d.ts","sourceRoot":"","sources":["../../../src/client/src/Chat.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvD,qBAAa,IAAI;IACf,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAqB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAC,CAAa;IAE7B,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAqB;IAEvC,YAAY,MAAM,EAAE,UAAU,EA0B7B;IAED,OAAO,CAAC,MAAM;IAoBd,OAAO,CAAC,oBAAoB;YA8Cd,UAAU;IA4DxB,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,KAAK,IAAI,IAAI,CAGZ;IAED;;OAEG;IACH,WAAW,IAAI,WAAW,EAAE,CAE3B;IAED;;OAEG;IACH,OAAO,IAAI,IAAI,CAEd;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;CAGjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"ChatButton.d.ts","sourceRoot":"","sources":["../../../src/client/src/ChatButton.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,MAAM,EAAE,gBAAgB,EASnC;IAED,OAAO,CAAC,MAAM;IAsBd,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,MAAM;IAQd,IAAI,IAAI,IAAI,CAgDX;IAED,KAAK,IAAI,IAAI,CAcZ;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,IAAI,IAAI,CAId;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CAElB;CACF"}
1
+ {"version":3,"file":"ChatButton.d.ts","sourceRoot":"","sources":["../../../src/client/src/ChatButton.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEhD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,aAAa,CAAqB;IAC1C,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,IAAI,CAAqB;IACjC,OAAO,CAAC,MAAM,CAAS;IAEvB,YAAY,MAAM,EAAE,gBAAgB,EASnC;IAED,OAAO,CAAC,MAAM;IAkBd,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,MAAM;IAQd,IAAI,IAAI,IAAI,CA+CX;IAED,KAAK,IAAI,IAAI,CAcZ;IAED;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,IAAI,IAAI,CAId;IAED;;OAEG;IACH,QAAQ,IAAI,OAAO,CAElB;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/client/src/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,OAAO,CAAC;YACxB,IAAI,EAAE,OAAO,IAAI,CAAC;YAClB,UAAU,EAAE,OAAO,UAAU,CAAC;SAC/B,CAAC;KACH;CACF;AAWD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../../src/client/src/browser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,OAAO,EAAE;YACP,OAAO,EAAE,OAAO,OAAO,CAAC;YACxB,IAAI,EAAE,OAAO,IAAI,CAAC;YAClB,UAAU,EAAE,OAAO,UAAU,CAAC;SAC/B,CAAC;KACH;CACF;AAYD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC"}