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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +3 -0
  2. package/docs/guides/add-channel.md +12 -6
  3. package/docs/guides/add-knowledge.md +10 -0
  4. package/docs/guides/add-managed-composio.md +4 -2
  5. package/docs/guides/channel-security.md +26 -2
  6. package/docs/guides/connect-discord.md +178 -0
  7. package/docs/guides/create-agent.md +13 -0
  8. package/docs/guides/debug-channel.md +8 -2
  9. package/docs/guides/improve-from-production.md +151 -0
  10. package/docs/guides/prepare-deploy.md +29 -8
  11. package/docs/guides/replay-production-traces.md +72 -0
  12. package/docs/guides/run-evals.md +18 -0
  13. package/docs/guides/security-rules.md +5 -5
  14. package/docs/guides/use-provider.md +11 -1
  15. package/docs/llms-full.txt +100 -11
  16. package/docs/llms.txt +17 -1
  17. package/package.json +1 -1
  18. package/src/cli/args.ts +23 -2
  19. package/src/cli/cloud-client.ts +63 -0
  20. package/src/cli/commands/channels.ts +139 -14
  21. package/src/cli/deploy-readiness.ts +5 -2
  22. package/src/cli/help.ts +26 -2
  23. package/src/cli/index.ts +382 -17
  24. package/src/create-project.ts +13 -2
  25. package/src/index.ts +42 -3
  26. package/src/providers/pi.ts +49 -15
  27. package/src/runtime/channel-test-harness.ts +4 -1
  28. package/src/runtime/channels/discord.ts +887 -0
  29. package/src/runtime/channels.ts +15 -0
  30. package/src/runtime/config.ts +35 -3
  31. package/src/runtime/dev-server.ts +149 -8
  32. package/src/runtime/evals.ts +27 -6
  33. package/src/runtime/improve.ts +868 -0
  34. package/src/runtime/knowledge/retrieve.ts +25 -5
  35. package/src/runtime/knowledge/schema.ts +45 -1
  36. package/src/runtime/runtime-contract.ts +54 -0
  37. package/src/runtime/targets/cloudflare/build.ts +248 -193
  38. package/src/runtime/targets/vps/deploy.ts +1 -1
  39. package/src/storage/sqlite.ts +7 -2
  40. package/src/templates/skills/agentkit-capsule/SKILL.md +8 -1
  41. package/src/templates/skills/agentkit-capsule/references/docs-router.md +1 -2
  42. package/src/templates/skills/agentkit-channels/SKILL.md +6 -1
  43. package/src/templates/skills/agentkit-channels/references/channel-debugging.md +2 -1
  44. package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
  45. package/src/templates/skills/agentkit-deploy/SKILL.md +6 -0
  46. package/src/templates/skills/agentkit-evals/SKILL.md +12 -3
  47. package/src/templates/skills/agentkit-improve/SKILL.md +86 -0
  48. package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
  49. package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
  50. package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
  51. package/src/templates/skills/agentkit-integrations/SKILL.md +1 -0
  52. package/src/templates/skills/agentkit-knowledge/SKILL.md +4 -1
  53. package/src/templates/skills/agentkit-provider/SKILL.md +4 -1
  54. package/src/templates/skills/agentkit-security/SKILL.md +3 -2
  55. package/src/templates/skills/agentkit-troubleshooting/SKILL.md +9 -0
  56. package/src/templates/support.ts +4 -2
