Docs Building Chat mode

Chat mode

Chat is the cockpit. Think of it as the agent's desk — open a chat and the agent gets a fresh sandbox, full web access, every Skill you've installed, every Connect you've authorized, and a blank canvas to work on. You use chat to explore (one-shot tasks), to build Apps (turn a conversation into a saved workflow), to edit existing Apps, and to debug failed runs. Everything else in this section is operational detail.

When chat vs an App? Chat for one-time work, exploration, debugging. An App for "I'll want to run this again, possibly on a schedule, possibly with different inputs, possibly handed to a teammate." The transition is one click (Save as App) or one phrase ("save this as an app").

What chat is for

Four operational uses, all in the same surface:

1. Explore

Try a task before committing to an App. The agent runs in a fresh sandbox; nothing persists unless you save. Best for: "I'm not sure if this is even possible", "let me try a few phrasings", "I need a one-time answer".

2. Build Apps

Use a trigger phrase ("create an app that…") to activate the App Builder skill. The agent walks you through the design conversationally and saves the App via the API. Best for: turning a working chat into a reusable workflow.

3. Edit existing Apps

Ask the agent to modify an existing App ("update Company Brief to also include hiring data"). The App Builder fetches the App, modifies it, re-saves as a new version. Best for: incremental improvements without learning the App's editor UI.

4. Debug failed runs

Open a failed run from the App's history. Click Debug in chat — a chat opens with the run's context: inputs, partial artifacts, the agent's reasoning trace, the error. Now you can ask the agent what went wrong and how to fix it. Best for: "this used to work, why doesn't it now".

Opening a chat

  1. From any page, click + New Chat in the sidebar.
  2. A blank chat opens. Message input at the bottom, conversation area above, breadcrumb at top.
  3. The chat runs in an isolated E2B sandbox using the claude-code template — the agent has full read/write access to a temp filesystem and can execute code, but nothing touches your machine or other chats.

Layout of the chat surface

┌──────────────────────────────────────────────────────────────┐
📁 My workspace / Chat • 12 MaySave as App ▾
├──────────────────────────────────────────────────────────────┤
You
Summarize last week's commits in shop-frontend.

🤖 Agent [github] · 1.4s
I'll pull commits via GitHub. One moment.
→ github.list_commits(repo=shop-frontend, since=...)
← 47 commits returned
<writes summary as markdown>
├──────────────────────────────────────────────────────────────┤
📎 Skills: 12 active · Connects: 4 auth
Type your reply… [↵ Send]
└──────────────────────────────────────────────────────────────┘
  • Breadcrumb (top) — workspace name / chat name.
  • Save as App ▾ (top-right) — drop-down with "Save as App" and "Save into existing App". Grayed out until the conversation is saveable.
  • Conversation thread (center) — alternating user and agent turns. Tool calls (Skill invocations, Connect calls) appear inline with input + output.
  • Status bar (above input) — count of active Skills and authorized Connects.
  • Attach (📎) — open a file picker or drag files into the conversation.
  • Send (↵) — Enter or click.

What the agent has access to

Inside every chat the agent has:

  • Sandbox runtime. An E2B sandbox using the claude-code template. Can execute Python, Node, install packages, read/write a temp filesystem, make HTTP requests.
  • Web access. Search, fetch URLs, render pages, screenshot.
  • Installed Skills. Every Skill in your workspace is available. The aitroop-app-create skill is built in.
  • Authorized Connects. Every OAuth integration you've authorized. Tokens are injected as env vars (or via internal service calls) at run start.
  • Conversation context. Previous turns, attached files, and any artifact you've opened in the chat.

Writing a useful first message

The quality of the first message shapes the rest of the conversation. A useful template:

# Task
What you want the agent to do, in one or two sentences.

# Inputs
Specific data points — dates, names, IDs, file references.

# Output
What the result should look like — format, length, structure.

# Constraints
What to include, what to skip, language, tone.

You don't need this template every time. But when the agent's output is missing something, the missing piece is usually one of these four — add it and try again.

Example: a well-formed first message

# Task
Summarize this week's customer support tickets.

# Inputs
Tickets in HubSpot, status=open, last 7 days.

# Output
One-page Markdown brief with:
- Top 3 themes (one bullet each)
- Escalations (with ticket IDs)
- Sentiment trend vs prior week

# Constraints
Skip tickets marked as spam.
Executive tone, no jargon.

Attaching files

  1. Drag a file from your machine into the chat, or click the 📎 attach button.
  2. The file uploads and appears as a chip above the input.
  3. The agent gets read access to the file inside its sandbox — it can parse, transform, summarize.
  4. The attachment lives for the chat. It doesn't follow you to other chats.

Supported file types

  • Text: .txt, .md, .csv, .json, .xml, .yaml.
  • Documents: .pdf, .docx, .xlsx, .pptx.
  • Images: .png, .jpg, .gif, .webp, .svg.
  • Code: any source file. The agent identifies the language and renders accordingly.
  • Archives: .zip, .tar.gz — the agent can list contents and extract.

Tips for files

  • Mention the file in your prompt. "Extract the key dates from the attached contract." The agent doesn't always proactively look at attachments.
  • For App inputs, don't attach in chat. Use a file AppInput instead, so users upload fresh each run.
  • Large CSVs: the agent reads them in chunks; works well up to ~100MB.

How the agent uses Skills

You don't invoke Skills by name. The agent decides when to call them based on the task. When it does, you see the call inline:

🤖 Agent [web-search] · 2.1s
Let me search the web for recent news.

→ web-search(query="Stripe funding 2025", limit=10)
← 10 results: ["Stripe raises Series H...", ...]

<agent continues with results in context>

The most important built-in Skill: App Builder

The aitroop-app-create skill activates automatically when your message contains a trigger phrase:

  • "Create an app that…"
  • "Build me a workflow for…"
  • "I want an app to…"
  • "Make an automation that…"
  • "Update my app…"

Trigger phrases work regardless of capitalization or surrounding text. "I'd like an app to summarize emails" triggers it just as well as "Create an app that summarizes emails".

Checking which Skills are active

Look at the status bar above the input — it shows a count ("Skills: 12 active"). Click for a list. Or ask the agent directly:

> what Skills do I have available?

How the agent uses Connects

Connects work invisibly. The agent uses your authorized OAuth tokens to read or write to external systems. You don't have to mention the Connect by name.

First-time authorization

  1. The agent decides it needs a Connect you haven't authorized (e.g., the user asks for "my unread Gmail").
  2. The agent pauses and shows an authorization prompt:
    🔒 This chat needs Gmail access to read your inbox.
      [ Authorize Gmail ]   [ Skip ]
  3. Click Authorize Gmail. A popup opens with Google's OAuth screen.
  4. Approve the scopes the platform is requesting.
  5. You're returned to the chat. The agent resumes from where it paused.

Subsequent runs

After the first authorization, future chats and runs use the Connect transparently — no prompts. Revoke at any time from Settings → Connects.

Confirmation for writes

For write-capable Connect actions (sending email, creating CRM records, modifying files), the agent shows you what it's about to do and waits for explicit approval:

🤖 Agent About to send this email via Gmail:
  To:     [email protected]
  Subject: Following up on yesterday's call
  Body:    Hi Jane, thanks for the time yesterday...

  [ Send ]   [ Edit first ]   [ Cancel ]

How a message becomes a turn

The chat box looks like one big text field, but underneath, every send goes through a small, cluster-safe message queue. Understanding what happens is worth two minutes — it explains every "why didn't my message send?" question you'll ever have.

The state machine

pending  →  dispatching  →  sent

                    dispatching  →  pending (transient failure, attempt < 5)

                    dispatching  →  failed (after 5 attempts)
  1. You hit send. The server inserts an app_message row with status: 'pending', a session-scoped position (monotonically increasing), and a priority (defaults to wall-clock time so messages run in send order). The UI immediately renders the row as "Sending…".
  2. A worker claims it. Servers in the cluster listen on a queue_dispatch Postgres channel; the writer also NOTIFYs after inserting. Whichever worker wins the race claims the row with SELECT … FOR UPDATE SKIP LOCKED ordered by priority DESC, position ASC, flips it to dispatching, and increments attempts.
  3. The runner runs. The worker hands the message to the agent runner (via the protocol detailed in Core concepts). JSONL events stream back; each one is fanned out to the chat's SSE subscribers in real time.
  4. Completion. Successful turn → row goes to sent. Transient error (network, session_expired, etc.) → row goes back to pending for another worker to pick up. After 5 failed attempts the row goes to failed and the UI surfaces the captured last_error.

One turn at a time, per session

The schema enforces a single in-flight user message per session via a partial unique index over session_id WHERE status = 'dispatching' AND role = 'user'. If you somehow send two messages before the first dispatches, the second waits in pending until the first finishes — no interleaved turns, no race between two Claude responses. Multi-instance dispatch can never violate this; the database is the source of truth.

Recovery from a crashed worker

Workers can die mid-dispatch — Kubernetes evicts a pod, a node crashes. A separate recovery poller scans every 60 seconds for rows stuck in dispatching for more than 900 seconds (15 minutes) and flips them back to pending so another worker can claim them. You'll see this in practice as a 15-minute worst-case delay on a fresh dispatch attempt after an infra incident — never a silently-lost message.

What "Sending…" really means in the UI

  • Spinner stays on briefly. Status is pending or dispatching; the worker is connecting to the sandbox or starting the runner. Normal for the first few hundred milliseconds.
  • Spinner stays on for >30 s without text. The runner is up but Claude is in long thinking; the keepalive is firing. Wait it out.
  • Spinner stays on for 15+ min. The worker hosting the dispatch may have died. The recovery poller will reset it shortly.
  • Red bubble with an error. Status is failed; the last_error field is what you're looking at. Retry by sending again — the queue picks up.

