@andreprado/agentkit 0.1.0-alpha.9 → 0.1.0

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 (117) hide show
  1. package/README.md +18 -1
  2. package/docs/guides/add-channel.md +251 -7
  3. package/docs/guides/add-knowledge.md +10 -0
  4. package/docs/guides/add-managed-composio.md +165 -0
  5. package/docs/guides/add-tool.md +10 -3
  6. package/docs/guides/channel-security.md +162 -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 +61 -1
  10. package/docs/guides/connect-whatsapp-evolution.md +121 -0
  11. package/docs/guides/connect-whatsapp-uazapi.md +139 -0
  12. package/docs/guides/connect-whatsapp-zapster.md +119 -16
  13. package/docs/guides/create-agent.md +31 -4
  14. package/docs/guides/debug-channel.md +159 -0
  15. package/docs/guides/improve-from-production.md +151 -0
  16. package/docs/guides/prepare-deploy.md +32 -14
  17. package/docs/guides/replay-production-traces.md +72 -0
  18. package/docs/guides/run-evals.md +95 -25
  19. package/docs/guides/security-rules.md +9 -5
  20. package/docs/guides/send-feedback.md +135 -0
  21. package/docs/guides/use-jev.md +67 -0
  22. package/docs/guides/use-provider.md +70 -3
  23. package/docs/llms-full.txt +295 -25
  24. package/docs/llms.txt +54 -7
  25. package/package.json +3 -7
  26. package/src/cli/args.ts +23 -2
  27. package/src/cli/cloud-client.ts +121 -9
  28. package/src/cli/commands/channels.ts +856 -36
  29. package/src/cli/commands/feedback.ts +438 -0
  30. package/src/cli/commands/provider.ts +47 -0
  31. package/src/cli/commands/transcribe.ts +171 -0
  32. package/src/cli/deploy-chat-ui.ts +232 -18
  33. package/src/cli/deploy-readiness.ts +227 -14
  34. package/src/cli/help.ts +67 -9
  35. package/src/cli/index.ts +740 -35
  36. package/src/cli/new-command.ts +41 -0
  37. package/src/cloud/client.ts +4 -3
  38. package/src/cloud/contracts.ts +1 -1
  39. package/src/create-project.ts +18 -35
  40. package/src/index.ts +565 -11
  41. package/src/providers/codex-auth.ts +111 -0
  42. package/src/providers/pi.ts +88 -19
  43. package/src/providers/test.ts +36 -0
  44. package/src/providers/types.ts +8 -0
  45. package/src/runtime/channel-test-harness.ts +21 -1
  46. package/src/runtime/channels/discord.ts +896 -0
  47. package/src/runtime/channels/generic-webhook.ts +974 -0
  48. package/src/runtime/channels/slack.ts +646 -0
  49. package/src/runtime/channels/telegram.ts +343 -12
  50. package/src/runtime/channels/whatsapp-evolution.ts +1357 -0
  51. package/src/runtime/channels/whatsapp-meta.ts +9 -0
  52. package/src/runtime/channels/whatsapp-uazapi.ts +1323 -0
  53. package/src/runtime/channels/whatsapp-zapster.ts +674 -40
  54. package/src/runtime/channels.ts +83 -3
  55. package/src/runtime/chat.ts +70 -44
  56. package/src/runtime/config.ts +489 -20
  57. package/src/runtime/core/manifest.ts +75 -5
  58. package/src/runtime/core/targets.ts +5 -5
  59. package/src/runtime/deploy-readiness.ts +34 -4
  60. package/src/runtime/dev-server.ts +639 -39
  61. package/src/runtime/env.ts +8 -3
  62. package/src/runtime/evals.ts +445 -74
  63. package/src/runtime/improve.ts +868 -0
  64. package/src/runtime/inspect.ts +173 -4
  65. package/src/runtime/integrations/composio.ts +425 -0
  66. package/src/runtime/knowledge/retrieve.ts +25 -5
  67. package/src/runtime/knowledge/schema.ts +45 -1
  68. package/src/runtime/prompt-context.ts +141 -0
  69. package/src/runtime/runtime-contract.ts +71 -7
  70. package/src/runtime/skills.ts +95 -0
  71. package/src/runtime/targets/cloudflare/build.ts +1010 -208
  72. package/src/runtime/targets/container/server.ts +1 -1
  73. package/src/runtime/targets/vps/deploy.ts +26 -9
  74. package/src/runtime/tool-runner.ts +9 -1
  75. package/src/runtime/tools.ts +26 -2
  76. package/src/runtime/transcription.ts +483 -0
  77. package/src/storage/sqlite.ts +7 -2
  78. package/src/templates/blank.ts +37 -9
  79. package/src/templates/dentista.ts +40 -14
  80. package/src/templates/skills/agentkit-build-agent/SKILL.md +34 -5
  81. package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +2 -1
  82. package/src/templates/skills/agentkit-capsule/SKILL.md +32 -3
  83. package/src/templates/skills/agentkit-capsule/references/docs-router.md +2 -2
  84. package/src/templates/skills/agentkit-channels/SKILL.md +66 -1
  85. package/src/templates/skills/agentkit-channels/references/channel-buffering.md +8 -1
  86. package/src/templates/skills/agentkit-channels/references/channel-debugging.md +28 -3
  87. package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
  88. package/src/templates/skills/agentkit-channels/references/slack.md +56 -0
  89. package/src/templates/skills/agentkit-channels/references/telegram.md +34 -0
  90. package/src/templates/skills/agentkit-channels/references/whatsapp-evolution.md +57 -0
  91. package/src/templates/skills/agentkit-channels/references/whatsapp-uazapi.md +54 -0
  92. package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +42 -8
  93. package/src/templates/skills/agentkit-database/SKILL.md +11 -0
  94. package/src/templates/skills/agentkit-deploy/SKILL.md +9 -1
  95. package/src/templates/skills/agentkit-evals/SKILL.md +77 -13
  96. package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +13 -6
  97. package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +8 -4
  98. package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +8 -4
  99. package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +16 -7
  100. package/src/templates/skills/agentkit-improve/SKILL.md +96 -0
  101. package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
  102. package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
  103. package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
  104. package/src/templates/skills/agentkit-integrations/SKILL.md +98 -0
  105. package/src/templates/skills/agentkit-knowledge/SKILL.md +4 -1
  106. package/src/templates/skills/agentkit-prompts/SKILL.md +3 -1
  107. package/src/templates/skills/agentkit-provider/SKILL.md +29 -4
  108. package/src/templates/skills/agentkit-security/SKILL.md +5 -2
  109. package/src/templates/skills/agentkit-tools/SKILL.md +8 -1
  110. package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +8 -8
  111. package/src/templates/skills/agentkit-tools/examples/jev-service-fit.tool.md +110 -0
  112. package/src/templates/skills/agentkit-troubleshooting/SKILL.md +25 -1
  113. package/src/templates/support.ts +42 -12
  114. package/docs/guides/agentkit-skills-architecture.md +0 -471
  115. package/docs/guides/channels-implementation-map.md +0 -243
  116. package/docs/guides/channels-production-handoff.md +0 -101
  117. package/docs/portable-deploy-release-checklist.md +0 -41
@@ -12,7 +12,7 @@ export async function startContainerRuntime(options: ContainerRuntimeOptions = {
12
12
  const capsuleRoot = resolve(options.capsuleRoot ?? process.env.AGENTKIT_CAPSULE_ROOT ?? process.cwd());
13
13
  const hostname = options.hostname ?? process.env.HOST ?? "0.0.0.0";
14
14
  const port = options.port ?? parsePort(process.env.PORT) ?? 4123;
15
- return startAgentDevServer(capsuleRoot, { hostname, port });
15
+ return startAgentDevServer(capsuleRoot, { hostname, port, access: "enforce" });
16
16
  }
17
17
 
18
18
  function parsePort(value: string | undefined): number | undefined {
@@ -1,4 +1,4 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
 
4
4
  import type { LocalDeployState } from "../../core/deploy-state";
@@ -38,15 +38,19 @@ export async function prepareVpsDeploy(
38
38
  const manifest = JSON.parse(await readFile(container.manifestPath, "utf8")) as {
39
39
  name: string;
40
40
  secrets: string[];
41
+ access: {
42
+ mode: "private" | "token" | "public";
43
+ };
41
44
  };
42
45
 
43
46
  await mkdir(buildDir, { recursive: true });
44
47
  const envExample = renderEnvExample(manifest.secrets);
45
48
  await writeFile(composePath, renderCompose(manifest.name));
46
49
  await writeFile(envExamplePath, envExample);
47
- await writeFile(envPath, envExample);
50
+ await writeFile(envPath, envExample, { mode: 0o600 });
51
+ await chmod(envPath, 0o600);
48
52
  await writeFile(secretsPath, renderSecretsChecklist(manifest.secrets));
49
- await writeFile(handoffPath, renderProductionHandoff(options.host, manifest.name));
53
+ await writeFile(handoffPath, renderProductionHandoff(options.host, manifest.name, manifest.access.mode));
50
54
 
51
55
  const state: LocalDeployState = {
52
56
  deploy_id: `vps_${slugify(manifest.name)}`,
@@ -71,7 +75,8 @@ export async function prepareVpsDeploy(
71
75
  },
72
76
  created_at: new Date().toISOString(),
73
77
  };
74
- await writeFile(statePath, `${JSON.stringify(state, null, 2)}\n`);
78
+ await writeFile(statePath, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
79
+ await chmod(statePath, 0o600);
75
80
 
76
81
  return {
77
82
  target: "vps",
@@ -88,7 +93,7 @@ export async function prepareVpsDeploy(
88
93
  `docker compose -f ${composePath} --env-file ${envPath} config`,
89
94
  `docker compose -f ${composePath} --env-file ${envPath} up -d --build`,
90
95
  `curl -fsS https://${options.host}/health`,
91
- `curl -fsS https://${options.host}/_agentkit`,
96
+ `curl -fsS -H "Authorization: Bearer $AGENTKIT_PRIVATE_TOKEN" https://${options.host}/_agentkit`,
92
97
  ],
93
98
  };
94
99
  }
@@ -113,7 +118,7 @@ function renderCompose(agentName: string): string {
113
118
  - agentkit_data:/data
114
119
  - agentkit_files:/capsule/.agentkit/files
115
120
  healthcheck:
116
- test: ["CMD", "bun", "-e", "const r=await fetch('http://127.0.0.1:4123/health'); process.exit(r.ok?0:1)"]
121
+ test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:4123/health').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
117
122
  interval: 30s
118
123
  timeout: 5s
119
124
  retries: 3
@@ -145,7 +150,7 @@ ${lines}
145
150
  `;
146
151
  }
147
152
 
148
- function renderProductionHandoff(host: string, agentName: string): string {
153
+ function renderProductionHandoff(host: string, agentName: string, accessMode: "private" | "token" | "public"): string {
149
154
  return `# VPS Production Handoff
150
155
 
151
156
  ## Deploy
@@ -169,12 +174,14 @@ docker compose -f .agentkit/build/vps/compose.yaml --env-file .agentkit/build/vp
169
174
 
170
175
  \`\`\`sh
171
176
  curl -fsS https://${host}/health
172
- curl -fsS https://${host}/_agentkit
177
+ curl -fsS -H "Authorization: Bearer $AGENTKIT_PRIVATE_TOKEN" https://${host}/_agentkit
173
178
  curl -fsS -X POST https://${host}/chat \\
174
- -H 'content-type: application/json' \\
179
+ -H 'content-type: application/json'${renderChatAuthHeader(accessMode)} \\
175
180
  -d '{"message":{"role":"user","content":"hello"}}'
176
181
  \`\`\`
177
182
 
183
+ Set AGENTKIT_PRIVATE_TOKEN for privileged AgentKit endpoints. Chat access follows access.mode: ${accessMode}.
184
+
178
185
  ## Database
179
186
 
180
187
  - Default database: SQLite at /data/agentkit.db in the agentkit_data volume.
@@ -195,6 +202,16 @@ docker compose -f .agentkit/build/vps/compose.yaml --env-file .agentkit/build/vp
195
202
  `;
196
203
  }
197
204
 
205
+ function renderChatAuthHeader(accessMode: "private" | "token" | "public"): string {
206
+ if (accessMode === "public") {
207
+ return "";
208
+ }
209
+
210
+ const secretName = accessMode === "private" ? "AGENTKIT_PRIVATE_TOKEN" : "AGENTKIT_ACCESS_TOKEN";
211
+ return ` \\
212
+ -H "Authorization: Bearer $${secretName}"`;
213
+ }
214
+
198
215
  function slugify(value: string): string {
199
216
  const slug = value
200
217
  .toLowerCase()
@@ -2,12 +2,15 @@ import { loadAgentCapsule } from "./config";
2
2
  import { openPreparedCapsuleStore } from "./database";
3
3
  import { loadCapsuleEnv } from "./env";
4
4
  import { isAgentKitError } from "./errors";
5
+ import { createManagedComposioTools } from "./integrations/composio";
6
+ import { buildRuntimeClockContext } from "./prompt-context";
5
7
  import { createToolRuntime, type ToolCallResult } from "./tools";
6
8
 
7
9
  export type RunToolOptions = {
8
10
  name: string;
9
11
  input?: unknown;
10
12
  signal?: AbortSignal;
13
+ now?: Date;
11
14
  };
12
15
 
13
16
  export async function runToolFromCwd(cwd: string, options: RunToolOptions): Promise<ToolCallResult> {
@@ -24,12 +27,17 @@ export async function runToolFromCwd(cwd: string, options: RunToolOptions): Prom
24
27
  model: capsule.config.provider.model,
25
28
  });
26
29
  const toolRuntime = createToolRuntime({
27
- tools: capsule.config.tools ?? [],
30
+ tools: [...createManagedComposioTools(capsule.config), ...(capsule.config.tools ?? [])],
28
31
  store,
29
32
  runId: run.id,
30
33
  conversationId: conversation.id,
31
34
  env,
32
35
  signal: options.signal,
36
+ clock: buildRuntimeClockContext({
37
+ timeZone: capsule.config.timeZone,
38
+ env,
39
+ now: options.now,
40
+ }),
33
41
  runtime: {
34
42
  environment: "local",
35
43
  invocation: "tool",
@@ -2,6 +2,7 @@ import type { AgentTool, JsonSchema, ToolContext, ToolRenderResult, ToolRuntimeC
2
2
  import type { SqliteAgentKitStore } from "../storage/sqlite";
3
3
  import { createLocalDatabaseRunner } from "./database";
4
4
  import { AgentKitError } from "./errors";
5
+ import type { RuntimeClockContext } from "./prompt-context";
5
6
 
6
7
  export type ToolCallRequest = {
7
8
  name: string;
@@ -31,6 +32,7 @@ export type ToolRuntimeOptions = {
31
32
  signal?: AbortSignal;
32
33
  defaultTimeoutMs?: number;
33
34
  runtime: ToolRuntimeContext;
35
+ clock: RuntimeClockContext;
34
36
  };
35
37
 
36
38
  const DEFAULT_TOOL_TIMEOUT_MS = 30_000;
@@ -79,6 +81,7 @@ async function executeToolCall(
79
81
 
80
82
  input = normalizeOptionalNulls(input, tool.inputSchema);
81
83
  validateSchema(input, tool.inputSchema, `tool "${tool.name}" input`);
84
+ assertToolInvocationAuthorized(tool, options.runtime);
82
85
 
83
86
  const { secrets, secretValues } = resolveToolSecrets(tool, options.env ?? process.env);
84
87
  const database = createLocalDatabaseRunner(options.store);
@@ -89,6 +92,7 @@ async function executeToolCall(
89
92
  secrets,
90
93
  database,
91
94
  runtime: options.runtime,
95
+ clock: options.clock,
92
96
  signal: options.signal,
93
97
  },
94
98
  tool.timeoutMs ?? options.defaultTimeoutMs ?? DEFAULT_TOOL_TIMEOUT_MS,
@@ -98,7 +102,7 @@ async function executeToolCall(
98
102
  validateSchema(output, tool.outputSchema, `tool "${tool.name}" output`);
99
103
  }
100
104
 
101
- const rendered = renderToolOutput(tool, input, output, options.runtime);
105
+ const rendered = renderToolOutput(tool, input, output, options.runtime, options.clock);
102
106
 
103
107
  options.store.completeToolCall({
104
108
  toolCallId: toolCall.id,
@@ -130,11 +134,29 @@ async function executeToolCall(
130
134
  }
131
135
  }
132
136
 
137
+ function assertToolInvocationAuthorized(tool: AgentTool, runtime: ToolRuntimeContext): void {
138
+ if (runtime.invocation === "tool") {
139
+ return;
140
+ }
141
+
142
+ const privilegedPermissions = (tool.permissions ?? []).filter((permission) => !permission.endsWith(":read"));
143
+
144
+ if (privilegedPermissions.length === 0) {
145
+ return;
146
+ }
147
+
148
+ throw new AgentKitError(
149
+ "tool_authorization_required",
150
+ `Tool "${tool.name}" requires an explicit operator invocation because it declares privileged permissions: ${privilegedPermissions.join(", ")}. Run it with "agentkit tool ${tool.name} --input '<json>'" after reviewing the exact action.`,
151
+ );
152
+ }
153
+
133
154
  function renderToolOutput(
134
155
  tool: AgentTool,
135
156
  input: unknown,
136
157
  output: unknown,
137
158
  runtime: ToolRuntimeContext,
159
+ clock: RuntimeClockContext,
138
160
  ): ToolRenderResult | undefined {
139
161
  if (!tool.render) {
140
162
  return undefined;
@@ -143,6 +165,7 @@ function renderToolOutput(
143
165
  const rendered = tool.render(output, {
144
166
  input,
145
167
  runtime,
168
+ clock,
146
169
  });
147
170
 
148
171
  if (typeof rendered === "string") {
@@ -278,7 +301,7 @@ function collectConfiguredSecretValues(tool: AgentTool | undefined, env: Record<
278
301
  async function runToolWithTimeout(
279
302
  tool: AgentTool,
280
303
  input: unknown,
281
- context: Pick<ToolContext, "secrets" | "database" | "runtime"> & { signal?: AbortSignal },
304
+ context: Pick<ToolContext, "secrets" | "database" | "runtime" | "clock"> & { signal?: AbortSignal },
282
305
  timeoutMs: number,
283
306
  ): Promise<unknown> {
284
307
  const controller = new AbortController();
@@ -306,6 +329,7 @@ async function runToolWithTimeout(
306
329
  secrets: context.secrets,
307
330
  signal: controller.signal,
308
331
  runtime: context.runtime,
332
+ clock: context.clock,
309
333
  database: context.database,
310
334
  db: context.database,
311
335
  storage: {