@@ -14,8 +14,9 @@ type DeployState = LocalDeployState;
14
14
  type CloudChannel = {
15
15
  id: string;
16
16
  name: string;
17
- type: "website" | "telegram" | "whatsapp";
18
- provider: "agentkit" | "telegram" | "zapster" | "meta";
17
+ type: "website" | "telegram" | "whatsapp" | "discord";
18
+ provider: "agentkit" | "telegram" | "zapster" | "meta" | "discord";
19
+ mode?: "interactions" | "bot";
19
20
  status: string;
20
21
  webhook_url: string;
21
22
  required_secrets: Array<{ name: string; status: string }>;
@@ -128,6 +129,7 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
128
129
  name: channel.name,
129
130
  type: channel.type,
130
131
  provider: channel.provider,
132
+ ...(channel.type === "discord" ? { mode: channel.mode } : {}),
131
133
  status: "local_config",
132
134
  webhook_url: "",
133
135
  required_secrets: channel.secrets.map((name) => ({ name, status: "missing" })),
@@ -140,11 +142,11 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
140
142
  const type = first;
141
143
  const name = second;
142
144
 
143
- if (!type || !name || (type !== "website" && type !== "telegram" && type !== "whatsapp")) {
144
- throw new Error("Usage: agentkit channels add <website|telegram|whatsapp> <name> [--provider zapster|meta]");
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]");
145
147
  }
146
148
 
147
- const response = await createHostedChannel(type, name, args.flags.provider, args.flags.api);
149
+ const response = await createHostedChannel(type, name, args.flags.provider, args.flags.mode, args.flags.api);
148
150
  printChannelStatus(response.channel);
149
151
  printSecretRepairHint(response.channel);
150
152
  return;
@@ -154,11 +156,11 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
154
156
  const type = first;
155
157
  const name = second;
156
158
 
157
- if (!type || !name || (type !== "website" && type !== "telegram" && type !== "whatsapp")) {
158
- throw new Error("Usage: agentkit channels connect <website|telegram|whatsapp> <name> [--provider zapster|meta]");
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]");
159
161
  }
160
162
 
161
- const created = await createHostedChannel(type, name, args.flags.provider, args.flags.api);
163
+ const created = await createHostedChannel(type, name, args.flags.provider, args.flags.mode, args.flags.api);
162
164
  let channel = created.channel;
163
165
  printChannelStatus(channel);
164
166
  printSecretRepairHint(channel);
@@ -192,6 +194,15 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
192
194
  return;
193
195
  }
194
196
 
197
+ if (channel.type === "discord") {
198
+ const smoke = await runConnectSmoke(() => runChannelSmoke(channel, args.flags.api, args.flags.message));
199
+ printDiscordHumanNextStep(channel);
200
+ if (!smoke) {
201
+ process.exitCode = 1;
202
+ }
203
+ return;
204
+ }
205
+
195
206
  if (channel.type === "whatsapp" && channel.provider === "zapster") {
196
207
  const smoke = await runConnectSmoke(() => runChannelSmoke(channel, args.flags.api, args.flags.message));
197
208
  console.log(`Next human step: paste ${channel.webhook_url} into ${channel.provider}'s webhook settings.`);
@@ -230,6 +241,8 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
230
241
  }
