> ## Documentation Index
> Fetch the complete documentation index at: https://flow.engineer/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Try it in the playground

> Test the same agent across channels and inspect every tool call.

The playground runs your actual messaging agent with test people. Switch between WhatsApp,
SMS, iMessage, Telegram and web to see how the same agent replies on each interface.

## Start it

From your project folder, with a model key set in `.env`:

```sh Terminal
npm start
```

Open the URL it prints. The starter uses `PORT`, else 8788 or the next available port.

**1. Choose a person and a channel**

Pick one of the test people and send a request such as “What's on the menu?” The playground
uses that person's identity and history on the agent's declared channels.

**2. Inspect the tool call**

Turn on **Debug** to see which tools ran and how long the reply took. For the menu request,
look for `get_menu` and a reply based on its result.

**3. Try a change of mind**

Send “a large latte” and then “oat milk actually.” Watch how the agent combines the messages
or reads a new message while a tool is running.

**4. Start a fresh conversation**

Use **Clear history** before repeating a case from the beginning. Switching channels keeps
the person's conversation; it does not reset the test.

## Who can the playground play?

Declare test people on the agent. For example, include these options when building it:

```ts Agent options
testPeople: [
  { name: "Sam", phone: "+15555550102" },
],
```

A test person is resolved the same way as someone writing from a real channel. Replies return
to where the person last wrote, in the playground or on their phone.

From Framework 0.8.1, [traces](https://flow.engineer/docs/traces.md#channel-and-playground-turns) of playground turns (and of
`flow chat`) carry `chinwag.via` = `"playground"`, so the dashboard keeps them apart from real
traffic. Turns from the person's phone have none.

> [!NOTE]
>
> Use test identities and test data. If a test person is also connected through a real provider,
> the agent treats them as the same person.

## Build your own playground

The starter wires this up already. For your own entry point, pass the playground's event sink
when building the agent:

```ts src/main.ts
import { simulators } from "@flow-engineer/flow/simulators";
import { buildAgent } from "./agent.ts";

const play = simulators({ title: "My agent" });
const agent = buildAgent({ events: [play.events] });
const { url } = await play.listen(agent, 8788);
console.log("Playground: " + url);
```

Your `buildAgent` must declare the channels and test people you want to exercise.

## Time, reminders and nudges

The **Person** view lets you inspect scheduled and held messages and the agent's
[wake-ups](https://flow.engineer/docs/wake-ups.md), set the person's time zone
and quiet hours, and send nudges. To move time, connect the playground clock to both the
simulator and the agent:

```ts Shared test clock
import { playgroundClock, simulators } from "@flow-engineer/flow/simulators";

const clock = playgroundClock();
const play = simulators({ clock });
// Supply now: clock.now when creating the agent.
```

See [reminders and nudges](https://flow.engineer/docs/nudges.md) for delivery rules and [scenario testing](https://flow.engineer/docs/testing.md) for
repeatable checks.

## The agent's records

For an agent that declares collections, the **Records** tab lists its own [records](https://flow.engineer/docs/records.md),
every person's, by collection. It shows the newest 200 with each collection's full count and how
many older records it leaves out (`flow records export` lists every one). It is read only and
refreshes after each turn. **Clear history** forgets the person, which also deletes
the records that name them in a `people` field.

## Test sign-in

Give `simulators` an `authentication({ channel, visitor })` hook. The person picker then offers
**New user · signed out**. The hook returns a sign-in URL until your app verifies the visitor,
then the account's key and channel address.

Each interface authenticates independently. Existing test people keep their identity shortcut.
The [authentication guide](https://github.com/flow-engineer/flow/blob/main/coding-agents/auth-skill.md#exercise-sign-in-in-the-playground)
has the complete setup.

> **Serve the playground on a deployed agent**
>
> Local previews accept requests from localhost and the playground's own page. On a deployed
> agent, mount `play.handler(agent, { token })` with a token of at least 32 characters.
>
> The handler exchanges a `?token=` link for a cookie scoped to the playground path and limits
> wrong-token attempts. Keep that link private.

> **[Connect a real channel](https://flow.engineer/docs/conversations.md)**
>
> Wire the same agent to Flow Messaging or your own provider.

> **[Automate your checks](https://flow.engineer/docs/testing.md)**
>
> Turn the cases you tried into scenario tests.
