Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[FEAT] Early Termination for SubAgent Workflows (bail/done)Β #680

@douglac

Description

@douglac

Is your feature request related to a problem? Please describe.

🎯 Feature Request: Early Termination for SubAgent Workflows

Problem Statement

Currently, when using the supervisor/subagent pattern in VoltAgent, the workflow always returns to the supervisor after a subagent completes, even when the subagent's output is final and requires no further processing.

Current Flow:


User β†’ Supervisor β†’ SubAgent (generates final output) β†’ Supervisor (processes output) β†’ User

↑

Unnecessary token usage (~2K tokens)

This causes significant token waste when a specialized subagent generates a complete, final result (like a JSON structure, report, or formatted document) that doesn't need any supervisor processing.

Proposed Solution

Implement a bail() or done() method (similar to Mastra's bail()) that allows a subagent or tool to terminate the workflow early and return a result directly to the user.

Desired Flow:


User β†’ Supervisor β†’ SubAgent β†’ [bail(result)] β†’ User βœ…

Use Case Example

I'm building a workout planning system where:

  1. Supervisor orchestrates the flow
  2. Exercise List Agent fetches exercises
  3. Workout Builder Agent generates complete JSON (~2K tokens)
  4. Problem: Supervisor receives the 2K token JSON just to "pass it through"

Token Impact:

  • Current: ~2,650 tokens per request
  • With bail(): ~560 tokens per request
  • Savings: 79% (~2,000 tokens / ~$0.020 per request)

API Design Suggestion

Option A: Tool-level bail (in execute function)

const buildWorkoutTool = createTool({
  name: 'build_workout',
  execute: async (args, context) => {
    const result = generateFinalOutput(args);
    
    // Early terminate - skip supervisor processing
    return context.bail(result);
  }
});

Option B: Agent-level done method

const workoutBuilderAgent = new Agent({
  name: 'Workout Builder',
  tools: [buildWorkoutTool],
  onComplete: (result) => {
    // Signal this is the final result
    return { done: true, result };
  }
});

Option C: Supervisor config to skip processing

const supervisorAgent = new Agent({
  subAgents: [workoutBuilder],
  supervisorConfig: {
    skipProcessingFor: ['Workout Builder'], // Don't process these agents' results
  }
});

Expected Benefits

  1. Token Efficiency: 70-90% reduction in scenarios with large final outputs
  2. Cost Savings: Proportional to token reduction
  3. Performance: Faster response times (skip LLM processing step)
  4. Control: Explicit flow termination when appropriate

Similar Implementation in Mastra

Mastra implements this via bail() in workflow steps:

const step = createStep({
  execute: async ({ bail }) => {
    const finalResult = generateOutput();
    return bail({ result: finalResult }); // Ends workflow here
  }
});

Reference: https://mastra.ai/en/docs/workflows/error-handling#exiting-early-with-bail

Alternative Workarounds Considered

  1. βœ… AbortController (current): Can abort but throws error, not ideal for success cases
  2. ⚠️ Direct agent calls: Loses supervisor orchestration benefits
  3. ⚠️ Workflows instead of subagents: Different architecture, more complex migration

Community Interest

This pattern is common in AI systems where:

  • A supervisor orchestrates multi-step processes
  • Specialized agents generate final outputs (JSON, reports, structured data)
  • No additional processing is needed after generation
  • The supervisor's role is purely orchestration, not post-processing

I believe this would benefit many VoltAgent users building similar workflows.

Willingness to Contribute

I'm happy to:

  • Test beta implementations
  • Provide real-world usage feedback
  • Help with documentation
  • Contribute to implementation (if guidance provided)

Related:

Describe alternatives you've considered

No response

Additional context

No response

Describe the thing to improve

Problem

When using supervisor/subagent pattern, subagents ALWAYS return to the supervisor for processing, even when they generate final outputs (like JSON structures or reports) that need no additional handling. This causes unnecessary token consumption.

Current behavior:

Supervisor β†’ SubAgent (generates 2K token JSON) β†’ Supervisor (processes JSON) β†’ User
↑ Wastes ~2K tokens

Desired behavior:

Supervisor β†’ SubAgent β†’ bail(result) β†’ User βœ…

Benefits:

  • 70-90% token reduction for workflows with large final outputs
  • Proportional cost savings
  • Faster response times (skip unnecessary LLM step)
  • Explicit control over flow termination

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions