@andreprado/agentkit 0.1.0-alpha.2 → 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.
Files changed (135) hide show
  1. package/README.md +67 -6
  2. package/docs/guides/add-channel.md +118 -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 +97 -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-zapster.md +112 -8
  11. package/docs/guides/create-agent.md +45 -4
  12. package/docs/guides/debug-channel.md +147 -0
  13. package/docs/guides/improve-from-production.md +151 -0
  14. package/docs/guides/prepare-deploy.md +47 -17
  15. package/docs/guides/replay-production-traces.md +72 -0
  16. package/docs/guides/run-evals.md +147 -20
  17. package/docs/guides/security-rules.md +7 -6
  18. package/docs/guides/send-feedback.md +135 -0
  19. package/docs/guides/use-provider.md +27 -3
  20. package/docs/llms-full.txt +303 -55
  21. package/docs/llms.txt +57 -7
  22. package/package.json +2 -5
  23. package/src/cli/args.ts +57 -0
  24. package/src/cli/cloud-client.ts +377 -0
  25. package/src/cli/commands/channels.ts +1315 -0
  26. package/src/cli/commands/feedback.ts +438 -0
  27. package/src/cli/commands/knowledge.ts +136 -0
  28. package/src/cli/commands/transcribe.ts +171 -0
  29. package/src/cli/constants.ts +4 -0
  30. package/src/cli/deploy-chat-ui.ts +535 -0
  31. package/src/cli/deploy-readiness.ts +481 -0
  32. package/src/cli/flags.ts +162 -0
  33. package/src/cli/help.ts +236 -0
  34. package/src/cli/index.ts +1167 -1005
  35. package/src/cli/process.ts +31 -0
  36. package/src/cloud/artifact.ts +139 -0
  37. package/src/cloud/client.ts +80 -0
  38. package/src/cloud/contracts.ts +63 -0
  39. package/src/cloud/index.ts +3 -0
  40. package/src/create-project.ts +21 -6
  41. package/src/index.ts +479 -7
  42. package/src/providers/pi.ts +70 -16
  43. package/src/providers/test.ts +88 -1
  44. package/src/providers/types.ts +7 -0
  45. package/src/runtime/channel-buffer.ts +30 -0
  46. package/src/runtime/channel-test-harness.ts +8 -1
  47. package/src/runtime/channels/discord.ts +896 -0
  48. package/src/runtime/channels/slack.ts +646 -0
  49. package/src/runtime/channels/telegram.ts +466 -23
  50. package/src/runtime/channels/whatsapp-meta.ts +9 -0
  51. package/src/runtime/channels/whatsapp-zapster.ts +677 -40
  52. package/src/runtime/channels.ts +86 -3
  53. package/src/runtime/chat.ts +130 -38
  54. package/src/runtime/config.ts +483 -18
  55. package/src/runtime/core/manifest.ts +103 -5
  56. package/src/runtime/core/targets.ts +5 -5
  57. package/src/runtime/database.ts +93 -2
  58. package/src/runtime/db-commands.ts +9 -0
  59. package/src/runtime/deploy-readiness.ts +46 -4
  60. package/src/runtime/deploy.ts +1 -1
  61. package/src/runtime/dev-server.ts +759 -41
  62. package/src/runtime/env.ts +8 -3
  63. package/src/runtime/evals.ts +589 -43
  64. package/src/runtime/improve.ts +868 -0
  65. package/src/runtime/inspect.ts +194 -4
  66. package/src/runtime/integrations/composio.ts +423 -0
  67. package/src/runtime/knowledge/chunk.ts +333 -0
  68. package/src/runtime/knowledge/config.ts +135 -0
  69. package/src/runtime/knowledge/embeddings.ts +133 -0
  70. package/src/runtime/knowledge/ingest.ts +521 -0
  71. package/src/runtime/knowledge/prompt-policy.ts +30 -0
  72. package/src/runtime/knowledge/retrieve.ts +303 -0
  73. package/src/runtime/knowledge/schema.ts +100 -0
  74. package/src/runtime/knowledge/tool.ts +64 -0
  75. package/src/runtime/knowledge/vector.ts +258 -0
  76. package/src/runtime/prompt-context.ts +141 -0
  77. package/src/runtime/runtime-contract.ts +86 -8
  78. package/src/runtime/skills.ts +95 -0
  79. package/src/runtime/spec.ts +152 -0
  80. package/src/runtime/sync.ts +144 -0
  81. package/src/runtime/targets/cloudflare/build.ts +1430 -185
  82. package/src/runtime/targets/container/server.ts +1 -1
  83. package/src/runtime/targets/vps/deploy.ts +26 -9
  84. package/src/runtime/tool-runner.ts +9 -1
  85. package/src/runtime/tools.ts +128 -2
  86. package/src/runtime/traces.ts +41 -0
  87. package/src/runtime/transcription.ts +483 -0
  88. package/src/storage/sqlite.ts +149 -3
  89. package/src/templates/blank.ts +76 -17
  90. package/src/templates/dentista.ts +1011 -0
  91. package/src/templates/index.ts +2 -0
  92. package/src/templates/skills/agentkit-build-agent/SKILL.md +52 -0
  93. package/src/templates/skills/agentkit-build-agent/templates/appointment-intake.instructions.md +21 -0
  94. package/src/templates/skills/agentkit-build-agent/templates/sales-qualifier.instructions.md +17 -0
  95. package/src/templates/skills/agentkit-build-agent/templates/support-agent.instructions.md +16 -0
  96. package/src/templates/skills/agentkit-capsule/SKILL.md +70 -0
  97. package/src/templates/skills/agentkit-capsule/references/docs-router.md +15 -0
  98. package/src/templates/skills/agentkit-channels/SKILL.md +104 -0
  99. package/src/templates/skills/agentkit-channels/references/channel-buffering.md +65 -0
  100. package/src/templates/skills/agentkit-channels/references/channel-debugging.md +66 -0
  101. package/src/templates/skills/agentkit-channels/references/discord.md +93 -0
  102. package/src/templates/skills/agentkit-channels/references/slack.md +56 -0
  103. package/src/templates/skills/agentkit-channels/references/telegram.md +72 -0
  104. package/src/templates/skills/agentkit-channels/references/whatsapp-zapster.md +77 -0
  105. package/src/templates/skills/agentkit-database/SKILL.md +45 -0
  106. package/src/templates/skills/agentkit-database/templates/appointments.schema.sql +15 -0
  107. package/src/templates/skills/agentkit-database/templates/leads.schema.sql +17 -0
  108. package/src/templates/skills/agentkit-deploy/SKILL.md +50 -0
  109. package/src/templates/skills/agentkit-evals/SKILL.md +109 -0
  110. package/src/templates/skills/agentkit-evals/templates/multi-turn.eval.md +29 -0
  111. package/src/templates/skills/agentkit-evals/templates/no-leak.eval.md +18 -0
  112. package/src/templates/skills/agentkit-evals/templates/smoke.eval.md +18 -0
  113. package/src/templates/skills/agentkit-evals/templates/tool-call.eval.md +27 -0
  114. package/src/templates/skills/agentkit-improve/SKILL.md +86 -0
  115. package/src/templates/skills/agentkit-improve/references/replay-side-effects.md +18 -0
  116. package/src/templates/skills/agentkit-improve/references/trace-packets.md +22 -0
  117. package/src/templates/skills/agentkit-improve/templates/regression.eval.md +18 -0
  118. package/src/templates/skills/agentkit-integrations/SKILL.md +76 -0
  119. package/src/templates/skills/agentkit-knowledge/SKILL.md +43 -0
  120. package/src/templates/skills/agentkit-knowledge/templates/faq.md +14 -0
  121. package/src/templates/skills/agentkit-knowledge/templates/policies.md +14 -0
  122. package/src/templates/skills/agentkit-knowledge/templates/prices.csv +3 -0
  123. package/src/templates/skills/agentkit-prompts/SKILL.md +47 -0
  124. package/src/templates/skills/agentkit-prompts/templates/knowledge-grounded-faq.instructions.md +11 -0
  125. package/src/templates/skills/agentkit-provider/SKILL.md +60 -0
  126. package/src/templates/skills/agentkit-security/SKILL.md +56 -0
  127. package/src/templates/skills/agentkit-tools/SKILL.md +37 -0
  128. package/src/templates/skills/agentkit-tools/examples/database-write.tool.md +35 -0
  129. package/src/templates/skills/agentkit-tools/examples/eval-safe-external-action.tool.md +37 -0
  130. package/src/templates/skills/agentkit-tools/examples/lookup-order.tool.md +46 -0
  131. package/src/templates/skills/agentkit-troubleshooting/SKILL.md +76 -0
  132. package/src/templates/support.ts +77 -18
  133. package/docs/guides/channels-production-handoff.md +0 -99
  134. package/docs/portable-deploy-release-checklist.md +0 -41
  135. package/src/runtime/targets/cloudflare/deploy.ts +0 -5475
