The Problem

DeepTutor is a collection of four semi-independent projects (deeptutor, web, deeptutor_cli, scripts) totaling 1,012 files with 779 analyzed code files. The repository functions as an agent-native personalized learning assistant, but its architecture spans multiple codebases with shared credentials, circular imports, and committed secrets that affect production readiness.

What This Does

DeepTutor provides an agent-native tutoring system with RAG capabilities, persistent chat, knowledge base management, and a CLI interface. The core deeptutor package (521 files, 395 code files) contains the agent orchestration, LLM configuration, and knowledge management. The web directory (219 files, 196 code files) is a Next.js frontend. The deeptutor_cli (15 files) provides agent-native CLI commands, and scripts (13 files) contains utility scripts.

Key files and their reach:

  • deeptutor_cli/main.py:142 - main entry point reaching 399 functions
  • deeptutor/agents/base_agent.py - 1 class, 19 functions, called from 21 files, calls into 103
  • deeptutor/services/path_service.py - defines file path resolution used across the project
  • deeptutor/services/llm/config.py - LLM configuration hub, called from 28 files
  • deeptutor/runtime/orchestrator.py:36 - handle entry point reaching 399 functions
  • deeptutor/agents/chat/agentic_pipeline.py:163 - run entry point reaching 402 functions

The deeptutor/services/llm/config.py module is a high-blast-radius hub: 43 modules depend on it, and it carries instability 0.1 from its own circular dependency with deeptutor/services/llm/__init__.py and deeptutor/services/config/__init__.py.

How It Is Wired

Execution flows through a few concentrated entry points. From main in deeptutor_cli/main.py, control reaches 399 functions including get_prompt (called from 37 places), get_llm_config (33 places), and stream_llm (30 places). The run function in deeptutor/agents/chat/agentic_pipeline.py:163 similarly reaches 402 functions and is the primary path for message processing.

Traced paths from entry points to external effects:

  • main -> fetch_github_api [network via urllib.request.Request]
  • handle -> _run [subprocess via subprocess.run]
  • run -> save_to_json [filesystem via Path(filepath).parent.mkdir]
  • start -> build [network via session.get("compressed_summary")]

The internal call graph has 6000 resolved call edges. Key hub functions include model_dump (51 callers), post (44), _t (43), and _run (38). The deeptutor/services/llm/config.py hub has 43 importers, making changes there high-radius.

Four circular dependency cycles exist involving deeptutor/services/llm/__init__.py, deeptutor/services/config/__init__.py, deeptutor/book/blocks/base.py, and associated modules. These increase cognitive load for any modification touching LLM or config code.

How To Use It

Setup: The repository uses pyproject.toml as the Python manifest and web/package.json for the frontend. No single install command covers the full stack; deeptutor requires Python 3.11+ dependencies resolved through the package manager, and web requires npm install.

Configuration: Environment variables are defined in .env.example and .env.example_CN. The deeptutor/services/llm/config.py file handles OpenAI-compatible binding setup via _set_openai_env_vars and _setup_openai_env_vars_early. The web/.env.local file is tracked despite being gitignored, containing active credentials.

Running it:

# CLI entry point
python -m deeptutor_cli.main

# Or the package CLI
deeptutor <command>

The README documents release tags from v0.2.0 through v1.3.5, with docker-compose files for development and GHCR deployment.

Real-World Use

A tutor agent processes a user message through the pipeline: _process_message constructs an OutboundMessage, which flows through execute -> ToolResult and get_definition -> ToolParameter. The agent calls call_llm or stream_llm for generation, persists conversation state via deeptutor/services/session/sqlite_store.py (78 functions, reads/writes a database), and may invoke RAG pipelines that make outbound network calls to embedding endpoints. A complete request from message entry to database write typically traverses 5-7 resolved call hops.

Code Health & Issues

Static analysis of 779 files found 411 issues across 6 kinds:

  • [CRITICAL] Rotate credentials in committed .env.example_CN - SILICONFLOW_API_KEY, COHERE_API_KEY hold generated values loaded at boot
  • [HIGH] Untrack web/.env.local though .gitignore excludes it - contains active credentials
  • [HIGH] Pin GitHub Actions to commit SHAs - docker/setup-qemu-action@v3, docker/login-action@v3 etc. use mutable tags
  • [HIGH] Add lockfile for pyproject.toml - manifest without committed lockfile means tested and shipped artifacts can differ
  • [HIGH] Remove committed .env and rotate credentials - .env.example_CN is tracked
  • [MEDIUM] Enable Dependabot or Renovate - 3 manifests, no update bot configured
  • [MEDIUM] Pin container base images by digest - python:3.11-slim, node:22-slim use mutable tags
  • [MEDIUM] Gate PRs on dependency vulnerability scan - no dependency scan in CI
  • [MEDIUM] Set persist-credentials: false on checkout - tests.yml checkout keeps the token

Additional measured findings: 8 import cycle members, 21 deep nesting instances across base_agent.py, path_service.py, manager.py, 5 oversized files (610+ lines each), and 8 hub modules with high blast radius.

The Bottom Line

DeepTutor is a substantial, functional agent-native tutoring system with working RAG, persistent chat, and CLI capabilities across four codebases. The architecture is coherent within each project but fragile at the boundaries: circular imports between LLM and config modules, committed credentials in example files, and mutable Docker base tags introduce real production risk. The codebase will suit teams that need a personalized learning assistant out of the box and have operational bandwidth to rotate secrets and pin dependencies. Teams requiring minimal operational overhead or strict supply-chain guarantees should look elsewhere, as the current state demands credential rotation, lockfile commitment, and cycle breaking before production use.