@diegoaltoworks/chatter 0.61.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 +55 -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 +25 -6
  15. package/dist/channels/matrix/api.d.ts.map +1 -1
  16. package/dist/channels/matrix/channel.d.ts +4 -56
  17. package/dist/channels/matrix/channel.d.ts.map +1 -1
  18. package/dist/channels/matrix/handler.d.ts +16 -9
  19. package/dist/channels/matrix/handler.d.ts.map +1 -1
  20. package/dist/channels/matrix/index.d.ts +2 -2
  21. package/dist/channels/matrix/index.d.ts.map +1 -1
  22. package/dist/channels/matrix/index.js +196 -40
  23. package/dist/channels/matrix/index.mjs +189 -39
  24. package/dist/channels/matrix/sync.d.ts +4 -1
  25. package/dist/channels/matrix/sync.d.ts.map +1 -1
  26. package/dist/channels/matrix/updates.d.ts +39 -10
  27. package/dist/channels/matrix/updates.d.ts.map +1 -1
  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 +4 -1
@@ -1,16 +1,18 @@
1
1
  /**
2
- * Turso/libsql-backed Baileys auth state, encrypted at rest.
2
+ * Baileys auth state, encrypted at rest, over an injectable {@link WaAuthKV}.
3
3
  *
4
4
  * Same contract as Baileys' own `useMultiFileAuthState`, but rows in a
5
- * `wa_auth` table instead of files, AES-GCM encrypted (see `crypto.ts`) so
6
- * session material — which grants full account access — is never stored
7
- * readable.
5
+ * key-value store instead of files, AES-GCM encrypted (see `crypto.ts`) so
6
+ * session material - which grants full account access - is never stored
7
+ * readable. The store itself only ever sees ciphertext: encryption lives in
8
+ * this module, above the store, so a custom `WaAuthKV` cannot accidentally
9
+ * persist plaintext session material.
8
10
  *
9
11
  * Only Baileys *types* are imported here (erased at compile time, so they add
10
12
  * no runtime dependency); the few Baileys runtime values this module needs
11
13
  * (`BufferJSON`, `initAuthCreds`, the app-state-sync-key constructor) are
12
14
  * passed in by the caller, which already holds them from the dynamic import
13
- * in `baileys.ts` — see that module for why the import is dynamic.
15
+ * in `baileys.ts` - see that module for why the import is dynamic.
14
16
  */
15
17
  import type { Client } from "@libsql/client";
16
18
  import type { AuthenticationCreds, AuthenticationState, SignalDataTypeMap } from "@whiskeysockets/baileys";
@@ -30,10 +32,39 @@ export interface AuthStateRuntime {
30
32
  appStateSyncKeyFromObject: (value: Record<string, unknown>) => SignalDataTypeMap["app-state-sync-key"];
31
33
  }
32
34
  /**
33
- * Sessions share the `wa_auth` table, namespaced by row-id prefix. The
34
- * "default" session uses UNPREFIXED ids — exactly a single-session layout —
35
- * so an existing default session needs no migration when multi-session
36
- * support is introduced.
35
+ * Raw storage for Baileys auth rows, keyed by an already session-scoped
36
+ * `id` (see `useAuthState`'s `rowId`). Values are opaque ciphertext strings -
37
+ * this layer has no encryption knowledge, only persistence.
37
38
  */
39
+ export interface WaAuthKV {
40
+ read(id: string): Promise<string | null>;
41
+ write(id: string, value: string): Promise<void>;
42
+ remove(id: string): Promise<void>;
43
+ /**
44
+ * Deletes every row belonging to `sessionId` and no other session's -
45
+ * use {@link isAuthRowForSession} to decide which stored ids qualify
46
+ * rather than re-deriving the "default" session's unprefixed special case
47
+ * by hand; getting this wrong logs out a sibling number.
48
+ */
49
+ clear(sessionId: string): Promise<void>;
50
+ }
51
+ /**
52
+ * Pure: does row id `id` (as stored - already passed through `rowId`) belong
53
+ * to `sessionId`? Mirrors `useAuthState`'s `rowId` and the SQL in
54
+ * `createTursoWaAuthKV`'s `clear` - keep the three in sync. The "default"
55
+ * session's rows are UNPREFIXED (see `useAuthState`), so its scope is
56
+ * everything *not* claimed by a named session's `s:<sessionId>/` prefix.
57
+ */
58
+ export declare function isAuthRowForSession(id: string, sessionId: string): boolean;
59
+ /** The shipped `WaAuthKV`: a `wa_auth` table in the same libsql database the rest of chatter uses. */
60
+ export declare function createTursoWaAuthKV(db: Client): WaAuthKV;
61
+ /**
62
+ * Sessions share one `WaAuthKV`, namespaced by row-id prefix. The "default"
63
+ * session uses UNPREFIXED ids - exactly a single-session layout - so an
64
+ * existing default session needs no migration when multi-session support is
65
+ * introduced.
66
+ */
67
+ export declare function useAuthState(store: WaAuthKV, secret: string, sessionId: string, runtime: AuthStateRuntime): Promise<TursoAuthStateResult>;
68
+ /** Convenience wrapper over `useAuthState` for the shipped Turso-backed `WaAuthKV`. */
38
69
  export declare function useTursoAuthState(db: Client, secret: string, sessionId: string, runtime: AuthStateRuntime): Promise<TursoAuthStateResult>;
39
70
  //# sourceMappingURL=authState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authState.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/authState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE;QACV,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;QACnD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;KACnD,CAAC;IACF,aAAa,EAAE,MAAM,mBAAmB,CAAC;IACzC,yBAAyB,EAAE,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;CAC9C;AAiBD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CA6E/B"}
1
+ {"version":3,"file":"authState.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/authState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,mBAAmB,CAAC;IAC3B,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,kDAAkD;IAClD,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,qFAAqF;AACrF,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE;QACV,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;QACnD,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;KACnD,CAAC;IACF,aAAa,EAAE,MAAM,mBAAmB,CAAC;IACzC,yBAAyB,EAAE,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC3B,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;CAC9C;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC;;;;;OAKG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAG1E;AAiBD,sGAAsG;AACtG,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAmCxD;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CA2D/B;AAED,uFAAuF;AACvF,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * WhatsApp web-client transport: a {@link Channel} that runs one Baileys
3
3
  * socket per configured session id (one WhatsApp number each), auth state
4
- * encrypted in the host's own database (`deps.db` — no second connection
5
- * opened), and a deploy lease so two overlapping instances can never hold the
6
- * same session's socket at once (WhatsApp treats a second connection as a
7
- * takeover and logs the first one out).
4
+ * encrypted above an injectable {@link WaAuthKV} (defaults to a table in the
5
+ * host's own database, `deps.db` - no second connection opened), and a
6
+ * deploy lease behind an injectable `WaLeaseStore` so two overlapping
7
+ * instances can never hold the same session's socket at once (WhatsApp
8
+ * treats a second connection as a takeover and logs the first one out).
8
9
  *
9
10
  * Message INTERPRETATION — mention/reply detection, allowlists, loop guards —
10
11
  * is deliberately not this module's job; it hands every raw inbound message
@@ -18,6 +19,7 @@
18
19
  import type { WAMessage, WASocket } from "@whiskeysockets/baileys";
19
20
  import { type Logger } from "../../core/logger";
20
21
  import type { Channel } from "../index";
22
+ import type { WaAuthKV } from "./authState";
21
23
  import { type Baileys } from "./baileys";
22
24
  import { type WaLeaseStore } from "./lease";
23
25
  /** Exponential backoff: 5s, 10s, 20s ... capped at 10 minutes. Hammering
@@ -31,6 +33,8 @@ export interface WhatsAppMessageEvent {
31
33
  export interface WhatsAppChannelConfig {
32
34
  /** Passphrase that encrypts auth state at rest (AES-256-GCM key material). Keep it stable across restarts and deploys — losing it means re-pairing. */
33
35
  sessionSecret: string;
36
+ /** Channel and sender-registry name prefix (see {@link senderNameFor}). Override to run more than one WhatsApp channel in one process. @default "whatsapp" */
37
+ name?: string;
34
38
  /** One Baileys connection per id, each a separate WhatsApp number. Defaults to `["default"]`, whose auth rows are unprefixed (a pre-multi-session deployment needs no migration). */
35
39
  sessionIds?: string[];
36
40
  /**
@@ -52,6 +56,10 @@ export interface WhatsAppChannelConfig {
52
56
  waitMs?: number;
53
57
  /** Logger for connection/lease lifecycle events. Default: a console logger writing to stderr. */
54
58
  logger?: Logger;
59
+ /** Deploy-overlap lease. Defaults to a `wa_lease` table in `deps.db`; inject your own to run this channel without a libsql database (see docs/patterns/adding-a-store.md). */
60
+ leaseStore?: WaLeaseStore;
61
+ /** Baileys auth-state persistence, encrypted above this seam. Defaults to a `wa_auth` table in `deps.db`; inject your own to run this channel without a libsql database. */
62
+ authStore?: WaAuthKV;
55
63
  }
