Introducing Flue: A Pure TypeScript Open‑Source Agent Harness Framework

Flue, an open‑source Agent Harness framework written entirely in TypeScript, lets developers build headless, code‑driven AI agents with session management, tool integration, markdown‑based skills, and a virtual sandbox, supporting multiple runtimes like Node.js, Cloudflare Workers, and CI/CD pipelines.

Full-Stack Cultivation Path
Full-Stack Cultivation Path
Full-Stack Cultivation Path
Introducing Flue: A Pure TypeScript Open‑Source Agent Harness Framework

Flue is an open‑source repository under the withastro organization that provides an "Agent Harness Framework" for building autonomous agents.

Agent = Model + Harness

The framework defines an Agent as the combination of a model (producing tokens, calling tools, interpreting prompts) and a harness that supplies the surrounding shell needed for autonomous task completion.

Sessions : maintain context across multi‑turn dialogs and multiple events.

Tools : enable the model to call APIs, query data, and modify resources.

Skills : reusable domain knowledge packaged as Markdown files and loaded on demand.

Directives & Memory : defined in AGENTS.md and long‑term memory files.

Sandbox : a relatively safe execution environment that can run bash, read/write files, etc.

The architecture is visualized as a stack from bottom to top: model → harness → sandbox → file system. First‑generation agents only call LLM APIs (chat bots, scripted tasks). True agents such as Claude Code or Codex receive a goal and autonomously use context and tools to accomplish it.

Runtime‑agnostic design

Flue mirrors the developer experience of web frameworks like Astro or Next.js, but the target is an Agent rather than a web page. An Agent written once can be built for different environments, including:

Node.js servers

Cloudflare Workers

GitHub Actions

GitLab CI/CD

Package composition

@flue/runtime

: runtime containing the harness, sessions, tools, and sandbox. @flue/cli: CLI and build tool exposing the flue command.

Most logic lives in Markdown

Agent logic is primarily expressed in Markdown files (skills, context, and AGENTS.md), while the executable code is minimal. The official "hello‑world" translation agent demonstrates this pattern:

// .flue/workflows/hello-world.ts
import { createAgent, type FlueContext, type WorkflowRouteHandler } from '@flue/runtime';
import * as v from 'valibot';

export const route: WorkflowRouteHandler = async (_c, next) => next();

const translator = createAgent(() => ({ model: 'anthropic/claude-sonnet-4-6' }));

export async function run({ init, payload }: FlueContext) {
  const harness = await init(translator);
  const session = await harness.session();
  const { data } = await session.prompt(
    `Translate this to ${payload.language}: "${payload.text}"`,
    {
      result: v.object({
        translation: v.string(),
        confidence: v.picklist(['low', 'medium', 'high']),
      }),
    }
  );
  return data;
}

Key details:

Models are declared as simple strings (e.g., 'anthropic/claude-sonnet-4-6'), making provider swaps trivial.

The result argument to prompt() accepts a valibot schema; the returned data is validated, typed, and ready for branching logic instead of raw text.

Default virtual sandbox (no containers)

Instead of launching a Docker container per Agent, Flue uses a pure‑JavaScript in‑memory bash implementation called just-bash from Vercel Labs. This virtual sandbox provides utilities such as grep, glob, and read, offering far better performance and cost for high‑concurrency scenarios.

Example support agent that reads markdown articles from a virtual workspace:

// .flue/workflows/support.ts
import { createAgent, type FlueContext, type WorkflowRouteHandler } from '@flue/runtime';

export const route: WorkflowRouteHandler = async (_c, next) => next();

const support = createAgent(() => ({ model: 'openrouter/moonshotai/kimi-k2.6' }));

export async function run({ init, payload }: FlueContext) {
  const harness = await init(support);
  const session = await harness.session();
  await session.fs.mkdir('/workspace/articles', { recursive: true });
  await session.fs.writeFile(
    '/workspace/articles/reset-password.md',
    '# Reset your password

Use the account settings page to request a password reset email.'
  );
  return await session.prompt(
    `You are a support agent. Search the workspace for articles relevant to this request, then write a helpful response.

Customer: ${payload.message}`
  );
}

Flue offers three sandbox tiers:

Virtual sandbox : the default in‑memory just-bash, fastest and cheapest.

Local() : runs on the host’s file system and shell (e.g., gh, git, npm) via $PATH, suitable for CI environments.

Remote container : connects to a real Linux environment through connectors like Daytona or E2B, with image caching for quick session start.

Sub‑Agents, task delegation, and MCP

Complex agents can decompose work using session.task() to launch a one‑off sub‑Agent that shares the sandbox and file system but has its own message history:

const session = await harness.session();
const research = await session.task(
  'Research the auth flow and summarize the key files.',
  { cwd: '/workspace/project', agent: 'researcher' }
);
const answer = await session.prompt(`Use this research to draft the implementation plan:

${research.text}`);

Roles can be pre‑defined with defineAgentProfile(). Flue also integrates with the Modular Compute Platform (MCP). By connecting to a remote MCP server, tools can be injected via init() while keeping secrets in env variables:

const github = await connectMcpServer('github', {
  url: 'https://mcp.github.com/mcp',
  headers: { Authorization: `Bearer ${env.GITHUB_TOKEN}` },
});
const agent = createAgent(() => ({
  model: 'anthropic/claude-sonnet-4-6',
  tools: github.tools,
}));

Current MCP support is limited to modern streamable HTTP transports; older SSE, local stdio detection, and OAuth callbacks are not handled.

Development experience: full‑package CLI

flue dev

: watch‑mode development server; changes trigger a rebuild, viewable via curl on default port 3583. flue run: builds and runs any workflow locally, ideal for CI or one‑off scripts. flue connect: opens an interactive session with a running Agent, sharing in‑memory session state across prompts. flue build: outputs a bundled .mjs for Node targets and a Cloudflare‑compatible build that uses Durable Objects for session persistence.

Session state handling varies by platform: on Cloudflare, Durable Objects persist across requests; on Node.js it lives in memory unless a custom store is added.

Adoption considerations

Flue is still experimental (first commit February 2024, latest version v0.8.1). The README warns that the API may change, so production use requires readiness to adapt. The project is Apache‑2.0 licensed and commercially friendly.

Project URL: https://github.com/withastro/

Official site: https://flueframework.com/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CLITypeScriptAI agentsAgent FrameworkVirtual SandboxFlue
Full-Stack Cultivation Path
Written by

Full-Stack Cultivation Path

Focused on sharing practical tech content about TypeScript, Vue 3, front-end architecture, and source code analysis.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.