-
Notifications
You must be signed in to change notification settings - Fork 124
Description
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
- 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-
Observe that after the initial setup output, the CLI shows only "⏳ Running..." with no further progress
-
Wait for agent completion (5-60 minutes depending on task)
-
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:
- Only streams text messages: The current implementation only handles
msg.type === 'assistant'with text content - Ignores tool calls: Tool use events (
msg.type === 'tool_use',msg.type === 'tool_result') are not logged - No progress indicators: No intermediate status updates during long-running operations
- Buffered stderr: Progress messages go to stdout along with output, not stderr
- 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
- Unit Tests: Add tests for streaming message handlers
- Integration Tests: Test with long-running agent tasks (5+ minutes)
- E2B Sandbox Tests: Verify streaming works in containerized environments
- Performance: Ensure streaming doesn't significantly impact performance
Additional Notes
- Use
process.stderrfor progress indicators to keepstdoutclean for output capture - Add timestamps to all progress messages for debugging
- Ensure
process.stdout.uncork()andprocess.stderr.uncork()are called to force immediate output - Consider adding a
--quietflag 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)