@economic/agents-playground
v1.5.0
Published
A local chat UI for testing agents built with @economic/agents.
Downloads
1,017
Keywords
Readme
@economic/agents-playground
A local chat UI for testing and interacting with agents built with @economic/agents.
Run it with npx — no install needed.
Quick start
Make sure your agent is running — locally or remotely — then launch the playground from your project root:
npx @economic/agents-playgroundThe playground opens automatically at http://localhost:3000. Enter your agent's URL in the bar at the top to connect.
Run from your project root. The CLI reads your
wrangler.toml,wrangler.json, orwrangler.jsoncfrom the current directory to auto-detect the agent name and port. If you run it from a different directory, auto-detection will not work and you will need to enter the agent URL manually.
CLI flags
| Flag | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --port <n> | Preferred HTTP port for the static server (default 3000). If that port is in use, the next free port is used. |
| --params <keys> | Comma-separated names of app-specific WebSocket query parameters. Example: npx @economic/agents-playground --params token or --params token,tenantId. The initial setup dialog shows one plain text field per key, and the key icon in the header lets you add more generic query params later. |
Local development (npm run dev)
The published CLI injects window.__PLAYGROUND_CONFIG__ when serving the built UI. Vite’s dev server does not run that script. Use either:
Same flag as production (the dev script wraps Vite and strips --params before starting it):
npm run dev -- --params token
# or
npm run dev -- --params token,tenantIdDo not run vite --params … — Vite does not define --params and will error.
Or set the env var (e.g. in packages/playground/.env):
VITE_PLAYGROUND_QUERY_PARAM_KEYS=token,tenantIdIf __PLAYGROUND_CONFIG__.queryParamKeys is present (from the CLI), it wins over VITE_PLAYGROUND_QUERY_PARAM_KEYS.
Agent URL
The playground connects to your agent over a WebSocket. The agent URL must follow this format:
http://<host>/agents/<agent-name>For example: http://localhost:8787/agents/my-agent
The agent name is the kebab-case version of your Durable Object class name. A class named ChatAgent becomes chat-agent, and MyCustomAgent becomes my-custom-agent.
Auto-detection
When you run npx @economic/agents-playground from your project root, the CLI reads your Wrangler config to pre-fill the agent URL automatically. It checks (in order):
wrangler.jsoncwrangler.jsonwrangler.toml
It reads the class_name from the first Durable Object binding it finds and the port from the [dev] section (defaulting to 8787). The class name is converted to kebab-case to match Cloudflare's routing convention.
If no Wrangler config is found, the URL field in the UI will be empty and you will need to enter the URL manually.
Changing the URL
The agent URL is shown as an editable field in the top-left of the header bar. Click it to edit, then press Enter to connect. Press Escape to cancel and revert. The URL is saved to localStorage so it persists across page reloads.
Changing the URL automatically starts a new session (a new Durable Object instance).
The UI
┌─────────────────────────────────────────────────────────────────┐
│ ● Connected to agent [Conversations] [New chat]│
│ http://localhost:8787/agents/my-agent │
├─────────────────────────────────────────────────────────────────┤
│ │
│ (conversation) │
│ │
├─────────────────────────────────────────────────────────────────┤
│ [+] Type a message... [→ Send] │
└─────────────────────────────────────────────────────────────────┘| Element | Description |
| -------------------- | ---------------------------------------------------------------------------------------- |
| Status dot | Green = connected, amber (pulsing) = connecting, red (pulsing) = disconnected |
| URL bar | The current agent URL. Click to edit, Enter to apply, Escape to cancel |
| Conversations | Opens a right-side panel that loads getConversations() from the connected agent |
| New chat | Starts a fresh conversation by generating a new session ID (new Durable Object instance) |
| ⊟ (sliders icon) | Opens the request body dialog. A blue dot appears when a body is configured |
| [+] action menu | Attach files, take a screenshot, or add attachments to the message |
| Send / Stop | Submits the message or stops a running stream |
Sessions
Each conversation is a Cloudflare Durable Object instance identified by a session ID. The session ID is stored in the URL as a query parameter:
http://localhost:3000/?chat=playground-<uuid>Sharing a conversation
Copy the browser URL and share it to resume the same conversation in another browser or tab. The recipient will connect to the same Durable Object instance and see the full conversation history until that conversation is deleted by any configured retention policy.
Starting a new conversation
Click New chat in the top-right of the header to generate a new session ID. This creates a new Durable Object instance — the previous conversation is preserved in the old instance and can be resumed by navigating back to its URL until it expires under the agent's retention settings.
Changing the agent URL also starts a new session automatically.
The conversations panel always reflects the currently connected agent identity. It fetches the list on open and on refresh, so it is useful for quickly checking what the backend thinks the current user can see.
Request body
Click the ⊟ sliders icon in the top-right to open the request body dialog. Paste any JSON object — it is merged into the body of every chat request sent to your agent. A blue dot on the button indicates a body is currently configured. The value is saved to localStorage and persists across page reloads.
Use case: auth tokens and metadata
If your agent tools need data that cannot be embedded in the message itself — auth tokens, tenant context, account metadata — put it in the request body and read it inside the tool's execute function via experimental_context:
// In the playground UI: paste into the request body dialog
// {
// "authorization": "Bearer my-token",
// "tenantId": "tenant_123"
// }
// In your tool definition
execute: async (args, { experimental_context }) => {
const { authorization, tenantId } = experimental_context as {
authorization: string;
tenantId: string;
};
const response = await fetch(`https://api.example.com/tenants/${tenantId}`, {
headers: { Authorization: authorization },
});
return response.text();
};CLI options
npx @economic/agents-playground [--port <number>] [--params <keys>]| Flag | Default | Description |
| ---------- | ------- | ------------------------------------------------------------------------ |
| --port | 3000 | Preferred port for the playground server |
| --params | - | Comma-separated app-specific WebSocket query params for the setup dialog |
If the preferred port is already in use, the CLI automatically finds the next available port and prints a message indicating which port was chosen:
Port 3000 in use, using 3001 instead.Template project shortcut
If your project uses the template-chat-agent scaffold, a playground script is already wired up in package.json:
npm run playgroundThis is equivalent to running npx @economic/agents-playground from your project root.
.
