@andreprado/agentkit 0.1.0-alpha.19 → 0.1.0-alpha.20

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.
@@ -16,9 +16,10 @@ agentkit deploy
16
16
  agentkit channels list
17
17
  agentkit channels add website website-chat
18
18
  agentkit channels add telegram support-telegram
19
- agentkit channels add whatsapp support-whatsapp --provider zapster
20
19
  agentkit channels connect discord support-discord
21
20
  agentkit channels connect discord server-discord --mode bot
21
+ agentkit channels connect slack support-slack
22
+ agentkit channels add whatsapp support-whatsapp --provider zapster
22
23
  agentkit channels setup support-telegram
23
24
  agentkit channels status support-telegram
24
25
  agentkit channels test support-telegram --message "hello"
@@ -30,7 +31,7 @@ Use `--api <url>` only when the owner gives you a non-default AgentKit Cloud API
30
31
 
31
32
  ## Files Created Or Edited
32
33
 
33
- - `agentkit.config.ts`: declare channel config with `websiteChannel`, `telegramChannel`, `whatsappChannel`, or `discordChannel`.
34
+ - `agentkit.config.ts`: declare channel config with `websiteChannel`, `telegramChannel`, `whatsappChannel`, `discordChannel`, or `slackChannel`.
34
35
  - `.agentkit/deploy.json`: written by `agentkit deploy`; used by `agentkit channels ...`.
35
36
  - No user Turso tables: AgentKit owns channel resources, dedupe, identities, queue state, and delivery logs.
36
37
  - Website channel clients must send `AGENTKIT_WEBSITE_CHANNEL_TOKEN` as `Authorization: Bearer <token>` or `X-AgentKit-Channel-Token`.
@@ -38,7 +39,7 @@ Use `--api <url>` only when the owner gives you a non-default AgentKit Cloud API
38
39
  ## Minimal Working Example
39
40
 
40
41
  ```ts
41
- import { defineAgent, discordChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
42
+ import { defineAgent, discordChannel, slackChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
42
43
 
43
44
  export default defineAgent({
44
45
  name: "support-agent",
@@ -53,6 +54,7 @@ export default defineAgent({
53
54
  whatsappChannel({ name: "support-whatsapp", provider: "zapster" }),
54
55
  discordChannel({ name: "support-discord" }),
55
56
  discordChannel({ name: "server-discord", mode: "bot" }),
57
+ slackChannel({ name: "support-slack" }),
56
58
  ],
57
59
  access: { mode: "public" },
58
60
  storage: { driver: "agentkit" },
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Goal
4
4
 
5
- Configure website, Telegram, WhatsApp, and Discord channels without leaking secrets, storing raw provider payloads, or treating public webhook URLs as authorization.
5
+ Configure website, Telegram, WhatsApp, Discord, and Slack 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
 
@@ -32,6 +32,7 @@ agentkit channels deliveries show <delivery-id>
32
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
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
+ - Do not expose Slack bot tokens or signing secrets. Slack signing secrets authenticate webhook origin; Slack bot tokens authorize outbound replies.
35
36
  - Inspect delivery IDs, hashes, redacted metadata, and statuses instead of raw provider payloads.
36
37
  - Keep channel plumbing out of the agent's application database. The user's Turso tables are for the agent's business data.
37
38
  - Enable audio transcription only when the capsule declares a transcription provider and bounded `limits`.
@@ -100,6 +101,17 @@ discordChannel({
100
101
 
101
102
  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.
102
103
 
104
+ Slack Events API uses a bot token and signing secret:
105
+
106
+ ```ts
107
+ slackChannel({
108
+ name: "support-slack",
109
+ secrets: ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"],
110
+ });
111
+ ```
112
+
113
+ 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
+
103
115
  ## Verification
104
116
 
105
117
  ```sh
@@ -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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## Goal
4
4
 
5
- Diagnose website, Telegram, WhatsApp, or Discord channel setup, webhook validation, dedupe, buffering, outbound sends, and delivery failures from the Agent Capsule CLI.
5
+ Diagnose website, Telegram, WhatsApp, Discord, or Slack 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
 
