E40B Fix: Streaming output not working in agentic-flow CLI - only shows text messages, not tool calls · Issue #40 · ruvnet/agentic-flow · GitHub
[go: up one dir, main page]

Skip to content

Fix: Streaming output not working in agentic-flow CLI - only shows text messages, not tool calls #40

@ruvnet

Description

@ruvnet

Streaming Output Not Working in agentic-flow CLI

Summary

The --stream flag in agentic-flow CLI does not produce real-time output during agent execution. The agent runs successfully and generates reports, but provides no progress indication beyond the initial "⏳ Running..." message until completion.

Environment

  • agentic-flow version: 1.8.10
  • Node.js version: 22.17.0
  • Platform: Linux (Ubuntu/Debian in container)
  • Execution context: E2B sandbox / containerized environment

Expected Behavior

When running an agent with streaming enabled (default behavior unless --no-stream is specified), the CLI should output:

  • Real-time progress updates from the agent
  • Tool calls being made (MCP tool execution)
  • Intermediate reasoning steps
  • Status updates during long-running operations

Actual Behavior

The CLI outputs initial configuration and setup messages, then shows:

⏳ Running...

And produces no further output until the agent completes (which can take 5-60 minutes). All output is buffered and displayed only after completion.

Reproduction Steps

  1. Run any agentic-flow agent with a task that takes >30 seconds:
npx agentic-flow@latest \
  --agent sign-code-researcher \
  --task "123 Main St, Los Angeles, CA 90012" \
  --provider anthropic \
  --model claude-sonnet-4-20250514 \
  --stream
  1. Observe that after the initial setup output, the CLI shows only "⏳ Running..." with no further progress

  2. Wait for agent completion (5-60 minutes depending on task)

  3. All agent output appears at once after completion

Root Cause Analysis

After investigating the code in agentic-flow/src/agents/claudeAgent.ts and agentic-flow/src/index.ts, I found that:

Current Implementation (Lines 274-282 in claudeAgent.ts):

let output = '';
for await (const msg of result) {
  if (msg.type === 'assistant') {
    const chunk = msg.message.content?.map((c: any) => c.type === 'text' ? c.text : '').join('') || '';
    output += chunk;

    if (onStream && chunk) {
      onStream(chunk);
    }
  }
}

Problems Identified:

  1. Only streams text messages: The current implementation only handles msg.type === 'assistant' with text content
  2. Ignores tool calls: Tool use events (msg.type === 'tool_use', msg.type === 'tool_result') are not logged
  3. No progress indicators: No intermediate status updates during long-running operations
  4. Buffered stderr: Progress messages go to stdout along with output, not stderr
  5. No flush calls: No explicit process.stdout.uncork() to force immediate output

Impact

High Impact - This affects:

  • User Experience: Users have no visibility into long-running agents (5-60 minute tasks appear frozen)
  • Debugging: Cannot see where agent gets stuck or what tools are failing
  • Production Monitoring: Cannot track agent progress in real-time
  • E2B Sandboxes: Cloud execution environments need progress for timeout management
  • Cost Monitoring: Cannot see token usage in real-time

Proposed Solution

1. Enhanced Message Handling in claudeAgent.ts

Replace the current streaming implementation (lines 274-282) with:

let output = '';
let toolCallCount = 0;

for await (const msg of result) {
  // Handle assistant text messages
  if (msg.type === 'assistant') {
    const chunk = msg.message.content?.map((c: any) => c.type === 'text' ? c.text : '').join('') || '';
    output += chunk;

    if (onStream && chunk) {
      onStream(chunk);
    }
  }
  
  // Handle tool use (when agent calls a tool)
  if (msg.type === 'tool_use') {
    toolCallCount++;
    const toolName = msg.tool_name || 'unknown';
    const toolInput = JSON.stringify(msg.input || {}, null, 2).substring(0, 200);
    
    const progressMsg = `\n[${new Date().toISOString().split('T')[1].split('.')[0]}] 🔍 Tool call #${toolCallCount}: ${toolName}\n`;
    process.stderr.write(progressMsg);
    
    if (onStream) {
      onStream(progressMsg);
    }
    
    // Log tool input for debugging (truncated)
    if (toolInput && process.env.VERBOSE === 'true') {
      process.stderr.write(`   Input: ${toolInput}...\n`);
    }
  }
  
  // Handle tool results (when tool execution completes)
  if (msg.type === 'tool_result') {
    const resultMsg = `[${new Date().toISOString().split('T')[1].split('.')[0]}] ✅ Tool completed\n`;
    process.stderr.write(resultMsg);
    
    if (onStream) {
      onStream(resultMsg);
    }
  }
  
  // Handle errors
  if (msg.type === 'error') {
    const errorMsg = `\n[${new Date().toISOString().split('T')[1].split('.')[0]}] ❌ Error: ${msg.error?.message || 'Unknown error'}\n`;
    process.stderr.write(errorMsg);
    
    if (onStream) {
      onStream(errorMsg);
    }
  }
  
  // Flush output to ensure immediate visibility
  process.stderr.uncork();
  process.stdout.uncork();
}

2. Add Progress Logging in index.ts

Update the runAgentMode function (line 65) to provide better progress indicators:

// Enhanced stream handler that writes to stderr for progress
const streamHandler = stream ? (chunk: string) => {
  // Write text content to stdout
  if (!chunk.startsWith('[') && !chunk.includes('🔍') && !chunk.includes('✅')) {
    process.stdout.write(chunk);
  } else {
    // Write progress indicators to stderr
    process.stderr.write(chunk);
  }
  
  // Force flush
  process.stdout.uncork();
  process.stderr.uncork();
} : undefined;

Expected Output After Fix

🚀 Starting Optimized Researcher Agent
Agent: sign-code-researcher
⏳ Running...

[16:40:15] 🔍 Tool call #1: mcp__gemini-search__search
[16:40:19] ✅ Tool completed
[16:40:20] 🔍 Tool call #2: mcp__gemini-search__search
[16:40:24] ✅ Tool completed
[16:40:25] 🤖 Analyzing regulations...
[16:40:45] 🔍 Tool call #3: Write
[16:40:46] ✅ Tool completed
[16:40:46] 📊 Progress: Report generation complete
[16:40:46] ✅ Analysis complete
📊 Generated report: 277 lines
📊 Grounding score: 94%

Testing Plan

  1. Unit Tests: Add tests for streaming message handlers
  2. Integration Tests: Test with long-running agent tasks (5+ minutes)
  3. E2B Sandbox Tests: Verify streaming works in containerized environments
  4. Performance: Ensure streaming doesn't significantly impact performance

Additional Notes

  • Use process.stderr for progress indicators to keep stdout clean for output capture
  • Add timestamps to all progress messages for debugging
  • Ensure process.stdout.uncork() and process.stderr.uncork() are called to force immediate output
  • Consider adding a --quiet flag to suppress progress messages if needed

Priority

High - This significantly impacts usability and production monitoring capabilities.


Files to modify:

  • agentic-flow/src/agents/claudeAgent.ts (lines 274-282)
  • agentic-flow/src/index.ts (lines 65-107)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0