@andreprado/agentkit 0.1.0-alpha.3 → 0.1.0-alpha.5

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.
package/README.md CHANGED
@@ -11,6 +11,12 @@ npm run dev
11
11
  npm run chat -- --message "hello"
12
12
  ```
13
13
 
14
+ For a Portuguese dental-office starter, use:
15
+
16
+ ```sh
17
+ npx @andreprado/agentkit@alpha new clara-dentista --template dentista
18
+ ```
19
+
14
20
  `agentkit new` installs the generated capsule dependencies by default so `agentkit.config.ts` resolves `@andreprado/agentkit` immediately in editors. Use `--no-install` only for offline or scripted scaffolds where you want to run `npm install` later.
15
21
 
16
22
  Generated capsules use the built-in `test/fake` provider by default, so the first local run works without provider keys.
@@ -18,9 +24,9 @@ Generated capsules use the built-in `test/fake` provider by default, so the firs
18
24
  ## What To Know First
19
25
 
20
26
  ```sh
21
- agentkit new <name> [--template blank|support] [--no-install]
27
+ agentkit new <name> [--template blank|support|dentista] [--no-install]
22
28
  agentkit dev
23
- agentkit chat --message <text>
29
+ agentkit chat --message <text> [--conversation-id <id>]
24
30
  agentkit inspect
25
31
  ```
26
32
 
@@ -51,4 +57,4 @@ The npm package contains the public CLI/runtime/client surface only. AgentKit Cl
51
57
 
52
58
  ## Full Reference
53
59
 
54
- `agentkit --help` keeps the first surface focused. Run `agentkit help commands` for the full CLI reference and `agentkit docs full` for the full agent-facing operating contract.
60
+ `agentkit --help` keeps the first surface focused. Run `agentkit help commands` for the full CLI reference and `agentkit docs full` to print the path to the full agent-facing operating contract.
@@ -329,7 +329,7 @@ Compare the JSON message input to `inputSchema`.
329
329
  Add the secret name to `.env.schema`, write the local value to ignored `.env`, and inspect again:
330
330
 
331
331
  ```sh
332
- npm run agentkit -- env set CRM_API_KEY "<value>"
332
+ printf %s "$CRM_API_KEY" | npm run agentkit -- env set CRM_API_KEY --stdin
333
333
  npm run agentkit -- inspect
