Flue Zero to Expert, Part 7: Operate Like an Expert

Operate Flue with structured observation, repeatable evals, and schedules that match the work lifetime.

Series map

Part 1: Your First Flue Agent · Part 2: Typed Workflows · Part 3: Safe Tools · Part 4: Autonomous Agents · Part 5: Persistence and Durable Execution · Part 6: Production Routing and Deployment · Part 7: Operate Like an Expert

Tested with @flue/runtime 1.0.0-beta.9 on Node.js. The dispatch(..., { id, input }) shape below matches that installed version.

Observe useful outcomes

Actions expose log.info(...), log.warn(...), and log.error(...). Put values you need to search or aggregate in attributes instead of formatted messages.

Add observe(...) to the secured src/app.ts from Part 6 without changing its authentication middleware or flue() mount:

import { observe } from '@flue/runtime';

observe((event) => {
  if (event.type === 'run_end' && event.isError) {
    console.error('Workflow failed', {
      runId: event.runId,
      error: event.error,
    });
  }

  if (event.type === 'operation' && event.durationMs > 5_000) {
    console.warn('Slow operation', {
      kind: event.operationKind,
      durationMs: event.durationMs,
    });
  }
});

Keep observers lightweight. Flue monitors returned promises for rejection but does not wait for them. Each application context sees only its own activity, so aggregate events externally across processes or isolates.

Workflow invocations have a runId and run history. Direct prompts and dispatched agent input do not create workflow runs; inspect their session and operation activity instead.

Telemetry may contain prompts, workflow inputs, tool values, model messages, logs, and errors. Treat it as sensitive and apply explicit export, redaction, and retention policies.

Evaluate behavior before shipping

Flue does not include an eval runner. Its guide recommends vitest-evals, but any runner can use the public SDK. Add the official blueprint:

npx flue add tooling vitest-evals

It adds the required dependencies, configuration, starter case, and local harness. Each generated case gets a fresh agent instance; custom harnesses need the same isolation.

Run Flue in one terminal and the generated suite in another:

npx flue dev
npm run evals

Use direct assertions for exact behavior. Reserve a model judge for qualities such as clarity, and use a distinct grading model or configuration from the model under test. For workflows, build the harness around client.workflows.invoke(...) and grade the result.

Schedule the right lifetime

A schedule is only a trigger; your deployment platform must provide the scheduler.

Use workflow invoke(...) for bounded work such as reports, cleanup, or synchronization. Every occurrence gets its own runId, lifecycle, and history. Invocation returns after admission rather than waiting for completion.

Use agent dispatch(...) when every occurrence should enter one continuing session:

import { dispatch } from '@flue/runtime';
import helloWorld from './agents/hello-world.ts';

await dispatch(helloWorld, {
  id: 'scheduled-jokes',
  input: {
    message: 'Tell one short engineering joke.',
    scheduledAt: new Date().toISOString(),
  },
});

The stable ID reuses the same agent instance and conversation. Dispatch returns a dispatchId, not a workflow runId.

A daily report normally belongs in a workflow. A continuing assistant may need agent dispatch. Choose shared state deliberately.

Node has no built-in cron scheduler. An in-process scheduler stops with its process and may run in every replica. Use a persistent, coordinated scheduler when missed or duplicate occurrences are unacceptable.

Sources

You now have the full path from a first Flue agent to operating workflows and agents with evidence.