> ## 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.

# Inspect traces

> Follow conversations and tool calls across messaging, MCP, plugins and the CLI.

See which tools ran, how long they took and where a request failed. Flow can send runtime events
to your own system or export traces to Flow Observe.

## Trace a conversation

Use an `EventSink` to send events to your logs or observability system. Events include messages,
turns, model calls, tool calls and schedules.

```ts Event sink
import type { EventSink } from "@flow-engineer/flow";

const log: EventSink = (event) => {
  console.log(event.type, event.conversationId, event.at);
};
// Pass events: [log] when creating the agent.
```

An event sink must not throw. `jsonlSink(path)` is available for writing events to a local file.

To export OTLP/JSON traces, set the following on the agent's host:

```dotenv Trace configuration
FLOW_FRAMEWORK_TRACES_KEY=your_trace_key
FLOW_FRAMEWORK_TRACES_URL=https://flow.engineer/observe
```

Metadata is exported by default. Set `FLOW_FRAMEWORK_TRACES_CONTENT=1` to include message content.
From Framework 0.8.1, `flow setup` writes that line, under a comment, when it adds a test traces
key (`otk_test_`, the Staging dashboard) and `.env` does not set it already, so test chats can be
read and graded there. Set it to `0` for metadata only. Setup never turns content on for a live key.

Scenario-test traces carry a test run marker so the dashboard can distinguish them from production.

### Channel and playground turns

From Framework 0.8.1:

* `chinwag.channel` is the platform the turn was on: `whatsapp`, `sms`, `telegram`, `imessage`,
  `web` (a custom UI), `cli` (the terminal), `voice` or `other`. It is the same on the root span
  and on every `send <name>` span; the channel's own name is only in the span name. Flow
  Messaging's `fm.telegram()` and `fm.imessage()` trace as `telegram` and `imessage` (before, `web`).
  A custom channel of your own names its platform with `traceChannel`; any other value traces as
  `other`.
* A playground turn (`npm start`'s page, `flow chat`, `agent.simulate()`, `agent.simulateVisitor()`)
  has `chinwag.via` set to `"playground"` on its root span. So does a message to the playground
  person that `intercept` or a keyword answered, and one sent to them outside a turn. Real turns
  have no `chinwag.via`. Playground turns share the process, and so `chinwag.run_kind`, with real
  conversations; the dashboard keeps them apart from real traffic by this attribute.

> [!NOTE]
>
> Upgrading to 0.8.1: a dashboard or query that read a `send` span's `chinwag.channel` as the
> channel's name should read the span name (`send <name>`) instead. To keep a test key's traces
> metadata only, set `FLOW_FRAMEWORK_TRACES_CONTENT=0` in `.env`; setup leaves an existing line alone.

**Check it worked:** send a message that calls a tool, then find the turn and its tool span in
your trace backend. Raw event sinks may contain message and tool content regardless of the trace
content flag; apply your own access and retention controls.

## Tool-call traces

MCP, plugin and CLI calls emit `tool.start` and `tool.end` events with their surface, client
name and version, session, person, duration, outcome and error.

`mcpServer` uses the same `FLOW_FRAMEWORK_TRACES_*` environment settings. Explicit `traces`
options override them; `traces: false` stops trace export without disabling event sinks.

> **What an MCP or CLI trace contains**
>
> Each call is a root trace without a conversation. Arguments and results are included only with
> `FLOW_FRAMEWORK_TRACES_CONTENT=1`. `await handle.flushTraces()` flushes the bounded background queue.
>
> CLI calls send the command and an idempotency key in `_meta`; the caller can reuse its key on
> a retry. `defineCli` sends its `version` (default `"1"`). CLI arguments and trace credentials
> are not placed in `_meta`.
>
> Legacy client initialization metadata is retained for at most 24 hours and 4,096 sessions.
> Bearer tokens are never cached.

> **[Test a failure](https://flow.engineer/docs/testing.md)**
>
> Reproduce a conversation with a scenario test.

> **[Run your own infrastructure](https://flow.engineer/docs/self-hosting.md)**
>
> Configure persistence and restart behavior.
