# How to Debug Issues in DeepTutor: A Complete Troubleshooting Guide

> Debug DeepTutor issues effectively. Enable verbose logging, inspect UnifiedContext, and monitor StreamBus events to trace execution flow from input to output.

- Repository: [✨Data Intelligence Lab@HKU✨/DeepTutor](https://github.com/HKUDS/DeepTutor)
- Tags: how-to-guide
- Published: 2026-04-08

---

**Enable verbose logging via `load_logging_config()`, inspect the `UnifiedContext` before calling the orchestrator, and monitor `StreamBus` events to trace every execution step from input to output.**

DeepTutor is a sophisticated AI tutoring framework built around a single-turn orchestrator that coordinates capabilities and tools through asynchronous event streams. When issues arise in the HKUDS/DeepTutor codebase, debugging requires understanding how the **Orchestrator**, **StreamBus**, and **EventBus** interact to process requests. This guide walks through the exact source code locations and debugging patterns you need to isolate failures in capabilities, tool execution, or context handling.

## Understanding DeepTutor's Debugging Architecture

DeepTutor processes each request through three interconnected layers that emit traceable events. Understanding these components is essential before applying specific debugging techniques.

- **Orchestrator Layer**: The `ChatOrchestrator` class in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py) (lines 32-49) receives a `UnifiedContext`, looks up the requested capability, initializes a `StreamBus`, and publishes completion events. This is the central entry point for every tutoring interaction.

- **Registry Layer**: The `CapabilityRegistry` ([`deeptutor/runtime/registry/capability_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/capability_registry.py), lines 48-55) and `ToolRegistry` ([`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py), lines 41-52) maintain the catalog of available functions. These registries expose OpenAI function schemas and handle plugin discovery.

- **Event & Stream Infrastructure**: The `StreamBus` ([`deeptutor/core/stream_bus.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/stream_bus.py), lines 39-48) manages per-turn asynchronous events including content, tool calls, and errors. The global `EventBus` ([`deeptutor/events/event_bus.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/events/event_bus.py), lines 101-107) handles cross-module notifications like `CAPABILITY_COMPLETE`.

- **Context Object**: The `UnifiedContext` defined in [`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py) (lines 26-58) carries all request data including session IDs, enabled tools, and knowledge bases through the entire stack.

- **Logging System**: The `LoggingConfig` in [`deeptutor/logging/config.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/logging/config.py) (lines 71-79) controls global log levels across all modules including RAG components.

## Step-by-Step DeepTutor Debugging Workflow

Follow this systematic approach to isolate issues in the DeepTutor pipeline. Each step targets a specific failure point in the request lifecycle.