56
64
  /** A live, leased session: what `stop()` (or losing the lease) must tear down. */
57
65
  export interface WaSessionHandle {
@@ -95,5 +103,18 @@ export interface LeaseGatedConnectDeps {
95
103
  export declare function acquireSessionLease(sessionId: string, deps: LeaseGatedConnectDeps): Promise<void>;
96
104
  /** Sender-registry name for a session — the default session stays unprefixed so single-number deployments see a plain `"whatsapp"` name. */
97
105
  export declare function senderNameFor(channelName: string, sessionId: string): string;
106
+ /** `ChannelSender.sendMedia`'s payload shape for this channel: a URL Baileys fetches itself, matching `./images`' own `{ image: { url } }` usage. A bare string is shorthand for the URL, the same convention `./telegram` and `./matrix` use. */
107
+ export interface WhatsAppMediaPayload {
108
+ url: string;
109
+ caption?: string;
110
+ }
111
+ /**
112
+ * Turns the registry's opaque `sendMedia` payload into what `sock.sendMessage`
113
+ * needs. `ChannelSender.sendMedia` types its payload as `unknown` (payload
114
+ * shapes are transport-defined), so this is where that unknown is checked:
115
+ * a malformed payload throws here, which the sender registry reports as
116
+ * `false` rather than sending Baileys a `{ image: { url: undefined } }`.
117
+ */
118
+ export declare function normalizeWaMediaPayload(payload: unknown): WhatsAppMediaPayload;
98
119
  export declare function createWhatsAppChannel(config: WhatsAppChannelConfig): Channel;
99
120
  //# sourceMappingURL=channel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/channel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/channel.ts"],"names":[],"mappings":"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"}
@@ -6,12 +6,12 @@
6
6
  * interpretation.
7
7
  *
8
8
  * Message-shape parsing (text/caption extraction, contextInfo mentions and
9
- * quoted-reply resolution) is genericized from the reference implementation:
10
- * text AND contextInfo live in a DIFFERENT place per message shape — plain
11
- * text carries both on `extendedTextMessage`, but a photo/video/document
12
- * carries its caption on its own message type and its contextInfo there too.
13
- * Missing that meant mentions in photo captions were invisible and group
14
- * photo requests were silently ignored.
9
+ * quoted-reply resolution) accounts for a Baileys quirk: text AND contextInfo
10
+ * live in a DIFFERENT place per message shape - plain text carries both on
11
+ * `extendedTextMessage`, but a photo/video/document carries its caption on
12
+ * its own message type and its contextInfo there too. Missing that meant
13
+ * mentions in photo captions were invisible and group photo requests were
14
+ * silently ignored.
15
15
  *
16
16
  * `createWhatsAppInboundHandler` needs `ServerDependencies`
17
17
  * (`client`/`store`/`prompts`), which only exists once `createServer` builds
@@ -34,11 +34,10 @@
34
34
  * client: deps.client,
35
35
  * store: deps.store,
36
36
  * prompts: deps.prompts,
37
- * answerFn: deps.config.answerFn,
38
- * bucketsFor: deps.config.bucketsFor,
39
- * rewriteQuery: deps.config.rewriteQuery,
40
- * rerankContext: deps.config.rerankContext,
41
- * transformReply: deps.config.transformReply,
37
+ * // Falls back to deps.config.{answerFn,bucketsFor,rewriteQuery,
38
+ * // rerankContext,fallbackFn,transformReply} for whichever of those
39
+ * // this config doesn't set itself.
40
+ * serverConfig: deps.config,
42
41
  * registry: new Map(),
43
42
  * logger: deps.logger,
44
43
  * });
@@ -48,14 +47,12 @@
48
47
  */
49
48
  import type { WAMessage, WASocket } from "@whiskeysockets/baileys";
50
49
  import type OpenAI from "openai";
51
- import type { AnswerFn, TransformReply } from "../../core/answer";
52
- import type { BucketsFor } from "../../core/buckets";
53
50
  import { type Logger } from "../../core/logger";
54
- import type { RerankContext, RewriteQuery } from "../../core/pipeline";
55
51
  import type { PromptLoader } from "../../core/prompts";
56
- import type { VectorStore } from "../../core/retrieval";
52
+ import type { Retriever } from "../../core/retrieval";
57
53
  import type { HistoryCompactionOptions } from "../../history/compaction";
58
54
  import type { HistoryStore } from "../../history/types";
55
+ import type { BrainHooks } from "../../types";
59
56
  import { type ChannelMessage, type SessionIdentityRegistry } from "../gates";
60
57
  import type { WhatsAppMessageEvent } from "./channel";
61
58
  import type { WhatsAppImageHandler } from "./images";
@@ -127,18 +124,19 @@ export interface ResolvedWaMessage {
127
124
  * multiplies this work.
128
125
  */
129
126
  export declare function resolveWaMessage(event: WhatsAppMessageEvent, registry: SessionIdentityRegistry): ResolvedWaMessage;
130
- export interface WhatsAppInboundConfig {
127
+ export interface WhatsAppInboundConfig extends BrainHooks {
131
128
  client: OpenAI;
132
- store: VectorStore;
129
+ store: Retriever;
133
130
  prompts: PromptLoader;
134
- answerFn?: AnswerFn;
135
- bucketsFor?: BucketsFor;
136
- /** Rewrites the retrieval query before it reaches the vector store — see `ChatterConfig.rewriteQuery`. */
137
- rewriteQuery?: RewriteQuery;
138
- /** Post-processes retrieved chunks before they're folded into the prompt — see `ChatterConfig.rerankContext`. */
139
- rerankContext?: RerankContext;
140
- /** Modifies or vetoes the produced reply before delivery — see `ChatterConfig.transformReply`. */
141
- transformReply?: TransformReply;
131
+ /**
132
+ * Fallback source for the brain hooks above, each consulted only when this
133
+ * config's own field is unset. Pass `deps.config` from the `customRoutes`
134
+ * callback (see the module docstring) so this handler automatically
135
+ * honours a server-level hook, the same precedence `./telegram` and
136
+ * `./matrix` apply internally via `resolveBrainHooks`. Unset: only this
137
+ * config's own fields count.
138
+ */
139
+ serverConfig?: BrainHooks;
142
140
  model?: string;
143
141
  /**
144
142
  * Own identities per session — share ONE registry across every session
@@ -1 +1 @@
1
- {"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/inbound.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inbound.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/inbound.ts"],"names":[],"mappings":"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"}
@@ -23,11 +23,11 @@
23
23
  *
24
24
  * @packageDocumentation
25
25
  */
26
- export type { AuthStateRuntime, TursoAuthStateResult } from "./authState";
27
- export { useTursoAuthState } from "./authState";
26
+ export type { AuthStateRuntime, TursoAuthStateResult, WaAuthKV } from "./authState";
27
+ export { createTursoWaAuthKV, useAuthState, useTursoAuthState } from "./authState";
28
28
  export type { Baileys } from "./baileys";
29
29
  export { loadBaileys } from "./baileys";
30
- export { acquireSessionLease, createWhatsAppChannel, type LeaseGatedConnectDeps, reconnectDelayMs, senderNameFor, shutdownWaSessions, type WaSessionHandle, type WhatsAppChannelConfig, type WhatsAppMessageEvent, } from "./channel";
30
+ export { acquireSessionLease, createWhatsAppChannel, type LeaseGatedConnectDeps, normalizeWaMediaPayload, reconnectDelayMs, senderNameFor, shutdownWaSessions, type WaSessionHandle, type WhatsAppChannelConfig, type WhatsAppMediaPayload, type WhatsAppMessageEvent, } from "./channel";
31
31
  export { decrypt, encrypt } from "./crypto";
32
32
  export { createWhatsAppImageHandler, type DrawRequestDetectorConfig, drawSubject, isDrawRequest, type WhatsAppImageHandler, type WhatsAppImageHandlerDeps, type WhatsAppImageRequestContext, type WhatsAppImageStrings, } from "./images";
33
33
  export { createWhatsAppInboundHandler, extractText, isGroupJid, jidsMatch, jidToPhoneNumber, messageContext, type ResolvedWaMessage, resolveWaMessage, senderPhoneFor, stripOwnMentions, type WaMessageContext, type WhatsAppInboundConfig, } from "./inbound";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,KAAK,yBAAyB,EAC9B,WAAW,EACX,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,4BAA4B,EAC5B,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,2BAA2B,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,GACjC,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/whatsapp/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnF,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,uBAAuB,EACvB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,0BAA0B,EAC1B,KAAK,yBAAyB,EAC9B,WAAW,EACX,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,oBAAoB,GAC1B,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,4BAA4B,EAC5B,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,GAC3B,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,2BAA2B,EAC3B,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,GACjC,MAAM,UAAU,CAAC"}
@@ -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
  });