Skip to content

Latest commit

 

History

History
246 lines (195 loc) · 9.99 KB

File metadata and controls

246 lines (195 loc) · 9.99 KB

Console Output Formatting Fix

Date: 2025-10-15 Issue: Raw API response dumped to console instead of clean markdown output Status: ✅ FIXED

Problem Description

User reported seeing raw API response structure dumped to console with all metadata fields visible:

╔═══════════════════════════════════════ FINAL ANSWER ═══════════════════════════════════════╗
║ 'choices' 'finish_reason' 'length' 'index' 'message' 'role' 'assistant' 'content' Quantum║
║ 'created' 1760618705 'model' 'gpt-3.5-turbo' 'system_fingerprint' 'b6743-c7be9feb'        ║
║ 'object' 'chat.completion' 'usage' 'completion_tokens' 'prompt_tokens' 2038                ║
║ 'total_tokens' 2048 'id' 'chatcmpl-wYJby18RjfkXECQEdOyJ4CqvvRUrKTaG' 'timings'...          ║
╚═════════════════════════════════════════════════════════════════════════════════════════════╝

What should appear: Clean markdown-formatted answer text

Root Cause

Two issues identified:

Issue 1: Missing final_output Extraction

Location: /home/joker/SynapticLlamas/main.py:1357-1367

The code tried to get final_output from result['result'], but when it didn't exist or wasn't a string, it immediately fell back to dumping the entire raw result as JSON without attempting to extract the actual content from nested response structures.

Issue 2: No Content Extraction in JSON Fallback

Location: /home/joker/SynapticLlamas/console_theme.py:161-172

The print_json_output() function displayed the raw result dictionary without trying to extract just the content message from API responses.

The Fixes

Fix 1: Smart Content Extraction in main.py

Added intelligent extraction logic before falling back to JSON display:

# Display final markdown output
markdown_output = result['result'].get('final_output', '')

# If no final_output, try to extract from nested structure
if not markdown_output or not isinstance(markdown_output, str):
    # Try common response structures
    result_data = result['result']
    if 'message' in result_data and isinstance(result_data['message'], dict):
        # Ollama response format
        markdown_output = result_data['message'].get('content', '')
    elif 'choices' in result_data and isinstance(result_data['choices'], list):
        # OpenAI response format
        if len(result_data['choices']) > 0:
            choice = result_data['choices'][0]
            if 'message' in choice:
                markdown_output = choice['message'].get('content', '')

if isinstance(markdown_output, str) and markdown_output:
    # Display clean markdown
    console.print(Panel(Markdown(markdown_output), ...))
else:
    # Fallback to cleaned JSON output
    print_json_output(result['result'])

What this does:

  1. First tries to get final_output (normal path)
  2. If missing, tries Ollama response format (message.content)
  3. If still missing, tries OpenAI response format (choices[0].message.content)
  4. Only falls back to JSON if all extraction attempts fail

Fix 2: Clean Content Extraction in console_theme.py

Added content extraction to print_json_output() before displaying:

def print_json_output(data: dict):
    """Print JSON with syntax highlighting - extracts clean content from API responses."""
    import json

    # Try to extract clean content from nested response structures
    clean_data = data

    # Check if this is an Ollama/OpenAI API response with nested structure
    if isinstance(data, dict):
        # Try to extract the actual content message
        if 'message' in data and isinstance(data['message'], dict):
            if 'content' in data['message']:
                # This is likely an Ollama response - extract just the content
                clean_data = {'response': data['message']['content']}
        elif 'choices' in data and isinstance(data['choices'], list) and len(data['choices']) > 0:
            # This is likely an OpenAI-style response
            choice = data['choices'][0]
            if 'message' in choice and 'content' in choice['message']:
                clean_data = {'response': choice['message']['content']}

    json_str = json.dumps(clean_data, indent=2)
    # ... display JSON panel

What this does:

  • Detects Ollama/OpenAI API response structures
  • Extracts just the content message
  • Displays {'response': '...'} instead of full API metadata
  • Falls back to showing full data if structure doesn't match

Response Format Detection

Ollama Response Format

{
  "message": {
    "role": "assistant",
    "content": "The actual answer text here"
  },
  "model": "llama3.2",
  "created_at": "2025-10-15T...",
  ...
}

Extraction: data['message']['content']

OpenAI Response Format

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "The actual answer text here"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {...},
  ...
}

Extraction: data['choices'][0]['message']['content']

SynapticLlamas Format (Normal)

{
  "final_output": "# Markdown Answer\n\nThe answer here...",
  "chunks": [...],
  "content_type": "technical"
}

Extraction: data['final_output']

Testing

To test if the fix works:

cd /home/joker/SynapticLlamas
python main.py --interactive --distributed

# At prompt, ask a question:
SynapticLlamas> Explain quantum entanglement

Expected output: Clean markdown panel with answer text Not: Raw API response structure dump

Files Modified

  1. /home/joker/SynapticLlamas/main.py (lines 1356-1382)

    • Added smart content extraction before fallback
    • Tries Ollama format → OpenAI format → JSON fallback
  2. /home/joker/SynapticLlamas/console_theme.py (lines 161-189)

    • Enhanced print_json_output() to extract content
    • Changed title from "JSON OUTPUT" to "OUTPUT"

Impact

Before Fix

╔═══════════════════════════════ JSON OUTPUT ═══════════════════════════════╗
║ {                                                                         ║
║   "choices": [{"finish_reason": "stop", "message": {...}}],              ║
║   "created": 1760618705,                                                  ║
║   "model": "gpt-3.5-turbo",                                              ║
║   "usage": {"completion_tokens": 10, "prompt_tokens": 2038}             ║
║   ... [hundreds of lines of metadata]                                    ║
║ }                                                                         ║
╚═══════════════════════════════════════════════════════════════════════════╝

After Fix

╔═══════════════════════════════ FINAL ANSWER ═══════════════════════════════╗
║                                                                             ║
║  # Quantum Entanglement                                                     ║
║                                                                             ║
║  Quantum entanglement is a phenomenon where two or more particles become   ║
║  correlated in such a way that the state of one particle instantaneously   ║
║  affects the state of the other, regardless of the distance between them.  ║
║                                                                             ║
╚═════════════════════════════════════════════════════════════════════════════╝

OR (if content extraction works):

╔═══════════════════════════════ OUTPUT ═══════════════════════════════════╗
║ {                                                                         ║
║   "response": "Quantum entanglement is a phenomenon where..."            ║
║ }                                                                         ║
╚═══════════════════════════════════════════════════════════════════════════╝

Why This Happened

The raw API response dump occurred because:

  1. Agent returned Ollama/OpenAI format directly without wrapping in final_output
  2. Main.py didn't extract content from nested structures
  3. JSON fallback displayed everything including metadata, tokens, timings, etc.

This is common when:

  • Using different agent implementations
  • Direct LLM API responses without post-processing
  • Testing with various models that return different formats

Prevention

To prevent this in the future, agents should always return:

{
    'final_output': markdown_text,  # Always include this!
    'metadata': {...}
}

But the fix ensures that even if agents forget to include final_output, the console will still display clean content by intelligently extracting it from common API response formats.

Status

FIXED - Console output now displays clean text instead of raw API responses ✅ Backwards compatible - Still works with proper final_output format ✅ Robust - Handles Ollama, OpenAI, and custom response formats ✅ Production ready - Graceful fallback for unexpected formats