Gradio Example Click vs Chat Arrow - Code Path Analysis
Status: ANALYZED - NOT A BUG (Same code path, different timing) Priority: N/A (Symptom of upstream repr bug) Analyzed: 2025-12-01 Related: P0_HUGGINGFACE_TOOL_CALLING_BROKEN.md
Symptom Reported
User observed two different outputs when:
- Clicking an Example β Shows progress at 10%, "THINKING" message
- Clicking Chat Arrow β Shows full 5 rounds with repr garbage
User suspected divergent code paths from vestigial Simple Mode deletion.
Analysis: NO DIVERGENT CODE PATHS
Code Trace
Both Example Click and Chat Arrow use the exact same code path:
User Action (Example OR Chat Arrow)
β
app.py:research_agent() β SAME FUNCTION
β
app.py:configure_orchestrator() β SAME FUNCTION (mode="advanced" always)
β
factory.py:create_orchestrator() β SAME FUNCTION
β
factory.py:_determine_mode() β ALWAYS returns "advanced"
β
AdvancedOrchestrator β SAME CLASS
β
clients/factory.py:get_chat_client() β SAME FUNCTION
β
HuggingFaceChatClient (no API key) OR OpenAIChatClient (with API key)
Evidence from Code
app.py:279-325 - ChatInterface Setup:
demo = gr.ChatInterface(
fn=research_agent, # β SAME FUNCTION FOR BOTH
examples=[
["What drugs improve female libido post-menopause?", "sexual_health", None, None],
# ...
],
# ...
)
factory.py:76-90 - Mode Determination:
def _determine_mode(explicit_mode: str | None) -> str:
if explicit_mode == "hierarchical":
return "hierarchical"
# "simple" is deprecated -> upgrade to "advanced"
# "magentic" is alias for "advanced"
return "advanced" # β ALWAYS ADVANCED
Explanation of Visual Difference
The difference the user observed is timing, not code paths:
| Screenshot | When Captured | Content |
|---|---|---|
| Example Click | Mid-execution | Progress bar at 10%, "THINKING" |
| Chat Arrow | After completion | Full 5 rounds with repr garbage |
Both show the same process at different stages.
The repr garbage (<agent_framework._types.ChatMessage object at 0x...>) appears in BOTH:
- Example Click: Would show repr garbage if captured after completion
- Chat Arrow: Shows repr garbage because it was captured after completion
The Real Bug: Upstream repr Issue
The repr garbage is the upstream Microsoft Agent Framework bug documented in:
docs/bugs/P0_HUGGINGFACE_TOOL_CALLING_BROKEN.md
Root cause in upstream code:
# agent_framework/_workflows/_magentic.py line ~1799
text = last.text or str(last) # BUG: str(last) gives repr for tool-only messages
Our workaround in advanced.py:
def _extract_text(self, message: Any) -> str:
# Filter out repr strings
if isinstance(message, str) and message.startswith("<") and "object at" in message:
return ""
# ...
Verification
- No vestigial Simple Mode code -
simple.pyis deleted, not imported anywhere - Factory always returns AdvancedOrchestrator - verified in
factory.py:66-73 - Same research_agent function - Gradio routes both Example and Chat Arrow through it
Conclusion
There are NO divergent code paths. The unified architecture is correctly implemented:
| Component | Status |
|---|---|
| Simple Mode | β DELETED (no vestigial code) |
| Factory Pattern | β Always returns AdvancedOrchestrator |
| Chat Client Factory | β Auto-selects HuggingFace (free) or OpenAI (paid) |
| Example Click | β
Uses same research_agent() function |
| Chat Arrow Click | β
Uses same research_agent() function |
The only bug is the upstream repr display issue, which affects BOTH paths equally.
Next Steps
- Wait for upstream fix - PR #2566
- Once merged:
uv add agent-framework@latest - Test: Verify both Example Click and Chat Arrow work identically
References
src/app.py- Line 134-247 (research_agent())src/app.py- Line 279-325 (ChatInterface with examples)src/orchestrators/factory.py- Line 43-73 (create_orchestrator())src/clients/factory.py- Line 15-76 (get_chat_client())docs/bugs/P0_HUGGINGFACE_TOOL_CALLING_BROKEN.md- Upstream repr bug details