@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.
Files changed (142) hide show
  1. package/README.md +68 -6
  2. package/docs/guides/add-channel.md +189 -7
  3. package/docs/guides/add-knowledge.md +144 -0
  4. package/docs/guides/add-managed-composio.md +163 -0
  5. package/docs/guides/add-tool.md +1 -1
  6. package/docs/guides/channel-security.md +128 -32
  7. package/docs/guides/connect-discord.md +178 -0
  8. package/docs/guides/connect-slack.md +126 -0
  9. package/docs/guides/connect-telegram.md +78 -1
  10. package/docs/guides/connect-whatsapp-evolution.md +121 -0
  11. package/docs/guides/connect-whatsapp-uazapi.md +126 -0
  12. package/docs/guides/connect-whatsapp-zapster.md +112 -8
  13. package/docs/guides/create-agent.md +45 -4
  14. package/docs/guides/debug-channel.md +147 -0
  15. package/docs/guides/improve-from-production.md +151 -0
  16. package/docs/guides/prepare-deploy.md +47 -17
  17. package/docs/guides/replay-production-traces.md +72 -0
  18. package/docs/guides/run-evals.md +147 -20
  19. package/docs/guides/security-rules.md +7 -6
  20. package/docs/guides/send-feedback.md +135 -0
  21. package/docs/guides/use-provider.md +27 -3
  22. package/docs/llms-full.txt +348 -55
  23. package/docs/llms.txt +62 -7
  24. package/package.json +2 -5
  25. package/src/cli/args.ts +57 -0
  26. package/src/cli/cloud-client.ts +377 -0
  27. package/src/cli/commands/channels.ts +1586 -0
  28. package/src/cli/commands/feedback.ts +438 -0
  29. package/src/cli/commands/knowledge.ts +136 -0
  30. package/src/cli/commands/transcribe.ts +171 -0
  31. package/src/cli/constants.ts +4 -0
  32. package/src/cli/deploy-chat-ui.ts +535 -0
  33. package/src/cli/deploy-readiness.ts +481 -0
  34. package/src/cli/flags.ts +162 -0
  35. package/src/cli/help.ts +236 -0
  36. package/src/cli/index.ts +1167 -1005
  37. package/src/cli/process.ts +31 -0
  38. package/src/cloud/artifact.ts +139 -0
  39. package/src/cloud/client.ts +80 -0
  40. package/src/cloud/contracts.ts +63 -0
  41. package/src/cloud/index.ts +3 -0
  42. package/src/create-project.ts +21 -6
  43. package/src/index.ts +517 -8
  44. package/src/providers/pi.ts +70 -16
  45. package/src/providers/test.ts +88 -1
  46. package/src/providers/types.ts +7 -0
  47. package/src/runtime/channel-buffer.ts +30 -0
  48. package/src/runtime/channel-test-harness.ts +21 -1
  49. package/src/runtime/channels/discord.ts +896 -0
  50. package/src/runtime/channels/generic-webhook.ts +225 -0
  51. package/src/runtime/channels/slack.ts +646 -0
  52. package/src/runtime/channels/telegram.ts +466 -23
  53. package/src/runtime/channels/whatsapp-evolution.ts +1357 -0
  54. package/src/runtime/channels/whatsapp-meta.ts +9 -0
  55. package/src/runtime/channels/whatsapp-uazapi.ts +1327 -0
  56. package/src/runtime/channels/whatsapp-zapster.ts +677 -40
  57. package/src/runtime/channels.ts +87 -4
  58. package/src/runtime/chat.ts +130 -38
  59. package/src/runtime/config.ts +519 -19
  60. package/src/runtime/core/manifest.ts +103 -5
  61. package/src/runtime/core/targets.ts +5 -5
  62. package/src/runtime/database.ts +93 -2
  63. package/src/runtime/db-commands.ts +9 -0
  64. package/src/runtime/deploy-readiness.ts +46 -4
  65. package/src/runtime/deploy.ts +1 -1
  66. package/src/runtime/dev-server.ts +779 -45
  67. package/src/runtime/env.ts +8 -3
  68. package/src/runtime/evals.ts +589 -43
  69. package/src/runtime/improve.ts +868 -0
  70. package/src/runtime/inspect.ts +194 -4
  71. package/src/runtime/integrations/composio.ts +423 -0
  72. package/src/runtime/knowledge/chunk.ts +333 -0
  73. package/src/runtime/knowledge/config.ts +135 -0
  74. package/src/runtime/knowledge/embeddings.ts +133 -0
  75. package/src/runtime/knowledge/ingest.ts +521 -0
  76. package/src/runtime/knowledge/prompt-policy.ts +30 -0
  77. package/src/runtime/knowledge/retrieve.ts +303 -0
  78. package/src/runtime/knowledge/schema.ts +100 -0
  79. package/src/runtime/knowledge/tool.ts +64 -0
  80. package/src/runtime/knowledge/vector.ts +258 -0
  81. package/src/runtime/prompt-context.ts +141 -0
  82. package/src/runtime/runtime-contract.ts +86 -8
  83. package/src/runtime/skills.ts +95 -0
  84. package/src/runtime/spec.ts +152 -0
  85. package/src/runtime/sync.ts +144 -0
  86. package/src/runtime/targets/cloudflare/build.ts +1468 -203
  87. package/src/runtime/targets/container/server.ts +1 -1
  88. package/src/runtime/targets/vps/deploy.ts +26 -9
  89. package/src/runtime/tool-runner.ts +9 -1
  90. package/src/runtime/tools.ts +128 -2
  91. package/src/runtime/traces.ts +41 -0
  92. package/src/runtime/transcription.ts +483 -0
  93. package/src/storage/sqlite.ts +149 -3
  94. package/src/templates/blank.ts +76 -17
  95. package/src/templates/dentista.ts +1011 -0
  96. package/src/templates/index.ts +2 -0
  97. package/src/templates/skills/agentkit-build-agent/SKILL.md +52 -0
  98. package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +21 -0
  99. package/src/templates/skills/agentkit-build-agent/templates/sales-qualifier.instructions.md +17 -0
  100. package/src/templates/skills/agentkit-build-agent/templates/support-agent.instructions.md +16 -0
  101. package/src/templates/skills/agentkit-capsule/SKILL.md +70 -0
  102. package/src/templates/skills/agentkit-capsule/references/docs-router.md +15 -0
  103. package/src/templates/skills/agentkit-channels/SKILL.md +127 -0
  104. package/src/templates/skills/agentkit-channels/references/channel-buffering.md +65 -0
  105. package/src/templates/skills/agentkit-channels/references/channel-debugging.md +66 -0
  106. package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
  107. package/src/templates/skills/agentkit-channels/references/slack.md +56 -0
  108. package/src/templates/skills/agentkit-channels/references/telegram.md +72 -0
  109. package/src/templates/skills/agentkit-channels/references/whatsapp-evolution.md +57 -0
  110. package/src/templates/skills/agentkit-channels/references/whatsapp-uazapi.md +61 -0
  111. package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +77 -0
  112. package/src/templates/skills/agentkit-database/SKILL.md +45 -0
  113. package/src/templates/skills/agentkit-database/templates/appointments.schema.sql +15 -0
  114. package/src/templates/skills/agentkit-database/templates/leads.schema.sql +17 -0
  115. package/src/templates/skills/agentkit-deploy/SKILL.md +50 -0
  116. package/src/templates/skills/agentkit-evals/SKILL.md +109 -0
  117. package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +29 -0
  118. package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +18 -0
  119. package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +18 -0
  120. package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +27 -0
  121. package/src/templates/skills/agentkit-improve/SKILL.md +86 -0
  122. package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
  123. package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
  124. package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
  125. package/src/templates/skills/agentkit-integrations/SKILL.md +76 -0
  126. package/src/templates/skills/agentkit-knowledge/SKILL.md +43 -0
  127. package/src/templates/skills/agentkit-knowledge/templates/faq.md +14 -0
  128. package/src/templates/skills/agentkit-knowledge/templates/policies.md +14 -0
  129. package/src/templates/skills/agentkit-knowledge/templates/prices.csv +3 -0
  130. package/src/templates/skills/agentkit-prompts/SKILL.md +47 -0
  131. package/src/templates/skills/agentkit-prompts/templates/knowledge-grounded-faq.instructions.md +11 -0
  132. package/src/templates/skills/agentkit-provider/SKILL.md +60 -0
  133. package/src/templates/skills/agentkit-security/SKILL.md +56 -0
  134. package/src/templates/skills/agentkit-tools/SKILL.md +37 -0
  135. package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +35 -0
  136. package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +37 -0
  137. package/src/templates/skills/agentkit-tools/examples/lookup-order.tool.md +46 -0
  138. package/src/templates/skills/agentkit-troubleshooting/SKILL.md +76 -0
  139. package/src/templates/support.ts +77 -18
  140. package/docs/guides/channels-production-handoff.md +0 -99
  141. package/docs/portable-deploy-release-checklist.md +0 -41
  142. package/src/runtime/targets/cloudflare/deploy.ts +0 -5475