334
334
  ```
335
335
 
@@ -0,0 +1,243 @@
1
+ # Channels Implementation Map
2
+
3
+ Source of truth: [`../../CHANNELS_PRD.md`](../../CHANNELS_PRD.md).
4
+
5
+ Use this map before implementing Channels. It identifies the current AgentKit files that should absorb the Channels contract and the blocker order from `TASKS.md`.
6
+
7
+ ## Current State
8
+
9
+ AgentKit already has the hosted deploy spine that Channels should extend:
10
+
11
+ - Public config and exports live in `packages/agentkit/src/index.ts`.
12
+ - Config loading and validation live in `packages/agentkit/src/runtime/config.ts`.
13
+ - `agentkit inspect` state lives in `packages/agentkit/src/runtime/inspect.ts`.
14
+ - Cloudflare artifact generation lives in `packages/agentkit/src/runtime/targets/cloudflare/build.ts`.
15
+ - The CLI command switch lives in `packages/agentkit/src/cli/index.ts`.
16
+ - Local AgentKit Cloud control-plane routes live in `packages/agentkit/src/runtime/deploy.ts`.
17
+ - Local runtime conversation storage lives in `packages/agentkit/src/storage/sqlite.ts`.
18
+
19
+ Channels should not start inside provider-specific code. The obvious implementation path is contract-first, fixture-first, then hosted ingress.
20
+
21
+ ## First Files To Edit
22
+
23
+ ### Config Contract
24
+
25
+ Edit `packages/agentkit/src/index.ts` first.
26
+
27
+ Add:
28
+
29
+ - `AgentChannel`;
30
+ - `WebsiteChannelConfig`;
31
+ - `TelegramChannelConfig`;
32
+ - `WhatsappChannelConfig`;
33
+ - `ChannelType`;
34
+ - `ChannelProvider`;
35
+ - `websiteChannel(...)`;
36
+ - `telegramChannel(...)`;
37
+ - `whatsappChannel(...)`;
38
+ - optional `channels?: AgentChannel[]` on `AgentConfig`.
39
+
40
+ Reason: generated capsules import public helpers from `@andreprado/agentkit`, so the public contract must exist before config validation, templates, docs, or CLI commands can rely on it.
41
+
42
+ ### Config Validation
43
+
44
+ Edit `packages/agentkit/src/runtime/config.ts` after the public types exist.
45
+
46
+ Add validation for:
47
+
48
+ - lowercase stable channel names;
49
+ - unique names within a capsule;
50
+ - supported type/provider combinations;
51
+ - required channel secret name arrays;
52
+ - `runtime: "edge"` when channels are configured for hosted use;
53
+ - no secret values in channel config.
54
+
55
+ Tests belong in `packages/agentkit/src/runtime/config.test.ts`.
56
+
57
+ ### Inspect State
58
+
59
+ Edit `packages/agentkit/src/runtime/inspect.ts` after validation.
60
+
61
+ Add:
62
+
63
+ - channel summaries;
64
+ - channel required secrets merged into the existing `secrets` status map;
65
+ - no provider API values or webhook secret values.
66
+
67
+ Tests belong in `packages/agentkit/src/runtime/config.test.ts` or a new focused inspect test if the file grows too large.
68
+
69
+ ### Build Manifest
70
+
71
+ Edit `packages/agentkit/src/runtime/targets/cloudflare/build.ts` after inspect.
72
+
73
+ Add channels to:
74
+
75
+ - `AgentManifest`;
76
+ - `buildManifest(...)`;
77
+ - generated Worker manifest JSON;
78
+ - warning text if a channel needs hosted bindings that the current artifact cannot run yet.
79
+
80
+ The generated Worker should not perform real channel processing until ingress/queue tasks land, but the manifest must carry enough metadata for the control plane to create resources.
81
+
82
+ Tests belong in `packages/agentkit/src/runtime/build.test.ts`.
83
+
84
+ ## New Runtime Modules
85
+
86
+ Add `packages/agentkit/src/runtime/channels.ts` for normalized types and registry-level helpers.
87
+
88
+ It should own:
89
+
90
+ - `RawWebhookEvent`;
91
+ - `NormalizedChannelEvent`;
92
+ - `NormalizedChannelMessage`;
93
+ - `ChannelAdapter`;
94
+ - `ChannelSendInput`;
95
+ - `ChannelSendResult`;
96
+ - `WebhookVerificationInput`;
97
+ - `WebhookVerificationResult`;
98
+ - `ChannelStatusInput`;
99
+ - `ChannelStatusResult`;
100
+ - adapter lookup by channel type/provider;
101
+ - shared secret redaction helpers if they are not already generic.
102
+
103
+ Add adapter modules under `packages/agentkit/src/runtime/channels/`:
104
+
105
+ - `website.ts`;
106
+ - `telegram.ts`;
107
+ - `whatsapp-zapster.ts`;
108
+ - `whatsapp-meta.ts` as a compatibility stub.
109
+
110
+ Add fixtures under `packages/agentkit/src/runtime/fixtures/channels/`:
111
+
112
+ - `website-message.json`;
113
+ - `telegram-message.json`;
114
+ - `telegram-unsupported-update.json`;
115
+ - `zapster-message.json`;
116
+ - `zapster-unsupported-media.json`;
117
+ - duplicate-event variants where useful.
118
+
119
+ Default tests must use these fixtures and fake fetchers only.
120
+
121
+ ## CLI Entry Points
122
+
123
+ Edit `packages/agentkit/src/cli/index.ts` only after config/build/control-plane basics exist.
124
+
125
+ Add a `channels` command with subcommands:
126
+
127
+ - `list`;
128
+ - `add`;
129
+ - `setup`;
130
+ - `status`;
131
+ - `test`;
132
+ - `deliveries list`;
133
+ - `deliveries show`.
134
+
135
+ Keep command behavior split:
136
+
137
+ - Before deploy: read local capsule config and explain missing deploy/setup state.
138
+ - After deploy: read `.agentkit/deploy.json` and call the AgentKit Cloud API.
139
+
140
+ Do not make the CLI mutate real Telegram/Zapster settings in default tests. Provider mutations need explicit credentials and opt-in smoke gates.
141
+
142
+ ## Control Plane
143
+
144
+ Edit `packages/agentkit/src/runtime/deploy.ts` after manifest and CLI contracts are clear.
145
+
146
+ Current control-plane API only serves:
147
+
148
+ - `GET /health`;
149
+ - `POST /v1/deploys`.
150
+
151
+ Add:
152
+
153
+ - `POST /v1/deploys/{deploy_id}/channels`;
154
+ - `GET /v1/deploys/{deploy_id}/channels`;
155
+ - `GET /v1/channels/{channel_id}`;
156
+ - `DELETE /v1/channels/{channel_id}`;
157
+ - public webhook routes for `/channels/{channel_id}/{type}/{provider}/webhook`;
158
+ - delivery inspection routes for CLI use.
159
+
160
+ The local `npm run agentkit:operator -- serve` path can use an in-memory or local SQLite fake store first. Production Postgres support can follow once the contract is tested. In both stores, persist only secret names and statuses, never secret values.
161
+
162
+ ## Hosted Worker And Cloudflare Bindings
163
+
164
+ Edit `packages/agentkit/src/runtime/targets/cloudflare/build.ts` when adding real hosted ingress.
165
+
166
+ The Worker currently handles:
167
+
168
+ - `GET /_agentkit`;
169
+ - `GET /`;
170
+ - `POST /chat`;
171
+ - Turso health/query helpers;
172
+ - R2 file routes.
173
+
174
+ Channels will need:
175
+
176
+ - a channel ingress route;
177
+ - raw body preservation for verification;
178
+ - a channel coordination Durable Object for dedupe and identity mapping;
179
+ - Cloudflare Queue producer and consumer bindings;
180
+ - delivery state persistence or calls back to AgentKit Cloud;
181
+ - redaction-aware logs.
182
+
183
+ Do not put AgentKit channel plumbing in the user's Turso database. Turso remains only for the user's agent application tables.
184
+
185
+ ## Storage Boundary Decision
186
+
187
+ For local tests, use the AgentKit Cloud fake/control-plane store for channel resource metadata and delivery records.
188
+
189
+ Use this boundary for V1 local cloud tests:
190
+
191
+ | Record | Local `npm run agentkit:operator -- serve` store | Generated Worker / Durable Object / Queue contract |
192
+ | --- | --- | --- |
193
+ | Channel resource metadata | Yes: `channels` table or equivalent fake store keyed by `chn_...`. | Read-only manifest input after deploy. |
194
+ | Channel secret references | Yes: names and `set`/`missing` status only. | Runtime receives injected secret values by name; no readback. |
195
+ | Channel endpoint URL | Yes: generated from deploy URL plus stable channel ID. | Worker routes requests by channel ID, type, and provider. |
196
+ | Channel delivery records | Yes: `deliveries` table keyed by `del_...` for CLI inspection. | Worker/consumer reports state transitions back to control plane or durable storage. |
197
+ | Channel event audit records | Yes: compact event records keyed by `chevt_...`, with redacted provider metadata. | Ingress creates or reports event records after provider validation. |
198
+ | External identity mappings | Fake DO-compatible store for local tests, keyed by `chid_...`. | Durable Object owns strongly consistent identity to conversation mapping. |
199
+ | Dedupe keys | Fake DO-compatible store with default 14-day retention. | Durable Object owns deterministic dedupe keys and retention. |
200
+ | Per-conversation ordering/backpressure | Fake DO-compatible store only when tests need it. | Durable Object owns locks and short-lived backpressure state. |
201
+ | Queue payloads | In-memory fake queue drained by tests. | Cloudflare Queue owns async ingress to consumer handoff. |
202
+ | Raw payload/media blobs | Do not persist by default in local tests; use fixtures. | R2 stores large raw payloads, media, exports, and debug bundles. |
203
+ | User application data | Never. | Never. User application tables stay in Turso. |
204
+
205
+ Use Durable Object-compatible abstractions for:
206
+
207
+ - dedupe keys;
208
+ - external identity to conversation ID mappings;
209
+ - ordering/backpressure state.
210
+
211
+ This keeps the implementation aligned with the production architecture while allowing deterministic tests without real Cloudflare bindings.
212
+
213
+ The first implementation should prefer an in-memory fake store for tests unless persistence across local control-plane restarts is being tested. Production Postgres can mirror the same resource/delivery tables later, after API behavior is stable.
214
+
215
+ ## Implementation Order
216
+
217
+ Start with the unblocked tasks from `TASKS.md`:
218
+
219
+ 1. CH-01: decide the final local fake store shape.
220
+ 2. CH-02: add public channel config helpers.
221
+ 3. CH-03: validate `channels` config.
222
+ 4. CH-04: include channels in inspect/build manifests.
223
+ 5. CH-05 and CH-06: add normalized runtime types and fixture-first adapter tests.
224
+
225
+ Do not begin channel CRUD or ingress until CH-04 exists. The control plane needs channel metadata in the build manifest, otherwise hosted resources are disconnected from the deploy artifact.
226
+
227
+ ## Test Strategy
228
+
229
+ Default verification should stay offline:
230
+
231
+ ```sh
232
+ bun test
233
+ npm run typecheck
234
+ ```
235
+
236
+ Provider tests should be opt-in:
237
+
238
+ ```sh
239
+ AGENTKIT_RUN_TELEGRAM_CHANNEL_TESTS=1 bun test
240
+ AGENTKIT_RUN_ZAPSTER_CHANNEL_TESTS=1 bun test
241
+ ```
242
+
243
+ Real-provider smoke tests must document required secret names and must never print secret values.
@@ -84,7 +84,7 @@ Primary flow:
84
84
  Develop an appointment and intake agent for an ophthalmology office.
85
85
  ```
