# Chatting

> How to interact with your agent.

**URL:** https://inference.sh/docs/agents/chatting
**Last updated:** 2026-10-11

---

How to interact with your agent.

---

## Public agent pages

Browse public agents on the Grid at [Agents](https://inference.sh/agents). Open a listing at `https://inference.sh/agents/{namespace}/{name}` to see what it does before you chat or integrate.

The page is a single centered column, with chat at the top:

1. **Identity** — avatar, display title, clickable `namespace/name` (copies the agent ref), description, and a short facts line (model or harness, tool and skill counts, last updated). When the listing has a banner image, it fades in behind the top of the page.
2. **Composer** — when you are signed in, a message box sits under the identity block, unless the agent uses an external harness bound to a connected remote. Sending the first message creates a chat the same way as **New chat** in the workspace, then opens that chat. Example prompt chips under the box send their text when you click them.
3. **Start chat / start session** — when you are signed out, or the agent uses an external harness bound to a connected remote, you get a **start chat** or **start session** button instead of the composer. Harness agents bound to a remote use **start session** to open that remote, where the harness folder is chosen.

Below the composer, **about** and **api** tabs share the same column:

| Tab | What you get |
|-----|----------------|
| **about** | Tools the agent can call (with type and whether it asks first), skills it can load, and context fields read when a chat starts. If none are configured, the tab explains the agent runs from its instructions alone. |
| **api** | In-page **API guide** — pick **python**, **javascript**, **curl**, or **belt cli**, optionally pin the listed version, and copy the whole guide as Markdown. Snippets use the agent ref (`namespace/name`, or `namespace/name@version` when pinned). |

Open the page with `#api` in the URL to land on the **api** tab (same deep link as public app pages).

For discovery from search or the CLI, see [Search](/docs/concepts/search) (`collection=agents`) and `belt suggest`.

---

## In the workspace

1. Open your agent
2. Type a message
3. Watch it work

You'll see:
- The agent's thinking
- Tool calls as they happen
- Results as they come back

### Chat header

The header stays focused on the conversation:

| Element | When it appears | What it does |
|---------|-----------------|--------------|
| **Title** | Always | The chat name, or **untitled chat** when the chat has no name yet, or **new chat** before the first message creates a chat |
| **Subtitle** | Before the first message only | **with `namespace/name`** — the agent you are about to talk to (settings are not available until a chat exists) |
| **Chat settings** (gear) | After the chat exists | Opens per-chat settings (name, agent, permissions, memory, hooks, trace) |
| **New chat** (compose) | Always | Starts a fresh conversation with the same agent (harness sessions use **new session** and return to the remote) |

Agent version, copy-reference, edit-agent, and the execution trace are not in the header anymore — open **chat settings** → **agent** for those controls.

---

## Chat settings

Open **chat settings** from the gear icon in the chat header (only after the conversation has started). Settings apply to **this conversation only** and save as you change them (same dialog pattern as workspace settings).

### General

| Setting | What it does |
|---------|----------------|
| **Name** | Renames the chat in your chat list |
| **Visibility** | **Only you** (`private`), **your workspace** (`team`, default), or **anyone with the link** (`public`) |
| **Share link** | When visibility is public, copy `https://1nf.sh/chats/{short_id}` to share a read-only view. People who open it can read the conversation but cannot send messages or answer approvals |
| **Delete chat** | Removes the conversation, messages, and tool history (cannot be undone) |

### Agent

See which template agent answers in this chat, copy its reference, open the version this chat runs, switch to another **platform loop** agent when allowed, and open the execution trace.

**Current agent** shows the agent title, `namespace/name`, and an 8-character version prefix when the chat is pinned to a template version.

| Control | When it appears | What it does |
|---------|-----------------|--------------|
| **Copy reference** | Always | Copies `namespace/name@version` (8-character version prefix) to the clipboard |
| **Edit agent** | Loop agents only (`inference` harness or no external harness) | Opens the agent version editor for the version this chat runs |
| **Show trace** | Always | Toggles the execution trace sheet (model calls, tool calls, results). Turning it on closes chat settings so the trace is visible |

External harness agents (Claude Code, Codex, and similar) have no editable template version in inference shell, so **edit agent** is hidden — the same rule the old header used.

| Situation | What you can do |
|-----------|-----------------|
| **Loop agent** (`inference` harness or no remote profile) | Pick another loop agent from the list. The **next message** goes to that agent; it still sees the transcript so far. Harness-backed agents are not listed — they keep their own session on a machine, so start a **new chat** to use one. |
| **Harness chat** (remote profile or `harness_session_id` set) | View the current harness agent and **folder** (`work_dir`). Switching is disabled — the harness keeps its own session and history on that host. |

Via API, call [`POST /chats/:id/agent`](/docs/api/rest/agents#set-agent) with `namespace/name` (same as the workspace picker). The JavaScript workspace uses `switchAgent()` from `useAgentActions()` when `AgentChatProvider` is mounted. For the graph programmatically, use [`GET /chats/:id/trace`](/docs/api/rest/agents#get-chat-trace).

### Permissions

Control human-in-the-loop tool approvals and other **allow / ask / deny** rules for this chat.

| Setting | What it does |
|---------|----------------|
| **Allow all tools** | Every tool call runs without asking (loop tools, harness tools, and remote commands). Turning it on also approves calls that are already waiting; turn it off to require approval again for tools that are not covered by an allow rule. Policy layers above this chat still apply. **New chats in the agent's home workspace** copy the agent version's `permissions.allow_all_tools` default when the conversation is created; chats another workspace starts with a published agent do not — see [Agent template defaults](/docs/api/agent/approval#agent-template-defaults). Redeploying the agent does not change this chat's switch |
| **Rules** | Every layer that applies to this chat, most specific first: **this chat** (editable), the agent template, your user defaults, and team or org **policy** (read-only, marked **policy**). Each rule shows its effect (`allow`, `ask`, or `deny`) and a short **label** from the API (for example `npm run commands on laptop`) — the same wording as **always allow** on an approval prompt. When the label differs from the typed rule (`RemoteExec[laptop](npm run:*)`, `Bash(git status:*)`, …), the typed form appears underneath in smaller monospace text |

When a tool needs approval, you can **approve**, **reject**, or **always allow** from the chat UI. **Always allow** adds an allow rule on the chat layer (and still approves the pending call).

On the **this chat** layer you can remove rules you added. **Allow** rules from an agent template written by another workspace do not apply in your chat (their **ask** and **deny** rules still can); only **allow** rules you add on this chat, or from an agent your workspace owns, open tools without asking.

Use **add a rule** to narrow what runs without asking (or to ask or deny specific tools, harness patterns, remote commands, or folders). Chat rules can only **narrow** what governance or agent layers allow; the API refuses an allow that a layer above asks about or denies.

Use **test a call** to see which layer and rule would decide a sample tool name, harness call, command, or path before you run it.

→ [Approval settings](/docs/api/agent/approval) · [Chat rules REST API](/docs/api/rest/agents#chat-permissions-rules) · [Chat settings API](/docs/api/rest/agents#chat-settings) · [Always allow tool](/docs/api/rest/agents#always-allow-tool)

### Memory

When the agent uses the internal [memory tools](/docs/api/agent/internal-tools#memory_set), it stores key–value **notes** on this chat (`agent_data.memory` on [Get chat](/docs/api/rest/agents#get-chat)). The memory pane lists every note and its value.

| Action | What it does |
|--------|----------------|
| **Forget** (per key) | Removes one note from this chat. The agent will not see it on later turns. |
| **Forget all** | Clears every note when more than one exists. |

Via API, pass `forget_memory` (array of keys) on [`POST /chats/:id/settings`](/docs/api/rest/agents#chat-settings). Keys that are not stored are ignored.

### Hooks

Toggle whether [lifecycle hooks](/docs/api/agent/lifecycle-hooks) configured on the agent (suggest, learn, webhooks, gates) run in **this chat** without editing the agent template.

| Setting | What it does |
|---------|----------------|
| **Run hooks** | When on, hooks fire as usual. When off, the chat is excluded from hook side effects. Review branches are created with hooks off automatically. |

Set `disable_hooks` on [`POST /chats/:id/settings`](/docs/api/rest/agents#chat-settings) or use the **Run hooks** switch in chat settings.

→ [Per-chat disable](/docs/api/agent/lifecycle-hooks#switching-hooks-off-for-a-chat)

---

## Long conversations and context

Very long threads can approach the agent model's context limit. Before each turn, the platform checks whether the next prompt would use more than **80%** of that limit. When it would, older parts of the **live** transcript are summarized into a compaction entry and only the newest portion (about **25%** of the budget) stays verbatim.

In the workspace you may see a compaction line in the transcript — a short summary of earlier user messages and assistant replies. Tool-heavy stretches are summarized without replaying every tool output. The chat keeps going; you do not need to start a new conversation unless you want a clean slate.

Compaction never cuts between a tool call and its result, so the model always sees matched pairs. If you use [lifecycle hooks](/docs/api/agent/lifecycle-hooks), `agent.pre_compact` runs before summarization (your webhook can return `deny` or `stop` to skip it for that turn) and `agent.post_compact` runs after. Turn off hooks for one chat with **Run hooks** in [chat settings](#chat-settings) or `disable_hooks` on [`POST /chats/:id/settings`](/docs/api/rest/agents#chat-settings).

Integrations can listen for `context.compacted` on the agent run event stream. See [Context auto-compaction](/docs/api/rest/agents#context-auto-compaction).

---

## Example conversation

```
You: Create a logo for "Morning Brew" coffee shop

Agent: I'd be happy to create a logo. A few questions:
       - What style? (minimal, vintage, modern)
       - Any specific colors?
       - Should I include a coffee cup icon?

You: Modern style, warm colors, yes include a cup

Agent: [Calling stable-diffusion...]
       
       Here's your logo! I created a modern design with 
       warm orange and brown tones featuring a stylized 
       coffee cup.
       
       Want me to create variations?
```

---

## Widgets

Sometimes agents need structured input.

They can generate small UI forms:

```
Agent: I need some details:

       ┌─────────────────────────┐
       │ Company: [____________] │
       │ Style: [Modern ▼]       │
       │ Colors: [____] [____]   │
       │                         │
       │ [Generate]              │
       └─────────────────────────┘
```

Fill it out and the agent continues.

---

## From the terminal

After `belt login`, run agents and manage chats without opening the workspace:

```bash
belt agent run myteam/my-agent "Hello"
belt agent run myteam/my-agent "Follow up" --chat chat_abc123
belt chat get chat_abc123
belt chat send chat_abc123 "What's the status?"   # streams the agent's reply
belt chat watch chat_abc123                       # re-attach without sending a new message
```

`belt chat send` streams the agent's response (same behavior as `belt agent run`). Use `belt chat watch` to follow a chat that is already running or after approving a tool without `--watch`.

When a tool requires approval, list and act on pending invocations:

```bash
belt chat pending
belt chat approve ti_abc123 --watch
```

→ [CLI setup](/docs/extend/cli-setup#agents-cli) · [Agents API](/docs/api/rest/agents)

---

## Per-chat context

Agents can declare context fields that their tools use as `{{context.NAME}}`. Pass values when you start a chat (`belt agent run --context key=value` on the CLI):

```json
{
  "agent_id": "agent_abc123",
  "context": {
    "project_id": "proj_456",
    "environment": "staging"
  }
}
```

Context is set once per chat and cannot change, so every tool call in that conversation uses the same project or environment. The server substitutes the values when tools run; they are not written into the system prompt unless the field sets `in_prompt: true`.

→ [Context in Adding Tools](/docs/agents/adding-tools#context) · [Create Chat REST API](/docs/api/rest/agents#create-chat)

---

## Structured results

When an agent uses the `finish` tool (required for [structured output](/docs/api/agent/structured-output)), the final JSON is stored on the chat as `output`. Retrieve it with `GET /chats/:id` (see [Get Chat](/docs/api/rest/agents#get-chat)) or `agent.run()` in the SDK.

---

## Inspecting execution

The workspace shows tool calls and reasoning as the agent runs. For integrations and debugging:

| Surface | What you get |
|---------|----------------|
| **Live stream** | `belt chat watch <id>` or [Stream chat messages](/docs/api/rest/streaming#stream-chat-updates) |
| **Snapshot** | [List chat messages](/docs/api/rest/agents#list-chat-messages) — message history, tool invocation status, and [lifecycle hook runs](/docs/api/agent/lifecycle-hooks#hook-runs-in-the-transcript) (`role: event`) |
| **Metadata** | `GET /chats/:id` — chat status, structured `output`, and `active_run` |
| **Runtime overview** | [Observability](/docs/runtime/observability) — how tracing works across agents and app tasks |
| **Workspace trace** | **Chat settings** → **agent** → **Show trace** — execution graph for this chat (same data as the API below) |

Use streaming when you need live updates; use [List chat messages](/docs/api/rest/agents#list-chat-messages) when you need a point-in-time transcript after the run. Use `GET /chats/:id` for chat-level metadata such as `output` and `status`.

---

## Sending messages mid-run

While the agent is still working (`chat.status` is `busy`), you can send additional user messages without waiting for the current turn to finish. In the workspace, these appear as pending messages until the agent picks them up on its next turn.

Via REST, call `POST /chats/:id/messages` with a `message` string, or send another message with `POST /agents/run` using the same `chat_id`. When a run is already active, the API auto-queues instead of starting a new run. The message is created with `status: "queued"`; when the agent's next turn starts, it transitions to `ready` and is included in context (its transcript `order` may update at that point so it appears after any tool results that finished while it was waiting). To withdraw a queued message before the agent consumes it, call `POST /chats/messages/:messageId/cancel`. See [Send chat message](/docs/api/rest/agents#send-chat-message), [Cancel message](/docs/api/rest/agents#cancel-message), [Queuing while a run is active](/docs/api/rest/agents#queuing-while-a-run-is-active), and [Chat message status](/docs/api/rest/agents#chat-message-status).

---

## Terminal and API

- **CLI** — `belt agent run`, then `belt chat get`, `pending`, `approve`, or `reject` for follow-ups and human-in-the-loop. See [CLI Setup](/docs/extend/cli-setup#chat-cli).
- **REST** — New conversation: `POST /chats` (with `agent`) → `POST /chats/:id/messages`. One-shot: `POST /agents/run`. Follow-ups: `GET /chats/:id` (metadata), `GET /chats/:id/messages` (transcript), `POST /chats/:id/messages`, and `POST /tools/:id/invoke` or `/reject`. See [Agents REST API](/docs/api/rest/agents).

---

## Chat integrations

Connect your agent to external chat platforms. For Slack, configure your app's event subscription URL to the agent's channel webhook (`POST /agents/{id}/channel/slack`). See [Messaging channel webhooks](/docs/api/rest/agents#messaging-channel-webhooks).

| Platform | Guide |
|----------|-------|
| Slack | [Slack integration](/docs/credentials/slack) — channel webhooks supported |
| Discord | [Discord integration](/docs/credentials/discord) |
| Telegram | Chat interface (workspace) |
| WhatsApp | Message-based (workspace) |

Talk to your workspace from where you already are. For custom HTTP tools mid-conversation, see [Agent webhooks](/docs/agents/webhooks).

---

## Tips

- Be specific about what you want
- Provide context when relevant
- Ask for variations if the first result isn't right

---

## Next

→ [Browsing the Grid](/docs/apps/browsing-grid) — discover apps on the same explore site  
→ [Agents REST API](/docs/api/rest/agents) — chats, runs, and streaming from your own code
