Klippy has five tools now: the weather, the time, saving and listing notes, and reading a link. Time to join them up, fix the one bug a full tour finds, ship it, and let bits check it. Then a last exercise on the idea under all of it: descriptions.
Verified wrangler 4.157.0agents 0.33.0ai 7.0.162zod 4.6.7remix 3.1.0
Start from b-08 on GitHub. Starting here, or behind? Get the code at that tag:
git clone https://github.com/ryanyogan/klippy cd klippy git checkout b-08
1. The bug a tour finds
Ask "Should I take an umbrella in Dublin today?" and the model may call getTime first (what's "today" there?), then getWeather in a second step. With isStepCount(2), Klippy stops right there, after two tool steps and before any answer, and the reply is "answer":"". We hit exactly this while recording. Fix it in apps/agent/src/ask.ts:
Three steps: up to two rounds of tools, then the answer. Still a hard stop. And if a question needs more than that, say so instead of sending an empty string:
text is empty when the last step was still a tool call. An honest "I ran out of steps" beats a blank reply. Course C is about loops and how many steps to allow; for now, three and a clear message.
2. Tell bits where you are
TAG in apps/agent/src/check.ts says which lesson your code is at. Move it to this checkpoint:
3. Run every test
test/check.spec.ts checks the tag too, so copy apps/agent/test/ from tag b-09 first (or change 'a-05' to 'b-09' in that file). Then:
pnpm typecheck pnpm test
Plus the driver's 24 tests in packages/data-table-d1. If any fail, compare the file with tag b-09 before you deploy.
4. The live database
Your live Worker gets its own D1 database, separate from the local copy. It's empty, so apply the migration there too. In apps/agent:
pnpm wrangler d1 migrations apply klippy-db --remoteType y when it asks. Always migrate before you deploy code that needs the table, so the first request after the deploy finds it there.
5. The tour
Before shipping, try every tool locally. Our tour (with the free fallback model, as all through this course):
We also asked the time in Sydney (getTime), what we'd noted lately (listNotes) and about https://example.com. On that last one the fallback model answered from memory without calling readLink, though it called it in the last lesson. Free models are less reliable at tool use than Claude; that's the trade.
6. Ship it
In apps/agent (your token is already set if you deployed in Your first Worker; if not, pnpm wrangler secret put KLIPPY_TOKEN first):
pnpm wrangler deployWhat we recorded, and what we didn't. As in Your first Worker, we haven't deployed the reference Klippy, so there's no recorded live deploy. Our dry run shows what goes up: the new DB binding is there.
7. Let bits check it
Paste your Worker's address. bits calls /klippy/check on it and looks for this checkpoint's tag.
A pass proves a Worker at that address answers the way this lesson asks. It doesn't prove who wrote it. Then, on your live Klippy, try a note with your token: it lands in the live database you migrated.
8. Last exercise: descriptions, one more time
Everything in this course rests on the descriptions Claude reads. Test that one last time in the sandbox: write a get_weather description, then have Claude decide tool or no tool for three messages. Only the first should need it.
Goal Write a get_weather description, then have Claude decide tool or no tool for three messages. Only the first needs the tool
What good looks likeThe coach checks the reply
- Names the toolnot checked yet
- Says what it doesnot checked yet
- Says what it can't donot checked yet
- Keeps the three messagesnot checked yet
- Ran at 1.0not checked yet
- Decides tool or no toolnot checked yet
- Message 1, weather in Lima right now: uses the toolnot checked yet
- Message 2, the capital of Peru: no tool, Claude already knows itnot checked yet
- Message 3, rain in Cusco tomorrow: no tool, because get_weather can't forecastnot checked yet
- Says what it would tell the user when the tool can't helpnice to have
Run your prompt and the replies land here.
That's Klippy with tools: five of them, guarded, tested, deployed and checked. Your code matches tag b-09 (changes from b-08). In the next course, Klippy becomes an agent: a loop, a memory, and one Klippy per person.