@@ -0,0 +1,225 @@
1
+ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
2
+
3
+ import type { ChannelAdapter, ChannelSendInput, RawWebhookEvent } from "../channels";
4
+ import { AgentKitError } from "../errors";
5
+
6
+ const DEFAULT_SECRET_NAME = "AGENTKIT_WEBHOOK_SECRET";
7
+
8
+ export const genericWebhookChannelAdapter: ChannelAdapter = {
9
+ type: "webhook",
10
+ provider: "generic",
11
+ requiredSecrets: [DEFAULT_SECRET_NAME],
12
+ verifyWebhook(input) {
13
+ const expected = input.secrets[DEFAULT_SECRET_NAME];
14
+
15
+ if (!expected) {
16
+ return {
17
+ ok: false,
18
+ code: "channel_secret_missing",
19
+ message: `Secret ${DEFAULT_SECRET_NAME} is not set for this channel.`,
20
+ };
21
+ }
22
+
23
+ const signature = input.headers.get("x-agentkit-webhook-signature") ?? input.headers.get("x-agentkit-signature");
24
+
25
+ if (signature) {
26
+ const expectedSignature = `sha256=${createHmac("sha256", expected).update(input.rawBody).digest("hex")}`;
27
+
28
+ if (constantTimeEqual(signature.trim(), expectedSignature)) {
29
+ return { ok: true };
30
+ }
31
+
32
+ return {
33
+ ok: false,
34
+ code: "channel_signature_invalid",
35
+ message: "Generic webhook HMAC signature did not match.",
36
+ };
37
+ }
38
+
39
+ const bearer = readBearerToken(input.headers.get("authorization"));
40
+ const headerToken =
41
+ input.headers.get("x-agentkit-webhook-secret") ??
42
+ input.headers.get("x-agentkit-channel-token") ??
43
+ input.headers.get("x-agentkit-webhook-token");
44
+
45
+ if (constantTimeEqual(bearer, expected) || constantTimeEqual(headerToken ?? "", expected)) {
46
+ return { ok: true };
47
+ }
48
+
49
+ return {
50
+ ok: false,
51
+ code: "channel_signature_invalid",
52
+ message: "Generic webhook token did not match.",
53
+ };
54
+ },
55
+ normalizeInbound(input) {
56
+ const body = parseJsonObject(input);
57
+ const eventId = readFirstScalar(body, ["event_id", "eventId", "id"]) ?? readNestedMessageId(body);
58
+
59
+ if (!eventId) {
60
+ throw new AgentKitError("channel_payload_invalid", "Generic webhook payload is missing event_id.");
61
+ }
62
+
63
+ const text = readMessageText(body);
64
+ const identitySource =
65
+ readFirstScalar(body, [
66
+ "external_id",
67
+ "externalId",
68
+ "user_id",
69
+ "userId",
70
+ "contact_id",
71
+ "contactId",
72
+ "conversation_id",
73
+ "conversationId",
74
+ "client_id",
75
+ "clientId",
76
+ "visitor_id",
77
+ "visitorId",
78
+ "source_id",
79
+ "sourceId",
80
+ ]) ?? `event:${eventId}`;
81
+ const identityKey = `webhook:generic:identity:${sha256(identitySource).slice(0, 32)}`;
82
+ const base = {
83
+ type: "webhook" as const,
84
+ provider: "generic" as const,
85
+ providerEventId: eventId,
86
+ dedupeKey: `webhook:generic:${input.channelId}:${eventId}`,
87
+ externalIdentity: {
88
+ key: identityKey,
89
+ redactedDisplay: identityKey,
90
+ },
91
+ receivedAt: input.receivedAt,
92
+ };
93
+
94
+ if (!text) {
95
+ return [
96
+ {
97
+ ...base,
98
+ kind: "unsupported" as const,
99
+ unsupportedReason: "unsupported_message_type:missing_text",
100
+ },
101
+ ];
102
+ }
103
+
104
+ return [
105
+ {
106
+ ...base,
107
+ kind: "message" as const,
108
+ message: {
109
+ role: "user" as const,
110
+ contentType: "text" as const,
111
+ content: text,
112
+ providerMessageId: readNestedMessageId(body) ?? eventId,
113
+ },
114
+ },
115
+ ];
116
+ },
117
+ async sendMessage(input) {
118
+ return {
119
+ ok: true,
120
+ status: "stubbed",
121
+ providerRequestId: buildGenericWebhookProviderRequestId(input),
122
+ };
123
+ },
124
+ getStatus() {
125
+ return {
126
+ status: "connected",
127
+ checkedAt: new Date().toISOString(),
128
+ providerMetadata: {
129
+ outbound: "stubbed",
130
+ },
131
+ };
132
+ },
133
+ };
134
+
135
+ function buildGenericWebhookProviderRequestId(input: ChannelSendInput): string {
136
+ return `webhook:generic:${input.channelId}:${input.conversationId}`;
137
+ }
138
+
139
+ function parseJsonObject(input: RawWebhookEvent): Record<string, unknown> {
140
+ const contentType = input.headers.get("content-type") ?? "";
141
+
142
+ if (contentType && !contentType.toLowerCase().includes("application/json")) {
143
+ throw new AgentKitError("channel_payload_invalid", "Generic webhook payload must use content-type application/json.");
144
+ }
145
+
146
+ try {
147
+ const parsed = JSON.parse(input.rawBody) as unknown;
148
+
149
+ if (isRecord(parsed)) {
150
+ return parsed;
151
+ }
152
+ } catch (error) {
153
+ throw new AgentKitError("channel_payload_invalid", "Generic webhook payload must be valid JSON.", {
154
+ cause: error,
155
+ });
156
+ }
157
+
158
+ throw new AgentKitError("channel_payload_invalid", "Generic webhook payload must be a JSON object.");
159
+ }
160
+
161
+ function readMessageText(body: Record<string, unknown>): string | undefined {
162
+ const message = body.message;
163
+
164
+ if (typeof message === "string") {
165
+ return normalizeNonEmpty(message);
166
+ }
167
+
168
+ if (isRecord(message)) {
169
+ return readFirstScalar(message, ["text", "content", "body"]);
170
+ }
171
+
172
+ return readFirstScalar(body, ["text", "content", "prompt", "input"]);
173
+ }
174
+
175
+ function readNestedMessageId(body: Record<string, unknown>): string | undefined {
176
+ const message = body.message;
177
+ return isRecord(message) ? readFirstScalar(message, ["id", "message_id", "messageId"]) : undefined;
178
+ }
179
+
180
+ function readFirstScalar(value: Record<string, unknown>, keys: string[]): string | undefined {
181
+ for (const key of keys) {
182
+ const field = value[key];
183
+
184
+ if (typeof field === "string") {
185
+ const normalized = normalizeNonEmpty(field);
186
+
187
+ if (normalized) {
188
+ return normalized;
189
+ }
190
+ }
191
+
192
+ if (typeof field === "number" && Number.isFinite(field)) {
193
+ return String(field);
194
+ }
195
+ }
196
+
197
+ return undefined;
198
+ }
199
+
200
+ function normalizeNonEmpty(value: string): string | undefined {
201
+ const trimmed = value.trim();
202
+ return trimmed.length > 0 ? trimmed : undefined;
203
+ }
204
+
205
+ function readBearerToken(value: string | null): string {
206
+ if (!value?.startsWith("Bearer ")) {
207
+ return "";
208
+ }
209
+
210
+ return value.slice("Bearer ".length).trim();
211
+ }
212
+
213
+ function constantTimeEqual(left: string, right: string): boolean {
214
+ const leftDigest = createHash("sha256").update(left).digest();
215
+ const rightDigest = createHash("sha256").update(right).digest();
216
+ return timingSafeEqual(leftDigest, rightDigest) && left === right;
217
+ }
218
+
219
+ function sha256(value: string): string {
220
+ return createHash("sha256").update(value).digest("hex");
221
+ }
222
+
223
+ function isRecord(value: unknown): value is Record<string, unknown> {
224
+ return typeof value === "object" && value !== null && !Array.isArray(value);
225
+ }