ConnectOnionConnectOnion

xray.trace()

Visual execution tracing for ConnectOnion agents. See exactly what happened during agent execution with timing, inputs, outputs, and errors.

Key Features

Visual Flow

See all tool calls in sequence

Performance

Execution timing for each step

Smart Display

Intelligent data truncation

Error Tracking

Clear error display and details

Progressive Examples

Learn xray.trace() from simple to advanced with these progressive examples. Each builds on the previous concepts.

1

1. Simple Single Tool

Minimal example with one tool call

Python Code
1from connectonion import Agent, xray
2
3@xray
4def greet(name: str) -> str:
5    """Simple greeting function."""
6    return f"Hello, {name}!"
7
8# Create agent
9agent = Agent("greeter", tools=[greet])
10result = agent.input("Say hello to Alice")
11
12# View execution trace
13xray.trace(agent)
Trace Output
Task: "Say hello to Alice" [1] 12ms greet(name="Alice") IN name: "Alice" OUT "Hello, Alice!" Total: 12ms 1 step 1 iteration
2

2. Multiple Tool Chain

Agent uses multiple tools in sequence

Python Code
1from connectonion import Agent, xray
2
3@xray
4def analyze_text(text: str) -> dict:
5    """Analyze text and return metrics."""
6    return {
7        'word_count': len(text.split()),
8        'char_count': len(text),
9        'sentiment': 'neutral'
10    }
11
12@xray
13def generate_summary(text: str, max_words: int = 10) -> str:
14    """Generate a summary of the text."""
15    words = text.split()[:max_words]
16    return f"Summary: {' '.join(words)}..."
17
18# Create and run agent
19agent = Agent(
20    name="text_processor",
21    tools=[analyze_text, generate_summary]
22)
23
24result = agent.input("Analyze this sample text and create a summary")
25
26# View the execution trace
27xray.trace(agent)
Trace Output
Task: "Analyze this sample text and create a summary" [1] 45ms analyze_text(text="Analyze this sample text and create a summary") IN text: "Analyze this sample text and create a summary" OUT {'word_count': 11, 'char_count': 51, 'sentiment': 'neutral'} [2] 23ms generate_summary(text="Analyze this sample text and create a summary", max_words=10) IN text: "Analyze this sample text and create a summary" IN max_words: 10 OUT "Summary: Analyze this sample text and create..." Total: 68ms 2 steps 1 iteration
3

3. Error Handling & Recovery

How trace displays errors and agent recovery

Python Code
1from connectonion import Agent, xray
2
3@xray
4def validate_email(email: str) -> dict:
5    """Validate email format."""
6    if '@' not in email:
7        raise ValueError("Invalid email: missing @ symbol")
8    parts = email.split('@')
9    if len(parts) != 2 or not parts[0] or not parts[1]:
10        raise ValueError("Invalid email format")
11    return {"email": email, "valid": True}
12
13@xray
14def send_notification(email_data: dict) -> str:
15    """Send notification to validated email."""
16    if not email_data.get("valid"):
17        return "❌ Cannot send to invalid email"
18    return f"✅ Notification sent to {email_data['email']}"
19
20@xray
21def fallback_contact(message: str) -> str:
22    """Fallback contact method when email fails."""
23    return f"📞 Fallback: {message} (via phone/SMS)"
24
25# Create agent
26agent = Agent(
27    name="notification_agent",
28    tools=[validate_email, send_notification, fallback_contact]
29)
30
31result = agent.input("Send notification to user at bad-email-format")
32
33# View trace showing error handling
34xray.trace(agent)
Trace Output
Task: "Send notification to user at bad-email-format" [1] ERROR validate_email(email="bad-email-format") IN email: "bad-email-format" ERR ValueError: Invalid email: missing @ symbol [2] 18ms fallback_contact(message="Send notification to user at bad-email-format") IN message: "Send notification to user at bad-email-format" OUT "📞 Fallback: Send notification to user at bad-email-format (via phone/SMS)" Total: 18ms 2 steps 1 iteration 1 error
4

4. Performance Bottleneck Analysis

Identify slow operations and optimization opportunities