86
86
 
87
- The generated `AGENTS.md`, `AGENTKIT.md`, and `CLAUDE.md` tell the coding agent which files to edit and which verification commands to run.
87
+ The generated `AGENTS.md`, `AGENTKIT.md`, and `CLAUDE.md` tell the coding agent which files to edit and which verification commands to run. There is no wizard or recipe layer: the coding agent edits the capsule directly from the scaffold, contract, and owner request.
88
88
 
89
89
  Optional shortcut when copying a prompt into another coding agent:
90
90
 
@@ -135,6 +135,27 @@ Expected chat output:
135
135
  Echo: hello
136
136
  ```
137
137
 
138
+ ## Testing With A UI
139
+
140
+ Local UI:
141
+
142
+ ```sh
143
+ npm run dev
144
+ ```
145
+
146
+ Open the printed `Chat:` URL and tell the owner the exact URL.
147
+
148
+ Hosted deploy UI:
149
+
150
+ ```sh
151
+ npm run agentkit -- deploy
152
+ npm run agentkit -- chat-ui --deploy
153
+ ```
154
+
155
+ Open the printed `Chat:` URL and tell the owner this local UI is connected to the hosted deploy.
156
+
157
+ `test/fake` is deterministic. It validates the scaffold, direct tool checks, and fake-provider evals, but it does not validate natural conversation quality. Before claiming real conversation behavior is tested, ask the owner which provider to use: OpenRouter, OpenAI, Anthropic, or another supported provider.
158
+
138
159
  ## Safety Rules
139
160
 
140
161
  - Do not commit `.env`.
@@ -30,8 +30,9 @@ All scaffold, local dev, chat, eval, inspect, database, and build commands are t
30
30
  ```sh
