How to Debug Issues in DeepTutor: A Complete Troubleshooting Guide
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
ChatOrchestratorclass indeeptutor/runtime/orchestrator.py(lines 32-49) receives aUnifiedContext, looks up the requested capability, initializes aStreamBus, and publishes completion events. This is the central entry point for every tutoring interaction. -
Registry Layer: The
CapabilityRegistry(deeptutor/runtime/registry/capability_registry.py, lines 48-55) andToolRegistry(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, lines 39-48) manages per-turn asynchronous events including content, tool calls, and errors. The globalEventBus(deeptutor/events/event_bus.py, lines 101-107) handles cross-module notifications likeCAPABILITY_COMPLETE. -
Context Object: The
UnifiedContextdefined indeeptutor/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
LoggingConfigindeeptutor/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.
-
Enable Verbose Logging: Set the global log level to
DEBUGusingload_logging_config(). This function readsmain.yamland applies the level to every logger in the system, including RAG modules. -
Validate the UnifiedContext: Before invoking the orchestrator, inspect the
UnifiedContextobject. Missingsession_idfields or emptyenabled_toolslists are frequent causes of silent failures. -
Monitor the StreamBus: Iterate over the async generator returned by
ChatOrchestrator.handle(). EachStreamEventreveals execution stages, tool invocations, and error states in chronological order. -
Attach EventBus Listeners: Subscribe to
EventType.CAPABILITY_COMPLETEevents to capture completion metadata. This reveals which tools executed and whether uncaught exceptions occurred. -
Verify Registry Contents: Call
list_capabilities()andlist_tools()on the respective registries at startup. If expected capabilities likedeep_solveare missing, check for import failures inbuiltin_capability_classes. -
Check Error Event Paths: The orchestrator catches capability exceptions and emits
ERRORstream events viabus.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:
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:
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:
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 |
Central turn orchestrator that routes context to capabilities and emits stream events |
deeptutor/core/context.py |
Definition of UnifiedContext carrying all request data |
deeptutor/runtime/registry/capability_registry.py |
Loads built-in and plugin capabilities |
deeptutor/runtime/registry/tool_registry.py |
Loads tools and resolves OpenAI schemas |
deeptutor/core/stream_bus.py |
Async fan-out bus for per-turn events |
deeptutor/events/event_bus.py |
Global event bus for cross-module notifications |
deeptutor/logging/config.py |
Global logging configuration loader |
Summary
- Enable DEBUG logging via
load_logging_config()indeeptutor/logging/config.pyto capture system-wide trace information. - Inspect
UnifiedContextbefore orchestration to catch missing session IDs or tool configurations. - Monitor
StreamBusevents by iterating overChatOrchestrator.handle()to observe real-time execution flow. - Validate registries using
list_capabilities()andlist_tools()to ensure all components are registered. - Capture
EventBusnotifications 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 and set the level to DEBUG in your 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 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →