Skip to content

Ask the docs

Answers come only from these docs and are written by an AI model (Gemini), so check the linked pages. Your question is not kept. Do not include personal details or keys.

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.

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

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:

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.

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.

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.

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.