@@ -102,6 +102,7 @@ defineTool({
102
102
  - Treat hosted deploy URLs as addresses, not access control.
103
103
  - Use deploy access tokens for hosted chat, hosted conversation reads, hosted trace reads, and any client app that talks to AgentKit Cloud.
104
104
  - Remove client PII before writing evals.
105
+ - Review `.agentkit/feedback/` drafts before sending AgentKit product feedback. Do not paste `.env` values, provider keys, cookies, client PII, or full private transcripts into feedback messages.
105
106
 
106
107
  ## Verification
107
108
 
@@ -0,0 +1,135 @@
1
+ # Send Feedback To AgentKit
2
+
3
+ ## Goal
4
+
5
+ Create a redacted local feedback draft when AgentKit itself is confusing, missing docs, or failing, then send it to AgentKit Cloud only after the user has authenticated.
6
+
7
+ ## When To Use This
8
+
9
+ Use this for AgentKit product feedback, not for the user's agent's client conversations.
10
+
11
+ Good cases:
12
+
13
+ - an AgentKit CLI command failed and the error did not explain recovery;
14
+ - a docs guide or generated skill is missing a step;
15
+ - deploy, channel, provider, eval, or runtime behavior looks like an AgentKit bug;
16
+ - the user's coding agent found a feature gap in AgentKit itself.
17
+
18
+ Do not use this to upload private client data, provider keys, `.env` values, or full conversation transcripts.
19
+
20
+ ## Commands
21
+
22
+ Create a local draft only:
23
+
24
+ ```sh
25
+ agentkit feedback create --about last-run --kind bug --summary "Deploy failed after secrets sync"
26
+ ```
27
+
28
+ Preview a draft:
29
+
30
+ ```sh
31
+ agentkit feedback preview .agentkit/feedback/<draft>.json
32
+ ```
33
+
34
+ Send a saved draft:
35
+
36
+ ```sh
37
+ agentkit login --token agk_user_...
38
+ agentkit feedback send .agentkit/feedback/<draft>.json
39
+ ```
40
+
41
+ Create and send in one command:
42
+
43
+ ```sh
44
+ agentkit feedback send --about deploy --kind deploy_issue --summary "Deploy doctor passed but deploy failed" --message "The recovery step was unclear."
45
+ ```
46
+
47
+ ## Files Created Or Edited
48
+
49
+ `feedback create` writes ignored local files:
50
+
51
+ ```txt
52
+ .agentkit/feedback/<timestamp>-<summary>.json
53
+ .agentkit/feedback/<timestamp>-<summary>.md
54
+ ```
55
+
56
+ These files are local diagnostic drafts. Keep `.agentkit/` out of commits.
57
+
58
+ ## Minimal Working Example
59
+
60
+ ```sh
61
+ agentkit feedback create \
62
+ --about last-run \
63
+ --kind missing_docs \
64
+ --summary "The channel debug guide did not explain Discord bot mode recovery" \
65
+ --message "The command failed after setup, and I could not tell whether to rerun connect or setup."
66
+ ```
67
+
68
+ Review the printed JSON path, then send it:
69
+
70
+ ```sh
71
+ agentkit feedback send .agentkit/feedback/<draft>.json
72
+ ```
73
+
74
+ ## Safety Rules
75
+
76
+ - Creating a draft never sends network feedback.
77
+ - Sending requires AgentKit Cloud login.
78
+ - The CLI redacts common bearer tokens, AgentKit tokens, provider key patterns, and Authorization headers before saving or sending.
79
+ - AgentKit Cloud validates the payload again and stores the redacted report under the authenticated account.
80
+ - Do not paste `.env` contents, provider key values, OAuth tokens, cookies, client PII, or full private transcripts into `--message`.
81
+ - The feedback command does not upload arbitrary files and does not ask AgentKit Cloud to fetch URLs.
82
+ - The deployed agent runtime does not send feedback to the AgentKit team.
83
+
84
+ ## Verification
85
+
86
+ After creating a draft:
87
+
88
+ ```sh
89
+ agentkit feedback preview .agentkit/feedback/<draft>.json
90
+ ```
91
+
92
+ Expected:
93
+
94
+ - `schema_version` is `agentkit.feedback.v1`;
95
+ - `source.channel` is `cli`;
96
+ - `context` describes the current capsule and deploy shape;
97
+ - no secret values are present.
98
+
99
+ After sending:
100
+
101
+ ```txt
102
+ Feedback sent
103
+ ID: fb_...
104
+ Status: new
105
+ ```
106
+
107
+ ## Troubleshooting
108
+
109
+ `auth_required`:
110
+
111
+ Log in before sending:
112
+
113
+ ```sh
114
+ agentkit login --token agk_user_...
115
+ ```
116
+
117
+ `feedback_draft_invalid`:
118
+
119
+ Recreate the draft with `agentkit feedback create`. Do not hand-edit the JSON schema unless you keep `schema_version: "agentkit.feedback.v1"`.
120
+
121
+ `payload_too_large`:
122
+
123
+ Shorten `--message`. Do not paste full logs; include the command, exact error code, and the smallest useful excerpt.
124
+
125
+ ## Backend Contracts Used
126
+
127
+ Feedback submit uses authenticated AgentKit Cloud account auth:
128
+
129
+ ```txt
130
+ POST /v1/feedback
131
+ Authorization: Bearer agk_user_...
132
+ Idempotency-Key: fbdraft_...
133
+ ```
134
+
135
+ The endpoint accepts only structured JSON feedback and stores it in the AgentKit Cloud feedback inbox.
@@ -53,12 +53,15 @@ agentkit eval from-conversation <conversation-id> [--out <path>] [--force]
53
53
  agentkit improve collect [--deploy] [--since <duration|iso>] [--conversation-id <id>] [--out <directory>]
54
54
  agentkit improve evals <bundle-dir-or-json> [--force]
55
55
  agentkit replay <bundle-dir-or-json> --against local
56
+ agentkit feedback create [--about last-run|deploy|manual] [--kind bug|confusion|missing_docs|feature_request|deploy_issue|runtime_issue|other] --summary <text> [--message <text>] [--out <path>]
57
+ agentkit feedback preview [draft.json]
58
+ agentkit feedback send [draft.json] [--about last-run|deploy|manual] [--kind <kind>] --summary <text> [--message <text>] [--api <url>] [--save]
56
59
  agentkit conversations list
57
60
  agentkit conversations show <conversation-id>
58
61
  agentkit conversations trace <conversation-id> [--deploy]
59
62
  agentkit channels list
60
- agentkit channels add <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
61
- agentkit channels connect <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
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>]
62
65
  agentkit channels setup <name> [--apply] [--api <url>]
63
66
  agentkit channels status <name> [--api <url>]
64
67
  agentkit channels test <name> [--message <text>] [--fixture <path>] [--api <url>]
@@ -112,6 +115,8 @@ agentkit help commands
112
115
 
113
116
  Prefer `env set --stdin` or `--from-env` for local secret values, and prefer `secret set --stdin`, `--from-env`, or `--from-local-env` for hosted secrets. Inline `<VALUE>` forms exist for simple non-sensitive values, but agents should avoid putting secrets in shell history.
114
117
 
118
+ Use `agentkit feedback create` when AgentKit itself fails, confuses the coding agent, or lacks docs. Drafts are local files under `.agentkit/feedback/` and are not sent automatically. Use `agentkit feedback send` only after reviewing the draft and logging in with `agentkit login --token agk_user_...`. Feedback upload uses authenticated AgentKit Cloud account auth, redacts common token/key patterns, does not upload arbitrary files, and does not cause the deployed agent runtime to phone home.
119
+
115
120
  On Windows PowerShell, if `npm.ps1` or `npx.ps1` is blocked with `PSSecurityException`, run capsule scripts through the `.cmd` shims instead of changing the workflow. Examples: `npx.cmd @andreprado/agentkit@alpha new demo --template blank`, `npm.cmd run agentkit -- inspect`, `npm.cmd run agentkit -- knowledge sync`, and `npm.cmd run eval`.
116
121
 
117
122
  Managed Composio is configured with `composioManaged({...})` in `agentkit.config.ts` and is paid hosted AgentKit infrastructure. It requires a non-anonymous AgentKit Cloud deploy with `managed_composio`, uses one Composio settings profile per agent, injects `COMPOSIO_API_KEY` as an AgentKit-managed secret, resolves toolkit auth configs from AgentKit Cloud, validates toolkit readiness during `agentkit deploy doctor`, and exposes the generated `agentkit_composio_execute` tool only for explicit configured action slugs. Calendar starters should include `GOOGLECALENDAR_EVENTS_LIST`, `GOOGLECALENDAR_CREATE_EVENT`, and `GOOGLECALENDAR_UPDATE_EVENT`; create-event calls must pass UTC `start_datetime` plus explicit duration. Managed external write actions require tool input `confirmed: true` by default unless the integration sets `confirmExternalWrites: false`. See `docs/guides/add-managed-composio.md`.
@@ -339,7 +344,7 @@ Channels are hosted inbound/outbound conversation transports. They are separate
339
344
  Use these helpers in `agentkit.config.ts`:
340
345
 
341
346
  ```ts
342
- import { defineAgent, discordChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
347
+ import { defineAgent, discordChannel, slackChannel, telegramChannel, whatsappChannel, websiteChannel } from "@andreprado/agentkit";
343
348
 
344
349
  export default defineAgent({
345
350
  name: "support-agent",
@@ -354,6 +359,7 @@ export default defineAgent({
354
359
  whatsappChannel({ name: "support-whatsapp", provider: "zapster" }),
355
360
  discordChannel({ name: "support-discord" }),
356
361
  discordChannel({ name: "server-discord", mode: "bot" }),
362
+ slackChannel({ name: "support-slack" }),
357
363
  ],
358
364
  access: { mode: "public" },
359
365
  storage: { driver: "agentkit" },
@@ -390,6 +396,7 @@ Useful guides:
390
396
 
391
397
  - Add a channel: `docs/guides/add-channel.md`
392
398
  - Connect Discord: `docs/guides/connect-discord.md`
399
+ - Connect Slack: `docs/guides/connect-slack.md`
393
400
  - Connect Telegram: `docs/guides/connect-telegram.md`
394
401
  - Connect WhatsApp through Zapster: `docs/guides/connect-whatsapp-zapster.md`
395
402
  - Debug a channel: `docs/guides/debug-channel.md`
@@ -431,6 +438,7 @@ agentkit channels list
431
438
  agentkit channels add telegram support-telegram
432
439
  agentkit channels connect discord support-discord
433
440
  agentkit channels connect discord server-discord --mode bot
441
+ agentkit channels connect slack support-slack
434
442
  agentkit channels setup support-telegram
435
443
  agentkit channels test support-telegram --message "hello"
436
444
  agentkit channels test-audio support-telegram --fixture voice-note
package/docs/llms.txt CHANGED
@@ -12,6 +12,7 @@ Task guides:
12
12
  - Run or prepare evals: `docs/guides/run-evals.md`
13
13
  - Improve from production traces: `docs/guides/improve-from-production.md`
14
14
  - Replay collected traces locally: `docs/guides/replay-production-traces.md`
15
+ - Send AgentKit product feedback safely: `docs/guides/send-feedback.md`
15
16
  - Switch from `test/fake` to a real provider: `docs/guides/use-provider.md`
16
17
  - Prepare for hosted deploy: `docs/guides/prepare-deploy.md`
17
18
  - Build Cloudflare artifact: `agentkit build --target cloudflare`
@@ -21,6 +22,7 @@ Task guides:
21
22
  - Add AgentKit-managed Composio: `docs/guides/add-managed-composio.md`
22
23
  - Buffer rapid channel messages: `docs/guides/add-channel.md#buffer-bursty-messages`
23
24
  - Connect Discord: `docs/guides/connect-discord.md`
25
+ - Connect Slack: `docs/guides/connect-slack.md`
24
26
  - Connect Telegram: `docs/guides/connect-telegram.md`
25
27
  - Connect WhatsApp through Zapster: `docs/guides/connect-whatsapp-zapster.md`
26
28
  - Follow channel webhook and delivery-log safety rules: `docs/guides/channel-security.md`
@@ -46,6 +48,8 @@ agentkit eval run
46
48
  agentkit improve collect --deploy --since 24h
47
49
  agentkit improve evals .agentkit/improve/<run>
48
50
  agentkit replay .agentkit/improve/<run> --against local
51
+ agentkit feedback create --about last-run --kind bug --summary "what failed"
52
+ agentkit feedback send .agentkit/feedback/<draft>.json
49
53
  agentkit conversations list
50
54
  agentkit conversations show <conversation-id>
51
55
  agentkit conversations trace <conversation-id> [--deploy]
@@ -53,6 +57,7 @@ agentkit channels list
53
57
  agentkit channels add telegram support-telegram
54
58
  agentkit channels connect discord support-discord
55
59
  agentkit channels connect discord server-discord --mode bot
60
+ agentkit channels connect slack support-slack
56
61
  agentkit channels setup support-telegram
57
62
  agentkit channels status support-telegram
58
63
  agentkit channels test support-telegram --message "hello"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@andreprado/agentkit",
3
- "version": "0.1.0-alpha.19",
3
+ "version": "0.1.0-alpha.20",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -155,6 +155,18 @@ export type CloudSecretsResponse = {
155
155
  }>;
156
156
  };
