@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.
- package/README.md +55 -17
- package/dist/auth/secretStrength.d.ts +1 -1
- package/dist/auth/secretStrength.d.ts.map +1 -1
- package/dist/bin/create-apikey.js +45 -28
- package/dist/bin/wa-pair.js +113 -46
- package/dist/channels/backoff.d.ts +10 -0
- package/dist/channels/backoff.d.ts.map +1 -0
- package/dist/channels/gates.d.ts +15 -8
- package/dist/channels/gates.d.ts.map +1 -1
- package/dist/channels/index.d.ts +1 -1
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +38 -5
- package/dist/channels/index.mjs +37 -5
- package/dist/channels/matrix/api.d.ts +25 -6
- package/dist/channels/matrix/api.d.ts.map +1 -1
- package/dist/channels/matrix/channel.d.ts +4 -56
- package/dist/channels/matrix/channel.d.ts.map +1 -1
- package/dist/channels/matrix/handler.d.ts +16 -9
- package/dist/channels/matrix/handler.d.ts.map +1 -1
- package/dist/channels/matrix/index.d.ts +2 -2
- package/dist/channels/matrix/index.d.ts.map +1 -1
- package/dist/channels/matrix/index.js +196 -40
- package/dist/channels/matrix/index.mjs +189 -39
- package/dist/channels/matrix/sync.d.ts +4 -1
- package/dist/channels/matrix/sync.d.ts.map +1 -1
- package/dist/channels/matrix/updates.d.ts +39 -10
- package/dist/channels/matrix/updates.d.ts.map +1 -1
- package/dist/channels/pipeline.d.ts +14 -14
- package/dist/channels/pipeline.d.ts.map +1 -1
- package/dist/channels/polling.d.ts +67 -0
- package/dist/channels/polling.d.ts.map +1 -0
- package/dist/channels/telegram/channel.d.ts +2 -56
- package/dist/channels/telegram/channel.d.ts.map +1 -1
- package/dist/channels/telegram/index.js +53 -23
- package/dist/channels/telegram/index.mjs +53 -23
- package/dist/channels/telegram/poll.d.ts +5 -1
- package/dist/channels/telegram/poll.d.ts.map +1 -1
- package/dist/channels/telegram/webhook.d.ts +2 -10
- package/dist/channels/telegram/webhook.d.ts.map +1 -1
- package/dist/channels/whatsapp/authState.d.ts +40 -9
- package/dist/channels/whatsapp/authState.d.ts.map +1 -1
- package/dist/channels/whatsapp/channel.d.ts +25 -4
- package/dist/channels/whatsapp/channel.d.ts.map +1 -1
- package/dist/channels/whatsapp/inbound.d.ts +23 -25
- package/dist/channels/whatsapp/inbound.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.d.ts +3 -3
- package/dist/channels/whatsapp/index.d.ts.map +1 -1
- package/dist/channels/whatsapp/index.js +123 -41
- package/dist/channels/whatsapp/index.mjs +120 -41
- package/dist/channels/whatsapp/pairing.d.ts.map +1 -1
- package/dist/client/src/Chat.d.ts.map +1 -1
- package/dist/client/src/ChatButton.d.ts.map +1 -1
- package/dist/client/src/browser.d.ts.map +1 -1
- package/dist/core/answer.d.ts +8 -0
- package/dist/core/answer.d.ts.map +1 -1
- package/dist/core/buildLock.d.ts +52 -0
- package/dist/core/buildLock.d.ts.map +1 -0
- package/dist/core/pipeline.d.ts +42 -5
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/prompts.d.ts +2 -0
- package/dist/core/prompts.d.ts.map +1 -1
- package/dist/core/retrieval.d.ts +100 -25
- package/dist/core/retrieval.d.ts.map +1 -1
- package/dist/core/session.d.ts +8 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/flows/index.d.ts +1 -1
- package/dist/flows/index.d.ts.map +1 -1
- package/dist/flows/index.js +8 -6
- package/dist/flows/index.mjs +7 -6
- package/dist/flows/intent.d.ts +1 -1
- package/dist/flows/intent.d.ts.map +1 -1
- package/dist/flows/loader.d.ts +1 -2
- package/dist/flows/loader.d.ts.map +1 -1
- package/dist/flows/params.d.ts +1 -1
- package/dist/flows/params.d.ts.map +1 -1
- package/dist/flows/session.d.ts +4 -2
- package/dist/flows/session.d.ts.map +1 -1
- package/dist/flows/types.d.ts +2 -3
- package/dist/flows/types.d.ts.map +1 -1
- package/dist/history/index.d.ts +1 -1
- package/dist/history/index.d.ts.map +1 -1
- package/dist/history/index.js +6 -3
- package/dist/history/index.mjs +5 -3
- package/dist/history/tursoStore.d.ts +6 -4
- package/dist/history/tursoStore.d.ts.map +1 -1
- package/dist/images/index.js +2 -2
- package/dist/images/index.mjs +2 -2
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +596 -295
- package/dist/index.mjs +595 -295
- package/dist/mcp-server/index.d.ts +5 -5
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/logger.d.ts +12 -2
- package/dist/mcp-server/logger.d.ts.map +1 -1
- package/dist/mcp-server/rate-limiter.d.ts +10 -3
- package/dist/mcp-server/rate-limiter.d.ts.map +1 -1
- package/dist/mcp-server/types.d.ts +20 -5
- package/dist/mcp-server/types.d.ts.map +1 -1
- package/dist/mcp-server.js +479 -244
- package/dist/mcp-server.mjs +485 -244
- package/dist/middleware/apiKey.d.ts +10 -0
- package/dist/middleware/apiKey.d.ts.map +1 -0
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/cors.d.ts.map +1 -1
- package/dist/middleware/ratelimit.d.ts.map +1 -1
- package/dist/middleware/referrer.d.ts.map +1 -1
- package/dist/middleware/session.d.ts +1 -1
- package/dist/middleware/session.d.ts.map +1 -1
- package/dist/routes/demo.d.ts.map +1 -1
- package/dist/routes/openai.d.ts.map +1 -1
- package/dist/routes/private.d.ts.map +1 -1
- package/dist/routes/public.d.ts.map +1 -1
- package/dist/scheduler/index.js +1 -1
- package/dist/scheduler/index.mjs +1 -1
- package/dist/scheduler/scheduler.d.ts +9 -1
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +491 -268
- package/dist/server.mjs +497 -268
- package/dist/shortener.d.ts +5 -4
- package/dist/shortener.d.ts.map +1 -1
- package/dist/types.d.ts +129 -75
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://github.com/diegoaltoworks/chatter/actions/workflows/ci.yml)
|
|
10
10
|
[](https://github.com/diegoaltoworks/chatter-demo)
|
|
11
11
|
|
|
12
|
-
[Features](#features)
|
|
12
|
+
[Features](#features) - [Quick Start](#quick-start) - [Documentation](#documentation) - [Demo](#demo)
|
|
13
13
|
|
|
14
14
|
</div>
|
|
15
15
|
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
- 🤖 **RAG-Powered**: Retrieval-Augmented Generation using OpenAI embeddings and Turso vector database
|
|
19
19
|
- 🎨 **Customizable Widgets**: Pre-built chat components (ChatBot, Chat, ChatButton) with full styling control
|
|
20
20
|
- 📝 **Markdown Rendering**: Assistant replies render Markdown (headings, lists, code blocks, links) safely with HTML escaping
|
|
21
|
-
- 🔌 **OpenAI-Compatible API**: `POST /v1/chat/completions` (streaming + non-streaming) so any chat UI or SDK
|
|
22
|
-
- 🎛️ **Headless Mode**: Run the server as a pure API with `features: { headless: true }`
|
|
21
|
+
- 🔌 **OpenAI-Compatible API**: `POST /v1/chat/completions` (streaming + non-streaming) so any chat UI or SDK - [Deep Chat](https://deepchat.dev), [assistant-ui](https://www.assistant-ui.com), the OpenAI SDKs - can be the front end ([guide](./docs/integrations.md))
|
|
22
|
+
- 🎛️ **Headless Mode**: Run the server as a pure API with `features: { headless: true }` - no built-in widget or demo pages
|
|
23
23
|
- 🔐 **Built-in API Key Management**: JWT-based API keys with CLI tool for easy creation
|
|
24
24
|
- 🔑 **Authentication Ready**: Built-in support for JWT, Clerk, and custom auth providers
|
|
25
25
|
- 📱 **Mobile Optimized**: Responsive design with iOS/Android-specific fixes
|
|
26
26
|
- ⚡ **High Performance**: Built on Hono with streaming support
|
|
27
27
|
- 🛡️ **Security First**: Rate limiting, CORS, referrer checking, and input guardrails
|
|
28
28
|
- 💸 **Usage Metering**: Per-caller and global daily caps for paid features, multi-instance safe, via `@diegoaltoworks/chatter/usage` ([guide](./docs/usage.md))
|
|
29
|
-
- 💬 **Channels**: Built-in WhatsApp, Telegram and Matrix transports plus a Channel SPI for plugging in any other one
|
|
29
|
+
- 💬 **Channels**: Built-in WhatsApp, Telegram and Matrix transports plus a Channel SPI for plugging in any other one - allowlist/mute gates, reply rate-limiting, and a shared inbound pipeline every channel reuses ([WhatsApp](./docs/channels.md), [Telegram](./docs/telegram.md), [Matrix](./docs/matrix.md), [build your own](./docs/build-a-channel.md))
|
|
30
30
|
- 🧩 **Flows**: Multi-turn, schema-driven slot-filling for structured conversations, with hybrid keyword + LLM intent matching ([guide](./docs/flows.md))
|
|
31
31
|
- 🖼️ **Images**: On-demand generation and editing with cache-before-spend ordering and optional Cloudinary upload ([guide](./docs/images.md))
|
|
32
32
|
- 🎭 **Personas**: Windowed, per-contact prompt layers and named greetings from a JSON registry ([guide](./docs/personas.md))
|
|
@@ -56,26 +56,26 @@ const app = await createServer({
|
|
|
56
56
|
Bun.serve({ port: 8181, fetch: app.fetch });
|
|
57
57
|
|
|
58
58
|
# Create API key for clients
|
|
59
|
-
npx chatter
|
|
59
|
+
npx chatter --name "my-app" --expires-in 365d
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
**Requirements:** OpenAI API key, Turso database, and Bun >= 1.2 or Node >= 24. See [Requirements Guide](./docs/requirements.md) for setup instructions.
|
|
63
63
|
|
|
64
64
|
### Runtime
|
|
65
65
|
|
|
66
|
-
The package runs on **Bun or Node** (>= 24
|
|
66
|
+
The package runs on **Bun or Node** (>= 24 - it is built and published for both,
|
|
67
67
|
and CI loads the built bundles under each). Two things differ:
|
|
68
68
|
|
|
69
|
-
- **Serving the app**
|
|
69
|
+
- **Serving the app** - `Bun.serve({ port: 8181, fetch: app.fetch })` on Bun;
|
|
70
70
|
`serve({ port: 8181, fetch: app.fetch })` from [`@hono/node-server`](https://github.com/honojs/node-server) on Node.
|
|
71
|
-
- **Static assets**
|
|
71
|
+
- **Static assets** - serving the widget files (`/chatter.js`, `/chatter.css`)
|
|
72
72
|
and a `publicDir` needs a runtime adapter, picked automatically. On Node that
|
|
73
73
|
adapter is `@hono/node-server`, an optional peer dependency: without it,
|
|
74
74
|
`/chatter.js` and `/chatter.css` 404 and the server logs an actionable
|
|
75
75
|
error naming the missing package. Install it, or run with
|
|
76
76
|
`features: { headless: true }` if the server should serve no files.
|
|
77
77
|
|
|
78
|
-
Everything else
|
|
78
|
+
Everything else - the chat pipeline, RAG, channels, the OpenAI-compatible API -
|
|
79
79
|
is runtime-neutral. Development and the quality gates run on Bun.
|
|
80
80
|
|
|
81
81
|
## Examples
|
|
@@ -90,7 +90,7 @@ is runtime-neutral. Development and the quality gates run on Bun.
|
|
|
90
90
|
|
|
91
91
|
## Documentation
|
|
92
92
|
|
|
93
|
-
Complete guides for setup, deployment, and integration
|
|
93
|
+
Complete guides for setup, deployment, and integration - see
|
|
94
94
|
[docs/index.md](./docs/index.md) for the full, ordered walkthrough:
|
|
95
95
|
|
|
96
96
|
- **[Architecture](./docs/ARCHITECTURE.md)** - Load-bearing invariants, each linked to the test that enforces it
|
|
@@ -111,8 +111,23 @@ Complete guides for setup, deployment, and integration — see
|
|
|
111
111
|
- **[Deployment](./docs/deployment.md)** - Google Cloud Run, Fly.io, Railway, VPS
|
|
112
112
|
- **[Packaging](./docs/packaging.md)** - The subpath contract and the release chain
|
|
113
113
|
- **[Testing](./docs/testing.md)** - Comprehensive testing guide
|
|
114
|
-
- **[Sprint Review](./docs/sprint-review.md)** - Cross-module & security-invariant audit
|
|
115
114
|
- **[FAQs](./docs/faqs.md)** - Troubleshooting and common questions
|
|
115
|
+
- **Architecture Decisions** - The ADRs behind the shape of the codebase:
|
|
116
|
+
[0001, brain and sockets split](./docs/decisions/0001-brain-and-sockets-split.md),
|
|
117
|
+
[0002, no LangChain in core](./docs/decisions/0002-no-langchain-in-core.md),
|
|
118
|
+
[0003, slot-filling is brain territory](./docs/decisions/0003-slot-filling-is-brain-territory.md),
|
|
119
|
+
[0004, main-protection keeps only non-fast-forward and deletion protections](./docs/decisions/0004-main-protection-stays-non-fast-forward-only.md)
|
|
120
|
+
- **Patterns** - Worked "how do I add X" guides:
|
|
121
|
+
[adding a capability](./docs/patterns/adding-a-capability.md),
|
|
122
|
+
[adding a store](./docs/patterns/adding-a-store.md),
|
|
123
|
+
[adding a retriever](./docs/patterns/adding-a-retriever.md),
|
|
124
|
+
[exemplars](./docs/patterns/exemplars.md)
|
|
125
|
+
|
|
126
|
+
### Archive
|
|
127
|
+
|
|
128
|
+
- **[Cross-Module Review](./docs/sprint-review.md)** - A dated, point-in-time
|
|
129
|
+
audit (v0.40) of cross-module paths and security invariants, not a
|
|
130
|
+
standing guarantee about the current codebase.
|
|
116
131
|
|
|
117
132
|
## Demo
|
|
118
133
|
|
|
@@ -121,7 +136,7 @@ Complete guides for setup, deployment, and integration — see
|
|
|
121
136
|
The [chatter-demo](https://github.com/diegoaltoworks/chatter-demo) repository contains a complete, production-ready implementation showing:
|
|
122
137
|
|
|
123
138
|
- Full server setup with custom configuration
|
|
124
|
-
- 8 live demo implementations (Widget/React
|
|
139
|
+
- 8 live demo implementations (Widget/React x Button/Inline x Public/Private)
|
|
125
140
|
- Clerk authentication integration
|
|
126
141
|
- Deployment configuration for Google Cloud Run
|
|
127
142
|
- Knowledge base and prompt customization
|
|
@@ -157,7 +172,7 @@ See [Client Setup Guide](./docs/client.md) for detailed integration examples, th
|
|
|
157
172
|
|
|
158
173
|
## MCP Server Integration
|
|
159
174
|
|
|
160
|
-
Use Chatter as a Model Context Protocol (MCP) server to expose your chatbot to Claude Desktop, VS Code extensions, and other MCP-compatible tools. `@modelcontextprotocol/sdk` and `zod` are optional peer dependencies scoped to this subpath
|
|
175
|
+
Use Chatter as a Model Context Protocol (MCP) server to expose your chatbot to Claude Desktop, VS Code extensions, and other MCP-compatible tools. `@modelcontextprotocol/sdk` and `zod` are optional peer dependencies scoped to this subpath - install them to use it: `bun add @modelcontextprotocol/sdk zod`.
|
|
161
176
|
|
|
162
177
|
**Basic Setup:**
|
|
163
178
|
```typescript
|
|
@@ -200,7 +215,8 @@ const server = await createMCPServer({
|
|
|
200
215
|
// ... other config ...
|
|
201
216
|
toolRateLimit: 30, // Max 30 requests per minute per tool (optional)
|
|
202
217
|
logging: {
|
|
203
|
-
console: true,
|
|
218
|
+
console: true, // JSON `mcp_chat` events via the logger, stderr (default: true)
|
|
219
|
+
content: false, // also log the conversation itself (default: false)
|
|
204
220
|
onChat: async (event) => {
|
|
205
221
|
// Custom logging - includes conversation tracking and cost data
|
|
206
222
|
console.log('Chat event:', {
|
|
@@ -231,6 +247,14 @@ const server = await createMCPServer({
|
|
|
231
247
|
});
|
|
232
248
|
```
|
|
233
249
|
|
|
250
|
+
The default `mcp_chat` console event carries metadata only: tool name,
|
|
251
|
+
conversation id, message and context counts, duration and token cost. Set
|
|
252
|
+
`logging.content: true` plus `logLevel: "debug"` to also get an
|
|
253
|
+
`mcp_chat_content` event with the user message, history, retrieved context and
|
|
254
|
+
answer. `onChat` always receives the full event, since the host decides where
|
|
255
|
+
it lands. Content is scrubbed of credentials wherever it is emitted. See
|
|
256
|
+
[docs/server.md](docs/server.md#logging).
|
|
257
|
+
|
|
234
258
|
**Claude Desktop Configuration:**
|
|
235
259
|
|
|
236
260
|
Add to your `claude_desktop_config.json`:
|
|
@@ -265,13 +289,13 @@ Both tools:
|
|
|
265
289
|
|
|
266
290
|
**Features:**
|
|
267
291
|
- **Conversation ID Tracking**: Pass `conversationId` parameter to maintain session continuity across tool calls
|
|
268
|
-
- **Cost Tracking**: Every response includes token usage (prompt/completion/total). Add `openai: { pricing: { promptPer1M, completionPer1M } }` to also get an estimated USD cost
|
|
292
|
+
- **Cost Tracking**: Every response includes token usage (prompt/completion/total). Add `openai: { pricing: { promptPer1M, completionPer1M } }` to also get an estimated USD cost - without it, `estimatedCost` is `null` rather than guessing at a price for the wrong model
|
|
269
293
|
- **Rate Limiting**: Optional per-tool rate limiting (requests per minute) to control API usage
|
|
270
294
|
- **Observability**: Comprehensive logging with conversation tracking and cost data
|
|
271
295
|
|
|
272
296
|
## Plugins
|
|
273
297
|
|
|
274
|
-
### Talker
|
|
298
|
+
### Talker - Voice Calls, SMS & WhatsApp
|
|
275
299
|
|
|
276
300
|
Add phone call and SMS support to your Chatter bot with [Talker](https://github.com/diegoaltoworks/talker):
|
|
277
301
|
|
|
@@ -294,7 +318,21 @@ const app = await createServer({
|
|
|
294
318
|
});
|
|
295
319
|
```
|
|
296
320
|
|
|
297
|
-
One server, one port
|
|
321
|
+
One server, one port - web chat, phone calls, and SMS. See the [Talker README](https://github.com/diegoaltoworks/talker) for full documentation.
|
|
322
|
+
|
|
323
|
+
### Two ways to do WhatsApp
|
|
324
|
+
|
|
325
|
+
Chatter's own [WhatsApp channel](./docs/channels.md) and Talker's Twilio
|
|
326
|
+
integration both reach WhatsApp, through very different paths - pick based on
|
|
327
|
+
what you're building:
|
|
328
|
+
|
|
329
|
+
| | This repo's [WhatsApp channel](./docs/channels.md) | Talker's Twilio WhatsApp |
|
|
330
|
+
| --- | --- | --- |
|
|
331
|
+
| WhatsApp access | Unofficial, via [Baileys](https://github.com/WhiskeySockets/Baileys) - a linked-device client, not the WhatsApp Business API | Sanctioned path, via Twilio's WhatsApp Business API integration |
|
|
332
|
+
| Cost | Free besides hosting | Twilio usage-based pricing |
|
|
333
|
+
| Risk | Real risk of the linked number being banned - use a number you can afford to lose | Runs through WhatsApp's own approved channel |
|
|
334
|
+
| Setup | Link a number by QR code or pairing code, no third party | Twilio account and WhatsApp Business API approval |
|
|
335
|
+
| Best for | Prototyping, personal or low-stakes bots | Production, customer-facing deployments |
|
|
298
336
|
|
|
299
337
|
## License
|
|
300
338
|
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
* forgery or WhatsApp account takeover — so a short or empty value fails
|
|
5
5
|
* fast with an actionable error instead of quietly producing a weak key.
|
|
6
6
|
*/
|
|
7
|
-
export declare function assertStrongSecret(secret: string | undefined, label: string):
|
|
7
|
+
export declare function assertStrongSecret(secret: string | undefined, label: string): asserts secret is string;
|
|
8
8
|
//# sourceMappingURL=secretStrength.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secretStrength.d.ts","sourceRoot":"","sources":["../../src/auth/secretStrength.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"secretStrength.d.ts","sourceRoot":"","sources":["../../src/auth/secretStrength.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,IAAI,MAAM,CAU1B"}
|
|
@@ -125,58 +125,75 @@ var ApiKeyManager = class {
|
|
|
125
125
|
}
|
|
126
126
|
};
|
|
127
127
|
|
|
128
|
-
// bin/create-apikey.ts
|
|
129
|
-
|
|
130
|
-
const args = process.argv.slice(2);
|
|
128
|
+
// bin/create-apikey-args.ts
|
|
129
|
+
function parseArgs(args) {
|
|
131
130
|
const options = {};
|
|
132
131
|
for (let i = 0; i < args.length; i++) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
137
|
-
|
|
132
|
+
const arg = args[i];
|
|
133
|
+
if (arg === "--help" || arg === "-h") {
|
|
134
|
+
return { ok: true, help: true };
|
|
135
|
+
}
|
|
136
|
+
if (arg === "--name" || arg === "--expires-in") {
|
|
137
|
+
const value = args[i + 1];
|
|
138
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
139
|
+
return { ok: false, error: `${arg} requires a value` };
|
|
140
|
+
}
|
|
141
|
+
if (arg === "--name") options.name = value;
|
|
142
|
+
else options.expiresIn = value;
|
|
138
143
|
i++;
|
|
139
|
-
|
|
140
|
-
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
return { ok: false, error: `Unknown argument: ${arg}` };
|
|
147
|
+
}
|
|
148
|
+
return { ok: true, help: false, ...options };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// bin/create-apikey.ts
|
|
152
|
+
var HELP_TEXT = `
|
|
141
153
|
Chatter API Key Generator
|
|
142
154
|
|
|
143
155
|
Usage:
|
|
144
|
-
npx chatter
|
|
156
|
+
npx chatter [options]
|
|
145
157
|
|
|
146
158
|
Options:
|
|
147
159
|
--name <name> Name/label for the API key (default: "api-key")
|
|
148
160
|
--expires-in <time> Expiration time (default: "365d")
|
|
149
161
|
Formats: s=seconds, m=minutes, h=hours, d=days, M=months, y=years
|
|
150
162
|
Examples: 30d, 12h, 1y, 6M
|
|
163
|
+
--help, -h Show this help.
|
|
151
164
|
|
|
152
165
|
Environment:
|
|
153
166
|
CHATTER_SECRET Required. Secret key for signing JWT tokens
|
|
154
167
|
|
|
155
168
|
Examples:
|
|
156
|
-
npx chatter
|
|
157
|
-
npx chatter
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
console.error("\u274C Error: CHATTER_SECRET environment variable is not set");
|
|
165
|
-
console.error("\n Please set it before running this command:");
|
|
166
|
-
console.error(" export CHATTER_SECRET=your-secret-key-here");
|
|
167
|
-
console.error("\n Or prefix the command:");
|
|
168
|
-
console.error(" CHATTER_SECRET=your-secret npx chatter create-apikey\n");
|
|
169
|
+
npx chatter --name "mobile-app" --expires-in 365d
|
|
170
|
+
npx chatter --name "test-key" --expires-in 1h
|
|
171
|
+
`;
|
|
172
|
+
async function main() {
|
|
173
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
174
|
+
if (!parsed.ok) {
|
|
175
|
+
console.error(`\u274C ${parsed.error}`);
|
|
176
|
+
console.log(HELP_TEXT);
|
|
169
177
|
process.exit(1);
|
|
170
178
|
}
|
|
179
|
+
if (parsed.help) {
|
|
180
|
+
console.log(HELP_TEXT);
|
|
181
|
+
process.exit(0);
|
|
182
|
+
}
|
|
183
|
+
const secret = process.env.CHATTER_SECRET;
|
|
171
184
|
try {
|
|
172
185
|
assertStrongSecret(secret, "CHATTER_SECRET");
|
|
173
186
|
} catch (error) {
|
|
174
187
|
console.error(`\u274C ${error.message}`);
|
|
188
|
+
console.error("\n Set it before running this command:");
|
|
189
|
+
console.error(" export CHATTER_SECRET=your-secret-key-here");
|
|
190
|
+
console.error("\n Or prefix the command:");
|
|
191
|
+
console.error(" CHATTER_SECRET=your-secret npx chatter\n");
|
|
175
192
|
process.exit(1);
|
|
176
193
|
}
|
|
177
194
|
const manager = new ApiKeyManager(secret);
|
|
178
|
-
const keyName =
|
|
179
|
-
const expiresIn =
|
|
195
|
+
const keyName = parsed.name || "api-key";
|
|
196
|
+
const expiresIn = parsed.expiresIn || "365d";
|
|
180
197
|
try {
|
|
181
198
|
const apiKey = await manager.create({
|
|
182
199
|
name: keyName,
|
|
@@ -199,12 +216,12 @@ Examples:
|
|
|
199
216
|
`);
|
|
200
217
|
console.log(" Usage:");
|
|
201
218
|
console.log(" curl -X POST https://your-bot.example.com/api/public/chat \\");
|
|
202
|
-
console.log(` -H "x-api-key: ${apiKey
|
|
219
|
+
console.log(` -H "x-api-key: ${apiKey}" \\`);
|
|
203
220
|
console.log(' -H "Content-Type: application/json" \\');
|
|
204
221
|
console.log(` -d '{"message": "Hello"}'`);
|
|
205
222
|
console.log("");
|
|
206
223
|
} catch (error) {
|
|
207
|
-
console.error(
|
|
224
|
+
console.error(`\u274C Error creating API key: ${error.message}`);
|
|
208
225
|
process.exit(1);
|
|
209
226
|
}
|
|
210
227
|
}
|
package/dist/bin/wa-pair.js
CHANGED
|
@@ -108,27 +108,55 @@ function ensureAuthSchema(client) {
|
|
|
108
108
|
}
|
|
109
109
|
return ready;
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
function createTursoWaAuthKV(db2) {
|
|
112
|
+
return {
|
|
113
|
+
async read(id) {
|
|
114
|
+
await ensureAuthSchema(db2);
|
|
115
|
+
const result = await db2.execute({
|
|
116
|
+
sql: "SELECT value FROM wa_auth WHERE id = ?",
|
|
117
|
+
args: [id]
|
|
118
|
+
});
|
|
119
|
+
const row = result.rows[0];
|
|
120
|
+
return row ? row.value : null;
|
|
121
|
+
},
|
|
122
|
+
async write(id, value) {
|
|
123
|
+
await ensureAuthSchema(db2);
|
|
124
|
+
await db2.execute({
|
|
125
|
+
sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
|
|
126
|
+
args: [id, value]
|
|
127
|
+
});
|
|
128
|
+
},
|
|
129
|
+
async remove(id) {
|
|
130
|
+
await ensureAuthSchema(db2);
|
|
131
|
+
await db2.execute({ sql: "DELETE FROM wa_auth WHERE id = ?", args: [id] });
|
|
132
|
+
},
|
|
133
|
+
// Mirrors isAuthRowForSession - keep the two in sync.
|
|
134
|
+
async clear(sessionId2) {
|
|
135
|
+
await ensureAuthSchema(db2);
|
|
136
|
+
if (sessionId2 === "default") {
|
|
137
|
+
await db2.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
|
|
138
|
+
} else {
|
|
139
|
+
await db2.execute({
|
|
140
|
+
sql: "DELETE FROM wa_auth WHERE id LIKE ?",
|
|
141
|
+
args: [`s:${sessionId2}/%`]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
async function useAuthState(store, secret, sessionId2, runtime) {
|
|
113
148
|
const rowId = (id) => sessionId2 === "default" ? id : `s:${sessionId2}/${id}`;
|
|
114
149
|
async function read(id) {
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
});
|
|
119
|
-
const row = result.rows[0];
|
|
120
|
-
if (!row) return null;
|
|
121
|
-
return JSON.parse(await decrypt(row.value, secret), runtime.bufferJSON.reviver);
|
|
150
|
+
const value = await store.read(rowId(id));
|
|
151
|
+
if (value === null) return null;
|
|
152
|
+
return JSON.parse(await decrypt(value, secret), runtime.bufferJSON.reviver);
|
|
122
153
|
}
|
|
123
154
|
async function write(id, value) {
|
|
124
155
|
const payload = await encrypt(JSON.stringify(value, runtime.bufferJSON.replacer), secret);
|
|
125
|
-
await
|
|
126
|
-
sql: "INSERT OR REPLACE INTO wa_auth (id, value) VALUES (?, ?)",
|
|
127
|
-
args: [rowId(id), payload]
|
|
128
|
-
});
|
|
156
|
+
await store.write(rowId(id), payload);
|
|
129
157
|
}
|
|
130
158
|
async function remove(id) {
|
|
131
|
-
await
|
|
159
|
+
await store.remove(rowId(id));
|
|
132
160
|
}
|
|
133
161
|
const creds = await read("creds") ?? runtime.initAuthCreds();
|
|
134
162
|
return {
|
|
@@ -165,18 +193,13 @@ async function useTursoAuthState(db2, secret, sessionId2, runtime) {
|
|
|
165
193
|
}
|
|
166
194
|
},
|
|
167
195
|
saveCreds: () => write("creds", creds),
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
await db2.execute("DELETE FROM wa_auth WHERE id NOT LIKE 's:%'");
|
|
171
|
-
} else {
|
|
172
|
-
await db2.execute({
|
|
173
|
-
sql: "DELETE FROM wa_auth WHERE id LIKE ?",
|
|
174
|
-
args: [`s:${sessionId2}/%`]
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
196
|
+
// Scoped to THIS session - never nuke a sibling number's pairing.
|
|
197
|
+
clear: () => store.clear(sessionId2)
|
|
178
198
|
};
|
|
179
199
|
}
|
|
200
|
+
async function useTursoAuthState(db2, secret, sessionId2, runtime) {
|
|
201
|
+
return useAuthState(createTursoWaAuthKV(db2), secret, sessionId2, runtime);
|
|
202
|
+
}
|
|
180
203
|
|
|
181
204
|
// src/channels/whatsapp/baileys.ts
|
|
182
205
|
function wrapMissingBaileysError(cause) {
|
|
@@ -196,6 +219,11 @@ function loadBaileys() {
|
|
|
196
219
|
return cached;
|
|
197
220
|
}
|
|
198
221
|
|
|
222
|
+
// src/channels/backoff.ts
|
|
223
|
+
function exponentialBackoffMs(baseMs, maxMs, n) {
|
|
224
|
+
return Math.min(baseMs * 2 ** Math.max(0, Math.min(n, 20)), maxMs);
|
|
225
|
+
}
|
|
226
|
+
|
|
199
227
|
// src/channels/whatsapp/pairing.ts
|
|
200
228
|
var RESTART_REQUIRED_STATUS = 515;
|
|
201
229
|
var MAX_PAIRING_RECONNECTS = 12;
|
|
@@ -206,9 +234,10 @@ var REGISTERED_CONFIRM_TIMEOUT_MS = 15e3;
|
|
|
206
234
|
var REGISTERED_CONFIRM_POLL_MS = 500;
|
|
207
235
|
function pairingReconnectDelayMs(statusCode, attempt) {
|
|
208
236
|
if (statusCode === RESTART_REQUIRED_STATUS) return RESTART_REQUIRED_DELAY_MS;
|
|
209
|
-
return
|
|
210
|
-
PAIRING_RECONNECT_DELAY_MS
|
|
211
|
-
PAIRING_RECONNECT_MAX_DELAY_MS
|
|
237
|
+
return exponentialBackoffMs(
|
|
238
|
+
PAIRING_RECONNECT_DELAY_MS,
|
|
239
|
+
PAIRING_RECONNECT_MAX_DELAY_MS,
|
|
240
|
+
attempt - 1
|
|
212
241
|
);
|
|
213
242
|
}
|
|
214
243
|
function decidePairingClose(input) {
|
|
@@ -395,14 +424,46 @@ function resolveQrGenerate(mod) {
|
|
|
395
424
|
return void 0;
|
|
396
425
|
}
|
|
397
426
|
|
|
398
|
-
// bin/wa-pair.ts
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
427
|
+
// bin/wa-pair-args.ts
|
|
428
|
+
function parseArgs(args) {
|
|
429
|
+
let sessionId2;
|
|
430
|
+
let codeValue;
|
|
431
|
+
let reset2 = false;
|
|
432
|
+
for (let i = 0; i < args.length; i++) {
|
|
433
|
+
const arg = args[i];
|
|
434
|
+
if (arg === "--help" || arg === "-h") {
|
|
435
|
+
return { ok: true, help: true };
|
|
436
|
+
}
|
|
437
|
+
if (arg === "--reset") {
|
|
438
|
+
reset2 = true;
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
if (arg === "--code") {
|
|
442
|
+
const value = args[i + 1];
|
|
443
|
+
if (value === void 0 || value.startsWith("-")) {
|
|
444
|
+
return { ok: false, error: "--code requires a phone number, e.g. --code 447700900123" };
|
|
445
|
+
}
|
|
446
|
+
codeValue = value;
|
|
447
|
+
i++;
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
if (arg.startsWith("-")) {
|
|
451
|
+
return { ok: false, error: `Unknown argument: ${arg}` };
|
|
452
|
+
}
|
|
453
|
+
if (sessionId2 !== void 0) {
|
|
454
|
+
return { ok: false, error: `Unexpected extra argument: ${arg}` };
|
|
455
|
+
}
|
|
456
|
+
sessionId2 = arg;
|
|
457
|
+
}
|
|
458
|
+
const phoneNumber2 = codeValue === void 0 ? void 0 : codeValue.replace(/[^0-9]/g, "");
|
|
459
|
+
if (codeValue !== void 0 && !phoneNumber2) {
|
|
460
|
+
return { ok: false, error: "--code requires a phone number, e.g. --code 447700900123" };
|
|
461
|
+
}
|
|
462
|
+
return { ok: true, help: false, sessionId: sessionId2 ?? "default", phoneNumber: phoneNumber2, reset: reset2 };
|
|
403
463
|
}
|
|
404
|
-
|
|
405
|
-
|
|
464
|
+
|
|
465
|
+
// bin/wa-pair.ts
|
|
466
|
+
var HELP_TEXT = `
|
|
406
467
|
WhatsApp pairing CLI
|
|
407
468
|
|
|
408
469
|
Usage:
|
|
@@ -416,21 +477,23 @@ Options:
|
|
|
416
477
|
--code <phoneNumber> Pair via pairing code instead of QR (digits only,
|
|
417
478
|
e.g. 447700900123). For headless setups.
|
|
418
479
|
--reset Wipe the stored session first, then pair fresh.
|
|
419
|
-
--help, -h
|
|
480
|
+
--help, -h Show this help.
|
|
420
481
|
|
|
421
482
|
Environment:
|
|
422
|
-
TURSO_URL, TURSO_AUTH_TOKEN Required. The database auth state is stored in.
|
|
483
|
+
TURSO_URL, TURSO_AUTH_TOKEN Required. The database the auth state is stored in.
|
|
423
484
|
WA_SESSION_SECRET Required. Encrypts the stored session at rest.
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
console.error("\u274C --code requires a phone number, e.g. --code 447700900123");
|
|
485
|
+
`;
|
|
486
|
+
var parsed = parseArgs(process.argv.slice(2));
|
|
487
|
+
if (!parsed.ok) {
|
|
488
|
+
console.error(`\u274C ${parsed.error}`);
|
|
489
|
+
console.log(HELP_TEXT);
|
|
430
490
|
process.exit(1);
|
|
431
491
|
}
|
|
432
|
-
|
|
433
|
-
|
|
492
|
+
if (parsed.help) {
|
|
493
|
+
console.log(HELP_TEXT);
|
|
494
|
+
process.exit(0);
|
|
495
|
+
}
|
|
496
|
+
var { sessionId, phoneNumber, reset } = parsed;
|
|
434
497
|
var sessionSecret = process.env.WA_SESSION_SECRET;
|
|
435
498
|
try {
|
|
436
499
|
assertStrongSecret(sessionSecret, "WA_SESSION_SECRET");
|
|
@@ -442,9 +505,13 @@ if (!process.env.TURSO_URL) {
|
|
|
442
505
|
console.error("\u274C TURSO_URL is required.");
|
|
443
506
|
process.exit(1);
|
|
444
507
|
}
|
|
508
|
+
if (!process.env.TURSO_AUTH_TOKEN) {
|
|
509
|
+
console.error("\u274C TURSO_AUTH_TOKEN is required.");
|
|
510
|
+
process.exit(1);
|
|
511
|
+
}
|
|
445
512
|
var db = (0, import_client.createClient)({
|
|
446
513
|
url: process.env.TURSO_URL,
|
|
447
|
-
authToken: process.env.TURSO_AUTH_TOKEN
|
|
514
|
+
authToken: process.env.TURSO_AUTH_TOKEN
|
|
448
515
|
});
|
|
449
516
|
var printedQrFallbackHelp = false;
|
|
450
517
|
function printQrFallback(qr) {
|
|
@@ -561,6 +628,6 @@ async function start() {
|
|
|
561
628
|
process.exit(0);
|
|
562
629
|
}
|
|
563
630
|
start().catch((error) => {
|
|
564
|
-
console.error(
|
|
631
|
+
console.error(`\u274C Unexpected error: ${error.message}`);
|
|
565
632
|
process.exit(1);
|
|
566
633
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exponential backoff with a cap: `base * 2^n`, `n` clamped to `[0, 20]` so
|
|
3
|
+
* the exponent never overflows long before `max` would bind anyway. Every
|
|
4
|
+
* poll/sync/reconnect loop in `src/channels/` computes its retry delay this
|
|
5
|
+
* way (`./telegram/poll.ts`, `./matrix/sync.ts`, `./whatsapp/channel.ts`,
|
|
6
|
+
* `./whatsapp/pairing.ts`); only `base`, `max`, and what `n` counts
|
|
7
|
+
* (failures seen vs. attempts made) differ between them.
|
|
8
|
+
*/
|
|
9
|
+
export declare function exponentialBackoffMs(baseMs: number, maxMs: number, n: number): number;
|
|
10
|
+
//# sourceMappingURL=backoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../../src/channels/backoff.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErF"}
|
package/dist/channels/gates.d.ts
CHANGED
|
@@ -95,14 +95,21 @@ export declare function underReplyRateLimit(msg: Pick<ChannelMessage, "chatId" |
|
|
|
95
95
|
group: (chatId: string) => boolean;
|
|
96
96
|
}): boolean;
|
|
97
97
|
/**
|
|
98
|
-
* Every session's own identities ever seen, keyed by session id.
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
98
|
+
* Every session's own identities ever seen, keyed by session id.
|
|
99
|
+
*
|
|
100
|
+
* The failure this exists to prevent: link two numbers to one process (a
|
|
101
|
+
* common WhatsApp setup — a "support" and a "sales" line sharing a server),
|
|
102
|
+
* and each session's transport only tells that session its own identity. A
|
|
103
|
+
* message from the OTHER linked number's session then looks like a
|
|
104
|
+
* stranger, not "us" — the bot answers it, the other session sees THAT
|
|
105
|
+
* reply as a new stranger message and answers it back, and the two numbers
|
|
106
|
+
* ping-pong replies at each other indefinitely, burning the rate limit and
|
|
107
|
+
* spamming both chats until someone notices and kills the process. Sharing
|
|
108
|
+
* one registry across every session (rather than each session checking only
|
|
109
|
+
* its own identity) is what lets session A recognise session B's identity
|
|
110
|
+
* as "us" too, and stop the loop before it starts. Callers populate this
|
|
111
|
+
* directly (`registry.set(sessionId, ids)`) as each session's identities
|
|
112
|
+
* become known, typically on connect and kept in sync as they change.
|
|
106
113
|
*
|
|
107
114
|
* Entries are NOT expected to be removed when a session disconnects: a
|
|
108
115
|
* session's own identity is still "us" while it reconnects, and losing that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/channels/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,YAAY,EAAE,OAAO,CAAC;IACtB,sHAAsH;IACtH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kIAAkI;IAClI,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,GAC9C,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAUjG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,MAAiB;UAcR,MAAM,GAAG,OAAO;;EAiBrC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,iBAAiB,CAAC,EACvD,QAAQ,EAAE;IAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAChF,OAAO,CAET;AAED
|
|
1
|
+
{"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/channels/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,YAAY,EAAE,OAAO,CAAC;IACtB,sHAAsH;IACtH,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kIAAkI;IAClI,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,GAC9C,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAUjG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,MAAiB;UAcR,MAAM,GAAG,OAAO;;EAiBrC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,iBAAiB,CAAC,EACvD,QAAQ,EAAE;IAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAChF,OAAO,CAET;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,uBAAuB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE5D,qHAAqH;AACrH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAMT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,UAAU,CAAC,EACjD,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAET"}
|
package/dist/channels/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export interface Channel {
|
|
|
42
42
|
stop?(): void | Promise<void>;
|
|
43
43
|
}
|
|
44
44
|
export * from "./gates";
|
|
45
|
-
export { createInboundPipeline, type InboundPipeline, type InboundPipelineConfig, type InboundPipelineDeps, type InboundPipelineOutcome, type InboundReplySender, type InboundTurn, } from "./pipeline";
|
|
45
|
+
export { createInboundPipeline, type InboundPipeline, type InboundPipelineConfig, type InboundPipelineDeps, type InboundPipelineOutcome, type InboundReplySender, type InboundTurn, resolveBrainHooks, } from "./pipeline";
|
|
46
46
|
export type { ChannelSender, ChannelSenderRegistry } from "./senders";
|
|
47
47
|
export { createSenderRegistry } from "./senders";
|
|
48
48
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,OAAO;IACtB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,OAAO;IACtB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
|