Task Tool for Child Agent Delegation with Separate Working Directories

Flue's built-in task tool spawns isolated child agents with dedicated working directories and independent contexts, enabling sandboxed file operations and recursive workflows without contaminating the parent session.

The withastro/flue SDK provides a first-class primitive for delegating work through its task tool, which allows an agent to spawn detached child processes. Each child receives its own current working directory (cwd), skill set, and system prompt, ensuring that file system operations and context remain strictly scoped to the child's environment.

Architecture of the Task Tool

The implementation spans three core files in packages/sdk/src/, working together to create a clean delegation primitive.

Defining the Tool Schema in agent.ts

In packages/sdk/src/agent.ts (lines 78-90), the TaskParams schema defines the contract for child agent creation:

const TaskParams = Type.Object({
  description: Type.Optional(Type.String()),
  prompt:     Type.String({ description: 'Focused instructions for the child agent' }),
  role:       Type.Optional(Type.String({ description: 'Role to use for the child agent' })),
  cwd:        Type.Optional(Type.String({
    description:
      'Working directory for the child agent. AGENTS.md and skills are discovered from here.',
  })),
});

The createTaskTool() function registers this schema under the name task. The tool description automatically includes available roles configured in the harness, ensuring the LLM selects valid role strings when delegating work.

Orchestrating Execution in session.ts

When the LLM invokes the task tool, Flue calls runTask(params, signal), which forwards to runTaskExclusive in packages/sdk/src/session.ts (lines 1010-1090). This function handles the complete lifecycle:

  1. Validation: Checks that the current session can create children and that the maximum task depth hasn't been exceeded.
  2. Session Creation: Generates a unique taskId and calls this.createTaskSession() to build the child environment.
  3. Execution: Invokes child.prompt(text, childOptions) to run the isolated instructions.
  4. Result Collection: Gathers output (text, messageId, role, cwd) and emits a task event to the parent.
  5. Cleanup: Removes the child from activeTasks and releases resources.

The child inherits schema, model, and thinking level configurations from the parent unless explicitly overridden in the tool call.

Building Isolated Environments in harness.ts

The createTaskSession method in packages/sdk/src/harness.ts (lines 31-81) constructs the child's sandboxed environment:

  • Resolves the working directory using createCwdSessionEnv, ensuring relative paths resolve correctly.
  • Discovers local context via discoverSessionContext(taskEnv), which searches the child's cwd for AGENTS.md and skill files.
  • Merges the parent configuration with the discovered local context to produce the child's AgentConfig.
  • Persists the session entry for potential resumption.
  • Returns a new Session instance with the harness's createTaskSession method attached, allowing recursive delegation.

Because each child receives its own SessionEnv rooted at the specified cwd, subsequent tool calls like exec, grep, or glob operate strictly within that directory tree.

Implementing Child Agent Delegation

Basic Usage via SDK

import { init } from '@flue/sdk';

const harness = await init({ name: 'example' });

await harness.run(`
  Use the task tool to list all *.ts files in the "src" folder.
`, {
  tools: [/* task tool is automatically available */],
});

Direct Tool Invocation

When calling via CLI or API, invoke the tool explicitly:

{
  "name": "task",
  "params": {
    "prompt": "Find all TypeScript source files in the \"src\" directory and summarize their purpose.",
    "cwd": "src",
    "role": "code-researcher"
  }
}

The parent receives a structured response:

{
  "content": [
    { "type": "text", "text": "Here is a short summary of each file …" }
  ],
  "details": {
    "taskId": "9a7c3b…",
    "session": "task:example:9a7c3b…",
    "messageId": "msg‑123"
  }
}

Configuring Custom Roles

Define roles in your harness configuration to specialize child agents:

// flue.config.ts
import { defineConfig } from '@flue/sdk/config';

export default defineConfig({
  roles: {
    'code-researcher': {
      systemPrompt: 'You are an expert code researcher...',
      model: 'anthropic/claude-sonnet-4-6',
    },
  },
});

The task tool description automatically lists available roles, enabling the LLM to select "role": "code-researcher" when creating the child session.

Recursive Workflows and Safety Limits

Child agents can themselves invoke the task tool, creating nested delegation chains. Flue tracks recursion depth in metadata.depth and enforces a hard limit via MAX_TASK_DEPTH defined in session.ts.

When exceeding the configured depth, the system throws:


[flue] Maximum task depth (3) exceeded.

This prevents runaway recursion while allowing legitimate multi-level workflows, such as a parent delegating to a researcher that further delegates to a file analyzer.

Abort propagation ensures that if the parent session terminates, all active child tasks receive cancellation signals. The parent maintains a registry of activeTasks, enabling proper lifecycle management across the delegation tree.

Summary

  • The task tool creates isolated child agents with distinct working directories, preventing filesystem contamination in parent sessions.
  • Tool schema resides in packages/sdk/src/agent.ts, execution logic in packages/sdk/src/session.ts, and environment construction in packages/sdk/src/harness.ts.
  • The cwd parameter scopes all child file operations to a specific directory, with AGENTS.md and skills discovered from that location.
  • Recursive delegation is supported up to MAX_TASK_DEPTH, with automatic abort propagation from parent to child sessions.
  • Custom roles configured in the harness can be assigned to children for specialized behavior models.

Frequently Asked Questions

How does the task tool ensure filesystem isolation between parent and child agents?

The child receives its own SessionEnv object created via createCwdSessionEnv in packages/sdk/src/harness.ts. This environment resolves all relative paths against the child's specified cwd, meaning exec, glob, and file read operations access only the child's designated directory tree, completely separate from the parent's working directory.

Can child agents access the parent's conversation history?

No. Each child session is instantiated with a fresh context. While the child inherits the parent's configuration defaults (schema, model, thinking level), it receives only the specific prompt string passed to the tool. The parent may optionally include context in that prompt, but the child does not automatically see previous parent messages or tool results.

What happens if a child agent attempts to delegate work recursively?

The child can invoke the task tool itself, subject to the MAX_TASK_DEPTH limit tracked in session.ts (lines 1010-1090). The depth counter increments with each nesting level, and exceeding the limit throws a maximum depth error. This allows carefully designed multi-tier workflows while preventing infinite delegation loops.

Where does the child agent load its skills and system instructions?

When createTaskSession executes in packages/sdk/src/harness.ts (lines 31-81), it calls discoverSessionContext(taskEnv) targeting the child's cwd. This searches for AGENTS.md files and skill definitions within the child's directory only, producing a local context that overrides or extends the parent's configuration. The child sees only skills relevant to its specific workspace.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →