Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/withastro/flue/llms.txt

Use this file to discover all available pages before exploring further.

FlueContext<TPayload, TEnv> is the single argument to every Flue agent handler function. It carries everything the handler needs for a run: the agent instance id, a server-minted run id, the parsed request body, platform environment bindings, the raw HTTP request, a structured logger, and the init() method that creates a harness.

Type signature

export interface FlueContext<TPayload = any, TEnv = Record<string, any>> {
  readonly id: string;
  readonly runId: string;
  readonly payload: TPayload;
  readonly env: TEnv;
  readonly req: Request | undefined;
  readonly log: FlueLogger;
  init(options: AgentInit): Promise<FlueHarness>;
}

Generic type parameters

ParameterDefaultDescription
TPayloadanyType of ctx.payload. Compile-time only — no runtime validation is performed.
TEnvRecord<string, any>Type of ctx.env. On Cloudflare, pass the Env interface generated by wrangler types.

Properties

id
string
required
Agent instance id, taken from the URL <id> segment (POST /agents/<name>/<id>). Identifies the durable runtime scope — one customer, repository, conversation, or other caller-defined boundary. Reuse the same id to continue the same agent instance; use a new id to start fresh.
runId
string
required
Server-minted identifier for this HTTP invocation. Unique per request. Useful for correlating logs and events to a specific run.
payload
TPayload
required
The request body, parsed from JSON. The type is TPayload at compile time; there is no runtime schema validation. Validate with Valibot or another library if you need runtime safety.
env
TEnv
required
Platform environment bindings. On Node.js this is process.env. On Cloudflare Workers this is the Worker environment object (bindings declared in wrangler.jsonc). Pass your Env interface as TEnv to get typed access to KV namespaces, R2 buckets, Durable Object bindings, etc.
req
Request | undefined
required
The standard Fetch API Request for the current invocation. Use it to read headers, method, URL, and the raw body. Undefined when the agent is invoked outside an HTTP context (no non-HTTP triggers exist today, but the optional type keeps the contract sound when other trigger types ship).See Working with req below.
log
FlueLogger
required
Emit structured log events into the run event stream. See FlueLogger below.

Methods

init
(options: AgentInit) => Promise<FlueHarness>
required
Initialize a harness. Creates a FlueHarness with the configured model, sandbox, tools, session store, and default role. Call this once (or multiple times for multiple named harnesses) at the top of your handler.See AgentInit for the full options reference and FlueHarness for the returned object.

FlueLogger

export interface FlueLogger {
  info(message: string, attributes?: Record<string, unknown>): void;
  warn(message: string, attributes?: Record<string, unknown>): void;
  error(message: string, attributes?: Record<string, unknown>): void;
}
ctx.log emits structured events that appear in the run event stream as { type: 'log', level, message, attributes }. Use it instead of console.log so log entries are correlated to the run and visible in observability tooling.
ctx.log.info('starting triage', { issueNumber: payload.issueNumber });
ctx.log.warn('low confidence result', { score: data.confidence });
ctx.log.error('upstream request failed', { status: 503 });

Working with req

ctx.req is a standard Fetch Request. Use it to read headers and inspect the raw body.
// Read a header
const auth = ctx.req?.headers.get('authorization');

// Read body (single-use — see note below)
const raw = await ctx.req?.text();

// Parse manually (alternative to ctx.payload)
const body = await ctx.req?.json();
Body access is single-use. Once you call text(), json(), arrayBuffer(), or formData(), calling another body-reading method throws. If you need the body more than once, clone the request first.
const clone = ctx.req?.clone();
const bytes = await clone?.arrayBuffer(); // read raw bytes
const text = await ctx.req?.text();       // read text from the original

Client IP

There is no built-in accessor for the client IP address. Parse the platform header yourself.
// Cloudflare Workers
const ip = ctx.req?.headers.get('cf-connecting-ip');

// Behind a trusted proxy (Node.js)
const ip = ctx.req?.headers.get('x-forwarded-for')?.split(',')[0]?.trim();
Do not trust IP headers you do not control. Only read headers set by your platform or a proxy you own.

Full example

// .flue/agents/translate.ts
import type { FlueContext } from '@flue/runtime';
import * as v from 'valibot';

export const triggers = { webhook: true };

interface Payload {
  text: string;
  language: string;
}

interface Env {
  ANTHROPIC_API_KEY: string;
}

export default async function (ctx: FlueContext<Payload, Env>) {
  ctx.log.info('translation request', {
    language: ctx.payload.language,
    runId: ctx.runId,
  });

  const harness = await ctx.init({ model: 'anthropic/claude-sonnet-4-6' });
  const session = await harness.session();

  const { data } = await session.prompt(
    `Translate this to ${ctx.payload.language}: "${ctx.payload.text}"`,
    {
      result: v.object({
        translation: v.string(),
        confidence: v.picklist(['low', 'medium', 'high']),
      }),
    },
  );

  ctx.log.info('translation complete', { confidence: data.confidence });
  return data;
}

Build docs developers (and LLMs) love