# Lab 2 — Streaming & Tool-Calling Agent

> **Summary — what this page covers**
> Attendees add a streaming endpoint and a multi-tool agent to BookTracker — committed. The agent
> calls real C# functions against the database before producing its final answer. Keep steps exact.

**Duration: 35 min · Deliverable: streaming endpoint + multi-tool agent — committed**

## Part A — Streaming endpoint (≈15 min)

Implement SSE streaming so tokens appear one at a time. Use `client.Messages.CreateStreaming`,
surface the text deltas as `IAsyncEnumerable<string>` from a `StreamingService`, and write each as a
`data:` frame, flushing per chunk (see [Section 2](05-section-2-streaming-tools.md)). Verify with:

```bash
curl -N http://localhost:5000/api/chat/stream?q=hello
# Tokens should appear one at a time, not all at once at the end
```

## Part B — Tool-calling agent (≈20 min)

Define **2+ tools** wired to real BookTracker services (e.g. `find_book`, `update_reading_progress`),
each with a clear, trigger-style description. Run the agent loop until `StopReason` is `EndTurn` —
the `BetaToolRunner` handles the loop for you, or write a manual loop if you want to log each call.
Cap iterations and return `is_error` tool results on failure. Verify multiple tool calls fire:

```bash
# Ask something that needs two lookups, e.g.:
#   "Find Dune and mark it as completed"
# Should see 2+ tool calls in the logs before the final response
```

## Checkpoint

- [ ] Streaming endpoint emits tokens incrementally
- [ ] Agent makes 2+ tool calls before its final response
- [ ] Tools read/write real BookTracker data
- [ ] Committed to your fork

## Bonus — The Streaming Agent

No time pressure. Combine both halves into **one endpoint**: run the tool-calling agent loop, then
**stream the final answer** token-by-token after the last tool call completes — the agent acts on
real data *and* feels responsive.
