Skip to content

[Bug] Specialist-to-Specialist Handoff Fails to Pass Context (Missing Default Input Filter Logic) #112

@cyjme

Description

@cyjme

Description

I have identified a bug in the Agent.stream method where context (specifically tool results from the previous agent) is not passed when handing off from one specialist agent to another, unless a custom inputFilter is explicitly configured.

This behavior is inconsistent with the orchestrator-to-specialist handoff, which correctly applies a default input filter to transfer relevant context (like tool outputs) to the next agent.

Root Cause

In packages/agents/src/agent.ts, specifically within the logic handling specialist-to-specialist handoffs, the code checks if configuredHandoff.config.inputFilter exists. However, it lacks an else block to handle the default case.

As a result, if a user does not provide a custom inputFilter, the code simply skips context processing, and the target agent receives the conversation history without the critical tool results generated by the previous agent.

Code Location

File: packages/agents/src/agent.ts

Current Implementation (Pseudocode):

// Inside Agent.stream loop
if (configuredHandoff?.config?.inputFilter) {
    // Applies custom filter
    const filteredData = configuredHandoff.config.inputFilter(handoffInputData);
    // ... updates conversationMessages ...
}
// <--- MISSING ELSE BLOCK HERE: No fallback to default filter!

Proposed Fix

Add an else block to apply createDefaultInputFilter when no custom filter is configured. This ensures that toolResults are correctly extracted and injected into the conversation history for the next agent, maintaining continuity.

Suggested Change:

if (configuredHandoff?.config?.inputFilter) {
    // ... existing custom filter logic ...
} else {
    // FIX: Apply default filter if no custom one is provided
    const defaultFilter = createDefaultInputFilter();
    
    // Construct input data using the captured toolResults
    const handoffInputData: HandoffInputData = {
        inputHistory: conversationMessages,
        preHandoffItems: [],
        newItems: Array.from(toolResults.entries()).map(([name, result]) => ({
            toolName: name,
            result: result
        })),
        runContext
    };

    const filteredData = defaultFilter(handoffInputData);
    conversationMessages.length = 0;
    conversationMessages.push(...filteredData.inputHistory);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions