@andreprado/agentkit 0.1.0-alpha.2 → 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 +68 -6
- package/docs/guides/add-channel.md +189 -7
- package/docs/guides/add-knowledge.md +144 -0
- package/docs/guides/add-managed-composio.md +163 -0
- package/docs/guides/add-tool.md +1 -1
- package/docs/guides/channel-security.md +128 -32
- package/docs/guides/connect-discord.md +178 -0
- package/docs/guides/connect-slack.md +126 -0
- package/docs/guides/connect-telegram.md +78 -1
- package/docs/guides/connect-whatsapp-evolution.md +121 -0
- package/docs/guides/connect-whatsapp-uazapi.md +126 -0
- package/docs/guides/connect-whatsapp-zapster.md +112 -8
- package/docs/guides/create-agent.md +45 -4
- package/docs/guides/debug-channel.md +147 -0
- package/docs/guides/improve-from-production.md +151 -0
- package/docs/guides/prepare-deploy.md +47 -17
- package/docs/guides/replay-production-traces.md +72 -0
- package/docs/guides/run-evals.md +147 -20
- package/docs/guides/security-rules.md +7 -6
- package/docs/guides/send-feedback.md +135 -0
- package/docs/guides/use-provider.md +27 -3
- package/docs/llms-full.txt +348 -55
- package/docs/llms.txt +62 -7
- package/package.json +2 -5
- package/src/cli/args.ts +57 -0
- package/src/cli/cloud-client.ts +377 -0
- package/src/cli/commands/channels.ts +1586 -0
- package/src/cli/commands/feedback.ts +438 -0
- package/src/cli/commands/knowledge.ts +136 -0
- package/src/cli/commands/transcribe.ts +171 -0
- package/src/cli/constants.ts +4 -0
- package/src/cli/deploy-chat-ui.ts +535 -0
- package/src/cli/deploy-readiness.ts +481 -0
- package/src/cli/flags.ts +162 -0
- package/src/cli/help.ts +236 -0
- package/src/cli/index.ts +1167 -1005
- package/src/cli/process.ts +31 -0
- package/src/cloud/artifact.ts +139 -0
- package/src/cloud/client.ts +80 -0
- package/src/cloud/contracts.ts +63 -0
- package/src/cloud/index.ts +3 -0
- package/src/create-project.ts +21 -6
- package/src/index.ts +517 -8
- package/src/providers/pi.ts +70 -16
- package/src/providers/test.ts +88 -1
- package/src/providers/types.ts +7 -0
- package/src/runtime/channel-buffer.ts +30 -0
- package/src/runtime/channel-test-harness.ts +21 -1
- package/src/runtime/channels/discord.ts +896 -0
- package/src/runtime/channels/generic-webhook.ts +225 -0
- package/src/runtime/channels/slack.ts +646 -0
- package/src/runtime/channels/telegram.ts +466 -23
- package/src/runtime/channels/whatsapp-evolution.ts +1357 -0
- package/src/runtime/channels/whatsapp-meta.ts +9 -0
- package/src/runtime/channels/whatsapp-uazapi.ts +1327 -0
- package/src/runtime/channels/whatsapp-zapster.ts +677 -40
- package/src/runtime/channels.ts +87 -4
- package/src/runtime/chat.ts +130 -38
- package/src/runtime/config.ts +519 -19
- package/src/runtime/core/manifest.ts +103 -5
- package/src/runtime/core/targets.ts +5 -5
- package/src/runtime/database.ts +93 -2
- package/src/runtime/db-commands.ts +9 -0
- package/src/runtime/deploy-readiness.ts +46 -4
- package/src/runtime/deploy.ts +1 -1
- package/src/runtime/dev-server.ts +779 -45
- package/src/runtime/env.ts +8 -3
- package/src/runtime/evals.ts +589 -43
- package/src/runtime/improve.ts +868 -0
- package/src/runtime/inspect.ts +194 -4
- package/src/runtime/integrations/composio.ts +423 -0
- package/src/runtime/knowledge/chunk.ts +333 -0
- package/src/runtime/knowledge/config.ts +135 -0
- package/src/runtime/knowledge/embeddings.ts +133 -0
- package/src/runtime/knowledge/ingest.ts +521 -0
- package/src/runtime/knowledge/prompt-policy.ts +30 -0
- package/src/runtime/knowledge/retrieve.ts +303 -0
- package/src/runtime/knowledge/schema.ts +100 -0
- package/src/runtime/knowledge/tool.ts +64 -0
- package/src/runtime/knowledge/vector.ts +258 -0
- package/src/runtime/prompt-context.ts +141 -0
- package/src/runtime/runtime-contract.ts +86 -8
- package/src/runtime/skills.ts +95 -0
- package/src/runtime/spec.ts +152 -0
- package/src/runtime/sync.ts +144 -0
- package/src/runtime/targets/cloudflare/build.ts +1468 -203
- package/src/runtime/targets/container/server.ts +1 -1
- package/src/runtime/targets/vps/deploy.ts +26 -9
- package/src/runtime/tool-runner.ts +9 -1
- package/src/runtime/tools.ts +128 -2
- package/src/runtime/traces.ts +41 -0
- package/src/runtime/transcription.ts +483 -0
- package/src/storage/sqlite.ts +149 -3
- package/src/templates/blank.ts +76 -17
- package/src/templates/dentista.ts +1011 -0
- package/src/templates/index.ts +2 -0
- package/src/templates/skills/agentkit-build-agent/SKILL.md +52 -0
- package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +21 -0
- package/src/templates/skills/agentkit-build-agent/templates/sales-qualifier.instructions.md +17 -0
- package/src/templates/skills/agentkit-build-agent/templates/support-agent.instructions.md +16 -0
- package/src/templates/skills/agentkit-capsule/SKILL.md +70 -0
- package/src/templates/skills/agentkit-capsule/references/docs-router.md +15 -0
- package/src/templates/skills/agentkit-channels/SKILL.md +127 -0
- package/src/templates/skills/agentkit-channels/references/channel-buffering.md +65 -0
- package/src/templates/skills/agentkit-channels/references/channel-debugging.md +66 -0
- package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
- package/src/templates/skills/agentkit-channels/references/slack.md +56 -0
- package/src/templates/skills/agentkit-channels/references/telegram.md +72 -0
- 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/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +77 -0
- package/src/templates/skills/agentkit-database/SKILL.md +45 -0
- package/src/templates/skills/agentkit-database/templates/appointments.schema.sql +15 -0
- package/src/templates/skills/agentkit-database/templates/leads.schema.sql +17 -0
- package/src/templates/skills/agentkit-deploy/SKILL.md +50 -0
- package/src/templates/skills/agentkit-evals/SKILL.md +109 -0
- package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +29 -0
- package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +18 -0
- package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +18 -0
- package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +27 -0
- package/src/templates/skills/agentkit-improve/SKILL.md +86 -0
- package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
- package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
- package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
- package/src/templates/skills/agentkit-integrations/SKILL.md +76 -0
- package/src/templates/skills/agentkit-knowledge/SKILL.md +43 -0
- package/src/templates/skills/agentkit-knowledge/templates/faq.md +14 -0
- package/src/templates/skills/agentkit-knowledge/templates/policies.md +14 -0
- package/src/templates/skills/agentkit-knowledge/templates/prices.csv +3 -0
- package/src/templates/skills/agentkit-prompts/SKILL.md +47 -0
- package/src/templates/skills/agentkit-prompts/templates/knowledge-grounded-faq.instructions.md +11 -0
- package/src/templates/skills/agentkit-provider/SKILL.md +60 -0
- package/src/templates/skills/agentkit-security/SKILL.md +56 -0
- package/src/templates/skills/agentkit-tools/SKILL.md +37 -0
- package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +35 -0
- package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +37 -0
- package/src/templates/skills/agentkit-tools/examples/lookup-order.tool.md +46 -0
- package/src/templates/skills/agentkit-troubleshooting/SKILL.md +76 -0
- package/src/templates/support.ts +77 -18
- package/docs/guides/channels-production-handoff.md +0 -99
- package/docs/portable-deploy-release-checklist.md +0 -41
- package/src/runtime/targets/cloudflare/deploy.ts +0 -5475
|
@@ -2,48 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|
## Goal
|
|
4
4
|
|
|
5
|
-
|
|
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
|
|
|
9
|
-
Use this
|
|
9
|
+
Use this when a coding agent adds or changes channels in an Agent Capsule, enables audio transcription, inspects deliveries, or prepares a hosted deploy that receives provider webhooks.
|
|
10
10
|
|
|
11
11
|
## Commands
|
|
12
12
|
|
|
13
13
|
```sh
|
|
14
14
|
agentkit inspect
|
|
15
15
|
agentkit channels status <name>
|
|
16
|
+
agentkit channels doctor <name>
|
|
17
|
+
agentkit channels deliveries list <name> --since 24h
|
|
16
18
|
agentkit channels deliveries show <delivery-id>
|
|
17
|
-
bun test packages/agentkit/src/runtime/channels/adapters.test.ts
|
|
18
|
-
bun test packages/agentkit/src/runtime/deploy.test.ts
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Real-provider gates are opt-in:
|
|
22
|
-
|
|
23
|
-
```sh
|
|
24
|
-
AGENTKIT_RUN_TELEGRAM_CHANNEL_TESTS=1 bun test
|
|
25
|
-
AGENTKIT_RUN_ZAPSTER_CHANNEL_TESTS=1 bun test
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Telegram smoke also requires `TELEGRAM_BOT_TOKEN`, `TELEGRAM_WEBHOOK_SECRET`, and `AGENTKIT_TELEGRAM_WEBHOOK_URL`.
|
|
29
|
-
|
|
30
|
-
Zapster smoke also requires `ZAPSTER_API_KEY`, `AGENTKIT_ZAPSTER_SEND_URL`, and `AGENTKIT_ZAPSTER_TO`.
|
|
31
|
-
|
|
32
21
|
## Files Created Or Edited
|
|
33
22
|
|
|
34
|
-
- `agentkit.config.ts`: secret names only.
|
|
35
|
-
-
|
|
36
|
-
-
|
|
23
|
+
- `agentkit.config.ts`: channel names, provider choices, audio/buffer config, and secret names only.
|
|
24
|
+
- `.env.schema`: local secret names only when the capsule needs a local provider or local smoke.
|
|
25
|
+
- `.env`: local-only secret values; do not commit it.
|
|
26
|
+
- Hosted managed secrets: production secret values with no readback.
|
|
37
27
|
|
|
38
28
|
## Safety Rules
|
|
39
29
|
|
|
40
30
|
- Public webhook URLs are not permission grants.
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
- Do not store raw webhook bodies in
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
31
|
+
- Keep provider tokens, webhook secrets, bot tokens, transcription keys, and bearer tokens out of source files.
|
|
32
|
+
- Put secret names in `agentkit.config.ts`; put local values in ignored `.env`; upload production values with `agentkit secret set` or `agentkit secret sync`.
|
|
33
|
+
- Do not store raw webhook bodies, raw audio, or provider secret values in tools, prompts, evals, fixtures, or delivery notes.
|
|
34
|
+
- Do not expose Discord interaction tokens or bot tokens. Interaction tokens are reply tokens, not public identifiers.
|
|
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.
|
|
39
|
+
- Inspect delivery IDs, hashes, redacted metadata, and statuses instead of raw provider payloads.
|
|
40
|
+
- Keep channel plumbing out of the agent's application database. The user's Turso tables are for the agent's business data.
|
|
41
|
+
- Enable audio transcription only when the capsule declares a transcription provider and bounded `limits`.
|
|
42
|
+
- Keep channel buffer limits bounded so bursty client messages cannot create unbounded runs or provider spend.
|
|
47
43
|
|
|
48
44
|
## Minimal Working Example
|
|
49
45
|
|
|
@@ -54,28 +50,128 @@ telegramChannel({
|
|
|
54
50
|
});
|
|
55
51
|
```
|
|
56
52
|
|
|
57
|
-
|
|
53
|
+
With audio transcription:
|
|
54
|
+
|
|
55
|
+
```ts
|
|
56
|
+
export default defineAgent({
|
|
57
|
+
// ...
|
|
58
|
+
transcription: {
|
|
59
|
+
provider: "groq",
|
|
60
|
+
model: "whisper-large-v3-turbo",
|
|
61
|
+
secret: "GROQ_API_KEY",
|
|
62
|
+
limits: {
|
|
63
|
+
maxDurationSeconds: 180,
|
|
64
|
+
maxBytes: 20_000_000,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
channels: [
|
|
68
|
+
telegramChannel({
|
|
69
|
+
name: "support-telegram",
|
|
70
|
+
audio: { mode: "transcribe" },
|
|
71
|
+
}),
|
|
72
|
+
],
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The config contains secret names only. Hosted responses report status, not values:
|
|
58
77
|
|
|
59
78
|
```txt
|
|
60
79
|
TELEGRAM_BOT_TOKEN: set
|
|
61
80
|
TELEGRAM_WEBHOOK_SECRET: missing
|
|
81
|
+
GROQ_API_KEY: set
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Discord slash-command mode uses a public key rather than a shared webhook secret:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
discordChannel({
|
|
88
|
+
name: "support-discord",
|
|
89
|
+
secrets: ["DISCORD_PUBLIC_KEY"],
|
|
90
|
+
});
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
AgentKit validates `X-Signature-Ed25519` and `X-Signature-Timestamp` against the raw body, returns `type: 1` for Discord `PING`, and sends follow-up replies with `allowed_mentions: { parse: [] }`.
|
|
94
|
+
|
|
95
|
+
Discord bot mode uses a bot token and Gateway connection:
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
discordChannel({
|
|
99
|
+
name: "server-discord",
|
|
100
|
+
mode: "bot",
|
|
101
|
+
secrets: ["DISCORD_BOT_TOKEN"],
|
|
102
|
+
});
|
|
62
103
|
```
|
|
63
104
|
|
|
105
|
+
Bot mode requires Message Content Intent in the Discord Developer Portal and channel permissions for `View Channel`, `Read Message History`, and `Send Messages`. AgentKit must redact `DISCORD_BOT_TOKEN` anywhere delivery, queue, buffer, or doctor output is returned.
|
|
106
|
+
|
|
107
|
+
Slack Events API uses a bot token and signing secret:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
slackChannel({
|
|
111
|
+
name: "support-slack",
|
|
112
|
+
secrets: ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"],
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
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.
|
|
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
|
+
|
|
64
146
|
## Verification
|
|
65
147
|
|
|
66
148
|
```sh
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
npm run
|
|
149
|
+
npm run agentkit -- inspect
|
|
150
|
+
npm run agentkit -- deploy doctor
|
|
151
|
+
npm run agentkit -- channels status <name>
|
|
152
|
+
npm run agentkit -- channels doctor <name>
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
For a synthetic channel smoke after deploy:
|
|
156
|
+
|
|
157
|
+
```sh
|
|
158
|
+
npm run agentkit -- channels test <name> --message "hello"
|
|
159
|
+
npm run agentkit -- channels deliveries list <name> --since 1h
|
|
70
160
|
```
|
|
71
161
|
|
|
72
162
|
## Troubleshooting
|
|
73
163
|
|
|
74
164
|
Secret value appears in output:
|
|
75
|
-
Stop and
|
|
165
|
+
Stop and remove the value from source, fixtures, prompts, evals, and delivery notes. Hosted delivery APIs must not return secret values.
|
|
76
166
|
|
|
77
167
|
Phone number appears in delivery logs:
|
|
78
|
-
|
|
168
|
+
Use the redacted delivery metadata and avoid pasting full phone numbers into committed fixtures.
|
|
169
|
+
|
|
170
|
+
`channel_secret_missing`:
|
|
171
|
+
Set the named hosted secret with `agentkit secret set <NAME> --from-local-env` or `agentkit secret sync --from-local`.
|
|
172
|
+
|
|
173
|
+
`channel_signature_invalid`:
|
|
174
|
+
Check that the provider webhook secret/token configured in the provider dashboard matches the hosted secret name declared by the channel. For Discord slash-command mode, check that `DISCORD_PUBLIC_KEY` matches the application's public key. For Discord bot mode, check that `DISCORD_BOT_TOKEN` is set and Message Content Intent is enabled.
|
|
79
175
|
|
|
80
|
-
|
|
81
|
-
|
|
176
|
+
Raw audio appears in files or logs:
|
|
177
|
+
Remove it. AgentKit may pass transcript text into the normalized agent message after successful transcription, but raw audio belongs outside committed capsule files.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Connect Discord
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Connect Discord to a hosted AgentKit channel. Discord has two supported modes:
|
|
6
|
+
|
|
7
|
+
- `interactions`: slash commands through Discord's Interactions Endpoint URL.
|
|
8
|
+
- `bot`: normal server messages through a Discord Bot user connected to the Gateway.
|
|
9
|
+
|
|
10
|
+
Use `bot` mode when the agent should answer messages without a slash command.
|
|
11
|
+
|
|
12
|
+
## Commands
|
|
13
|
+
|
|
14
|
+
Slash-command mode:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
agentkit deploy
|
|
18
|
+
agentkit secret set DISCORD_PUBLIC_KEY --stdin
|
|
19
|
+
agentkit channels connect discord support-discord
|
|
20
|
+
agentkit channels test support-discord --message "hello"
|
|
21
|
+
agentkit channels deliveries list support-discord
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Bot/server-message mode:
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
agentkit deploy
|
|
28
|
+
agentkit secret set DISCORD_BOT_TOKEN --stdin
|
|
29
|
+
agentkit channels connect discord server-discord --mode bot
|
|
30
|
+
agentkit channels test server-discord --message "hello"
|
|
31
|
+
agentkit channels deliveries list server-discord
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Minimal Config
|
|
35
|
+
|
|
36
|
+
Slash commands:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
discordChannel({ name: "support-discord" })
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Normal server messages:
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
discordChannel({
|
|
46
|
+
name: "server-discord",
|
|
47
|
+
mode: "bot",
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Full example:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { defineAgent, discordChannel } from "@andreprado/agentkit";
|
|
55
|
+
|
|
56
|
+
export default defineAgent({
|
|
57
|
+
name: "support-agent",
|
|
58
|
+
runtime: "edge",
|
|
59
|
+
provider: { name: "test", model: "fake" },
|
|
60
|
+
instructions: "./prompts/instructions.md",
|
|
61
|
+
secrets: [],
|
|
62
|
+
tools: [],
|
|
63
|
+
channels: [
|
|
64
|
+
discordChannel({
|
|
65
|
+
name: "server-discord",
|
|
66
|
+
mode: "bot",
|
|
67
|
+
buffer: {
|
|
68
|
+
mode: "debounce",
|
|
69
|
+
quietWindowMs: 1500,
|
|
70
|
+
maxWaitMs: 8000,
|
|
71
|
+
maxMessages: 20,
|
|
72
|
+
maxChars: 8000,
|
|
73
|
+
},
|
|
74
|
+
}),
|
|
75
|
+
],
|
|
76
|
+
access: { mode: "public" },
|
|
77
|
+
storage: { driver: "agentkit" },
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Discord audio transcription is not supported in V1. Do not add `audio` to a Discord channel.
|
|
82
|
+
|
|
83
|
+
## Slash Command Setup
|
|
84
|
+
|
|
85
|
+
Use this when users should run `/ask message:<text>`.
|
|
86
|
+
|
|
87
|
+
Required secret:
|
|
88
|
+
|
|
89
|
+
```txt
|
|
90
|
+
DISCORD_PUBLIC_KEY
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`agentkit channels connect discord support-discord` creates or refreshes the hosted channel, validates the public key, runs an AgentKit synthetic smoke, and prints the human setup step.
|
|
94
|
+
|
|
95
|
+
Expected webhook URL:
|
|
96
|
+
|
|
97
|
+
```txt
|
|
98
|
+
https://<deploy-host>/channels/support-discord/discord/discord/webhook
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
In the Discord Developer Portal:
|
|
102
|
+
|
|
103
|
+
1. Open the application.
|
|
104
|
+
2. Copy the application's public key into the hosted secret named `DISCORD_PUBLIC_KEY`.
|
|
105
|
+
3. Paste the AgentKit webhook URL into `Interactions Endpoint URL`.
|
|
106
|
+
4. Register a slash command with a string option named `message`, `text`, `prompt`, `question`, `query`, or `input`.
|
|
107
|
+
|
|
108
|
+
AgentKit answers Discord's `PING` handshake with `{ "type": 1 }`. Normal command webhooks are acknowledged with a deferred response and the retryable channel worker sends the final answer as an interaction follow-up.
|
|
109
|
+
|
|
110
|
+
## Bot Setup
|
|
111
|
+
|
|
112
|
+
Use this when the agent should behave like a server member and answer normal messages.
|
|
113
|
+
|
|
114
|
+
Required secret:
|
|
115
|
+
|
|
116
|
+
```txt
|
|
117
|
+
DISCORD_BOT_TOKEN
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`agentkit channels connect discord server-discord --mode bot` creates or refreshes the hosted channel, validates the bot token secret is present, runs an AgentKit synthetic Gateway smoke, and prints the human setup step.
|
|
121
|
+
|
|
122
|
+
In the Discord Developer Portal:
|
|
123
|
+
|
|
124
|
+
1. Create or open the Discord application.
|
|
125
|
+
2. Open the Bot page.
|
|
126
|
+
3. Reset/copy the bot token and save it as hosted secret `DISCORD_BOT_TOKEN`.
|
|
127
|
+
4. Enable Message Content Intent on the Bot page.
|
|
128
|
+
5. Install the app into the server with bot permissions.
|
|
129
|
+
6. Grant the bot `View Channel`, `Read Message History`, and `Send Messages` in the channels it should answer.
|
|
130
|
+
|
|
131
|
+
Hosted AgentKit runs a Discord Gateway worker for bot-mode channels. Discord sends `MESSAGE_CREATE` events, AgentKit ignores messages authored by bots, maps each human message to a channel conversation, runs the agent, and replies in the same Discord channel with `allowed_mentions: { parse: [] }`.
|
|
132
|
+
|
|
133
|
+
For server hygiene, install or grant the bot only in channels where it should answer. Bot mode processes every readable non-bot text message the Gateway sends for that bot.
|
|
134
|
+
|
|
135
|
+
## Safety Rules
|
|
136
|
+
|
|
137
|
+
- Keep `DISCORD_PUBLIC_KEY` and `DISCORD_BOT_TOKEN` as managed hosted secrets; do not put values in prompts, fixtures, or source files.
|
|
138
|
+
- Discord interaction tokens and bot tokens must never appear in delivery, queue, buffer, or doctor API responses.
|
|
139
|
+
- Slash-command validation uses `X-Signature-Ed25519` and `X-Signature-Timestamp` against the exact raw request body.
|
|
140
|
+
- Bot mode requires Discord Message Content Intent; without it, Discord sends empty message content and AgentKit skips the event.
|
|
141
|
+
- Outbound Discord sends use `allowed_mentions: { parse: [] }` so agent text cannot accidentally ping users or roles.
|
|
142
|
+
- Only set `AGENTKIT_CHANNEL_SEND_DRY_RUN=1` in tests when Discord should not receive a real reply. Dry-run deliveries are recorded as `adapter_stubbed`.
|
|
143
|
+
|
|
144
|
+
## Verification
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
agentkit channels status server-discord
|
|
148
|
+
agentkit channels test server-discord --message "hello"
|
|
149
|
+
agentkit channels deliveries list server-discord
|
|
150
|
+
agentkit channels deliveries show <delivery-id>
|
|
151
|
+
agentkit channels buffers list server-discord
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Expected bot-mode flow:
|
|
155
|
+
|
|
156
|
+
1. A user sends a normal message in a Discord server channel where the bot has access.
|
|
157
|
+
2. Discord sends `MESSAGE_CREATE` over the Gateway.
|
|
158
|
+
3. AgentKit records an inbound delivery and enqueues the channel job.
|
|
159
|
+
4. The channel queue runs the agent.
|
|
160
|
+
5. AgentKit sends a bot message through `/channels/<channel_id>/messages`.
|
|
161
|
+
6. Delivery status becomes `provider_sent` for a real provider send or `adapter_stubbed` in dry-run mode.
|
|
162
|
+
|
|
163
|
+
## Troubleshooting
|
|
164
|
+
|
|
165
|
+
`channel_secret_missing`:
|
|
166
|
+
Set `DISCORD_PUBLIC_KEY` for slash-command mode or `DISCORD_BOT_TOKEN` for bot mode as a hosted managed secret.
|
|
167
|
+
|
|
168
|
+
Bot does not answer normal messages:
|
|
169
|
+
Confirm the channel was created with `--mode bot`, `DISCORD_BOT_TOKEN` is set, Message Content Intent is enabled in the Discord Developer Portal, and the bot has channel permissions to view, read history, and send messages.
|
|
170
|
+
|
|
171
|
+
Bot answers nothing and delivery events show empty content:
|
|
172
|
+
Discord Message Content Intent is missing, disabled, or not approved for the application.
|
|
173
|
+
|
|
174
|
+
Discord Developer Portal rejects the slash-command endpoint:
|
|
175
|
+
Confirm the deployed interaction channel is online, `DISCORD_PUBLIC_KEY` matches the application's public key, and the endpoint returns `{ "type": 1 }` for Discord's signed `PING` request.
|
|
176
|
+
|
|
177
|
+
No answer appears after a queued delivery:
|
|
178
|
+
Run `agentkit channels deliveries list <name>`, inspect the inbound delivery, and drain/check the channel queue.
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# Connect Slack
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Connect Slack to a hosted AgentKit channel through Slack Events API.
|
|
6
|
+
|
|
7
|
+
V1 supports:
|
|
8
|
+
|
|
9
|
+
- `app_mention` events in channels.
|
|
10
|
+
- `message.im` direct messages.
|
|
11
|
+
- Replies through `chat.postMessage`.
|
|
12
|
+
|
|
13
|
+
Slack Socket Mode, file events, audio transcription, app-management automation, and all-channel message listening are not supported in V1.
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
agentkit deploy
|
|
19
|
+
agentkit secret set SLACK_BOT_TOKEN --stdin
|
|
20
|
+
agentkit secret set SLACK_SIGNING_SECRET --stdin
|
|
21
|
+
agentkit channels connect slack support-slack
|
|
22
|
+
agentkit channels test support-slack --message "hello"
|
|
23
|
+
agentkit channels deliveries list support-slack
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Minimal Config
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { defineAgent, slackChannel } from "@andreprado/agentkit";
|
|
30
|
+
|
|
31
|
+
export default defineAgent({
|
|
32
|
+
name: "support-agent",
|
|
33
|
+
runtime: "edge",
|
|
34
|
+
provider: { name: "test", model: "fake" },
|
|
35
|
+
instructions: "./prompts/instructions.md",
|
|
36
|
+
secrets: [],
|
|
37
|
+
tools: [],
|
|
38
|
+
channels: [slackChannel({ name: "support-slack" })],
|
|
39
|
+
access: { mode: "public" },
|
|
40
|
+
storage: { driver: "agentkit" },
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Slack App Setup
|
|
45
|
+
|
|
46
|
+
Required hosted secrets:
|
|
47
|
+
|
|
48
|
+
```txt
|
|
49
|
+
SLACK_BOT_TOKEN
|
|
50
|
+
SLACK_SIGNING_SECRET
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Expected webhook URL:
|
|
54
|
+
|
|
55
|
+
```txt
|
|
56
|
+
https://<deploy-host>/channels/support-slack/slack/slack/webhook
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
In Slack app configuration:
|
|
60
|
+
|
|
61
|
+
1. Open **Basic Information** and copy the Signing Secret into hosted secret `SLACK_SIGNING_SECRET`.
|
|
62
|
+
2. Open **OAuth & Permissions** and add bot scopes:
|
|
63
|
+
- `app_mentions:read`
|
|
64
|
+
- `im:history`
|
|
65
|
+
- `chat:write`
|
|
66
|
+
3. Install or reinstall the app to the workspace.
|
|
67
|
+
4. Copy the Bot User OAuth Token into hosted secret `SLACK_BOT_TOKEN`.
|
|
68
|
+
5. Open **Event Subscriptions**.
|
|
69
|
+
6. Enable events and paste the AgentKit webhook URL as the Request URL.
|
|
70
|
+
7. Subscribe to bot events:
|
|
71
|
+
- `app_mention`
|
|
72
|
+
- `message.im`
|
|
73
|
+
|
|
74
|
+
AgentKit answers Slack `url_verification` challenges with the literal challenge string after signature validation.
|
|
75
|
+
|
|
76
|
+
## Runtime Behavior
|
|
77
|
+
|
|
78
|
+
Slack signs each request with `X-Slack-Signature` and `X-Slack-Request-Timestamp`. AgentKit verifies the signature against the raw body and rejects stale timestamps before normalizing events.
|
|
79
|
+
|
|
80
|
+
For channel mentions, AgentKit maps the conversation to the Slack thread and replies in that thread. For direct messages, AgentKit maps the conversation to the Slack DM channel and user.
|
|
81
|
+
|
|
82
|
+
AgentKit skips Slack bot/subtype messages to avoid reply loops. Outbound Slack delivery uses `chat.postMessage` with `parse: "none"`, disabled link-name expansion, disabled unfurls, and escaped Slack control mentions.
|
|
83
|
+
|
|
84
|
+
## Safety Rules
|
|
85
|
+
|
|
86
|
+
- Keep `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` as managed hosted secrets; do not put values in prompts, fixtures, evals, or source files.
|
|
87
|
+
- Do not configure `audio` on `slackChannel`; Slack audio is not supported in V1.
|
|
88
|
+
- Keep bot scopes narrow. V1 does not require broad channel-history scopes for all-channel listening.
|
|
89
|
+
- Only set `AGENTKIT_CHANNEL_SEND_DRY_RUN=1` in tests when Slack should not receive a real reply.
|
|
90
|
+
- Delivery logs return hashes and redacted metadata, never raw Slack request bodies or token values.
|
|
91
|
+
|
|
92
|
+
## Verification
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
agentkit channels status support-slack
|
|
96
|
+
agentkit channels test support-slack --message "hello"
|
|
97
|
+
agentkit channels deliveries list support-slack
|
|
98
|
+
agentkit channels deliveries show <delivery-id>
|
|
99
|
+
agentkit channels buffers list support-slack
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Expected flow:
|
|
103
|
+
|
|
104
|
+
1. A user mentions the Slack app or sends it a direct message.
|
|
105
|
+
2. Slack sends a signed Events API request.
|
|
106
|
+
3. AgentKit records an inbound delivery and enqueues the channel job.
|
|
107
|
+
4. The channel queue runs the agent.
|
|
108
|
+
5. AgentKit sends a Slack reply through `chat.postMessage`.
|
|
109
|
+
6. Delivery status becomes `provider_sent` for a real provider send or `adapter_stubbed` in dry-run mode.
|
|
110
|
+
|
|
111
|
+
## Troubleshooting
|
|
112
|
+
|
|
113
|
+
`channel_secret_missing`:
|
|
114
|
+
Set `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` as hosted managed secrets.
|
|
115
|
+
|
|
116
|
+
Slack rejects the Request URL:
|
|
117
|
+
Confirm the deployed channel is online, `SLACK_SIGNING_SECRET` matches the Slack app, and the endpoint can answer Slack's signed `url_verification` challenge.
|
|
118
|
+
|
|
119
|
+
No channel mention arrives:
|
|
120
|
+
Confirm Event Subscriptions includes `app_mention`, the app is installed in the workspace, and the app has access to the channel where it is mentioned.
|
|
121
|
+
|
|
122
|
+
No direct message arrives:
|
|
123
|
+
Confirm Event Subscriptions includes `message.im` and the app has `im:history`.
|
|
124
|
+
|
|
125
|
+
No answer appears after a queued delivery:
|
|
126
|
+
Run `agentkit channels deliveries list support-slack`, inspect the inbound delivery, and drain/check the channel queue.
|
|
@@ -27,6 +27,12 @@ TELEGRAM_BOT_TOKEN
|
|
|
27
27
|
TELEGRAM_WEBHOOK_SECRET
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
If Telegram audio transcription is enabled, also set the transcription provider secret declared by `agentkit inspect`, usually:
|
|
31
|
+
|
|
32
|
+
```txt
|
|
33
|
+
GROQ_API_KEY
|
|
34
|
+
```
|
|
35
|
+
|
|
30
36
|
## Files Created Or Edited
|
|
31
37
|
|
|
32
38
|
- `agentkit.config.ts`: `telegramChannel({ name: "support-telegram" })`.
|
|
@@ -51,6 +57,67 @@ export default defineAgent({
|
|
|
51
57
|
});
|
|
52
58
|
```
|
|
53
59
|
|
|
60
|
+
To answer once after a burst of Telegram messages, enable channel buffering:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
telegramChannel({
|
|
64
|
+
name: "support-telegram",
|
|
65
|
+
buffer: {
|
|
66
|
+
mode: "debounce",
|
|
67
|
+
quietWindowMs: 1500,
|
|
68
|
+
maxWaitMs: 8000,
|
|
69
|
+
maxMessages: 20,
|
|
70
|
+
maxChars: 8000,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Auto Transcribe Telegram Audio
|
|
76
|
+
|
|
77
|
+
Telegram voice notes arrive as OGG/Opus. In V1, use Groq for the most obvious Telegram voice-note path because the AgentKit Groq adapter accepts `audio/ogg`.
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
import { defineAgent, telegramChannel } from "@andreprado/agentkit";
|
|
81
|
+
|
|
82
|
+
export default defineAgent({
|
|
83
|
+
name: "support-agent",
|
|
84
|
+
runtime: "edge",
|
|
85
|
+
provider: { name: "openai", model: "gpt-5.4-mini" },
|
|
86
|
+
instructions: "./prompts/instructions.md",
|
|
87
|
+
transcription: {
|
|
88
|
+
provider: "groq",
|
|
89
|
+
model: "whisper-large-v3-turbo",
|
|
90
|
+
secret: "GROQ_API_KEY",
|
|
91
|
+
language: "pt",
|
|
92
|
+
limits: {
|
|
93
|
+
maxDurationSeconds: 180,
|
|
94
|
+
maxBytes: 20_000_000,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
channels: [
|
|
98
|
+
telegramChannel({
|
|
99
|
+
name: "support-telegram",
|
|
100
|
+
audio: {
|
|
101
|
+
mode: "transcribe",
|
|
102
|
+
},
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
access: { mode: "public" },
|
|
106
|
+
storage: { driver: "agentkit" },
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Processing order:
|
|
111
|
+
|
|
112
|
+
1. AgentKit validates `X-Telegram-Bot-Api-Secret-Token`.
|
|
113
|
+
2. Telegram `voice` or `audio` payloads become normalized audio messages.
|
|
114
|
+
3. AgentKit records `audio_received` and enqueues a channel job before acknowledging Telegram.
|
|
115
|
+
4. The retryable channel worker calls Telegram `getFile`, downloads the file with `TELEGRAM_BOT_TOKEN`, and does not log the token.
|
|
116
|
+
5. AgentKit sends the audio bytes to the configured transcription provider using the user's managed secret.
|
|
117
|
+
6. The agent run receives a text message with the transcript.
|
|
118
|
+
|
|
119
|
+
OpenAI transcription can be used for Telegram files that arrive as MP3, MP4, MPEG, MPGA, M4A, WAV, or WEBM. Telegram voice notes are usually OGG/Opus, so they should use Groq in V1 unless the provider payload is converted before it reaches AgentKit.
|
|
120
|
+
|
|
54
121
|
## Setup Behavior
|
|
55
122
|
|
|
56
123
|
`agentkit channels setup support-telegram` is read-only and prints the webhook URL.
|
|
@@ -61,6 +128,8 @@ export default defineAgent({
|
|
|
61
128
|
- `secret_token`: `TELEGRAM_WEBHOOK_SECRET`;
|
|
62
129
|
- `allowed_updates`: `["message"]`.
|
|
63
130
|
|
|
131
|
+
Against AgentKit Cloud, `--apply` runs through the Cloud API and uses managed hosted secrets. The legacy local fallback only uses `TELEGRAM_BOT_TOKEN` and `TELEGRAM_WEBHOOK_SECRET` from the shell when the Cloud API does not expose channel setup.
|
|
132
|
+
|
|
64
133
|
## Safety Rules
|
|
65
134
|
|
|
66
135
|
- Use `--apply` only when real Telegram secrets are present.
|
|
@@ -72,13 +141,15 @@ export default defineAgent({
|
|
|
72
141
|
```sh
|
|
73
142
|
agentkit channels status support-telegram
|
|
74
143
|
agentkit channels test support-telegram --message "hello"
|
|
144
|
+
agentkit channels test-audio support-telegram --fixture voice-note
|
|
145
|
+
agentkit transcribe smoke --provider groq
|
|
75
146
|
agentkit channels deliveries show <delivery-id>
|
|
76
147
|
```
|
|
77
148
|
|
|
78
149
|
Expected webhook URL shape:
|
|
79
150
|
|
|
80
151
|
```txt
|
|
81
|
-
https://<deploy-host>/channels/
|
|
152
|
+
https://<deploy-host>/channels/support-telegram/telegram/telegram/webhook
|
|
82
153
|
```
|
|
83
154
|
|
|
84
155
|
## Troubleshooting
|
|
@@ -91,3 +162,9 @@ The incoming Telegram secret token does not match `TELEGRAM_WEBHOOK_SECRET`.
|
|
|
91
162
|
|
|
92
163
|
`channel_payload_invalid`:
|
|
93
164
|
The update is malformed or is not a supported private text message.
|
|
165
|
+
|
|
166
|
+
`transcription_secret_missing`:
|
|
167
|
+
Set `GROQ_API_KEY` or the custom secret named in `transcription.secret` as a managed hosted secret.
|
|
168
|
+
|
|
169
|
+
`transcription_audio_format_unsupported`:
|
|
170
|
+
The configured transcription provider does not accept the Telegram file format. Use Groq for OGG/Opus voice notes in V1. `agentkit inspect` warns when a Telegram channel uses `audio.mode: "transcribe"` with OpenAI transcription.
|