@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
@@ -19,6 +19,9 @@ import type { ProviderAdapter, ProviderRunInput, ProviderRunResult } from "./typ
19
19
 
20
20
  const PI_PROVIDER_NAMES = ["openai", "anthropic", "openrouter"] as const satisfies AgentProviderName[];
21
21
  const MAX_TOOL_TURNS = 8;
22
+ const OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1";
23
+ const UNKNOWN_OPENROUTER_CONTEXT_WINDOW = 128000;
24
+ const UNKNOWN_OPENROUTER_MAX_TOKENS = 8192;
22
25
 
23
26
  export const piProviderAdapters: ProviderAdapter[] = PI_PROVIDER_NAMES.map((name) => ({
24
27
  name,
@@ -97,7 +100,7 @@ async function runPiProvider(input: ProviderRunInput): Promise<ProviderRunResult
97
100
  content: [
98
101
  {
99
102
  type: "text",
100
- text: JSON.stringify(result.output),
103
+ text: providerToolResultText(result),
101
104
  },
102
105
  ],
103
106
  isError: false,
@@ -109,6 +112,19 @@ async function runPiProvider(input: ProviderRunInput): Promise<ProviderRunResult
109
112
  throw new AgentKitError("runtime_error", `Pi provider exceeded ${MAX_TOOL_TURNS} tool turns.`);
110
113
  }
111
114
 
115
+ export function providerToolResultText(result: {
116
+ name: string;
117
+ visibility?: "user" | "internal";
118
+ rendered?: { text?: string };
119
+ output: unknown;
120
+ }): string {
121
+ if (result.visibility === "internal") {
122
+ return `Internal tool ${result.name} completed.`;
123
+ }
124
+
125
+ return result.rendered?.text ?? JSON.stringify(result.output);
126
+ }
127
+
112
128
  async function runPiTurn(
113
129
  model: Model<any>,
114
130
  context: Parameters<typeof stream>[1],
@@ -176,25 +192,56 @@ function formatSecretList(names: string[]): string {
176
192
  return `one of: ${names.join(", ")}`;
177
193
  }
178
194
 
179
- function resolveModel(provider: Provider, modelId: string): Model<any> {
180
- const modelExists = getModels(provider as any).some((model) => model.id === modelId);
195
+ export function resolveModel(provider: Provider, modelId: string): Model<any> {
196
+ const model = getModel(provider as any, modelId as any) as Model<any> | undefined;
181
197
 
182
- if (!modelExists) {
183
- throw new AgentKitError(
184
- "provider_model_unsupported",
185
- `Pi SDK could not resolve provider "${provider}" model "${modelId}".`,
186
- );
198
+ if (model) {
199
+ return model;
187
200
  }
188
201
 
189
- try {
190
- return getModel(provider as any, modelId as any) as Model<any>;
191
- } catch (error) {
192
- throw new AgentKitError(
193
- "provider_model_unsupported",
194
- `Pi SDK could not resolve provider "${provider}" model "${modelId}".`,
195
- { cause: error },
196
- );
202
+ if (provider === "openrouter") {
203
+ return createOpenRouterPassThroughModel(modelId);
197
204
  }
205
+
206
+ throw new AgentKitError(
207
+ "provider_model_unsupported",
208
+ `Pi SDK could not resolve provider "${provider}" model "${modelId}". ${knownModelHint(provider)}`,
209
+ );
210
+ }
211
+
212
+ function createOpenRouterPassThroughModel(modelId: string): Model<"openai-completions"> {
213
+ return {
214
+ id: modelId,
215
+ name: `OpenRouter ${modelId}`,
216
+ api: "openai-completions",
217
+ provider: "openrouter",
218
+ baseUrl: OPENROUTER_BASE_URL,
219
+ reasoning: false,
220
+ input: ["text"],
221
+ cost: {
222
+ input: 0,
223
+ output: 0,
224
+ cacheRead: 0,
225
+ cacheWrite: 0,
226
+ },
227
+ contextWindow: UNKNOWN_OPENROUTER_CONTEXT_WINDOW,
228
+ maxTokens: UNKNOWN_OPENROUTER_MAX_TOKENS,
229
+ compat: {
230
+ openRouterRouting: {},
231
+ },
232
+ };
233
+ }
234
+
235
+ function knownModelHint(provider: Provider): string {
236
+ const examples = getModels(provider as any)
237
+ .slice(0, 5)
238
+ .map((model) => model.id);
239
+
240
+ if (examples.length === 0) {
241
+ return "Use a model id supported by the installed Pi SDK for that provider.";
242
+ }
243
+
244
+ return `Use a model id supported by the installed Pi SDK for that provider. Examples: ${examples.join(", ")}.`;
198
245
  }
199
246
 
200
247
  function toPiMessages(messages: ProviderRunInput["messages"]): Message[] {
@@ -244,6 +291,13 @@ function normalizeUsage(usage: Usage | undefined): ProviderRunResult["usage"] |
244
291
  inputTokens: usage.input,
245
292
  outputTokens: usage.output,
246
293
  totalTokens: usage.totalTokens,
294
+ cost: {
295
+ input: usage.cost.input,
296
+ output: usage.cost.output,
297
+ cacheRead: usage.cost.cacheRead,
298
+ cacheWrite: usage.cost.cacheWrite,
299
+ total: usage.cost.total,
300
+ },
247
301
  };
248
302
  }
249
303
 
@@ -29,7 +29,7 @@ export const testProviderAdapter: ProviderAdapter = {
29
29
  content:
30
30
  toolResult.visibility === "internal"
31
31
  ? `Tool ${toolResult.name}: completed`
32
- : `Tool ${toolResult.name}: ${JSON.stringify(toolResult.output)}`,
32
+ : toolResult.rendered?.text ?? `Tool ${toolResult.name}: ${JSON.stringify(toolResult.output)}`,
33
33
  },
34
34
  raw: {
35
35
  toolCalls: [toolResult],
@@ -37,6 +37,28 @@ export const testProviderAdapter: ProviderAdapter = {
37
37
  };
38
38
  }
39
39
 
40
+ const currentDate = answerCurrentDate(input.instructions, userMessage.content);
41
+
42
+ if (currentDate) {
43
+ return {
44
+ message: {
45
+ role: "assistant",
46
+ content: currentDate,
47
+ },
48
+ };
49
+ }
50
+
51
+ const rememberedName = answerRememberedName(input.messages);
52
+
53
+ if (rememberedName) {
54
+ return {
55
+ message: {
56
+ role: "assistant",
57
+ content: rememberedName,
58
+ },
59
+ };
60
+ }
61
+
40
62
  return {
41
63
  message: {
42
64
  role: "assistant",
@@ -58,6 +80,71 @@ function findLastUserMessage(messages: AgentMessage[]): AgentMessage | undefined
58
80
  return undefined;
59
81
  }
60
82
 
83
+ function answerRememberedName(messages: AgentMessage[]): string | null {
84
+ const lastUserMessage = findLastUserMessage(messages);
85
+
86
+ if (!lastUserMessage || !asksForName(lastUserMessage.content)) {
87
+ return null;
88
+ }
89
+
90
+ for (let index = messages.length - 2; index >= 0; index -= 1) {
91
+ const message = messages[index];
92
+
93
+ if (message.role !== "user") {
94
+ continue;
95
+ }
96
+
97
+ const name = extractName(message.content);
98
+
99
+ if (name) {
100
+ return /meu nome|qual\s+(é|e)\s*meu nome|como\s+(é|e)\s*meu nome/i.test(lastUserMessage.content)
101
+ ? `Seu nome é ${name}.`
102
+ : `Your name is ${name}.`;
103
+ }
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ function answerCurrentDate(instructions: string, content: string): string | null {
110
+ if (!/(today|current date|what date|data de hoje|hoje)/i.test(content)) {
111
+ return null;
112
+ }
113
+
114
+ const localDate = readRuntimeContextValue(instructions, "Local date");
115
+
116
+ if (!localDate) {
117
+ return null;
118
+ }
119
+
120
+ const localWeekday = readRuntimeContextValue(instructions, "Local weekday");
121
+ const timeZone = readRuntimeContextValue(instructions, "Time zone");
122
+ const weekday = localWeekday ? ` (${localWeekday})` : "";
123
+ const zone = timeZone ? ` in ${timeZone}` : "";
124
+
125
+ return `Today is ${localDate}${weekday}${zone}.`;
126
+ }
127
+
128
+ function readRuntimeContextValue(instructions: string, label: string): string | null {
129
+ const escapedLabel = label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
130
+ const match = instructions.match(new RegExp(`^- ${escapedLabel}: (.+)$`, "m"));
131
+ return match?.[1]?.trim() || null;
132
+ }
133
+
134
+ function asksForName(content: string): boolean {
135
+ return /what(?:'s| is) my name\??/i.test(content) || /(como|qual)\s+(é|e)\s*(o\s+)?meu nome\??/i.test(content);
136
+ }
137
+
138
+ function extractName(content: string): string | null {
139
+ const match = content.match(/\bmy name is\s+(.+)$/i) ?? content.match(/\bmeu nome (?:é|e)\s+(.+)$/i);
140
+
141
+ if (!match) {
142
+ return null;
143
+ }
144
+
145
+ return match[1].trim().replace(/[.!?]+$/g, "") || null;
146
+ }
147
+
61
148
  function parseToolRequest(content: string): { name: string; input?: unknown } | null {
62
149
  let parsed: unknown;
63
150
 
@@ -24,6 +24,13 @@ export type ProviderRunResult = {
24
24
  inputTokens?: number;
25
25
  outputTokens?: number;
26
26
  totalTokens?: number;
27
+ cost?: {
28
+ input?: number;
29
+ output?: number;
30
+ cacheRead?: number;
31
+ cacheWrite?: number;
32
+ total?: number;
33
+ };
27
34
  };
28
35
  raw?: unknown;
29
36
  };
@@ -0,0 +1,30 @@
1
+ import type { ChannelBufferConfig, ChannelType } from "../index";
2
+
3
+ export type ChannelBufferCarrier = {
4
+ type: ChannelType;
5
+ buffer?: ChannelBufferConfig;
6
+ };
7
+
8
+ export type ChannelBufferedMessage = {
9
+ content: string;
10
+ receivedAt: string;
11
+ };
12
+
13
+ export function resolveChannelBuffer(channel: ChannelBufferCarrier): ChannelBufferConfig {
14
+ return channel.buffer ?? { mode: "off" };
15
+ }
16
+
17
+ export function isChannelBufferEnabled(channel: ChannelBufferCarrier): boolean {
18
+ return resolveChannelBuffer(channel).mode === "debounce";
19
+ }
20
+
21
+ export function renderBufferedChannelMessage(messages: ChannelBufferedMessage[]): string {
22
+ if (messages.length === 1) {
23
+ return messages[0]?.content ?? "";
24
+ }
25
+
26
+ const lines = messages.map((message, index) => `${index + 1}. ${message.content}`);
27
+
28
+ return `The client sent ${messages.length} messages in one burst. Answer once, using the full context below:\n\n${lines.join("\n")}`;
29
+ }
30
+
@@ -8,11 +8,31 @@ import type { NormalizedChannelEvent, RawWebhookEvent } from "./channels";
8
8
  export type ChannelFixtureName =
9
9
  | "website-message"
10
10
  | "telegram-message"
11
+ | "telegram-audio-message"
11
12
  | "telegram-duplicate-message"
12
13
  | "telegram-malformed-payload"
13
14
  | "zapster-message"
15
+ | "zapster-audio-message"
14
16
  | "zapster-duplicate-message"
15
- | "zapster-unsupported-media";
17
+ | "zapster-unsupported-media"
18
+ | "uazapi-message"
19
+ | "uazapi-audio-message"
20
+ | "uazapi-duplicate-message"
21
+ | "uazapi-unsupported-media"
22
+ | "uazapi-was-sent-by-api"
23
+ | "evolution-message"
24
+ | "evolution-audio-message"
25
+ | "evolution-captioned-media"
26
+ | "evolution-duplicate-message"
27
+ | "evolution-from-me"
28
+ | "evolution-unsupported-media"
29
+ | "discord-command"
30
+ | "discord-message-create"
31
+ | "discord-ping"
32
+ | "slack-app-mention"
33
+ | "slack-direct-message"
34
+ | "generic-webhook-message"
35
+ | "generic-webhook-duplicate";
16
36
 
17
37
  export type ChannelFixture = {
18
38
  name: ChannelFixtureName;