> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flue

> Trace Flue agent workflows in Braintrust to debug LLM turns, tool calls, subtasks, and context compaction

If you are a coding agent, prefer the Braintrust [`bt` CLI](/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, such as ad-hoc lookups and exploration from your IDE.

[Flue](https://flueframework.com/) is an open-source TypeScript agent harness framework. Braintrust traces Flue workflow runs, including LLM turns, tool calls, subtasks, and context compaction.

<View title="TypeScript" icon="https://img.logo.dev/typescriptlang.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-typescript">
    Setup
  </h2>

  Install Braintrust alongside the Flue runtime, CLI, and Hono, then set your API keys. Install `@flue/runtime` and `@flue/cli` together so their versions stay aligned.

  <Steps>
    <Step title="Install packages">
      <CodeGroup>
        ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        pnpm add braintrust @flue/runtime @flue/cli hono
        ```

        ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        npm install braintrust @flue/runtime @flue/cli hono
        ```
      </CodeGroup>
    </Step>

    <Step title="Set environment variables">
      ```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      BRAINTRUST_API_KEY=<your-braintrust-api-key>
      ANTHROPIC_API_KEY=<your-anthropic-api-key>
      ```
    </Step>
  </Steps>

  <h2 id="auto-instrumentation-typescript">
    Auto-instrumentation
  </h2>

  <Warning>
    Auto-instrumentation is supported for Flue v0.8.x only. For Flue v1.0.0-beta.3 or later, use [manual instrumentation](#manual-instrumentation-typescript), which requires `braintrust` v3.20.0 or later.
  </Warning>

  To trace Flue v0.8.x workflows without modifying your application code, initialize Braintrust in your Flue app entry, then run your app with Braintrust's import hook to patch the Flue runtime.

  <Steps>
    <Step title="Configure your Flue project">
      Flue loads its app entry from `src/app.ts`, discovered through a `flue.config.ts` at the project root. Running `flue init --target node` generates this config:

      ```ts title="flue.config.ts" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      import { defineConfig } from "@flue/cli/config";

      export default defineConfig({ target: "node" });
      ```
    </Step>

    <Step title="Initialize Braintrust in your app entry">
      Call `initLogger` at the top of the app entry, before the Hono app is created, so Braintrust is ready before any workflow runs. `flue()` (from `@flue/runtime/routing`) returns the routes you mount with `app.route("/", flue())`:

      ```ts title="src/app.ts" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      import { flue } from "@flue/runtime/routing";
      import { initLogger } from "braintrust";
      import { Hono } from "hono";

      initLogger({
        projectName: "my-flue-app", // Replace with your project name
        apiKey: process.env.BRAINTRUST_API_KEY,
      });

      const app = new Hono();
      app.route("/", flue());

      export default app;
      ```
    </Step>

    <Step title="Define a workflow">
      A workflow lives in `src/workflows/` and is named after its file, so this is the `hello` workflow. Its exported `run` function receives the `--payload` you pass at run time. This one defines an agent and sends it the question from the payload:

      ```ts title="src/workflows/hello.ts" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      import { createAgent, type FlueContext } from "@flue/runtime";

      const assistant = createAgent(() => ({
        model: "anthropic/claude-haiku-4-5",
        instructions: "Answer in one short sentence.",
      }));

      export async function run({ init, payload }: FlueContext<{ question: string }>) {
        const harness = await init(assistant);
        const session = await harness.session();
        const response = await session.prompt(payload.question);
        return { answer: response.text };
      }
      ```
    </Step>

    <Step title="Run with the import hook">
      Run the `hello` workflow. The import hook patches the Flue runtime so the run is traced, and `--payload` is passed to your workflow's `run` function:

      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      NODE_OPTIONS="--import braintrust/hook.mjs" flue run hello --target node --payload '{"question":"What is the capital of France?"}'
      ```

      The auto-instrumentation example uses plain JavaScript so `node --import` can run the file directly. The Braintrust APIs work the same in TypeScript projects — compile your TypeScript to JavaScript, then run the compiled file with the import hook.

      <Note>
        If you're using a bundler, see [Trace LLM calls](/instrument/trace-llm-calls#auto-instrumentation) for plugin and loader setup.
      </Note>
    </Step>
  </Steps>

  <h2 id="manual-instrumentation-typescript">
    Manual instrumentation
  </h2>

  To trace Flue manually, register Braintrust in your app entry. The `flue.config.ts` and workflow definitions are the same as above; only the app entry changes, depending on your Flue version:

  * **Flue v0.8.x**: register the observer with `observe(braintrustFlueObserver)`.
  * **Flue v1**: register the instrumentation with `instrument(braintrustFlueInstrumentation())`.

  With Flue v1, workflow and tool spans become the active context for your application code, so spans you create with Braintrust nest under the current Flue span.

  <CodeGroup>
    ```ts title="src/app.ts (Flue v0.8.x)" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import { flue } from "@flue/runtime/routing";
    import { observe } from "@flue/runtime";
    import { braintrustFlueObserver, initLogger } from "braintrust";
    import { Hono } from "hono";

    initLogger({
      projectName: "my-flue-app", // Replace with your project name
      apiKey: process.env.BRAINTRUST_API_KEY,
    });

    observe(braintrustFlueObserver);

    const app = new Hono();
    app.route("/", flue());

    export default app;
    ```

    ```ts title="src/app.ts (Flue v1)" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import { instrument } from "@flue/runtime";
    import { flue } from "@flue/runtime/routing";
    import { braintrustFlueInstrumentation, initLogger } from "braintrust";
    import { Hono } from "hono";

    initLogger({
      projectName: "my-flue-app", // Replace with your project name
      apiKey: process.env.BRAINTRUST_API_KEY,
    });

    instrument(braintrustFlueInstrumentation());

    const app = new Hono();
    app.route("/", flue());

    export default app;
    ```
  </CodeGroup>

  Run your workflow normally. No import hook is needed because you register the instrumentation directly:

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  flue run hello --target node --payload '{"question":"What is the capital of France?"}'
  ```

  <h2 id="what-traced-typescript">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * Workflow run spans (`workflow:<name>`), with the run input and result.
  * Operation spans (`flue.prompt`, `flue.skill`, and `flue.compact`) for agent operations.
  * LLM turn spans (`llm:<model>`), with messages as input, the model and request parameters as metadata, and the response as output.
  * Tool call spans (`tool:<name>`), with the tool arguments as input and the tool result as output.
  * Subtask spans (`task:<agent>`), with the subtask prompt as input and its result as output.
  * Context compaction spans (`compaction:<reason>`), with message counts before and after compaction.
  * Token usage and cost metrics (prompt, completion, total, cached, cache-creation, and estimated cost) on LLM turns.
  * Errors captured on every span.

  <h2 id="resources-typescript">
    Resources
  </h2>

  * [Flue's Braintrust integration guide](https://flueframework.com/docs/ecosystem/tooling/braintrust/)
  * [@flue/runtime on npm](https://www.npmjs.com/package/@flue/runtime)
</View>