@@ -6,6 +6,7 @@ import type { DatabaseArgs, DatabaseResult, DatabaseRow, DatabaseStatement } fro
6
6
  import type { AgentMessageRole, ProviderRunResult } from "../providers";
7
7
  import type { LoadedAgentCapsule } from "../runtime/config";
8
8
  import { AgentKitError } from "../runtime/errors";
9
+ import { applyKnowledgeSchema, KNOWLEDGE_MIGRATION_ID, KNOWLEDGE_SCHEMA_SQL } from "../runtime/knowledge/schema";
9
10
 
10
11
  export type ConversationSummary = {
11
12
  id: string;
@@ -41,12 +42,30 @@ export type StoredToolCall = {
41
42
  visibility: ToolCallVisibility;
42
43
  input: unknown;
43
44
  output: unknown;
45
+ rendered: unknown;
44
46
  status: ToolCallStatus;
45
47
  startedAt: string;
46
48
  completedAt: string | null;
47
49
  errorMessage: string | null;
48
50
  };
49
51
 
52
+ export type StoredRun = {
53
+ id: string;
54
+ conversationId: string | null;
55
+ provider: string;
56
+ model: string;
57
+ status: RunStatus;
58
+ usage: {
59
+ inputTokens: number | null;
60
+ outputTokens: number | null;
61
+ totalTokens: number | null;
62
+ };
63
+ startedAt: string;
64
+ completedAt: string | null;
65
+ errorCode: string | null;
66
+ errorMessage: string | null;
67
+ };
68
+
50
69
  export type PersistedChatRun = {
51
70
  conversationId: string;
52
71
  runId: string;
@@ -153,6 +172,17 @@ const MIGRATIONS = [
153
172
  ADD COLUMN visibility TEXT NOT NULL DEFAULT 'user';
154
173
  `,
155
174
  },
175
+ {
176
+ id: KNOWLEDGE_MIGRATION_ID,
177
+ sql: KNOWLEDGE_SCHEMA_SQL,
178
+ },
179
+ {
180
+ id: "0007_add_tool_call_rendered",
181
+ sql: `
182
+ ALTER TABLE tool_calls
183
+ ADD COLUMN rendered_json TEXT;
184
+ `,
185
+ },
156
186
  ] as const;
157
187
 
158
188
  export async function openCapsuleStore(capsule: LoadedAgentCapsule): Promise<SqliteAgentKitStore> {
@@ -218,10 +248,10 @@ export class SqliteAgentKitStore {
218
248
  this.db.close();
219
249
  }
220
250
 
221
- createConversation(input: { agentName: string; title: string | null; now?: string }): ConversationSummary {
251
+ createConversation(input: { id?: string; agentName: string; title: string | null; now?: string }): ConversationSummary {
222
252
  return this.sqlite(() => {
223
253
  const now = input.now ?? new Date().toISOString();
224
- const id = randomId();
254
+ const id = input.id ?? randomId();
225
255
 
226
256
  this.db
227
257
  .prepare(
@@ -457,6 +487,7 @@ export class SqliteAgentKitStore {
457
487
  toolCallId: string;
458
488
  status: ToolCallStatus;
459
489
  output?: unknown;
490
+ rendered?: unknown;
460
491
  completedAt?: string;
461
492
  errorMessage?: string;
462
493
  secretValues?: string[];
@@ -469,6 +500,7 @@ export class SqliteAgentKitStore {
469
500
  SET
470
501
  status = $status,
471
502
  output_json = $outputJson,
503
+ rendered_json = $renderedJson,
472
504
  completed_at = $completedAt,
473
505
  error_message = $errorMessage
474
506
  WHERE id = $toolCallId
@@ -478,6 +510,7 @@ export class SqliteAgentKitStore {
478
510
  $toolCallId: input.toolCallId,
479
511
  $status: input.status,
480
512
  $outputJson: input.output === undefined ? null : serializeJson(input.output, input.secretValues),
513
+ $renderedJson: input.rendered === undefined ? null : serializeJson(input.rendered, input.secretValues),
481
514
  $completedAt: input.completedAt ?? new Date().toISOString(),
482
515
  $errorMessage: redactSecrets(input.errorMessage ?? null, input.secretValues),
483
516
  });
@@ -550,6 +583,35 @@ export class SqliteAgentKitStore {
550
583
  });
551
584
  }
552
585
 
586
+ listRunsForConversation(conversationId: string): StoredRun[] {
587
+ return this.sqlite(() => {
588
+ const rows = this.db
589
+ .prepare(
590
+ `
591
+ SELECT
592
+ id,
593
+ conversation_id,
594
+ provider,
595
+ model,
596
+ status,
597
+ input_tokens,
598
+ output_tokens,
599
+ total_tokens,
600
+ started_at,
601
+ completed_at,
602
+ error_code,
603
+ error_message
604
+ FROM runs
605
+ WHERE conversation_id = $conversationId
606
+ ORDER BY started_at ASC
607
+ `,
608
+ )
609
+ .all({ $conversationId: conversationId }) as SqliteRow[];
610
+
611
+ return rows.map(storedRunFromRow);
612
+ });
613
+ }
614
+
553
615
  listToolCallsForRun(runId: string): StoredToolCall[] {
554
616
  return this.sqlite(() => {
555
617
  const rows = this.db
@@ -563,6 +625,7 @@ export class SqliteAgentKitStore {
563
625
  visibility,
564
626
  input_json,
565
627
  output_json,
628
+ rendered_json,
566
629
  status,
567
630
  started_at,
568
631
  completed_at,
@@ -578,6 +641,54 @@ export class SqliteAgentKitStore {
578
641
  });
579
642
  }
580
643
 
644
+ applyApplicationMigrations(migrations: Array<{ id: string; sql: string }>): { applied: string[]; skipped: string[] } {
645
+ return this.sqlite(() => {
646
+ if (migrations.length === 0) {
647
+ return { applied: [], skipped: [] };
648
+ }
649
+
650
+ this.db.exec(`
651
+ CREATE TABLE IF NOT EXISTS agentkit_app_migrations (
652
+ id TEXT PRIMARY KEY,
653
+ applied_at TEXT NOT NULL
654
+ )
655
+ `);
656
+
657
+ const applied = new Set(
658
+ (
659
+ this.db.prepare("SELECT id FROM agentkit_app_migrations").all() as Array<{
660
+ id: string;
661
+ }>
662
+ ).map((row) => row.id),
663
+ );
664
+ const result = {
665
+ applied: [] as string[],
666
+ skipped: [] as string[],
667
+ };
668
+
669
+ for (const migration of migrations) {
670
+ if (applied.has(migration.id)) {
671
+ result.skipped.push(migration.id);
672
+ continue;
673
+ }
674
+
675
+ const statements = splitSqlStatements(migration.sql);
676
+ this.transaction(() => {
677
+ for (const statement of statements) {
678
+ this.db.exec(statement);
679
+ }
680
+
681
+ this.db
682
+ .prepare("INSERT INTO agentkit_app_migrations (id, applied_at) VALUES ($id, $appliedAt)")
683
+ .run({ $id: migration.id, $appliedAt: new Date().toISOString() });
684
+ });
685
+ result.applied.push(migration.id);
686
+ }
687
+
688
+ return result;
689
+ });
690
+ }
691
+
581
692
  applyApplicationSchema(source: string): void {
582
693
  this.sqlite(() => {
583
694
  const statements = splitSqlStatements(source);
@@ -695,7 +806,12 @@ export class SqliteAgentKitStore {
695
806
  continue;
696
807
  }
697
808
 
698
- this.db.exec(migration.sql);
809
+ if (migration.id === KNOWLEDGE_MIGRATION_ID) {
810
+ applyKnowledgeSchema(this.db);
811
+ } else {
812
+ this.db.exec(migration.sql);
813
+ }
814
+
699
815
  this.db
700
816
  .prepare("INSERT INTO agentkit_migrations (id, applied_at) VALUES ($id, $appliedAt)")
701
817
  .run({ $id: migration.id, $appliedAt: new Date().toISOString() });
@@ -785,6 +901,31 @@ function storedMessageFromRow(row: SqliteRow): StoredMessage {
785
901
  };
786
902
  }
787
903
 
904
+ function storedRunFromRow(row: SqliteRow): StoredRun {
905
+ const status = String(row.status);
906
+
907
+ if (status !== "running" && status !== "completed" && status !== "failed") {
908
+ throw new AgentKitError("storage_error", `Invalid stored run status "${status}".`);
909
+ }
910
+
911
+ return {
912
+ id: String(row.id),
913
+ conversationId: row.conversation_id === null ? null : String(row.conversation_id),
914
+ provider: String(row.provider),
915
+ model: String(row.model),
916
+ status,
917
+ usage: {
918
+ inputTokens: nullableNumber(row.input_tokens),
919
+ outputTokens: nullableNumber(row.output_tokens),
920
+ totalTokens: nullableNumber(row.total_tokens),
921
+ },
922
+ startedAt: String(row.started_at),
923
+ completedAt: row.completed_at === null ? null : String(row.completed_at),
924
+ errorCode: row.error_code === null ? null : String(row.error_code),
925
+ errorMessage: row.error_message === null ? null : String(row.error_message),
926
+ };
927
+ }
928
+
788
929
  function storedToolCallFromRow(row: SqliteRow): StoredToolCall {
789
930
  const status = String(row.status);
790
931
  const visibility = String(row.visibility);
@@ -805,6 +946,7 @@ function storedToolCallFromRow(row: SqliteRow): StoredToolCall {
805
946
  visibility,
806
947
  input: parseStoredJson(row.input_json),
807
948
  output: row.output_json === null ? undefined : parseStoredJson(row.output_json),
949
+ rendered: row.rendered_json === null ? undefined : parseStoredJson(row.rendered_json),
808
950
  status,
809
951
  startedAt: String(row.started_at),
810
952
  completedAt: row.completed_at === null ? null : String(row.completed_at),
@@ -812,6 +954,10 @@ function storedToolCallFromRow(row: SqliteRow): StoredToolCall {
812
954
  };
813
955
  }
814
956
 
957
+ function nullableNumber(value: unknown): number | null {
958
+ return value === null || value === undefined ? null : Number(value);
959
+ }
960
+
815
961
  function parseStoredJson(value: unknown): unknown {
816
962
  if (typeof value !== "string") {
817
963
  return value;
@@ -65,6 +65,7 @@ node_modules/
65
65
  contents: `# Optional: only needed after switching agentkit.config.ts to a Pi-backed real provider.
66
66
  OPENAI_API_KEY=
67
67
  ANTHROPIC_API_KEY=
68
+ OPENROUTER_API_KEY=
68
69
  `,
69
70
  },
70
71
  {
@@ -123,13 +124,18 @@ Answer clearly, ask for missing context when needed, and do not claim to have pe
123
124
  },
124
125
  {
125
126
  path: "evals/smoke.eval.ts",
126
- contents: `export default {
127
+ contents: `import { defineEval } from "@andreprado/agentkit";
128
+
129
+ export default defineEval({
127
130
  name: "smoke",
128
131
  input: "Say hello in one short sentence.",
129
132
  expect: {
130
- contains: "hello",
133
+ response: {
134
+ caseInsensitiveContains: "hello",
135
+ maxLength: 160,
136
+ },
131
137
  },
132
- };
138
+ });
133
139
  `,
134
140
  },
135
141
  {
@@ -146,29 +152,43 @@ When the owner opens this folder in Codex, Claude Code, or another coding agent
146
152
 
147
153
  Start building immediately:
148
154
 
149
- - Read \`AGENTKIT.md\` and the full docs path from \`npm run agentkit -- docs full\`.
155
+ - Start with \`skills/agentkit-capsule/SKILL.md\`, then use \`npm run agentkit -- docs llms\` as the docs router.
156
+ - Create or update \`AGENT_SPEC.md\` from the owner's request with \`npm run agentkit -- spec init --brief "<owner request>"\`; the owner should not fill this file by hand before work starts.
150
157
  - Infer the first useful version from the owner's request.
151
158
  - Edit \`prompts/instructions.md\` for the agent behavior.
152
159
  - Edit \`agentkit.config.ts\` for provider, tools, secrets, access, and storage.
153
160
  - Add TypeScript tools under \`tools/\` when the requested agent needs actions or external data.
161
+ - Add \`sync.ts\`, \`seed.sql\`, and ordered \`migrations/*.sql\` when the requested agent depends on external catalogs or production-shaped data changes.
162
+ - Do not wait for a wizard or recipe. AgentKit provides the scaffold and contract; you decide the implementation from the owner's brief.
154
163
  - Ask follow-up questions only when missing information blocks a safe local implementation.
155
164
  - State assumptions in the final response.
156
165
 
157
166
  ## Local Commands
158
167
 
159
- - \`npm install\`: install capsule dependencies.
168
+ - \`npm install\`: restore capsule dependencies if this capsule used \`--no-install\`, install failed, or \`node_modules\` was deleted.
160
169
  - \`npm run dev\`: run the local Agent Capsule runtime.
161
170
  - \`npm run chat -- --message "hello"\`: send one local chat message.
162
171
  - \`npm run eval\`: run agent evals.
172
+ - \`npm run agentkit -- spec check\`: verify the local agent implementation contract exists.
173
+ - \`npm run agentkit -- eval from-conversation <conversation-id>\`: turn a real conversation into a regression eval.
174
+ - \`npm run agentkit -- conversations trace <conversation-id>\`: inspect messages, runs, tool calls, inputs, outputs, rendered output, and final responses.
163
175
  - \`npm run agentkit -- tool <name> --input fixtures/input.json\`: run one registered tool directly.
164
176
  - \`npm run agentkit -- db migrate\`: apply internal migrations and \`schema.sql\` locally.
165
177
  - \`npm run agentkit -- db reset --yes\`: recreate the local SQLite database and reapply schema.
166
178
  - \`npm run agentkit -- db seed --file seed.sql\`: apply local fixture data after migrate.
167
179
  - \`npm run agentkit -- db shell\`: inspect local development data when needed.
168
180
  - \`npm run agentkit -- inspect\`: print machine-readable capsule state.
169
- - \`npm run agentkit -- env set <NAME> <VALUE>\`: write a local secret value to ignored \`.env\`.
181
+ - \`printf %s "$VALUE" | npm run agentkit -- env set <NAME> --stdin\`: write a local secret value to ignored \`.env\` without putting it in shell history.
170
182
  - \`npm run agentkit -- env list\`: list local secret names without printing values.
171
- - \`npm run agentkit -- docs full\`: print the full AgentKit contract path.
183
+ - \`npm run agentkit -- docs llms\`: print the lightweight AgentKit docs router.
184
+ - \`npm run agentkit -- docs full\`: print the full AgentKit contract path only when a skill asks for it.
185
+
186
+ ## Testing With A UI
187
+
188
+ - Local UI: run \`npm run dev\`, open the printed \`Chat:\` URL, and tell the owner the exact URL.
189
+ - Hosted UI: after \`npm run agentkit -- deploy\`, run \`npm run agentkit -- chat-ui --deploy\`, open the printed \`Chat:\` URL, and tell the owner it is connected to the hosted deploy.
190
+ - \`test/fake\` is deterministic. It is useful for scaffold checks, direct tool checks, and fake-provider evals, but it does not validate natural conversation quality.
191
+ - Before claiming real conversation behavior is tested, ask the owner which provider to use: OpenRouter, OpenAI, Anthropic, or another supported provider. Do not choose for them.
172
192
 
173
193
  This blank capsule starts with the built-in \`test/fake\` provider, so local chat works without secrets or internet access. It is also deploy-ready by default: the user can edit the prompt, add tools, and run \`npm run agentkit -- deploy\`.
174
194
 
@@ -202,7 +222,7 @@ export const myTool = defineTool({
202
222
 
203
223
  Use \`ctx.db\` as the canonical helper. \`ctx.database\` and \`ctx.storage.sql\` are aliases. Use \`ctx.db.batch([...])\` for atomic writes; local tools can also use \`ctx.db.transaction(async (tx) => ...)\`. Do not import local database drivers or Node-only APIs in tools. AgentKit owns local and hosted database routing.
204
224
 
205
- \`schema.sql\` is an idempotent bootstrap file in v1. Use \`CREATE TABLE IF NOT EXISTS\`, \`CREATE INDEX IF NOT EXISTS\`, and safe additive changes. AgentKit does not run destructive schema changes or ordered \`migrations/*.sql\` automatically yet.
225
+ \`schema.sql\` is an idempotent bootstrap file. Use \`CREATE TABLE IF NOT EXISTS\`, \`CREATE INDEX IF NOT EXISTS\`, and safe additive changes. Use ordered \`migrations/*.sql\` for production-shaped schema evolution; \`npm run agentkit -- db migrate\` applies unapplied local migrations before \`schema.sql\`.
206
226
 
207
227
  ## Hosted Deploy
208
228
 
@@ -210,14 +230,16 @@ Use \`ctx.db\` as the canonical helper. \`ctx.database\` and \`ctx.storage.sql\`
210
230
  - AgentKit owns the hosted runtime, managed database, file storage, and production secret injection.
211
231
  - Local scaffold, dev, chat, eval, inspect, database, and build commands are token-free.
212
232
  - Hosted deploy requires an invited AgentKit Cloud alpha token. If no token is stored yet, ask the owner for one and run \`npm run agentkit -- login --token <token>\`.
213
- - Put production secret values into managed secrets with \`npm run agentkit -- secret set <NAME> <VALUE>\`, not into committed files.
233
+ - Put production secret values into managed secrets with \`npm run agentkit -- secret set <NAME> --from-local-env\`, \`--from-env\`, or \`--stdin\`, not into committed files or shell history.
214
234
  - The user should not choose a deploy target, create hosted databases, create buckets, copy production secrets into this capsule, or run operator/admin commands.
215
- - After a hosted deploy, create client-facing deploy access tokens with \`npm run agentkit -- access token create <name>\`.
235
+ - Hosted deploy writes the local chat/UI deploy access token to \`.agentkit/chat-access-token.json\`. Create extra client-facing tokens with \`npm run agentkit -- access token create <name> --out <path>\`.
236
+ - Use \`npm run agentkit -- deploy --smoke "hello"\` or \`npm run agentkit -- deploy smoke --message "hello"\` for an official hosted chat smoke check.
216
237
 
217
238
  ## Rules
218
239
 
219
240
  - Keep required local secret names in \`.env.schema\` and values in ignored \`.env\`. AgentKit local commands load \`.env\` directly.
220
241
  - Real providers are resolved by AgentKit through the internal Pi SDK backend; keep project code on \`@andreprado/agentkit\`.
242
+ - The owner must choose the real provider before you switch from \`test/fake\`. Update \`agentkit.config.ts\`, \`.env.schema\`, and local/hosted secrets after that choice.
221
243
  - Do not commit \`.env\` or \`.agentkit/\`.
222
244
  - Edit the agent contract in \`agentkit.config.ts\`.
223
245
  - Edit instructions in \`prompts/instructions.md\`.
@@ -240,41 +262,70 @@ Example owner request:
240
262
  Turn the request into a working local capsule:
241
263
 
242
264
  - Update \`prompts/instructions.md\` with domain-specific behavior, boundaries, intake questions, and escalation rules.
265
+ - Create or update \`AGENT_SPEC.md\` with \`npm run agentkit -- spec init --brief "<owner request>"\`. The owner gives the general idea; the coding agent turns it into the structured contract.
243
266
  - Update \`agentkit.config.ts\` when tools, secrets, provider, or access rules change.
244
267
  - Add TypeScript tools under \`tools/\` for real actions or external data.
268
+ - Use \`npm run agentkit -- sync init\` when the agent needs catalog sync, fixture seed data, or ordered migrations.
245
269
  - Keep the first version runnable with \`test/fake\` unless the owner explicitly asks for a real provider.
270
+ - Do not use a wizard or recipe. Build the capsule directly from the scaffold, the AgentKit contract, and the owner's brief.
246
271
  - Make practical assumptions and list them in your final response.
247
272
  - Ask follow-up questions only when missing information blocks a safe local implementation.
248
273
 
249
274
  ## Local Commands
250
275
 
251
276
  \`\`\`sh
252
- npm install
253
277
  npm run typecheck
254
278
  npm run agentkit -- inspect
255
279
  npm run chat -- --message "hello"
256
280
  \`\`\`
257
281
 
282
+ \`test/fake\` proves the scaffold and deterministic tool paths. It does not prove natural conversation quality.
283
+
284
+ \`agentkit new\` installs dependencies by default. Run \`npm install\` only if the capsule was created with \`--no-install\`, install failed, or \`node_modules\` was deleted.
285
+
258
286
  Set local development secrets without opening code:
259
287
 
260
288
  \`\`\`sh
261
- npm run agentkit -- env set OPENAI_API_KEY "<value>"
289
+ printf %s "$OPENAI_API_KEY" | npm run agentkit -- env set OPENAI_API_KEY --stdin
262
290
  npm run agentkit -- inspect
263
291
  npm run chat -- --message "hello"
264
292
  \`\`\`
265
293
 
294
+ ## Testing With A UI
295
+
296
+ Local UI:
297
+
298
+ \`\`\`sh
299
+ npm run dev
300
+ \`\`\`
301
+
302
+ Open the printed \`Chat:\` URL and tell the owner the exact URL.
303
+
304
+ Hosted deploy UI:
305
+
306
+ \`\`\`sh
307
+ npm run agentkit -- deploy
308
+ npm run agentkit -- chat-ui --deploy
309
+ \`\`\`
310
+
311
+ Open the printed \`Chat:\` URL and tell the owner this local UI is connected to the hosted deploy.
312
+
313
+ Before claiming real conversation behavior has been tested, ask the owner which provider to use: OpenRouter, OpenAI, Anthropic, or another supported provider. Do not choose for them. After they choose, update \`agentkit.config.ts\`, \`.env.schema\`, local secrets, hosted secrets if deploying, then rerun chat/UI checks.
314
+
266
315
  If you add a tool, also run a fake-provider tool smoke test:
267
316
 
268
317
  \`\`\`sh
269
318
  npm run agentkit -- tool tool_name --input '{}'
270
319
  \`\`\`
271
320
 
272
- For the full framework contract, read the path printed by:
321
+ For the lightweight docs router, read the path printed by:
273
322
 
274
323
  \`\`\`sh
275
- npm run agentkit -- docs full
324
+ npm run agentkit -- docs llms
276
325
  \`\`\`
277
326
 
327
+ Read the full framework contract with \`npm run agentkit -- docs full\` only when a skill asks for it.
328
+
278
329
  ## Hosted Deploy
279
330
 
280
331
  This capsule is hosted-deploy ready by default.
@@ -283,9 +334,10 @@ This capsule is hosted-deploy ready by default.
283
334
  2. Put agent-owned tables in \`schema.sql\`. AgentKit applies it locally and migrates/provisions hosted storage during deploy.
284
335
  3. Run \`npm run agentkit -- build\` only when you want to validate the artifact locally.
285
336
  4. If the owner has not logged in yet, ask for an invited AgentKit Cloud alpha token and run \`npm run agentkit -- login --token <token>\`.
286
- 5. Put production secrets into managed secrets with \`npm run agentkit -- secret set <NAME> <VALUE>\`.
337
+ 5. Put production secrets into managed secrets with \`npm run agentkit -- secret set <NAME> --from-local-env\`, \`--from-env\`, or \`--stdin\`.
287
338
  6. Run \`npm run agentkit -- deploy\`.
288
- 7. Create client-facing deploy access tokens with \`npm run agentkit -- access token create <name>\` when a website or app needs to call the hosted agent.
339
+ 7. Run \`npm run agentkit -- chat-ui --deploy\` to test the hosted agent through a local UI using the auto-created \`.agentkit/chat-access-token.json\`. Create extra client-facing deploy access tokens with \`npm run agentkit -- access token create <name> --out <path>\` when a separate website or app needs its own credential.
340
+ 8. Use \`npm run agentkit -- deploy --smoke "hello"\` during deploy or \`npm run agentkit -- deploy smoke --message "hello"\` afterward for an official hosted smoke check.
289
341
 
290
342
  AgentKit owns hosted infrastructure and production secrets. Do not put production secret values in this capsule. Do not run operator/admin commands from a user capsule.
291
343
  `,
@@ -302,9 +354,11 @@ Use AgentKit conventions when editing this project.
302
354
  - Local runtime state lives in \`.agentkit/\` and should not be committed.
303
355
  - The default provider is \`test/fake\`, which needs no secrets.
304
356
  - Real providers run through AgentKit's internal Pi SDK backend.
357
+ - Ask the owner which real provider to use before switching from \`test/fake\`; do not choose OpenRouter, OpenAI, or Anthropic automatically.
305
358
  - Production secrets must be managed secrets, not committed files.
306
359
  - Keep required local secret names in \`.env.schema\` and values in ignored \`.env\`. AgentKit local commands load \`.env\` directly.
307
360
  - Treat the owner's natural-language request as the brief and start implementing inside this capsule.
361
+ - Start with \`skills/agentkit-capsule/SKILL.md\` when the task is not obvious.
308
362
  `,
309
363
  },
310
364
  {
@@ -316,16 +370,21 @@ Generated by AgentKit as an Agent Capsule.
316
370
  ## Setup
317
371
 
318
372
  \`\`\`sh
319
- npm install
320
373
  npm run chat -- --message "hello"
321
374
  npm run dev
322
375
  \`\`\`
323
376
 
377
+ \`agentkit new\` installs dependencies by default. Run \`npm install\` only if this capsule was created with \`--no-install\`, install failed, or \`node_modules\` was deleted.
378
+
324
379
  \`agentkit.config.ts\` uses the built-in \`test/fake\` provider by default, so the first chat works without editing \`.env\`.
325
380
  When a real provider or tool needs a local development secret, keep the required name in \`.env.schema\`, keep the value in ignored \`.env\`, and run AgentKit commands normally; the local runtime loads \`.env\` directly.
326
381
 
327
382
  \`npm run dev\` runs the whole capsule locally. It should expose local chat, API, inspect, and storage endpoints.
328
383
 
384
+ For UI testing, run \`npm run dev\` and open the printed \`Chat:\` URL. After hosted deploy, run \`npm run agentkit -- chat-ui --deploy\` and open its printed \`Chat:\` URL.
385
+
386
+ \`test/fake\` does not validate real conversation quality. The owner must choose OpenRouter, OpenAI, Anthropic, or another supported provider before real model behavior is tested.
387
+
329
388
  ## Files
330
389
 
331
390
  - \`agentkit.config.ts\`: agent contract.