Python Code
1from connectonion import Agent, xray
2import time
3import random
4
5@xray
6def fetch_user_data(user_id: str) -> dict:
7    """Fast database lookup."""
8    time.sleep(0.05)  # 50ms DB query
9    return {"user_id": user_id, "name": "John Doe", "tier": "premium"}
10
11@xray
12def complex_calculation(data: dict) -> dict:
13    """CPU intensive calculation."""
14    time.sleep(1.2)  # 1.2s processing
15    score = random.randint(750, 850)
16    return {"score": score, "calculation_time": "1.2s", "tier": data["tier"]}
17
18@xray
19def external_api_call(user_data: dict, score_data: dict) -> dict:
20    """Slow external API call."""
21    time.sleep(0.8)  # 800ms network call
22    return {
23        "recommendation": f"Premium package for {user_data['name']}",
24        "api_response_time": "800ms",
25        "confidence": 0.95
26    }
27
28@xray
29def format_response(user_data: dict, score_data: dict, recommendation: dict) -> str:
30    """Fast formatting step."""
31    time.sleep(0.01)  # 10ms formatting
32    return f"""
33    🎯 Analysis Complete:
34    User: {user_data['name']} (ID: {user_data['user_id']})
35    Score: {score_data['score']} ({score_data['tier']} tier)
36    Recommendation: {recommendation['recommendation']}
37    Confidence: {recommendation['confidence']*100:.0f}%
38    """
39
40# Create agent
41agent = Agent(
42    name="analytics_engine",
43    tools=[fetch_user_data, complex_calculation, external_api_call, format_response]
44)
45
46result = agent.input("Generate analytics report for user ID 12345")
47
48# Analyze performance bottlenecks
49xray.trace(agent)
Trace Output
Task: "Generate analytics report for user ID 12345" [1] 52ms fetch_user_data(user_id="12345") IN user_id: "12345" OUT {"user_id": "12345", "name": "John Doe", "tier": "premium"} [2] 1.2s complex_calculation(data={...}) ⚠️ SLOW IN data: {"user_id": "12345", "name": "John Doe", "tier": "premium"} OUT {"score": 823, "calculation_time": "1.2s", "tier": "premium"} [3] 803ms external_api_call(user_data={...}, score_data={...}) ⚠️ SLOW IN user_data: {"user_id": "12345", "name": "John Doe", "tier": "premium"} IN score_data: {"score": 823, "calculation_time": "1.2s", "tier": "premium"} OUT {"recommendation": "Premium package for John Doe", "api_response_time": "800ms", "confidence": 0.95} [4] 11ms format_response(user_data={...}, score_data={...}, recommendation={...}) IN user_data: {"user_id": "12345", "name": "John Doe", "tier": "premium"} IN score_data: {"score": 823, "calculation_time": "1.2s", "tier": "premium"} IN recommendation: {"recommendation": "Premium package for John Doe", ... (2 more)} OUT "🎯 Analysis Complete:\nUser: John Doe (ID: 12345)\nScore: 823 (premium tier)..." Total: 2.07s 4 steps 1 iteration ⚠️ ⚠️ Performance Issues Detected: Step 2: complex_calculation (1.2s) - Consider caching or async processing Step 3: external_api_call (803ms) - Implement timeout/retry logic
5

5. IDE Breakpoint Debugging

Advanced debugging with IDE breakpoints and live context inspection

Python Code
1from connectonion import Agent, xray
2
3@xray
4def process_order(order_data: dict) -> dict:
5    """Process customer order with validation."""
6    # 🔴 SET BREAKPOINT HERE - Debug order validation
7    # In IDE debugger console:
8    # >>> xray.trace()  # See current execution state
9    # >>> xray.agent.name  # Current agent name
10    # >>> xray.task  # Original user request
11    # >>> order_data  # Inspect current parameters
12    
13    if not order_data.get("items"):
14        return {"error": "No items in order", "status": "failed"}
15    
16    # Calculate totals
17    total = sum(item.get("price", 0) * item.get("qty", 1) 
18                for item in order_data["items"])
19    
20    # 🔴 BREAKPOINT OPPORTUNITY - Check calculations
21    # >>> xray.trace()  # Updated trace
22    # >>> total  # Inspect calculated total
23    
24    return {
25        "order_id": f"ORD-{hash(str(order_data)) % 10000:04d}",
26        "total": total,
27        "status": "validated",
28        "items_count": len(order_data["items"])
29    }
30
31@xray
32def apply_discounts(validated_order: dict) -> dict:
33    """Apply business rules and discounts."""
34    # 🔴 BREAKPOINT - Discount logic debugging
35    # >>> xray.trace()  # See previous tool results
36    # >>> validated_order  # Inspect order from previous step
37    
38    if validated_order.get("error"):
39        return validated_order  # Pass through errors
40    
41    total = validated_order["total"]
42    discount = 0
43    
44    # Business rules
45    if total > 100:
46        discount = total * 0.1  # 10% discount for orders > $100
47    if validated_order["items_count"] >= 5:
48        discount = max(discount, total * 0.15)  # 15% for bulk orders
49    
50    # 🔴 BREAKPOINT - Final calculations
51    # >>> discount  # Check discount amount
52    # >>> xray.trace()  # See full execution flow
53    
54    final_total = total - discount
55    
56    return {
57        **validated_order,
58        "original_total": total,
59        "discount": discount,
60        "final_total": final_total,
61        "discount_percent": (discount / total * 100) if total > 0 else 0
62    }
63
64@xray
65def generate_invoice(order: dict) -> str:
66    """Generate final invoice."""
67    # 🔴 FINAL BREAKPOINT - Invoice generation
68    # >>> xray.trace()  # Complete execution trace
69    # >>> order  # Final order data
70    
71    if order.get("error"):
72        return f"❌ Order failed: {order['error']}"
73    
74    return f"""
75    🧾 INVOICE #{order['order_id']}
76    ═══════════════════════════
77    Items: {order['items_count']}
78    Subtotal: ${order['original_total']:.2f}
79    Discount ({order['discount_percent']:.1f}%): -${order['discount']:.2f}
80    ───────────────────────────
81    TOTAL: ${order['final_total']:.2f}
82    """
83
84# Create agent for step-by-step debugging
85agent = Agent(
86    name="order_processor",
87    tools=[process_order, apply_discounts, generate_invoice]
88)
89
90# Complex order to debug
91order_data = {
92    "customer": "Alice Smith",
93    "items": [
94        {"name": "Laptop", "price": 899.99, "qty": 1},
95        {"name": "Mouse", "price": 29.99, "qty": 2},
96        {"name": "Keyboard", "price": 79.99, "qty": 1},
97        {"name": "Monitor", "price": 299.99, "qty": 2},
98        {"name": "Cables", "price": 15.99, "qty": 3}
99    ]
100}
101
102# Run with IDE breakpoints set at marked locations
103result = agent.input(f"Process this order: {order_data}")
104
105# Final comprehensive trace
106xray.trace(agent)
Trace Output
💻 IDE Debugging Session - Order Processing: 🔴 Breakpoint 1: process_order() - Line 8 >>> xray.trace() Task: "Process this order: {'customer': 'Alice Smith', 'items': [...]}" [Starting] process_order(order_data={...}) IN order_data: {"customer": "Alice Smith", "items": [...] (5 items)} Context: agent='order_processor', iteration=1 Variables: order_data={'customer': 'Alice Smith', 'items': [5 items]} 🔴 Breakpoint 2: process_order() - Line 20 >>> total 1385.93 >>> xray.trace() [1] process_order(order_data={...}) [IN PROGRESS] IN order_data: {"customer": "Alice Smith", "items": [...] (5 items)} Progress: Calculated total=1385.93, processing... 🔴 Breakpoint 3: apply_discounts() - Line 35 >>> validated_order {'order_id': 'ORD-3847', 'total': 1385.93, 'status': 'validated', 'items_count': 5} >>> xray.trace() [1] 156ms process_order(order_data={...}) IN order_data: {"customer": "Alice Smith", "items": [...] (5 items)} OUT {"order_id": "ORD-3847", "total": 1385.93, "status": "validated", "items_count": 5} [2] apply_discounts(validated_order={...}) [IN PROGRESS] IN validated_order: {"order_id": "ORD-3847", "total": 1385.93, ... (3 more)} 🔴 Breakpoint 4: apply_discounts() - Line 47 >>> discount 207.89 >>> xray.trace() [1] 156ms process_order(order_data={...}) OUT {"order_id": "ORD-3847", "total": 1385.93, "status": "validated", "items_count": 5} [2] apply_discounts(validated_order={...}) [IN PROGRESS] Progress: Applied 15% bulk discount (5+ items), discount=207.89 🔴 Breakpoint 5: generate_invoice() - Line 60 >>> order {'order_id': 'ORD-3847', 'original_total': 1385.93, 'discount': 207.89, 'final_total': 1178.04, 'discount_percent': 15.0} >>> xray.trace() [1] 156ms process_order(order_data={...}) OUT {"order_id": "ORD-3847", "total": 1385.93, "status": "validated", "items_count": 5} [2] 89ms apply_discounts(validated_order={...}) OUT {"order_id": "ORD-3847", "original_total": 1385.93, "discount": 207.89, "final_total": 1178.04, "discount_percent": 15.0, ... (4 more)} [3] generate_invoice(order={...}) [IN PROGRESS] IN order: {"order_id": "ORD-3847", "original_total": 1385.93, ... (6 more)} 🎯 Final Complete Trace: [1] 156ms process_order(order_data={...}) IN order_data: {"customer": "Alice Smith", "items": [...] (5 items)} OUT {"order_id": "ORD-3847", "total": 1385.93, "status": "validated", "items_count": 5} [2] 89ms apply_discounts(validated_order={...}) IN validated_order: {"order_id": "ORD-3847", "total": 1385.93, ... (3 more)} OUT {"order_id": "ORD-3847", "original_total": 1385.93, "discount": 207.89, "final_total": 1178.04, ... (6 more)} [3] 23ms generate_invoice(order={...}) IN order: {"order_id": "ORD-3847", "original_total": 1385.93, "discount": 207.89, ... (6 more)} OUT "🧾 INVOICE #ORD-3847\n═══════════════════════════\nItems: 5\nSubtotal: $1385.93..." Total: 268ms 3 steps 1 iteration 🧠 🧠 Debugging Insights: Order validation: 5 items totaling $1385.93 Discount logic: 15% bulk discount applied (items >= 5) Final total: $1178.04 (saved $207.89) Use breakpoints to inspect variables at each step xray.trace() shows live execution state during debugging

Visual Format Reference

Status Indicators

Successful execution
ERRORFailed execution
...Pending/in-progress

Data Flow

IN →Input parameters
OUT ←Return values
ERR ✗Error messages

Timing Display

0.03msSub-millisecond
45msTypical operations
2.3sLonger operations