1. **Enable Verbose Logging**: Set the global log level to `DEBUG` using `load_logging_config()`. This function reads [`main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/main.yaml) and applies the level to every logger in the system, including RAG modules.

2. **Validate the UnifiedContext**: Before invoking the orchestrator, inspect the `UnifiedContext` object. Missing `session_id` fields or empty `enabled_tools` lists are frequent causes of silent failures.

3. **Monitor the StreamBus**: Iterate over the async generator returned by `ChatOrchestrator.handle()`. Each `StreamEvent` reveals execution stages, tool invocations, and error states in chronological order.

4. **Attach EventBus Listeners**: Subscribe to `EventType.CAPABILITY_COMPLETE` events to capture completion metadata. This reveals which tools executed and whether uncaught exceptions occurred.

5. **Verify Registry Contents**: Call `list_capabilities()` and `list_tools()` on the respective registries at startup. If expected capabilities like `deep_solve` are missing, check for import failures in `builtin_capability_classes`.

6. **Check Error Event Paths**: The orchestrator catches capability exceptions and emits `ERROR` stream events via `bus.error`. Search logs and stream output for these events to pinpoint failure locations.

## Practical Code Examples for Debugging DeepTutor

These runnable examples demonstrate how to instrument the DeepTutor runtime for debugging.

### Running a Single Turn with Debug Output

This example enables DEBUG logging and prints every `StreamEvent` to trace the execution flow:

```python
import asyncio
import logging

from deeptutor.runtime.orchestrator import ChatOrchestrator
from deeptutor.core.context import UnifiedContext
from deeptutor.logging.config import load_logging_config

# 1️⃣ Enable DEBUG logging for the whole app

cfg = load_logging_config()
logging.basicConfig(level=cfg.level)

async def debug_turn(message: str, tools: list[str] | None = None):
    ctx = UnifiedContext(
        user_message=message,
        enabled_tools=tools,
        # any other fields you care about …

    )
    orchestrator = ChatOrchestrator()
    async for ev in orchestrator.handle(ctx):
        # StreamBus events arrive in order – print them for live debugging

        print(f"[{ev.type}] {ev.source}: {getattr(ev, 'content', '')}")

# Example usage

asyncio.run(debug_turn("Explain the Fourier transform", tools=["rag", "web_search"]))

```

### Attaching EventBus Listeners for Capability Completion

This pattern captures high-level completion events regardless of how many stream events were emitted:

```python
import asyncio
from deeptutor.events.event_bus import EventType, get_event_bus, Event

async def on_capability_complete(event: Event):
    print("\n--- Capability completed ---")
    print(f"Capability: {event.metadata.get('capability')}")
    print(f"Session: {event.metadata.get('session_id')}")
    print(f"Turn: {event.metadata.get('turn_id')}")

async def main():
    bus = get_event_bus()
    bus.subscribe(EventType.CAPABILITY_COMPLETE, on_capability_complete)

    # Run a turn (reuse the debug_turn from above)

    await debug_turn("What is the derivative of sin(x)?")

    # Give the bus a moment to process the async handler

    await asyncio.sleep(0.1)

asyncio.run(main())

```

### Verifying Registry Contents at Startup

Check that your capabilities and tools are properly registered before processing requests:

```python
from deeptutor.runtime.registry.capability_registry import get_capability_registry
from deeptutor.runtime.registry.tool_registry import get_tool_registry

cap_registry = get_capability_registry()
tool_registry = get_tool_registry()

print("Capabilities:", cap_registry.list_capabilities())
print("Tools:", tool_registry.list_tools())

```

## Key Source Files for DeepTutor Debugging

When tracing issues, examine these specific files in the HKUDS/DeepTutor repository:

| File | Role |
|------|------|
| [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py) | Central turn orchestrator that routes context to capabilities and emits stream events |
| [`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py) | Definition of `UnifiedContext` carrying all request data |
| [`deeptutor/runtime/registry/capability_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/capability_registry.py) | Loads built-in and plugin capabilities |
| [`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py) | Loads tools and resolves OpenAI schemas |
| [`deeptutor/core/stream_bus.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/stream_bus.py) | Async fan-out bus for per-turn events |
| [`deeptutor/events/event_bus.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/events/event_bus.py) | Global event bus for cross-module notifications |
| [`deeptutor/logging/config.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/logging/config.py) | Global logging configuration loader |

## Summary

- **Enable DEBUG logging** via `load_logging_config()` in [`deeptutor/logging/config.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/logging/config.py) to capture system-wide trace information.
- **Inspect `UnifiedContext`** before orchestration to catch missing session IDs or tool configurations.
- **Monitor `StreamBus` events** by iterating over `ChatOrchestrator.handle()` to observe real-time execution flow.
- **Validate registries** using `list_capabilities()` and `list_tools()` to ensure all components are registered.
- **Capture `EventBus` notifications** for completion and error events that indicate turn-level success or failure.

## Frequently Asked Questions

### How do I enable DEBUG logging in DeepTutor?

Call `load_logging_config()` from [`deeptutor/logging/config.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/logging/config.py) and set the level to `DEBUG` in your [`main.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/main.yaml) configuration file. This applies the log level globally across all modules including RAG components, allowing you to trace execution through the orchestrator and tool layers.

### What is the UnifiedContext and why does it cause silent failures?

The `UnifiedContext` is the data object defined in [`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py) that carries session state, user messages, and enabled tools through the entire stack. Silent failures often occur when required fields like `session_id` are missing or when `enabled_tools` is empty, causing the orchestrator to route requests to default capabilities without the intended tool support.

### How can I trace tool execution in DeepTutor?

Iterate over the async generator returned by `ChatOrchestrator.handle()` and inspect the `StreamEvent` objects. Tool calls appear as `TOOL_CALL` events and results as `TOOL_RESULT` events. Alternatively, subscribe to the `EventBus` to capture `CAPABILITY_COMPLETE` events that include metadata about which tools were invoked during the turn.

### Where does DeepTutor log errors from capabilities?

The orchestrator catches exceptions from capabilities and emits them as `ERROR` events through the `StreamBus` via `bus.error()`. These events appear in your stream iteration output and are also available through the logging system if DEBUG level is enabled, allowing you to pinpoint the exact line where failures occur in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py).