Flue Zero to Expert, Part 4: Autonomous Agents
Compose continuing agents with instructions, skills, typed subagents, and the narrowest suitable sandbox.
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/runtime1.0.0-beta.9. Beta APIs can change; check the current Flue documentation when upgrading.
Continuing agents
A Flue agent can keep working within a continuing context. Each instance has an id; your application decides whether it identifies a ticket, repository, or customer. Conversation history belongs to the agent instance, while durable business data still belongs in your application database.
Instructions define the role. Tools add bounded application functions. Skills add reusable guidance. Sandboxes provide files and commands. Skills do not grant executable access: a skill may describe a code review, but a sandbox or tool must provide the capability.
Delegate focused work
Subagents are named profiles for focused research, classification, or review. Delegation creates a separate child session with the delegated request and its own context, not the parent's conversation transcript. The parent still owns the interaction; a subagent profile does not create a public agent route.
This workflow defines a coordinator and a typed review subagent:
import {
defineAgent,
defineAgentProfile,
defineWorkflow,
} from '@flue/runtime';
import * as v from 'valibot';
const Review = v.object({
summary: v.string(),
risks: v.array(v.string()),
approved: v.boolean(),
});
const reviewer = defineAgentProfile({
name: 'reviewer',
description: 'Reviews a proposed change for concrete correctness risks.',
instructions: [
'Review only the supplied change.',
'Report specific correctness risks.',
'Do not invent missing repository context.',
].join(' '),
});
const coordinator = defineAgent(() => ({
model: 'anthropic/claude-sonnet-4-6',
instructions: 'Delegate code review to reviewer and return its findings.',
subagents: [reviewer],
cwd: '/workspace',
}));
export default defineWorkflow({
agent: coordinator,
input: v.object({ change: v.string() }),
output: Review,
async run({ harness, input }) {
const session = await harness.session();
const response = await session.task(input.change, {
agent: 'reviewer',
result: Review,
});
return response.data;
},
});session.task(...) selects reviewer explicitly. The Review schema validates returned data, so invalid output fails instead of entering the application unchecked. A parent model can also choose delegation itself: configuring subagents gives it Flue's built-in task capability.
Delegation is not free or automatically safer. Each task can add model turns, tokens, latency, and tool activity. Give specialists narrow instructions and capabilities, pass only the context they need, and bound the parent operation with application-level limits such as timeouts, cancellation, budgets, or a fixed orchestration plan. Use a direct tool or ordinary application function when delegation adds no value.
Know what a child inherits
A named subagent profile owns its capabilities. Parent instructions, tools, skills, and subagents never flow into the delegated session; if the profile omits one, the child has none.
Environment defaults differ: model, thinkingLevel, and compaction fall back to the parent's values, while a profile value wins when declared. A subagent cannot declare durability; its task runs inside the parent operation.
The child uses the same sandbox boundary as its parent. It does not escape into a broader workspace. The task may select another cwd, but that does not widen the sandbox itself.
Calling task() without an agent name is different: it creates a fresh child context using the parent's full configuration rather than selecting a named subagent profile.
Choose the narrowest sandbox
Flue uses a virtual sandbox by default. It is a lightweight in-memory workspace for staged files and lightweight commands. It starts without host files, is not durable, and is not a full Linux environment. It is also not a network isolation boundary: the current generated runtimes permit network access from it.
Use local() only for trusted Node.js agents that need the host filesystem and installed shell commands. It gives model-directed work direct host access, not isolation. Expose only necessary environment variables and prefer a narrow tool when one operation is enough.
Use a remote sandbox for untrusted, tenant-specific, or tool-heavy work that should not run on the application host. A provider can supply an isolated Linux environment and managed lifecycle, but your application must still choose workspace ownership, credentials, network access, reuse, and expiry. Check the integration before assuming it exposes the usual file and command capabilities.
Sandbox persistence and conversation persistence are separate. A stored conversation does not preserve virtual files; a durable remote workspace does not preserve conversation history by itself.
Choose the narrowest environment that completes the task. Every added file, command, credential, network destination, and delegated model call expands capability or cost.
Sources
Next, continue to Part 5: Persistence and Durable Execution to preserve state and recover safely.