# How to Integrate DeepTutor with Other Systems: CLI, API, and Python SDK Patterns

> Learn how to integrate DeepTutor with other systems using CLI, HTTP API, or Python SDK. Explore patterns for automation scripts, web services, and embedded applications for consistent behavior.

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

---

**DeepTutor provides three integration surfaces—CLI, HTTP/WebSocket API, and Python SDK—that all converge on a single `ChatOrchestrator` runtime, ensuring consistent behavior across automation scripts, web services, and embedded applications.**

The HKUDS/DeepTutor repository is architected as an agent-native tutoring service designed for flexible integration. Whether you need to embed intelligent tutoring into a learning management system, automate content generation via shell scripts, or build real-time streaming interfaces, DeepTutor exposes the same core capabilities through multiple entry points.

## Integration Entry Points

DeepTutor exposes functionality through three independent surfaces that share identical runtime behavior:

- **Python SDK** – Direct in-process access via `ChatOrchestrator` for embedding in existing applications
- **HTTP/WebSocket API** – FastAPI-based REST endpoints and unified WebSocket for real-time streaming  
- **CLI (Typer)** – Command-line interface for scripting and containerized workflows

All three methods ultimately execute the same pipeline defined in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py), passing a `UnifiedContext` object through the capability registry and streaming `StreamEvent` objects back to the caller.

## Python SDK Integration

The Python SDK offers the tightest integration by importing the orchestrator directly into your application code.

### Direct Orchestrator Usage

The `ChatOrchestrator` class defined in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py) serves as the primary execution engine. It routes `UnifiedContext` objects to appropriate capabilities (such as `chat`, `deep_solve`, or `deep_research`) and returns an async stream of `StreamEvent` objects.

```python
import asyncio
from deeptutor.runtime.orchestrator import ChatOrchestrator
from deeptutor.core.context import UnifiedContext

async def run_question():
    ctx = UnifiedContext(
        user_message="Explain the Fourier transform and give a code example.",
        active_capability="deep_solve",
    )
    orchestrator = ChatOrchestrator()
    async for event in orchestrator.handle(ctx):
        if event.type == "content":
            print(event.content, end="", flush=True)

asyncio.run(run_question())

```

This approach instantiates the singleton registries defined in [`deeptutor/runtime/registry/capability_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/capability_registry.py) and [`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py), loading all available tools and capabilities automatically.

## HTTP and WebSocket API Integration

For service-oriented architectures, DeepTutor exposes a FastAPI application defined in [`deeptutor/api/main.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/api/main.py).

### REST API Endpoints

Deploy the server using `uvicorn deeptutor.api.main:app`, then send POST requests to capability-specific endpoints such as `/api/v1/chat` or `/api/v1/solve`. The request handlers construct a `UnifiedContext` from the JSON payload and stream `StreamEvent` objects back to the client.

```bash
curl -X POST http://localhost:8000/api/v1/chat \
     -H "Content-Type: application/json" \
     -d '{"user_message":"Summarize the Pythagorean theorem"}'

```

The chat router in [`deeptutor/api/routers/chat.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/api/routers/chat.py) processes these requests by forwarding the constructed context to `ChatOrchestrator.handle()`, ensuring parity with the Python SDK.

### WebSocket Streaming

For real-time, turn-based interactions, connect to the unified WebSocket endpoint at `/api/v1/ws` implemented in [`deeptutor/api/routers/unified_ws.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/api/routers/unified_ws.py). This endpoint supports asynchronous message types including `message`, `start_turn`, and `subscribe_turn`, enabling pause/resume functionality and cancellation of in-flight operations.

```python
import json, asyncio, websockets

async def ws_demo():
    async with websockets.connect("ws://localhost:8000/api/v1/ws") as ws:
        await ws.send(json.dumps({
            "type": "message",
            "user_message": "Generate a short Python script that prints prime numbers.",
            "session_id": "demo-session"
        }))
        
        while True:
            raw = await ws.recv()
            msg = json.loads(raw)
            if msg.get("type") == "content":
                print(msg["content"], end="", flush=True)
            if msg.get("type") == "done":
                break

asyncio.run(ws_demo())

```

The WebSocket handler subscribes to the orchestrator's `StreamBus` and forwards events directly to the connected client.

## Command Line Interface

The Typer-based CLI defined in [`deeptutor_cli/main.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor_cli/main.py) provides a thin wrapper around the orchestrator for shell-based automation.

