@andreprado/agentkit 0.1.0-alpha.20 → 0.1.0-alpha.21
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 +1 -0
- package/docs/guides/add-channel.md +75 -4
- package/docs/guides/channel-security.md +32 -1
- package/docs/guides/connect-whatsapp-evolution.md +121 -0
- package/docs/guides/connect-whatsapp-uazapi.md +126 -0
- package/docs/guides/debug-channel.md +3 -3
- package/docs/llms-full.txt +49 -4
- package/docs/llms.txt +5 -0
- package/package.json +1 -1
- package/src/cli/commands/channels.ts +285 -14
- package/src/cli/help.ts +2 -2
- package/src/index.ts +41 -4
- package/src/runtime/channel-test-harness.ts +14 -1
- package/src/runtime/channels/generic-webhook.ts +225 -0
- package/src/runtime/channels/whatsapp-evolution.ts +1357 -0
- package/src/runtime/channels/whatsapp-uazapi.ts +1327 -0
- package/src/runtime/channels.ts +1 -1
- package/src/runtime/config.ts +39 -4
- package/src/runtime/core/targets.ts +5 -5
- package/src/runtime/dev-server.ts +21 -5
- package/src/runtime/targets/cloudflare/build.ts +23 -3
- package/src/templates/skills/agentkit-capsule/SKILL.md +1 -1
- package/src/templates/skills/agentkit-capsule/references/docs-router.md +1 -1
- package/src/templates/skills/agentkit-channels/SKILL.md +25 -2
- package/src/templates/skills/agentkit-channels/references/channel-debugging.md +1 -1
- package/src/templates/skills/agentkit-channels/references/whatsapp-evolution.md +57 -0
- package/src/templates/skills/agentkit-channels/references/whatsapp-uazapi.md +61 -0
package/README.md
CHANGED
|
@@ -67,6 +67,7 @@ agentkit secret set OPENAI_API_KEY --from-local-env
|
|
|
67
67
|
agentkit deploy
|
|
68
68
|
agentkit deploy status
|
|
69
69
|
agentkit channels test support-telegram --message "hello"
|
|
70
|
+
agentkit channels connect webhook n8n-webhook
|
|
70
71
|
agentkit transcribe smoke --provider groq
|
|
71
72
|
agentkit chat-ui --deploy
|
|
72
73
|
```
|
|
@@ -6,7 +6,7 @@ Add a hosted messaging channel to an Agent Capsule, create the hosted channel re
|
|
|
6
6
|
|
|
7
7
|
## When To Use It
|
|
8
8
|
|
|
9
|
-
Use this when the agent should receive messages from website chat, Telegram, WhatsApp, or
|
|
9
|
+
Use this when the agent should receive messages from website chat, Telegram, WhatsApp, Discord, Slack, or a generic webhook through AgentKit-owned channel infrastructure.
|
|
10
10
|
|
|
11
11
|
## Commands
|
|
12
12
|
|
|
@@ -19,7 +19,10 @@ agentkit channels add telegram support-telegram
|
|
|
19
19
|
agentkit channels connect discord support-discord
|
|
20
20
|
agentkit channels connect discord server-discord --mode bot
|
|
21
21
|
agentkit channels connect slack support-slack
|
|
22
|
+
agentkit channels connect webhook n8n-webhook
|
|
22
23
|
agentkit channels add whatsapp support-whatsapp --provider zapster
|
|
24
|
+
agentkit channels connect whatsapp support-uazapi --provider uazapi
|
|
25
|
+
agentkit channels connect whatsapp main-whatsapp --provider evolution
|
|
23
26
|
agentkit channels setup support-telegram
|
|
24
27
|
agentkit channels status support-telegram
|
|
25
28
|
agentkit channels test support-telegram --message "hello"
|
|
@@ -31,15 +34,16 @@ Use `--api <url>` only when the owner gives you a non-default AgentKit Cloud API
|
|
|
31
34
|
|
|
32
35
|
## Files Created Or Edited
|
|
33
36
|
|
|
34
|
-
- `agentkit.config.ts`: declare channel config with `websiteChannel`, `telegramChannel`, `whatsappChannel`, `discordChannel`, or `
|
|
37
|
+
- `agentkit.config.ts`: declare channel config with `websiteChannel`, `telegramChannel`, `whatsappChannel`, `discordChannel`, `slackChannel`, or `webhookChannel`.
|
|
35
38
|
- `.agentkit/deploy.json`: written by `agentkit deploy`; used by `agentkit channels ...`.
|
|
36
39
|
- No user Turso tables: AgentKit owns channel resources, dedupe, identities, queue state, and delivery logs.
|
|
37
40
|
- Website channel clients must send `AGENTKIT_WEBSITE_CHANNEL_TOKEN` as `Authorization: Bearer <token>` or `X-AgentKit-Channel-Token`.
|
|
41
|
+
- Generic webhook clients must send `AGENTKIT_WEBHOOK_SECRET` as `Authorization: Bearer <token>`, `X-AgentKit-Webhook-Secret`, or `X-AgentKit-Webhook-Signature: sha256=<hmac>`.
|
|
38
42
|
|
|
39
43
|
## Minimal Working Example
|
|
40
44
|
|
|
41
45
|
```ts
|
|
42
|
-
import { defineAgent, discordChannel, slackChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
|
|
46
|
+
import { defineAgent, discordChannel, slackChannel, telegramChannel, webhookChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
|
|
43
47
|
|
|
44
48
|
export default defineAgent({
|
|
45
49
|
name: "support-agent",
|
|
@@ -52,9 +56,12 @@ export default defineAgent({
|
|
|
52
56
|
websiteChannel({ name: "website-chat" }),
|
|
53
57
|
telegramChannel({ name: "support-telegram" }),
|
|
54
58
|
whatsappChannel({ name: "support-whatsapp", provider: "zapster" }),
|
|
59
|
+
whatsappChannel({ name: "support-uazapi", provider: "uazapi" }),
|
|
60
|
+
whatsappChannel({ name: "main-whatsapp", provider: "evolution" }),
|
|
55
61
|
discordChannel({ name: "support-discord" }),
|
|
56
62
|
discordChannel({ name: "server-discord", mode: "bot" }),
|
|
57
63
|
slackChannel({ name: "support-slack" }),
|
|
64
|
+
webhookChannel({ name: "n8n-webhook" }),
|
|
58
65
|
],
|
|
59
66
|
access: { mode: "public" },
|
|
60
67
|
storage: { driver: "agentkit" },
|
|
@@ -95,6 +102,57 @@ agentkit channels buffers retry support-whatsapp <conversation-id>
|
|
|
95
102
|
|
|
96
103
|
Discord supports buffering for slash-command interactions and bot-mode server messages, but it does not support `audio` in V1.
|
|
97
104
|
|
|
105
|
+
## Generic Webhooks
|
|
106
|
+
|
|
107
|
+
Use `webhookChannel` when n8n, Make, Zapier, Pipedream, or a custom server should push a text event into the agent.
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
webhookChannel({
|
|
111
|
+
name: "n8n-webhook",
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
After deploy:
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
agentkit channels connect webhook n8n-webhook
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
The hosted webhook URL is:
|
|
122
|
+
|
|
123
|
+
```txt
|
|
124
|
+
https://<deploy-host>/channels/n8n-webhook/webhook
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Send canonical JSON:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"event_id": "evt_123",
|
|
132
|
+
"external_id": "customer_123",
|
|
133
|
+
"message": "hello from n8n"
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`event_id` is required for replay protection. `external_id` is optional but recommended; AgentKit hashes it before storing the channel identity and uses it to continue the same conversation. If `external_id` is omitted, the event id becomes the conversation identity and each event is treated as its own conversation.
|
|
138
|
+
|
|
139
|
+
Authenticate with a shared secret:
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
curl -X POST https://<deploy-host>/channels/n8n-webhook/webhook \
|
|
143
|
+
-H 'content-type: application/json' \
|
|
144
|
+
-H 'authorization: Bearer <AGENTKIT_WEBHOOK_SECRET>' \
|
|
145
|
+
-d '{"event_id":"evt_123","external_id":"customer_123","message":"hello from n8n"}'
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
For HMAC auth, compute `HMAC-SHA256(raw JSON body, AGENTKIT_WEBHOOK_SECRET)` and send:
|
|
149
|
+
|
|
150
|
+
```txt
|
|
151
|
+
X-AgentKit-Webhook-Signature: sha256=<hex digest>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Generic webhooks are inbound-only in V1. The agent run is queued and delivery logs show the result; AgentKit does not call back into n8n unless the agent has a separate tool that does so.
|
|
155
|
+
|
|
98
156
|
## Auto Transcribe Audio
|
|
99
157
|
|
|
100
158
|
Use `transcription` at the agent level and `audio.mode: "transcribe"` on each Telegram or WhatsApp channel that should accept voice notes or audio files.
|
|
@@ -125,6 +183,16 @@ export default defineAgent({
|
|
|
125
183
|
provider: "zapster",
|
|
126
184
|
audio: { mode: "transcribe" },
|
|
127
185
|
}),
|
|
186
|
+
whatsappChannel({
|
|
187
|
+
name: "support-uazapi",
|
|
188
|
+
provider: "uazapi",
|
|
189
|
+
audio: { mode: "transcribe" },
|
|
190
|
+
}),
|
|
191
|
+
whatsappChannel({
|
|
192
|
+
name: "main-whatsapp",
|
|
193
|
+
provider: "evolution",
|
|
194
|
+
audio: { mode: "transcribe" },
|
|
195
|
+
}),
|
|
128
196
|
],
|
|
129
197
|
access: { mode: "public" },
|
|
130
198
|
storage: { driver: "agentkit" },
|
|
@@ -149,6 +217,8 @@ Processing order:
|
|
|
149
217
|
5. The transcription adapter sends the file to the configured transcription provider.
|
|
150
218
|
6. The agent receives a text message containing the transcript.
|
|
151
219
|
|
|
220
|
+
Zapster audio downloads from trusted HTTPS Zapster media URLs. UAZAPI audio downloads through UAZAPI `/message/download` with base64 return enabled. Evolution audio downloads through Evolution API `/chat/getBase64FromMediaMessage/{instance}` with base64 return enabled. AgentKit does not fetch arbitrary UAZAPI or Evolution webhook media hosts.
|
|
221
|
+
|
|
152
222
|
V1 keeps the raw audio in memory for the request path and delivery metadata only records redacted status/error fields. `rawAudioTtlSeconds` is part of the manifest contract for future object-storage retention, but V1 does not persist raw audio by default.
|
|
153
223
|
|
|
154
224
|
## Safety Rules
|
|
@@ -167,6 +237,7 @@ npm run typecheck
|
|
|
167
237
|
bun test
|
|
168
238
|
agentkit inspect
|
|
169
239
|
agentkit channels list
|
|
240
|
+
agentkit channels test n8n-webhook --message "hello"
|
|
170
241
|
agentkit channels test support-telegram --message "hello"
|
|
171
242
|
agentkit channels test-audio support-telegram --fixture voice-note
|
|
172
243
|
agentkit transcribe smoke --provider groq
|
|
@@ -175,7 +246,7 @@ agentkit channels buffers list support-telegram
|
|
|
175
246
|
```
|
|
176
247
|
|
|
177
248
|
Expected hosted status includes `NAME`, `TYPE`, `PROVIDER`, `STATUS`, and `LAST_EVENT`. Secret output is name plus `set` or `missing`, never the value.
|
|
178
|
-
Outbound provider success is `provider_sent`.
|
|
249
|
+
Outbound provider success is `provider_sent`. `adapter_stubbed` means no outbound provider call was made, either because explicit dry-run mode is enabled or the channel is inbound-only.
|
|
179
250
|
|
|
180
251
|
## Troubleshooting
|
|
181
252
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Goal
|
|
4
4
|
|
|
5
|
-
Configure website, Telegram, WhatsApp, Discord, and
|
|
5
|
+
Configure website, Telegram, WhatsApp, Discord, Slack, and generic webhook channels without leaking secrets, storing raw provider payloads, or treating public webhook URLs as authorization.
|
|
6
6
|
|
|
7
7
|
## When To Use It
|
|
8
8
|
|
|
@@ -33,6 +33,9 @@ agentkit channels deliveries show <delivery-id>
|
|
|
33
33
|
- Do not store raw webhook bodies, raw audio, or provider secret values in tools, prompts, evals, fixtures, or delivery notes.
|
|
34
34
|
- Do not expose Discord interaction tokens or bot tokens. Interaction tokens are reply tokens, not public identifiers.
|
|
35
35
|
- Do not expose Slack bot tokens or signing secrets. Slack signing secrets authenticate webhook origin; Slack bot tokens authorize outbound replies.
|
|
36
|
+
- Do not expose `AGENTKIT_WEBHOOK_SECRET`. Generic webhook clients must authenticate with bearer/header token auth or an HMAC signature over the exact raw body.
|
|
37
|
+
- Do not remove `EVOLUTION_WEBHOOK_TOKEN` from Evolution WhatsApp webhooks. Evolution provider docs expose webhook delivery setup but no webhook signing-secret contract, so AgentKit requires a secret token query parameter and rejects requests without it.
|
|
38
|
+
- Keep `EVOLUTION_API_BASE_URL` on a public HTTPS origin. AgentKit rejects localhost, private network, link-local, and metadata-service hosts for Evolution outbound and media-download requests.
|
|
36
39
|
- Inspect delivery IDs, hashes, redacted metadata, and statuses instead of raw provider payloads.
|
|
37
40
|
- Keep channel plumbing out of the agent's application database. The user's Turso tables are for the agent's business data.
|
|
38
41
|
- Enable audio transcription only when the capsule declares a transcription provider and bounded `limits`.
|
|
@@ -112,6 +115,34 @@ slackChannel({
|
|
|
112
115
|
|
|
113
116
|
AgentKit validates `X-Slack-Signature` and `X-Slack-Request-Timestamp` against the raw body, rejects stale timestamps, answers Slack `url_verification` with the literal challenge, skips bot/subtype messages, and sends replies with Slack control mentions escaped.
|
|
114
117
|
|
|
118
|
+
Generic webhooks use an AgentKit shared secret:
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
webhookChannel({
|
|
122
|
+
name: "n8n-webhook",
|
|
123
|
+
secrets: ["AGENTKIT_WEBHOOK_SECRET"],
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
AgentKit validates `Authorization: Bearer <secret>`, `X-AgentKit-Webhook-Secret`, or `X-AgentKit-Webhook-Signature` against the raw body before parsing business fields. Payloads must include `event_id` for replay protection. `external_id` is hashed before storage.
|
|
128
|
+
|
|
129
|
+
Evolution WhatsApp uses a self-hosted API key and an AgentKit webhook token:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
whatsappChannel({
|
|
133
|
+
name: "support-whatsapp",
|
|
134
|
+
provider: "evolution",
|
|
135
|
+
secrets: [
|
|
136
|
+
"EVOLUTION_API_BASE_URL",
|
|
137
|
+
"EVOLUTION_API_KEY",
|
|
138
|
+
"EVOLUTION_INSTANCE_NAME",
|
|
139
|
+
"EVOLUTION_WEBHOOK_TOKEN",
|
|
140
|
+
],
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
AgentKit configures Evolution's webhook URL with `?token=<EVOLUTION_WEBHOOK_TOKEN>`, validates the token on ingress, redacts Evolution secret values, and rejects unsafe Evolution API base URLs before sending messages or downloading audio media.
|
|
145
|
+
|
|
115
146
|
## Verification
|
|
116
147
|
|
|
117
148
|
```sh
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Connect WhatsApp Through Evolution API
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Connect a self-hosted Evolution API WhatsApp instance to a hosted AgentKit WhatsApp channel.
|
|
6
|
+
|
|
7
|
+
## When To Use It
|
|
8
|
+
|
|
9
|
+
Use this after `whatsappChannel({ name: "main-whatsapp", provider: "evolution" })` exists in `agentkit.config.ts` and the capsule has been deployed.
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
agentkit deploy
|
|
15
|
+
agentkit channels connect whatsapp main-whatsapp --provider evolution
|
|
16
|
+
agentkit channels status main-whatsapp
|
|
17
|
+
agentkit channels test main-whatsapp --message "hello"
|
|
18
|
+
agentkit channels deliveries list main-whatsapp
|
|
19
|
+
agentkit channels buffers list main-whatsapp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Required secrets:
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
EVOLUTION_API_BASE_URL
|
|
26
|
+
EVOLUTION_API_KEY
|
|
27
|
+
EVOLUTION_INSTANCE_NAME
|
|
28
|
+
EVOLUTION_WEBHOOK_TOKEN
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
If WhatsApp audio transcription is enabled, also set the transcription provider secret declared by `agentkit inspect`, usually `OPENAI_API_KEY` or `GROQ_API_KEY`.
|
|
32
|
+
|
|
33
|
+
## Minimal Working Example
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { defineAgent, whatsappChannel } from "@andreprado/agentkit";
|
|
37
|
+
|
|
38
|
+
export default defineAgent({
|
|
39
|
+
name: "my-agent",
|
|
40
|
+
runtime: "edge",
|
|
41
|
+
provider: { name: "test", model: "fake" },
|
|
42
|
+
instructions: "./prompts/instructions.md",
|
|
43
|
+
secrets: [],
|
|
44
|
+
tools: [],
|
|
45
|
+
channels: [whatsappChannel({ name: "main-whatsapp", provider: "evolution" })],
|
|
46
|
+
access: { mode: "public" },
|
|
47
|
+
storage: { driver: "agentkit" },
|
|
48
|
+
});
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Setup Behavior
|
|
52
|
+
|
|
53
|
+
`agentkit channels connect whatsapp main-whatsapp --provider evolution` creates or updates the hosted channel, verifies managed secrets, calls Evolution API `POST /webhook/set/{instance}`, confirms the configured webhook through `GET /webhook/find/{instance}`, then runs a synthetic inbound smoke.
|
|
54
|
+
|
|
55
|
+
Expected webhook URL shape:
|
|
56
|
+
|
|
57
|
+
```txt
|
|
58
|
+
https://<deploy-host>/channels/main-whatsapp/whatsapp/evolution/webhook
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
AgentKit registers the webhook URL with the required token query parameter:
|
|
62
|
+
|
|
63
|
+
```txt
|
|
64
|
+
https://<deploy-host>/channels/main-whatsapp/whatsapp/evolution/webhook?token=<EVOLUTION_WEBHOOK_TOKEN>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`EVOLUTION_API_BASE_URL` must be the public HTTPS origin for the Evolution API server, for example `https://evolution.example.com`. AgentKit rejects HTTP, localhost, private-network, link-local, metadata, and credential-bearing base URLs before sending `EVOLUTION_API_KEY`.
|
|
68
|
+
|
|
69
|
+
## Audio
|
|
70
|
+
|
|
71
|
+
Use `transcription` at the agent level and `audio.mode: "transcribe"` on the Evolution channel.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
whatsappChannel({
|
|
75
|
+
name: "main-whatsapp",
|
|
76
|
+
provider: "evolution",
|
|
77
|
+
audio: {
|
|
78
|
+
mode: "transcribe",
|
|
79
|
+
},
|
|
80
|
+
})
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Evolution audio webhooks become normalized audio messages. The retryable channel worker downloads media through Evolution API `POST /chat/getBase64FromMediaMessage/{instance}` and sends the bytes to AgentKit's configured transcription provider.
|
|
84
|
+
|
|
85
|
+
## Safety Rules
|
|
86
|
+
|
|
87
|
+
- Keep phone numbers redacted in logs by default.
|
|
88
|
+
- Do not store Evolution API keys or webhook tokens in `agentkit.config.ts`.
|
|
89
|
+
- `EVOLUTION_WEBHOOK_TOKEN` is required because AgentKit V1 does not rely on an Evolution webhook body-signature contract.
|
|
90
|
+
- AgentKit ignores `fromMe` messages to avoid reply loops.
|
|
91
|
+
- Text replies call Evolution API `POST /message/sendText/{instance}` with the `apikey` header and a body containing `number` and `text`.
|
|
92
|
+
- Real provider success is recorded as `provider_sent` only when Evolution returns a provider message id.
|
|
93
|
+
- Only set `AGENTKIT_CHANNEL_SEND_DRY_RUN=1` in tests when Evolution should not receive a real message. Dry-run deliveries are recorded as `adapter_stubbed`, not sent.
|
|
94
|
+
|
|
95
|
+
## Verification
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
agentkit channels setup main-whatsapp --apply
|
|
99
|
+
agentkit channels status main-whatsapp
|
|
100
|
+
agentkit channels test main-whatsapp --message "hello"
|
|
101
|
+
agentkit channels test-audio main-whatsapp --fixture voice-note
|
|
102
|
+
agentkit channels deliveries list main-whatsapp
|
|
103
|
+
agentkit channels deliveries show <delivery-id>
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Troubleshooting
|
|
107
|
+
|
|
108
|
+
`channel_secret_missing`:
|
|
109
|
+
Set `EVOLUTION_API_BASE_URL`, `EVOLUTION_API_KEY`, `EVOLUTION_INSTANCE_NAME`, and `EVOLUTION_WEBHOOK_TOKEN` as hosted managed secrets.
|
|
110
|
+
|
|
111
|
+
`channel_signature_invalid`:
|
|
112
|
+
The Evolution webhook query token does not match.
|
|
113
|
+
|
|
114
|
+
`channel_provider_setup_invalid`:
|
|
115
|
+
`EVOLUTION_API_BASE_URL` is not an allowed public HTTPS base URL.
|
|
116
|
+
|
|
117
|
+
`channel_provider_setup_failed`:
|
|
118
|
+
AgentKit could not configure or verify the Evolution webhook through `/webhook/set/{instance}` and `/webhook/find/{instance}`.
|
|
119
|
+
|
|
120
|
+
`channel_audio_download_unavailable`:
|
|
121
|
+
Evolution did not return base64 media data from `/chat/getBase64FromMediaMessage/{instance}`, or the audio payload did not include a provider message id.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Connect WhatsApp Through UAZAPI
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Connect a UAZAPI WhatsApp instance to a hosted AgentKit WhatsApp channel.
|
|
6
|
+
|
|
7
|
+
## When To Use It
|
|
8
|
+
|
|
9
|
+
Use this after `whatsappChannel({ name: "support-whatsapp", provider: "uazapi" })` exists in `agentkit.config.ts` and the capsule has been deployed.
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
agentkit deploy
|
|
15
|
+
agentkit channels connect whatsapp support-whatsapp --provider uazapi
|
|
16
|
+
agentkit channels status support-whatsapp
|
|
17
|
+
agentkit channels test support-whatsapp --message "hello"
|
|
18
|
+
agentkit channels deliveries list support-whatsapp
|
|
19
|
+
agentkit channels buffers list support-whatsapp
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Required secrets:
|
|
23
|
+
|
|
24
|
+
```txt
|
|
25
|
+
UAZAPI_BASE_URL
|
|
26
|
+
UAZAPI_TOKEN
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Optional hardening secret:
|
|
30
|
+
|
|
31
|
+
```txt
|
|
32
|
+
UAZAPI_WEBHOOK_TOKEN
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
If WhatsApp audio transcription is enabled, also set the transcription provider secret declared by `agentkit inspect`, usually `OPENAI_API_KEY` or `GROQ_API_KEY`.
|
|
36
|
+
|
|
37
|
+
## Minimal Working Example
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { defineAgent, whatsappChannel } from "@andreprado/agentkit";
|
|
41
|
+
|
|
42
|
+
export default defineAgent({
|
|
43
|
+
name: "support-agent",
|
|
44
|
+
runtime: "edge",
|
|
45
|
+
provider: { name: "test", model: "fake" },
|
|
46
|
+
instructions: "./prompts/instructions.md",
|
|
47
|
+
secrets: [],
|
|
48
|
+
tools: [],
|
|
49
|
+
channels: [whatsappChannel({ name: "support-whatsapp", provider: "uazapi" })],
|
|
50
|
+
access: { mode: "public" },
|
|
51
|
+
storage: { driver: "agentkit" },
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Setup Behavior
|
|
56
|
+
|
|
57
|
+
`agentkit channels connect whatsapp support-whatsapp --provider uazapi` creates or updates the hosted channel, verifies managed secrets, calls UAZAPI `/webhook`, confirms the configured webhook is listed by UAZAPI, then runs a synthetic inbound smoke.
|
|
58
|
+
|
|
59
|
+
Expected webhook URL shape:
|
|
60
|
+
|
|
61
|
+
```txt
|
|
62
|
+
https://<deploy-host>/channels/support-whatsapp/whatsapp/uazapi/webhook
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If the channel declares `UAZAPI_WEBHOOK_TOKEN`, AgentKit registers the webhook URL with the token query parameter:
|
|
66
|
+
|
|
67
|
+
```txt
|
|
68
|
+
https://<deploy-host>/channels/support-whatsapp/whatsapp/uazapi/webhook?token=<UAZAPI_WEBHOOK_TOKEN>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`UAZAPI_BASE_URL` must be an HTTPS UAZAPI instance URL, for example `https://api.uazapi.com`. AgentKit rejects localhost, private-network, link-local, metadata, and credential-bearing base URLs before sending `UAZAPI_TOKEN`.
|
|
72
|
+
|
|
73
|
+
## Audio
|
|
74
|
+
|
|
75
|
+
Use `transcription` at the agent level and `audio.mode: "transcribe"` on the UAZAPI channel.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
whatsappChannel({
|
|
79
|
+
name: "support-whatsapp",
|
|
80
|
+
provider: "uazapi",
|
|
81
|
+
audio: {
|
|
82
|
+
mode: "transcribe",
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
UAZAPI audio webhooks become normalized audio messages. The retryable channel worker downloads media through UAZAPI `/message/download` using `return_base64: true`; AgentKit does not fetch arbitrary webhook-provided media URLs.
|
|
88
|
+
|
|
89
|
+
## Safety Rules
|
|
90
|
+
|
|
91
|
+
- Keep phone numbers redacted in logs by default.
|
|
92
|
+
- Do not store UAZAPI tokens in `agentkit.config.ts`.
|
|
93
|
+
- Use optional `UAZAPI_WEBHOOK_TOKEN` when the endpoint should require a secret query token in addition to the public route.
|
|
94
|
+
- UAZAPI does not expose a documented webhook body-signature contract in AgentKit V1; treat the optional query token as the hardening layer.
|
|
95
|
+
- AgentKit ignores `fromMe` and `wasSentByApi` messages to avoid reply loops.
|
|
96
|
+
- Text replies call UAZAPI `POST /send/text` with the `token` header and a body containing `number`, `text`, `readchat`, `async`, `track_source`, and `track_id`.
|
|
97
|
+
- Real provider success is recorded as `provider_sent` only when UAZAPI returns a provider message id.
|
|
98
|
+
- Only set `AGENTKIT_CHANNEL_SEND_DRY_RUN=1` in tests when UAZAPI should not receive a real message. Dry-run deliveries are recorded as `adapter_stubbed`, not sent.
|
|
99
|
+
|
|
100
|
+
## Verification
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
agentkit channels setup support-whatsapp --apply
|
|
104
|
+
agentkit channels status support-whatsapp
|
|
105
|
+
agentkit channels test support-whatsapp --message "hello"
|
|
106
|
+
agentkit channels test-audio support-whatsapp --fixture voice-note
|
|
107
|
+
agentkit channels deliveries list support-whatsapp
|
|
108
|
+
agentkit channels deliveries show <delivery-id>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
`channel_secret_missing`:
|
|
114
|
+
Set `UAZAPI_BASE_URL` and `UAZAPI_TOKEN` as hosted managed secrets. If the channel declares `UAZAPI_WEBHOOK_TOKEN`, set that managed secret too.
|
|
115
|
+
|
|
116
|
+
`channel_signature_invalid`:
|
|
117
|
+
The optional UAZAPI webhook query token does not match.
|
|
118
|
+
|
|
119
|
+
`channel_provider_setup_invalid`:
|
|
120
|
+
`UAZAPI_BASE_URL` is not an allowed HTTPS public base URL.
|
|
121
|
+
|
|
122
|
+
`channel_provider_setup_failed`:
|
|
123
|
+
AgentKit could not configure or verify the UAZAPI webhook through `/webhook`.
|
|
124
|
+
|
|
125
|
+
`channel_audio_download_unavailable`:
|
|
126
|
+
UAZAPI did not return base64 media data from `/message/download`, or the audio payload did not include a provider message id.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Goal
|
|
4
4
|
|
|
5
|
-
Diagnose website, Telegram, WhatsApp, Discord, or
|
|
5
|
+
Diagnose website, Telegram, WhatsApp, Discord, Slack, or generic webhook channel setup, webhook validation, dedupe, buffering, outbound sends, and delivery failures from the Agent Capsule CLI.
|
|
6
6
|
|
|
7
7
|
## When To Use It
|
|
8
8
|
|
|
@@ -69,7 +69,7 @@ Expected `show` output includes signature status, dedupe key, queue/run state, o
|
|
|
69
69
|
|
|
70
70
|
- Inspect delivery IDs, hashes, statuses, and redacted metadata rather than raw provider payloads.
|
|
71
71
|
- Never paste provider secrets into fixtures or prompts.
|
|
72
|
-
- Treat `adapter_stubbed` as
|
|
72
|
+
- Treat `adapter_stubbed` as "no outbound provider call happened", not proof that a client received a message. It can mean explicit dry-run mode or an inbound-only channel such as a generic webhook.
|
|
73
73
|
- Before replaying or flushing buffered conversations, confirm the channel name and conversation ID.
|
|
74
74
|
- Keep local `.env` values ignored and upload hosted production values through AgentKit secret commands.
|
|
75
75
|
|
|
@@ -117,7 +117,7 @@ The provider retried an already-processed event. No second agent run should be c
|
|
|
117
117
|
The message is accepted and waiting inside a per-conversation channel buffer. It should move to `queued` after the quiet window, max wait, max message count, or max character count.
|
|
118
118
|
|
|
119
119
|
`adapter_stubbed`:
|
|
120
|
-
The adapter
|
|
120
|
+
The adapter completed without calling an outbound provider. This can happen in explicit dry-run mode or for an inbound-only channel such as a generic webhook.
|
|
121
121
|
|
|
122
122
|
`provider_sent`:
|
|
123
123
|
The provider API accepted the outbound request and returned a provider message ID.
|
package/docs/llms-full.txt
CHANGED
|
@@ -60,8 +60,8 @@ agentkit conversations list
|
|
|
60
60
|
agentkit conversations show <conversation-id>
|
|
61
61
|
agentkit conversations trace <conversation-id> [--deploy]
|
|
62
62
|
agentkit channels list
|
|
63
|
-
agentkit channels add <website|telegram|whatsapp|discord|slack> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
|
|
64
|
-
agentkit channels connect <website|telegram|whatsapp|discord|slack> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
|
|
63
|
+
agentkit channels add <website|telegram|whatsapp|discord|slack|webhook> <name> [--provider zapster|meta|uazapi|evolution] [--mode interactions|bot] [--api <url>]
|
|
64
|
+
agentkit channels connect <website|telegram|whatsapp|discord|slack|webhook> <name> [--provider zapster|meta|uazapi|evolution] [--mode interactions|bot] [--api <url>]
|
|
65
65
|
agentkit channels setup <name> [--apply] [--api <url>]
|
|
66
66
|
agentkit channels status <name> [--api <url>]
|
|
67
67
|
agentkit channels test <name> [--message <text>] [--fixture <path>] [--api <url>]
|
|
@@ -344,7 +344,7 @@ Channels are hosted inbound/outbound conversation transports. They are separate
|
|
|
344
344
|
Use these helpers in `agentkit.config.ts`:
|
|
345
345
|
|
|
346
346
|
```ts
|
|
347
|
-
import { defineAgent, discordChannel, slackChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
|
|
347
|
+
import { defineAgent, discordChannel, slackChannel, telegramChannel, webhookChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
|
|
348
348
|
|
|
349
349
|
export default defineAgent({
|
|
350
350
|
name: "support-agent",
|
|
@@ -357,9 +357,11 @@ export default defineAgent({
|
|
|
357
357
|
websiteChannel({ name: "website-chat" }),
|
|
358
358
|
telegramChannel({ name: "support-telegram" }),
|
|
359
359
|
whatsappChannel({ name: "support-whatsapp", provider: "zapster" }),
|
|
360
|
+
whatsappChannel({ name: "support-uazapi", provider: "uazapi" }),
|
|
360
361
|
discordChannel({ name: "support-discord" }),
|
|
361
362
|
discordChannel({ name: "server-discord", mode: "bot" }),
|
|
362
363
|
slackChannel({ name: "support-slack" }),
|
|
364
|
+
webhookChannel({ name: "n8n-webhook" }),
|
|
363
365
|
],
|
|
364
366
|
access: { mode: "public" },
|
|
365
367
|
storage: { driver: "agentkit" },
|
|
@@ -398,6 +400,8 @@ Useful guides:
|
|
|
398
400
|
- Connect Discord: `docs/guides/connect-discord.md`
|
|
399
401
|
- Connect Slack: `docs/guides/connect-slack.md`
|
|
400
402
|
- Connect Telegram: `docs/guides/connect-telegram.md`
|
|
403
|
+
- Connect WhatsApp through Evolution API: `docs/guides/connect-whatsapp-evolution.md`
|
|
404
|
+
- Connect WhatsApp through UAZAPI: `docs/guides/connect-whatsapp-uazapi.md`
|
|
401
405
|
- Connect WhatsApp through Zapster: `docs/guides/connect-whatsapp-zapster.md`
|
|
402
406
|
- Debug a channel: `docs/guides/debug-channel.md`
|
|
403
407
|
- Channel security: `docs/guides/channel-security.md`
|
|
@@ -417,6 +421,22 @@ ZAPSTER_INSTANCE_ID
|
|
|
417
421
|
ZAPSTER_WEBHOOK_ID
|
|
418
422
|
```
|
|
419
423
|
|
|
424
|
+
UAZAPI WhatsApp required secrets:
|
|
425
|
+
|
|
426
|
+
```txt
|
|
427
|
+
UAZAPI_BASE_URL
|
|
428
|
+
UAZAPI_TOKEN
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Evolution API WhatsApp required secrets:
|
|
432
|
+
|
|
433
|
+
```txt
|
|
434
|
+
EVOLUTION_API_BASE_URL
|
|
435
|
+
EVOLUTION_API_KEY
|
|
436
|
+
EVOLUTION_INSTANCE_NAME
|
|
437
|
+
EVOLUTION_WEBHOOK_TOKEN
|
|
438
|
+
```
|
|
439
|
+
|
|
420
440
|
Discord slash-command required secret:
|
|
421
441
|
|
|
422
442
|
```txt
|
|
@@ -429,6 +449,24 @@ Discord bot-mode required secret:
|
|
|
429
449
|
DISCORD_BOT_TOKEN
|
|
430
450
|
```
|
|
431
451
|
|
|
452
|
+
Generic webhook required secret:
|
|
453
|
+
|
|
454
|
+
```txt
|
|
455
|
+
AGENTKIT_WEBHOOK_SECRET
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Generic webhook payloads should be canonical JSON:
|
|
459
|
+
|
|
460
|
+
```json
|
|
461
|
+
{
|
|
462
|
+
"event_id": "evt_123",
|
|
463
|
+
"external_id": "customer_123",
|
|
464
|
+
"message": "hello from n8n"
|
|
465
|
+
}
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Use `Authorization: Bearer <AGENTKIT_WEBHOOK_SECRET>`, `X-AgentKit-Webhook-Secret`, or `X-AgentKit-Webhook-Signature: sha256=<hmac>` where the HMAC is SHA-256 over the exact raw JSON body. The hosted URL is `/channels/<name>/webhook`.
|
|
469
|
+
|
|
432
470
|
Common channel verification:
|
|
433
471
|
|
|
434
472
|
```sh
|
|
@@ -436,9 +474,12 @@ agentkit inspect
|
|
|
436
474
|
agentkit deploy
|
|
437
475
|
agentkit channels list
|
|
438
476
|
agentkit channels add telegram support-telegram
|
|
477
|
+
agentkit channels connect whatsapp main-whatsapp --provider evolution
|
|
478
|
+
agentkit channels connect whatsapp support-whatsapp --provider uazapi
|
|
439
479
|
agentkit channels connect discord support-discord
|
|
440
480
|
agentkit channels connect discord server-discord --mode bot
|
|
441
481
|
agentkit channels connect slack support-slack
|
|
482
|
+
agentkit channels connect webhook n8n-webhook
|
|
442
483
|
agentkit channels setup support-telegram
|
|
443
484
|
agentkit channels test support-telegram --message "hello"
|
|
444
485
|
agentkit channels test-audio support-telegram --fixture voice-note
|
|
@@ -447,7 +488,7 @@ agentkit channels deliveries list support-telegram
|
|
|
447
488
|
agentkit channels deliveries show <delivery-id>
|
|
448
489
|
```
|
|
449
490
|
|
|
450
|
-
`channels connect` creates or refreshes the channel resource, validates secrets, runs provider setup when supported, then runs the official synthetic smoke. `channels setup` is read-only by default. `channels setup <telegram-name> --apply` calls Telegram `setWebhook` and requires `TELEGRAM_BOT_TOKEN` plus `TELEGRAM_WEBHOOK_SECRET`.
|
|
491
|
+
`channels connect` creates or refreshes the channel resource, validates secrets, runs provider setup when supported, then runs the official synthetic smoke. `channels setup` is read-only by default. `channels setup <telegram-name> --apply` calls Telegram `setWebhook` and requires `TELEGRAM_BOT_TOKEN` plus `TELEGRAM_WEBHOOK_SECRET`. `channels setup <uazapi-whatsapp-name> --apply` calls UAZAPI `/webhook` and requires `UAZAPI_BASE_URL` plus `UAZAPI_TOKEN`. `channels setup <evolution-whatsapp-name> --apply` calls Evolution API `/webhook/set/{instance}` and requires `EVOLUTION_API_BASE_URL`, `EVOLUTION_API_KEY`, `EVOLUTION_INSTANCE_NAME`, and `EVOLUTION_WEBHOOK_TOKEN`.
|
|
451
492
|
|
|
452
493
|
Discord slash-command mode validates `X-Signature-Ed25519` and `X-Signature-Timestamp` against `DISCORD_PUBLIC_KEY`, answers signed `PING` requests with `type: 1`, acknowledges slash commands with a deferred response, then sends the final answer as an interaction follow-up. Discord bot mode uses `DISCORD_BOT_TOKEN`, Discord Gateway `MESSAGE_CREATE`, Message Content Intent, and `/channels/<channel_id>/messages` bot replies. Discord channels support buffering but do not support `audio` in V1.
|
|
453
494
|
|
|
@@ -456,10 +497,14 @@ Default tests are offline. Real provider smoke tests are opt-in:
|
|
|
456
497
|
```sh
|
|
457
498
|
AGENTKIT_RUN_TELEGRAM_CHANNEL_TESTS=1 bun test
|
|
458
499
|
AGENTKIT_RUN_ZAPSTER_CHANNEL_TESTS=1 bun test
|
|
500
|
+
AGENTKIT_RUN_UAZAPI_CHANNEL_TESTS=1 bun test
|
|
501
|
+
AGENTKIT_RUN_EVOLUTION_CHANNEL_TESTS=1 bun test
|
|
459
502
|
```
|
|
460
503
|
|
|
461
504
|
Telegram smoke also requires `TELEGRAM_BOT_TOKEN`, `TELEGRAM_WEBHOOK_SECRET`, and `AGENTKIT_TELEGRAM_WEBHOOK_URL`.
|
|
462
505
|
Zapster smoke also requires `ZAPSTER_API_KEY`, `AGENTKIT_ZAPSTER_SEND_URL`, and `AGENTKIT_ZAPSTER_TO`.
|
|
506
|
+
UAZAPI smoke also requires `UAZAPI_BASE_URL`, `UAZAPI_TOKEN`, and `AGENTKIT_UAZAPI_TO`.
|
|
507
|
+
Evolution smoke also requires `EVOLUTION_API_BASE_URL`, `EVOLUTION_API_KEY`, `EVOLUTION_INSTANCE_NAME`, and `AGENTKIT_EVOLUTION_TO`.
|
|
463
508
|
|
|
464
509
|
## Tool Contract
|
|
465
510
|
|
package/docs/llms.txt
CHANGED
|
@@ -24,6 +24,8 @@ Task guides:
|
|
|
24
24
|
- Connect Discord: `docs/guides/connect-discord.md`
|
|
25
25
|
- Connect Slack: `docs/guides/connect-slack.md`
|
|
26
26
|
- Connect Telegram: `docs/guides/connect-telegram.md`
|
|
27
|
+
- Connect WhatsApp through Evolution API: `docs/guides/connect-whatsapp-evolution.md`
|
|
28
|
+
- Connect WhatsApp through UAZAPI: `docs/guides/connect-whatsapp-uazapi.md`
|
|
27
29
|
- Connect WhatsApp through Zapster: `docs/guides/connect-whatsapp-zapster.md`
|
|
28
30
|
- Follow channel webhook and delivery-log safety rules: `docs/guides/channel-security.md`
|
|
29
31
|
- Follow secret, access, and tool safety rules: `docs/guides/security-rules.md`
|
|
@@ -55,9 +57,12 @@ agentkit conversations show <conversation-id>
|
|
|
55
57
|
agentkit conversations trace <conversation-id> [--deploy]
|
|
56
58
|
agentkit channels list
|
|
57
59
|
agentkit channels add telegram support-telegram
|
|
60
|
+
agentkit channels connect whatsapp main-whatsapp --provider evolution
|
|
61
|
+
agentkit channels connect whatsapp support-whatsapp --provider uazapi
|
|
58
62
|
agentkit channels connect discord support-discord
|
|
59
63
|
agentkit channels connect discord server-discord --mode bot
|
|
60
64
|
agentkit channels connect slack support-slack
|
|
65
|
+
agentkit channels connect webhook n8n-webhook
|
|
61
66
|
agentkit channels setup support-telegram
|
|
62
67
|
agentkit channels status support-telegram
|
|
63
68
|
agentkit channels test support-telegram --message "hello"
|