---
title: "Find Real Openings"
description: "Add the check_availability tool, a second typed tool with no input, so the dispatcher offers real open repair slots instead of inventing times."
canonical_url: "https://vercel.com/academy/building-agents-with-eve/find-real-openings"
md_url: "https://vercel.com/academy/building-agents-with-eve/find-real-openings.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-06-30T09:12:36.555Z"
content_type: "lesson"
course: "building-agents-with-eve"
course_title: "Building Agents with eve"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Find Real Openings

# 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:

```ts
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"`.

\*\*Note: 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:

```bash
npx eve dev
```

```text
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.

\*\*Note: 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

```ts title="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.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