Iterating on output

The standard rhythm in a productive chat:

  1. The agent produces something — text, a draft, a structured output.
  2. You read it.
  3. You tell it what to change — specifically.
  4. The agent produces a new version.
  5. Repeat until satisfied.

Better feedback patterns

VagueBetter
"Make it better.""Cut by 30%. Make the tone less formal. Skip the disclaimer."
"Different format.""Switch from prose to a numbered list with one sentence per item."
"Not quite right.""The 'Strengths' section should be 3 paragraphs, not bullets. The 'Risks' section can stay as bullets."
"Too much.""Keep only the top 3 themes. Drop everything else."

Saving a chat as an App

Two paths to convert a productive chat into a saved workflow:

Path A: Use the trigger phrase mid-conversation

At any point in a chat, say:

> save this as an app

The App Builder activates, looks at the conversation so far, and proposes an AppDef. From here it's the same review-and-confirm flow as building from scratch.

Path B: Use the Save as App button

  1. Click Save as App ▾ in the top-right.
  2. Pick Save as App for a new App, or Save into existing App to merge into one you already have.
  3. The App Builder activates and proposes a design based on the chat.
  4. Review, confirm, save.

Sandbox details

Every chat runs in an isolated E2B sandbox with the claude-code template:

  • Fresh filesystem per chat. Created when the chat opens; destroyed when it ends or after a long idle.
  • Package install allowed. The agent installs whatever it needs for the task (Python packages, npm modules, system tools).
  • Network access allowed. Web search, API calls, fetching files.
  • Connects injected per-run. Your OAuth tokens are made available to the agent without being exposed in the conversation.
  • No cross-chat state. Two chats never share files or context.

Chat history and search

  • All chats live under Sidebar → Chats.
  • Click any chat to reopen — you can continue the conversation any time.
  • Use search (top of the chat list) to find a chat by content.
  • Pin chats you reference often.
  • Archive chats you're done with — they stay searchable but don't clutter the list.

When chat isn't the right surface

Build an App instead of using repeated chats when:

  • You've found a working version of the task.
  • You'd want to run the same kind of work again, with different inputs.
  • You'd want a teammate to run it without learning your prompt.
  • You want it to run automatically on a schedule.

For one-offs, exploration, debugging, and casual questions — stay in chat.

Built-in agent tools

Beyond your installed Skills and Connects, the agent has five always-available tools exposed via the built-in MCP server (mcp__aitroop__*):

ToolWhat it doesWhen the agent reaches for it
ask_questionPause and ask you a clarifying question.When information is missing and guessing would waste work.
get_taskLook up details on a task (for tasks generated inside a chat).Long sessions with structured to-do.
update_taskMark a task complete / in progress / blocked.Same.
get_asset_contentRe-read an artifact already produced in this chat."Now expand on section 3 of the brief you wrote."
generate_imageText-to-image via Gemini (if the host is configured with a key)."Draw a diagram of this workflow."

FAQ & troubleshooting

The agent isn't using a Skill / Connect I expect.

Likely cause: the agent picked a different approach. Often it's reasoning from context when you wanted it to call out to a tool.

Fix: tell it explicitly. "Use the web-search Skill for this." Or check the status bar above the input — if it says "Skills: 12 active" but the Skill you wanted isn't there, install it from Sidebar → Skills first.

I uploaded a file but the agent isn't looking at it.

Files attached via 📎 sit in the sandbox but the agent doesn't proactively read them unless your prompt mentions them. Add: "Use the attached contract.pdf as input".

My chat is taking forever to respond.

Three common causes:

  • Cold sandbox. First message of the chat: +1–2 s for sandbox provision.
  • Heavy tool call. A research task with 10 web searches takes 30–90 s. Watch the run log — you'll see each call as it happens.
  • Context overflow. Very long chats (50+ turns) slow down. The status bar shows context usage; consider starting a new chat with the artifact you care about as the seed.

How do I share a chat with a teammate?

Open the chat, click the share icon at the top-right, get a public URL. The chat becomes read-only at that URL — your teammate can read but not send messages or trigger new agent turns. Revoke any time from Settings → Shares.

Can I run the same chat twice with different inputs?

Not directly — chats are stateful conversations, not parametric workflows. If you want re-runs with different inputs, that's the entire point of an App. Type "save this as an app" and the App Builder converts the conversation into one.

The agent kept asking me clarifying questions. How do I shortcut?

Front-load the answers. A useful template at the top of your first message:

# Task
<what to do>
# Inputs
<exact data points>
# Output
<format, length, structure>
# Constraints
<what to include / skip>

What happens to my chat after I close the tab?

The conversation history is persisted permanently (until you delete it). The sandbox for the chat enters idle mode after 5 minutes and is destroyed shortly after. The next time you open the chat, a fresh sandbox is provisioned. Files attached earlier are re-uploaded automatically; the agent's reasoning carries over via the conversation history.