157
157
 
158
+ export type FeedbackSendResponse = {
159
+ feedback?: {
160
+ id?: string;
161
+ account_id?: string;
162
+ kind?: string;
163
+ summary?: string;
164
+ status?: string;
165
+ client_report_id?: string;
166
+ created_at?: string;
167
+ };
168
+ };
169
+
158
170
  export function cloudAuthPath(): string {
159
171
  return join(homedir(), ".agentkit", "cloud.json");
160
172
  }
@@ -1,3 +1,4 @@
1
+ import { createHmac } from "node:crypto";
1
2
  import { readFile } from "node:fs/promises";
2
3
  import { resolve } from "node:path";
3
4
 
@@ -14,8 +15,8 @@ type DeployState = LocalDeployState;
14
15
  type CloudChannel = {
15
16
  id: string;
16
17
  name: string;
17
- type: "website" | "telegram" | "whatsapp" | "discord";
18
- provider: "agentkit" | "telegram" | "zapster" | "meta" | "discord";
18
+ type: "website" | "telegram" | "whatsapp" | "discord" | "slack";
19
+ provider: "agentkit" | "telegram" | "zapster" | "meta" | "discord" | "slack";
19
20
  mode?: "interactions" | "bot";
20
21
  status: string;
21
22
  webhook_url: string;
@@ -142,8 +143,8 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
142
143
  const type = first;
143
144
  const name = second;
144
145
 
145
- if (!type || !name || (type !== "website" && type !== "telegram" && type !== "whatsapp" && type !== "discord")) {
146
- throw new Error("Usage: agentkit channels add <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot]");
146
+ if (!type || !name || !isCliChannelType(type)) {
147
+ throw new Error("Usage: agentkit channels add <website|telegram|whatsapp|discord|slack> <name> [--provider zapster|meta] [--mode interactions|bot]");
147
148
  }
148
149
 
149
150
  const response = await createHostedChannel(type, name, args.flags.provider, args.flags.mode, args.flags.api);
@@ -156,8 +157,8 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
156
157
  const type = first;
157
158
  const name = second;
158
159
 
159
- if (!type || !name || (type !== "website" && type !== "telegram" && type !== "whatsapp" && type !== "discord")) {
160
- throw new Error("Usage: agentkit channels connect <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot]");
160
+ if (!type || !name || !isCliChannelType(type)) {
161
+ throw new Error("Usage: agentkit channels connect <website|telegram|whatsapp|discord|slack> <name> [--provider zapster|meta] [--mode interactions|bot]");
161
162
  }
162
163
 
163
164
  const created = await createHostedChannel(type, name, args.flags.provider, args.flags.mode, args.flags.api);
@@ -203,6 +204,15 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
203
204
  return;
204
205
  }
205
206
 
207
+ if (channel.type === "slack") {
208
+ const smoke = await runConnectSmoke(() => runChannelSmoke(channel, args.flags.api, args.flags.message));
209
+ printSlackHumanNextStep(channel);
210
+ if (!smoke) {
211
+ process.exitCode = 1;
212
+ }
213
+ return;
214
+ }
215
+
206
216
  if (channel.type === "whatsapp" && channel.provider === "zapster") {
207
217
  const smoke = await runConnectSmoke(() => runChannelSmoke(channel, args.flags.api, args.flags.message));
208
218
  console.log(`Next human step: paste ${channel.webhook_url} into ${channel.provider}'s webhook settings.`);
@@ -243,6 +253,8 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
243
253
  console.log(`Next step: paste this URL into ${channel.provider}'s webhook settings.`);
244
254
  } else if (channel.type === "discord") {
245
255
  printDiscordHumanNextStep(channel);
256
+ } else if (channel.type === "slack") {
257
+ printSlackHumanNextStep(channel);
246
258
  } else {
247
259
  console.log(`Website endpoint: ${channel.webhook_url}`);
248
260
  console.log("Use this endpoint from the AgentKit website client or a signed server-to-server test.");
@@ -415,7 +427,7 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
415
427
  }
416
428
 
417
429
  async function createHostedChannel(
418
- type: "website" | "telegram" | "whatsapp" | "discord",
430
+ type: "website" | "telegram" | "whatsapp" | "discord" | "slack",
419
431
  name: string,
420
432
  providerFlag: string | boolean | undefined,
421
433
  modeFlag: string | boolean | undefined,
@@ -510,7 +522,7 @@ async function runLocallySignedChannelTest(
510
522
  }
511
523
 
512
524
  const path = `${webhookUrl.pathname}${webhookUrl.search}`;
513
- const headers = channelTestHeaders(channel);
525
+ const headers = channelTestHeaders(channel, rawBody);
514
526
  const response = await cloudFetch(apiUrl, path, {
515
527
  method: "POST",
516
528
  headers,
@@ -677,6 +689,19 @@ function printDiscordHumanNextStep(channel: CloudChannel): void {
677
689
  console.log(` Then run: npm run agentkit -- channels deliveries list ${channel.name}`);
678
690
  }
679
691
 
692
+ function printSlackHumanNextStep(channel: CloudChannel): void {
693
+ console.log("");
694
+ console.log("Next human step:");
695
+ console.log(" Open the Slack app configuration");
696
+ console.log(" Event Subscriptions: enable events");
697
+ console.log(` Request URL: paste ${channel.webhook_url}`);
698
+ console.log(" Subscribe to bot events: app_mention and message.im");
699
+ console.log(" OAuth scopes: app_mentions:read, im:history, chat:write");
700
+ console.log(" Install or reinstall the app to the workspace");
701
+ console.log(' Mention the app with "hello" or send it a direct message');
702
+ console.log(` Then run: npm run agentkit -- channels deliveries list ${channel.name}`);
703
+ }
704
+
680
705
  function isRecord(value: unknown): value is Record<string, unknown> {
681
706
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
682
707
  }
@@ -689,6 +714,10 @@ async function readDeployStateIfExists(cwd: string): Promise<DeployState | null>
689
714
  return readLocalDeployStateIfExists(cwd);
690
715
  }
691
716
 
717
+ function isCliChannelType(value: string): value is "website" | "telegram" | "whatsapp" | "discord" | "slack" {
718
+ return value === "website" || value === "telegram" || value === "whatsapp" || value === "discord" || value === "slack";
719
+ }
720
+
692
721
  async function readDeployStateRequired(cwd: string): Promise<DeployState> {
693
722
  const state = await readDeployStateIfExists(cwd);
694
723
 
@@ -972,6 +1001,14 @@ function channelProviderForCli(type: string, providerFlag: string | boolean | un
972
1001
  return "discord";
973
1002
  }
974
1003
 
1004
+ if (type === "slack") {
1005
+ if (providerFlag !== undefined) {
1006
+ throw new Error("--provider is not supported for Slack channels.");
1007
+ }
1008
+
1009
+ return "slack";
1010
+ }
1011
+
975
1012
  const provider = providerFlag ?? "zapster";
976
1013
 
977
1014
  if (provider !== "zapster" && provider !== "meta") {
@@ -1026,6 +1063,10 @@ function defaultChannelSecretsForCli(type: string, provider: string, mode?: "int
1026
1063
  return mode === "bot" ? ["DISCORD_BOT_TOKEN"] : ["DISCORD_PUBLIC_KEY"];
1027
1064
  }
1028
1065
 
1066
+ if (type === "slack") {
1067
+ return ["SLACK_BOT_TOKEN", "SLACK_SIGNING_SECRET"];
1068
+ }
1069
+
1029
1070
  return [];
1030
1071
  }
1031
1072
 
@@ -1137,6 +1178,29 @@ async function channelTestBody(
1137
1178
  });
1138
1179
  }
1139
1180
 
1181
+ if (channel.type === "slack") {
1182
+ const now = Date.now();
1183
+
1184
+ return JSON.stringify({
1185
+ token: "deprecated-verification-token",
1186
+ team_id: "T_AGENTKIT",
1187
+ api_app_id: "A_AGENTKIT",
1188
+ type: "event_callback",
1189
+ event_id: `Ev${now}`,
1190
+ event_time: Math.floor(now / 1000),
1191
+ event: {
1192
+ type: "app_mention",
1193
+ user: "UAGENTKITUSER",
1194
+ text: `<@UAGENTKITBOT> ${message}`,
1195
+ ts: `${Math.floor(now / 1000)}.000100`,
1196
+ channel: "C_AGENTKIT",
1197
+ event_ts: `${Math.floor(now / 1000)}.000100`,
1198
+ },
1199
+ authorizations: [],
1200
+ is_ext_shared_channel: false,
1201
+ });
1202
+ }
1203
+
1140
1204
  return JSON.stringify({
1141
1205
  event_id: `web_${Date.now()}`,
1142
1206
  visitor_id: "visitor_test",
@@ -1211,7 +1275,7 @@ function isExplicitFixturePath(value: string): boolean {
1211
1275
  return value.includes("/") || value.startsWith(".") || value.endsWith(".json");
1212
1276
  }
1213
1277
 
1214
- function channelTestHeaders(channel: CloudChannel): Headers {
1278
+ function channelTestHeaders(channel: CloudChannel, rawBody: string): Headers {
1215
1279
  const headers = new Headers({ "Content-Type": "application/json" });
1216
1280
 
1217
1281
  if (channel.type === "website") {
@@ -1234,5 +1298,18 @@ function channelTestHeaders(channel: CloudChannel): Headers {
1234
1298
  headers.set("User-Agent", "Zapsterapi/agentkit-cli");
1235
1299
  }
1236
1300
 
1301
+ if (channel.type === "slack") {
1302
+ const signingSecret = process.env.SLACK_SIGNING_SECRET;
1303
+
1304
+ if (signingSecret) {
1305
+ const timestamp = String(Math.floor(Date.now() / 1000));
1306
+ const signature = createHmac("sha256", signingSecret)
1307
+ .update(`v0:${timestamp}:${rawBody}`)
1308
+ .digest("hex");
1309
+ headers.set("X-Slack-Request-Timestamp", timestamp);
1310
+ headers.set("X-Slack-Signature", `v0=${signature}`);
1311
+ }
1312
+ }
1313
+
1237
1314
  return headers;
1238
1315
  }