```bash
pip install -r requirements/cli.txt && pip install -e .
deeptutor run chat "What is a quantum bit?"

```

The CLI parses arguments, builds a `UnifiedContext`, and streams output to stdout using the same `ChatOrchestrator` pipeline used by the API and SDK.

## Extending DeepTutor with Custom Tools

New capabilities and tools automatically propagate to all integration methods through the plugin system. Create a manifest in [`plugins/my_tool/manifest.yaml`](https://github.com/HKUDS/DeepTutor/blob/main/plugins/my_tool/manifest.yaml) and implement `BaseTool` from [`deeptutor/core/tool_protocol.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/tool_protocol.py):

```yaml
name: my_tool
version: 0.1.0
type: tool
description: "A demo tool that echoes a string."
entry: plugins.my_tool.tool:EchoTool

```

```python
from deeptutor.core.tool_protocol import BaseTool, ToolResult

class EchoTool(BaseTool):
    name = "echo"
    async def execute(self, text: str) -> ToolResult:
        return ToolResult(content=text)

```

When the `ToolRegistry` (defined in [`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py)) initializes, it discovers the plugin via [`deeptutor/plugins/loader.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/plugins/loader.py), making the tool immediately available across the CLI, HTTP API, and Python SDK without additional configuration.

## Core Architecture

### ChatOrchestrator

The `ChatOrchestrator` class in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py) functions as the single point of execution. It creates a `StreamBus` for each turn, manages the lifecycle of streaming events defined in [`deeptutor/core/stream.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/stream.py), and coordinates between the capability registry and tool registry.

### Registries and Configuration

- **Capability Registry** ([`deeptutor/runtime/registry/capability_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/capability_registry.py)) – Discovers capabilities at startup, exposing their OpenAI function-calling schemas
- **Tool Registry** ([`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py)) – Resolves tool aliases and emits JSON schemas for LLM function calling  
- **Settings** ([`deeptutor/config/settings.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/settings.py)) – Provides global configuration including LLM provider, model selection, and knowledge base paths to all components

Because these components are implemented as singletons, any tool or capability registered at startup becomes available uniformly across all integration surfaces.

## Summary

- **Three integration methods**—CLI, HTTP/WebSocket API, and Python SDK—all utilize the same `ChatOrchestrator` runtime in [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py)
- **`UnifiedContext`** serves as the standard contract between entry points and capabilities, defined in [`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py)
- **Streaming responses** use `StreamEvent` objects (defined in [`deeptutor/core/stream.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/stream.py)) regardless of whether you use the SDK, WebSocket, or CLI
- **Plugin architecture** allows custom tools to automatically appear in all interfaces via the registries in `deeptutor/runtime/registry/`
- **Configuration** is centralized in [`deeptutor/config/settings.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/settings.py) and accessible to every integration layer

## Frequently Asked Questions

### What is the difference between the REST API and WebSocket integration for DeepTutor?

The REST API at `/api/v1/chat` provides request/response workflows suitable for simple queries, while the WebSocket endpoint at `/api/v1/ws` defined in [`deeptutor/api/routers/unified_ws.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/api/routers/unified_ws.py) supports streaming `StreamEvent` objects in real-time with turn-based state management, pause/resume capabilities, and cancellation tokens.

### Can I use DeepTutor as a library in my existing Python application?

Yes, by importing `ChatOrchestrator` from [`deeptutor/runtime/orchestrator.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/orchestrator.py) and constructing `UnifiedContext` objects from [`deeptutor/core/context.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/core/context.py), you can embed DeepTutor directly into your service. This in-process method provides the lowest latency and full access to the async stream of events.

### How do custom tools propagate across integration methods?

When you place a plugin manifest and tool implementation in the `plugins/` directory, the `ToolRegistry` in [`deeptutor/runtime/registry/tool_registry.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/runtime/registry/tool_registry.py) automatically loads it at startup using the loader in [`deeptutor/plugins/loader.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/plugins/loader.py). Because the registries are singletons shared by all entry points, the new tool immediately appears in the CLI, HTTP API, and Python SDK without code changes.

### Which configuration file controls the LLM provider settings?

Global settings including the LLM provider, model name, and knowledge base locations are managed in [`deeptutor/config/settings.py`](https://github.com/HKUDS/DeepTutor/blob/main/deeptutor/config/settings.py). These settings are instantiated as singletons and consumed by the orchestrator and registry components, ensuring consistent LLM behavior across all three integration surfaces.