31
31
  npm run agentkit -- login --token agk_user_...
32
32
  npm run agentkit -- deploy doctor
33
- npm run agentkit -- secret set OPENAI_API_KEY sk-...
34
- npm run agentkit -- deploy
33
+ npm run agentkit -- secret set OPENAI_API_KEY --from-local-env
34
+ npm run agentkit -- deploy --smoke "hello"
35
+ npm run agentkit -- chat-ui --deploy
35
36
  ```
36
37
 
37
38
  If the capsule uses OpenAI locally, put the user’s local key in `.env`:
@@ -125,13 +126,17 @@ For a final end-to-end test, run:
125
126
 
126
127
  ```sh
127
128
  npm run agentkit -- login --token agk_user_...
129
+ npm run agentkit -- secret sync --from-local
128
130
  npm run agentkit -- secret list
129
- npm run agentkit -- deploy
131
+ npm run agentkit -- deploy --smoke "hello"
130
132
  npm run agentkit -- deploy status
133
+ npm run agentkit -- chat-ui --deploy
131
134
  npm run agentkit -- access token list
132
135
  ```
133
136
 
134
- For private hosted deploys, `npm run agentkit -- deploy` writes the local chat/UI access token to `.agentkit/chat-access-token.json`. Use `npm run agentkit -- access token create <name> --out <path>` only for additional clients.
137
+ For private hosted deploys, `npm run agentkit -- deploy` writes the local chat/UI access token to `.agentkit/chat-access-token.json`. Use `npm run agentkit -- deploy --smoke "hello"` for the official hosted chat smoke, and use `npm run agentkit -- chat-ui --deploy` for hosted UI testing. Use `npm run agentkit -- access token create <name> --out <path>` only for additional clients.
138
+
139
+ When the UI is running, open the printed `Chat:` URL and tell the owner the exact URL. If the capsule is still on `test/fake`, say the UI was tested only with the deterministic fake provider.
135
140
 
136
141
  ## Readiness Checklist
137
142
 
@@ -170,7 +175,13 @@ Missing hosted secret:
170
175
  Set the secret in AgentKit Cloud or the configured control plane:
171
176
 
172
177
  ```sh
173
- npm run agentkit -- secret set OPENAI_API_KEY sk-...
178
+ npm run agentkit -- secret set OPENAI_API_KEY --from-local-env
179
+ ```
180
+
181
+ To sync all declared user-managed secrets present in local `.env`:
182
+
183
+ ```sh
184
+ npm run agentkit -- secret sync --from-local
174
185
  ```
175
186
 
176
187
  Do not write hosted secret values into the capsule.
@@ -181,7 +192,7 @@ Before a hosted production deploy, run:
181
192
  npm run agentkit -- deploy doctor
182
193
  ```
183
194
 
184
- The doctor checks AgentKit Cloud login, alpha deploy entitlement, declared hosted secrets, local `.env` names that have not been uploaded with `agentkit secret set`, and private-access runtime token handling. `agentkit deploy` runs the same readiness check automatically before building and uploading the artifact.
195
+ The doctor checks AgentKit Cloud login, alpha deploy entitlement, online deploy capacity, declared hosted secrets, local `.env` names that have not been uploaded with `agentkit secret set`, and private-access runtime token handling. `agentkit deploy` runs the same readiness check automatically before building and uploading the artifact.
185
196
 
186
197
  `alpha_access_required`:
187
198
 
@@ -84,12 +84,38 @@ export default {
84
84
 
85
85
  `tool_call` remains accepted as a backwards-compatible alias, but new evals should use `persisted_tool_call`.
86
86
 
87
+ Safe external-tool pattern:
88
+
89
+ ```ts
90
+ export const sendFollowupEmail = defineTool({
91
+ name: "send_followup_email",
92
+ description: "Sends a follow-up email.",
93
+ inputSchema: {
94
+ type: "object",
95
+ properties: {
96
+ email: { type: "string" },
97
+ },
98
+ required: ["email"],
99
+ additionalProperties: false,
100
+ },
101
+ async execute(input: { email: string }, ctx) {
102
+ if (ctx.runtime.environment === "eval") {
103
+ return { sent: false, evalFixture: true, email: input.email };
104
+ }
105
+
106
+ // Real provider call here.
107
+ return { sent: true, evalFixture: false, email: input.email };
108
+ },
109
+ });
110
+ ```
111
+
87
112
  ## Safety Rules
88
113
 
89
114
  - Do not put provider keys in eval files.
90
115
  - Do not put real client PII in eval files.
91
116
  - Prefer small deterministic assertions.
92
- - Mock tools for evals that would write, delete, charge money, or email people.
117
+ - Keep eval tool calls deterministic and non-destructive.
118
+ - For tools that would write, delete, charge money, send email, or call a real customer system, branch inside the registered tool on `ctx.runtime.environment === "eval"` and return safe fixture output.
93
119
  - Treat conversations as source material, not as automatically safe training data.
94
120
 
95
121
  ## Verification
@@ -111,7 +137,7 @@ Use `test/fake` for deterministic smoke tests, then add provider-specific evals
111
137
 
112
138
  Tool eval hits a real API:
113
139
 
114
- Add tool mocks before running the eval suite.
140
+ Make the registered tool return deterministic fixture output when `ctx.runtime.environment === "eval"`, then rerun the eval suite. AgentKit does not expose a separate eval-only mock registry yet.
115
141
 
116
142
  ## Backend Contracts Used
117
143
 
@@ -29,7 +29,7 @@ Hosted alpha secret commands:
29
29
 
30
30
  ```sh
31
31
  agentkit login --token agk_user_...
32
- agentkit secret set OPENAI_API_KEY
32
+ agentkit secret set OPENAI_API_KEY --from-local-env
33
33
  agentkit secret list
34
34
  agentkit secret unset OPENAI_API_KEY
35
35
  ```
@@ -6,7 +6,9 @@ Switch a capsule from the offline `test/fake` provider to a Pi-backed provider.
6
6
 
7
7
  ## When To Use This
8
8
 
9
- Use this when local fake responses are no longer enough and the agent needs model behavior from OpenAI, Anthropic, or OpenRouter.
9
+ Use this when local fake responses are no longer enough and the agent needs model behavior from OpenRouter, OpenAI, Anthropic, or another supported provider.
10
+
11
+ The coding agent should not choose a real provider automatically. Ask the owner which provider to use, then update the capsule.
10
12
 
11
13
  ## Commands
12
14
 
@@ -75,6 +77,17 @@ provider: {
75
77
  secrets: ["OPENROUTER_API_KEY"],
76
78
  ```
77
79
 
80
+ ## UI Verification
81
+
82
+ After the provider is configured and the local secret is set, test through chat and UI:
83
+
84
+ ```sh
85
+ npm run chat -- --message "hello"
86
+ npm run dev
87
+ ```
88
+
89
+ Open the printed `Chat:` URL and tell the owner the exact URL. If the provider is still `test/fake`, say the UI was tested only with the deterministic fake provider.
90
+
78
91
  ## Safety Rules
79
92
 
80
93
  - Keep `.env` local.
@@ -84,6 +97,7 @@ secrets: ["OPENROUTER_API_KEY"],
84
97
  - Do not import provider SDKs in the Agent Capsule.
85
98
  - AgentKit uses Pi SDK internally.
86
99
  - Run `agentkit inspect` to confirm secret status without printing values.
100
+ - Do not claim real conversation behavior was tested until a real provider selected by the owner is configured.
87
101
 
88
102
  ## Verification
89
103
 
@@ -123,4 +137,4 @@ Check the key value, provider account status, and model access.
123
137
 
124
138
  ## Backend Contracts Used
125
139
 
126
- Local provider keys come from ignored `.env`, loaded directly by AgentKit. Hosted production will use `agentkit secret set <NAME>` and the secret API. Secret values have no readback in hosted responses.
140
+ Local provider keys come from ignored `.env`, loaded directly by AgentKit. Hosted production uses `agentkit secret set <NAME> --from-local-env`, `--from-env`, or `--stdin` and the secret API. Secret values have no readback in hosted responses.