231
242
  } else if (channel.type === "whatsapp") {
232
243
  console.log(`Next step: paste this URL into ${channel.provider}'s webhook settings.`);
244
+ } else if (channel.type === "discord") {
245
+ printDiscordHumanNextStep(channel);
233
246
  } else {
234
247
  console.log(`Website endpoint: ${channel.webhook_url}`);
235
248
  console.log("Use this endpoint from the AgentKit website client or a signed server-to-server test.");
@@ -402,19 +415,22 @@ export async function handleChannelsCommand(args: ParsedArgs): Promise<void> {
402
415
  }
403
416
 
404
417
  async function createHostedChannel(
405
- type: "website" | "telegram" | "whatsapp",
418
+ type: "website" | "telegram" | "whatsapp" | "discord",
406
419
  name: string,
407
420
  providerFlag: string | boolean | undefined,
421
+ modeFlag: string | boolean | undefined,
408
422
  apiFlag: string | boolean | undefined,
409
423
  ): Promise<{ channel: CloudChannel }> {
410
424
  const deployState = await readDeployStateRequired(process.cwd());
411
425
  const provider = channelProviderForCli(type, providerFlag);
412
426
  const localChannel = await readLocalChannelConfig(process.cwd(), type, provider, name);
427
+ const mode = discordModeForCli(type, modeFlag, localChannel);
413
428
  const payload = {
414
429
  name,
415
430
  type,
416
431
  provider,
417
- secrets: localChannel?.secrets ?? defaultChannelSecretsForCli(type, provider),
432
+ ...(mode ? { mode } : {}),
433
+ secrets: localChannel?.secrets ?? defaultChannelSecretsForCli(type, provider, mode),
418
434
  ...(localChannel?.limits ? { limits: channelLimitsForApi(localChannel.limits) } : {}),
419
435
  ...(localChannel?.buffer ? { buffer: localChannel.buffer } : {}),
420
436
  ...(localChannel?.audio ? { audio: localChannel.audio } : {}),
@@ -641,6 +657,26 @@ function printTelegramHumanNextStep(channelName: string, botUsername: string | u
641
657
  console.log(` Then run: npm run agentkit -- channels deliveries list ${channelName}`);
642
658
  }
643
659
 
660
+ function printDiscordHumanNextStep(channel: CloudChannel): void {
661
+ console.log("");
662
+ console.log("Next human step:");
663
+
664
+ if (channel.mode === "bot") {
665
+ console.log(" Open the Discord Developer Portal for your application");
666
+ console.log(" Bot page: enable Message Content Intent");
667
+ console.log(" Installation page: install the app into your server with bot permissions");
668
+ console.log(" Grant the bot View Channel, Read Message History, and Send Messages in the channels it should answer");
669
+ console.log(' Send "hello" in an allowed server channel');
670
+ console.log(` Then run: npm run agentkit -- channels deliveries list ${channel.name}`);
671
+ return;
672
+ }
673
+
674
+ console.log(" Open the Discord Developer Portal for your application");
675
+ console.log(` Paste ${channel.webhook_url} into Interactions Endpoint URL`);
676
+ console.log(" Register a slash command with a string option named message, text, prompt, question, query, or input");
677
+ console.log(` Then run: npm run agentkit -- channels deliveries list ${channel.name}`);
678
+ }
679
+
644
680
  function isRecord(value: unknown): value is Record<string, unknown> {
645
681
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
646
682
  }
@@ -682,12 +718,18 @@ function printChannelStatus(channel: CloudChannel): void {
682
718
  }
683
719
  console.log(`Type: ${channel.type}`);
684
720
  console.log(`Provider: ${channel.provider}`);
721
+ if (channel.type === "discord") {
722
+ console.log(`Mode: ${channel.mode ?? "interactions"}`);
723
+ }
685
724
  console.log(`Status: ${channel.status}`);
686
725
  if (channel.webhook_url) {
687
726
  console.log(`Webhook URL: ${channel.webhook_url}`);
688
727
  }
689
728
  console.log("Required secrets:");
690
- if (channel.required_secrets.length === 0 && defaultChannelSecretsForCli(channel.type, channel.provider).length > 0) {
729
+ if (
730
+ channel.required_secrets.length === 0 &&
731
+ defaultChannelSecretsForCli(channel.type, channel.provider, channel.mode).length > 0
732
+ ) {
691
733
  console.log(
692
734
  ` control-plane channel metadata bug: required_secrets is empty for ${channel.type}/${channel.provider}`,
693
735
  );
@@ -708,7 +750,10 @@ function printChannelStatus(channel: CloudChannel): void {
708
750
  }
709
751
 
710
752
  function printSecretRepairHint(channel: CloudChannel): void {
711
- if (channel.required_secrets.length > 0 || defaultChannelSecretsForCli(channel.type, channel.provider).length === 0) {
753
+ if (
754
+ channel.required_secrets.length > 0 ||
755
+ defaultChannelSecretsForCli(channel.type, channel.provider, channel.mode).length === 0
756
+ ) {
712
757
  return;
713
758
  }
714
759
 
@@ -718,7 +763,7 @@ function printSecretRepairHint(channel: CloudChannel): void {
718
763
  }
719
764
 
720
765
  function hasMissingRequiredSecrets(channel: CloudChannel): boolean {
721
- const expected = defaultChannelSecretsForCli(channel.type, channel.provider);
766
+ const expected = defaultChannelSecretsForCli(channel.type, channel.provider, channel.mode);
722
767
 
723
768
  if (channel.required_secrets.length === 0 && expected.length > 0) {
724
769
  return true;
@@ -923,6 +968,10 @@ function channelProviderForCli(type: string, providerFlag: string | boolean | un
923
968
  return "telegram";
924
969
  }
925
970
 
971
+ if (type === "discord") {
972
+ return "discord";
973
+ }
974
+
926
975
  const provider = providerFlag ?? "zapster";
927
976
 
928
977
  if (provider !== "zapster" && provider !== "meta") {
@@ -932,7 +981,31 @@ function channelProviderForCli(type: string, providerFlag: string | boolean | un
932
981
  return provider;
933
982
  }
934
983
 
935
- function defaultChannelSecretsForCli(type: string, provider: string): string[] {
984
+ function discordModeForCli(
985
+ type: string,
986
+ modeFlag: string | boolean | undefined,
987
+ localChannel: AgentChannel | null,
988
+ ): "interactions" | "bot" | undefined {
989
+ if (type !== "discord") {
990
+ if (modeFlag !== undefined) {
991
+ throw new Error("--mode is only supported for Discord channels.");
992
+ }
993
+
994
+ return undefined;
995
+ }
996
+
997
+ if (modeFlag !== undefined) {
998
+ if (modeFlag !== "interactions" && modeFlag !== "bot") {
999
+ throw new Error('Discord mode must be "interactions" or "bot".');
1000
+ }
1001
+
1002
+ return modeFlag;
1003
+ }
1004
+
1005
+ return localChannel?.type === "discord" ? localChannel.mode : "interactions";
1006
+ }
1007
+
1008
+ function defaultChannelSecretsForCli(type: string, provider: string, mode?: "interactions" | "bot"): string[] {
936
1009
  if (type === "website") {
937
1010
  return ["AGENTKIT_WEBSITE_CHANNEL_TOKEN"];
938
1011
  }
@@ -949,6 +1022,10 @@ function defaultChannelSecretsForCli(type: string, provider: string): string[] {
949
1022
  return ["META_WHATSAPP_ACCESS_TOKEN", "META_WHATSAPP_APP_SECRET", "META_WHATSAPP_VERIFY_TOKEN"];
950
1023
  }
951
1024
 
1025
+ if (type === "discord") {
1026
+ return mode === "bot" ? ["DISCORD_BOT_TOKEN"] : ["DISCORD_PUBLIC_KEY"];
1027
+ }
1028
+
952
1029
  return [];
953
1030
  }
954
1031
 
@@ -1012,6 +1089,54 @@ async function channelTestBody(
1012
1089
  });
1013
1090
  }
1014
1091
 
1092
+ if (channel.type === "discord") {
1093
+ if (channel.mode === "bot") {
1094
+ return JSON.stringify({
1095
+ id: `discord_message_${Date.now()}`,
1096
+ guild_id: "agentkit_guild",
1097
+ channel_id: "agentkit_channel",
1098
+ author: {
1099
+ id: "agentkit_user",
1100
+ username: "agentkit",
1101
+ },
1102
+ member: {
1103
+ nick: "AgentKit",
1104
+ },
1105
+ content: message,
1106
+ mentions: [],
1107
+ timestamp: new Date().toISOString(),
1108
+ });
1109
+ }
1110
+
1111
+ return JSON.stringify({
1112
+ id: `discord_interaction_${Date.now()}`,
1113
+ application_id: "agentkit_discord_app",
1114
+ type: 2,
1115
+ data: {
1116
+ id: "agentkit_command",
1117
+ name: "ask",
1118
+ type: 1,
1119
+ options: [
1120
+ {
1121
+ name: "message",
1122
+ type: 3,
1123
+ value: message,
1124
+ },
1125
+ ],
1126
+ },
1127
+ guild_id: "agentkit_guild",
1128
+ channel_id: "agentkit_channel",
1129
+ member: {
1130
+ user: {
1131
+ id: "agentkit_user",
1132
+ username: "agentkit",
1133
+ },
1134
+ },
1135
+ token: `agentkit_interaction_token_${Date.now()}`,
1136
+ version: 1,
1137
+ });
1138
+ }
1139
+
1015
1140
  return JSON.stringify({
1016
1141
  event_id: `web_${Date.now()}`,
1017
1142
  visitor_id: "visitor_test",
@@ -239,13 +239,16 @@ export async function checkDeployReadiness(options: {
239
239
  message: `Missing ${missingToolkits
240
240
  .map((toolkit) => `${toolkit.auth_config_env ?? "auth config"} for ${toolkit.toolkit ?? "unknown"}`)
241
241
  .join(", ")}.`,
242
- action: "ask the AgentKit Cloud operator to configure the missing toolkit auth config",
242
+ action: "ask the AgentKit Cloud operator to configure the Composio auth config registry or fallback env",
243
243
  });
244
244
  } else {
245
+ const toolkitSources = (managed?.toolkits ?? []).map((toolkit) =>
246
+ `${toolkit.toolkit ?? "unknown"}${toolkit.auth_config_source ? ` via ${toolkit.auth_config_source}` : ""}`,
247
+ );
245
248
  checks.push({
246
249
  status: "pass",
247
250
  title: "Managed Composio auth configs",
248
- message: `Auth configs are available for ${context.integrations.managedComposio.toolkits.join(", ")}.`,
251
+ message: `Auth configs are available for ${toolkitSources.join(", ")}.`,
249
252
  });
250
253
  }
251
254
  } catch (error) {
package/src/cli/help.ts CHANGED
@@ -29,6 +29,8 @@ Build:
29
29
  agentkit db migrate
30
30
  agentkit eval run
31
31
  agentkit eval from-conversation <id>
32
+ agentkit improve collect --deploy --since 24h
33
+ agentkit replay <bundle-dir> --against local
32
34
  agentkit conversations list
33
35
 
34
36
  Deploy:
@@ -42,6 +44,8 @@ Deploy:
42
44
  More:
43
45
  agentkit channels ...
44
46
  agentkit integrations status
47
+ agentkit billing checkout --slots <count>
48
+ agentkit account token ...
45
49
  agentkit access token ...
46
50
  agentkit env ...
47
51
  agentkit docs full
@@ -73,12 +77,15 @@ Usage:
73
77
  agentkit db seed [--file <path>]
74
78
  agentkit eval run
75
79
  agentkit eval from-conversation <conversation-id> [--out <path>] [--force]
80
+ agentkit improve collect [--deploy] [--since <duration|iso>] [--conversation-id <id>] [--out <directory>]
81
+ agentkit improve evals <bundle-dir-or-json> [--force]
82
+ agentkit replay <bundle-dir-or-json> --against local
76
83
  agentkit conversations list [--deploy]
77
84
  agentkit conversations show <conversation-id> [--deploy]
78
85
  agentkit conversations trace <conversation-id> [--deploy]
79
86
  agentkit channels list
80
- agentkit channels add <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
81
- agentkit channels connect <website|telegram|whatsapp> <name> [--provider zapster|meta] [--api <url>]
87
+ agentkit channels add <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
88
+ agentkit channels connect <website|telegram|whatsapp|discord> <name> [--provider zapster|meta] [--mode interactions|bot] [--api <url>]
82
89
  agentkit channels setup <name> [--apply] [--api <url>]
83
90
  agentkit channels status <name> [--api <url>]
84
91
  agentkit channels doctor <name> [--api <url>]
@@ -99,6 +106,13 @@ Usage:
99
106
  agentkit build [--target cloudflare|container]
100
107
  agentkit login --token <token> [--api <url>]
101
108
  agentkit logout
109
+ agentkit billing checkout --slots <count> [--email <email>] [--api <url>]
110
+ agentkit billing status <billing-intent-id> --secret <secret> [--api <url>]
111
+ agentkit billing claim <billing-intent-id> --secret <secret> [--token-name <name>] [--api <url>]
112
+ agentkit billing portal [--api <url>]
113
+ agentkit account token create <name> [--api <url>] [--use] [--out <path>]
114
+ agentkit account token list [--api <url>]
115
+ agentkit account token revoke <token-id> [--api <url>]
102
116
  agentkit deploy [--target cloudflare|vps] [--host <host>] [--api <url>] [--dry-run] [--anonymous] [--local-wrangler] [--smoke <message>]
103
117
  agentkit deploy doctor [--api <url>] [--anonymous]
104
118
  agentkit deploy smoke [--message <text>] [--api <url>]
@@ -140,6 +154,8 @@ Commands:
140
154
  sync Run or scaffold catalog/data synchronization
141
155
  db Manage the local SQLite database
142
156
  eval Run local eval files or create one from a conversation
157
+ improve Collect production or local traces and generate regression evals
158
+ replay Replay an improve bundle against the local Agent Capsule
143
159
  conversations List, inspect, and trace stored local conversations
144
160
  channels Manage hosted channel resources
145
161
  integrations Manage hosted AgentKit-managed integrations
@@ -149,6 +165,8 @@ Commands:
149
165
  build Build a hosted deploy artifact
150
166
  login Store an AgentKit Cloud alpha token outside the capsule
151
167
  logout Remove the stored AgentKit Cloud alpha token
168
+ billing Buy deploy slots, claim checkout tokens, and open the billing portal
169
+ account Manage AgentKit Cloud account tokens
152
170
  deploy Build and send a hosted artifact to AgentKit Cloud
153
171
  secret Manage hosted AgentKit Cloud secrets without readback
154
172
  access Manage hosted deploy access tokens
@@ -181,6 +199,9 @@ export function renderCommandHelp(command: string): string {
181
199
  spec: 'agentkit spec init --brief "owner request" | agentkit spec check',
182
200
  sync: "agentkit sync init [--force] | agentkit sync run [--file <path>]",
183
201
  eval: "agentkit eval run | agentkit eval from-conversation <conversation-id> [--out <path>] [--force]",
202
+ improve:
203
+ "agentkit improve collect [--deploy] [--since <duration|iso>] [--conversation-id <id>] [--out <directory>] | agentkit improve evals <bundle-dir-or-json> [--force]",
204
+ replay: "agentkit replay <bundle-dir-or-json> --against local",
184
205
  conversations:
185
206
  "agentkit conversations list [--deploy] | agentkit conversations show <conversation-id> [--deploy] | agentkit conversations trace <conversation-id> [--deploy]",
186
207
  channels:
@@ -192,6 +213,9 @@ export function renderCommandHelp(command: string): string {
192
213
  secret:
193
214
  "agentkit secret set <NAME> --stdin | --from-env [ENV_NAME] | --from-local-env | agentkit secret sync --from-local | list | unset <NAME>",
194
215
  access: "agentkit access token create <name> [--out <path>] | list | revoke <token-id>",
216
+ account: "agentkit account token create <name> [--use] [--out <path>] | list | revoke <token-id>",
217
+ billing:
218
+ "agentkit billing checkout --slots <count> [--email <email>] | status <intent-id> --secret <secret> | claim <intent-id> --secret <secret> | portal",
195
219
  integrations: "agentkit integrations status [--toolkit <slug>] | agentkit integrations connect composio [--toolkit <slug>]",
196
220
  env: "agentkit env set <NAME> --stdin | --from-env [ENV_NAME] | list | unset <NAME>",
197
221
  docs: "agentkit docs path | llms | full",