Vercel Logo

Find Real Openings

The dispatcher can share a quote now, but the very next thing a customer says is "great, when can you take it?" Watch what happens: with no way to see the calendar, it'll cheerfully offer you "Tuesday at 2" with the same confidence it once invented prices. Maybe Tuesday's booked solid. The agent has no idea.

We fixed pricing with a tool. We fix the calendar the same way. The pattern is going to start feeling familiar, and that's the point: in eve, "give the agent a new ability" almost always means "drop one more file in tools/." No second concept, no wiring.

This time the tool takes no input at all, which is its own small lesson.

Outcome

The dispatcher offers real open repair slots by calling a check_availability tool, instead of guessing at times.

Hands-on exercise

You've done this shape once, so this is mostly muscle memory now. Create agent/tools/check_availability.ts with the same three pieces: a description, an inputSchema, and an execute.

The new wrinkle is the input. Looking up open slots doesn't need any arguments, the shop's calendar is the shop's calendar. But inputSchema is still required. For a tool that takes nothing, you pass an empty object schema:

inputSchema: z.object({}),

That's not a placeholder you're tolerating; it's the contract. It tells the model "this tool takes no arguments," which is exactly what you want it to know. A tool with no schema at all wouldn't compile.

The calendar lives in agent/lib/shop.ts next to the catalog. Import listOpenSlots and return each open slot as a small object the model can read back to the customer, an id it can quote to a booking tool later, and a human when label like "Tue 10:00am".

Return ids, not just labels

Give the model both the slot's id and its human label. The label is what it says to the customer ("Tuesday at 10"); the id is what it'll hand to book_repair in Section 3. Returning both now saves a round-trip later.

Try It

Restart and walk the customer from price to booking:

npx eve dev
you › a basic tune-up sounds good, when can you fit me in?

  ⚙ check_availability  {}
  ↳ [{ slotId: "tue-10", when: "Tue 10:00am" }, { slotId: "wed-09", when: "Wed 9:00am" },
     { slotId: "thu-11", when: "Thu 11:00am" }]

dispatcher › I've got Tuesday at 10, Wednesday at 9, or Thursday at 11 open for a
basic tune-up. Any of those work for you?

Real openings, straight from the shop's calendar. And notice the dispatcher didn't offer the Wednesday 4pm slot, that one's already booked, so listOpenSlots() never returned it and the model never saw it.

The agent only knows what the tool returns

This is the quiet superpower of tools. The model can't offer a booked slot because the data never reached it. You don't have to instruct it to "avoid taken slots", you just don't return them. The tool's return value is the agent's whole reality for that question.

No check_availability in the loop? Run eve info and confirm the tool shows up. If the agent answers without calling it, your description is probably too vague, say plainly that it lists currently open booking slots, so the model knows that's the question it answers.

Done-When

  • agent/tools/check_availability.ts default-exports defineTool with an empty z.object({}) schema.
  • eve info lists check_availability.
  • Asking about scheduling triggers a check_availability call.
  • The offered times match the open slots in agent/lib/shop.ts, and exclude booked ones.

Solution

agent/tools/check_availability.ts
import { defineTool } from "eve/tools";
import { z } from "zod";
import { listOpenSlots } from "../lib/shop.js";
 
export default defineTool({
  description: "List the repair slots that are currently open for booking.",
  inputSchema: z.object({}),
  async execute() {
    return listOpenSlots().map((s) => ({ slotId: s.id, when: s.label }));
  },
});

Two tools in, the rhythm is clear: each new ability is a file, and the file's name is the ability. Next, we give the dispatcher something tools alone don't provide, a memory that lasts longer than a single answer.

Was this helpful?

supported.