DT
AI RESEARCH INSIGHTSsource → workflow → implementation
CODE STUDY · 2026-09-01
SOURCE TOPOLOGY · CODE REPOSITORY10 SOURCE GROUPSIMPLEMENTATION-GROUNDED
DeepTutor · agent-native learning architecture

One runtime.
Many ways to think.

DeepTutor is not a collection of disconnected AI features. It is a learning runtime that packages the learner’s world once, gives one capability ownership of a turn, lets tools perform bounded actions, and streams the same typed work to every interface.

The core design separates turn ownership from action execution. Capabilities own multi-stage learning workflows; tools return bounded results to an agentic loop; deterministic engine state guards planning and mastery; StreamBus decouples execution from presentation; and a three-layer memory system turns raw activity into auditable personalization.

DOCUMENTED ENTRY SURFACES3CLI · WebSocket · SDK
PLUGIN LEVELS2Tools · Capabilities
BUILT-IN CAPABILITY REGISTRATIONS11Verified in bootstrap map
MEMORY LAYERS3L1 evidence → L2 facts → L3 synthesis
01 · Core thesis + boundaries

The transferable idea is the control boundary.

“Agent-native” becomes concrete only when the system says who owns the turn, what may mutate state, how uncertainty is repaired, and which data is safe to publish.

IMPLEMENTED THESIS

Actions return; workflows own.

A BaseTool exposes a schema and returns ToolResult. A BaseCapability owns a named, staged run(). The orchestrator resolves exactly one capability for the turn.

turn_owner = registry.get(active_capability or "chat")
action_result = await tool_registry.execute(name, **args)
DESIGN INFERENCE

Share the intelligence loop; specialize the invariants.

Deep Solve and Mastery Path reuse AgenticChatPipeline, then add stateful plan or mastery tools. Deep Research and Visualize retain specialist pipelines where their artifact-production shape genuinely differs.

shared loop + mode tools + deterministic state
≠ one prompt pretending to be a control system
IMPLEMENTEDRouting, protocols, events, gates
DOCUMENTEDThree public entry surfaces
INFERENCEControl boundaries are the reusable pattern
OPEN QUESTIONProduction quality under every provider
02 · Core workflow + dependencies

Follow a request from learner context to durable knowledge.

The learning loop depends on contracts at both ends. Context determines which tools and skills can mount; protocol labels constrain the model’s next action; tool results can pause or terminate; the event stream makes progress observable; memory consolidation happens outside the immediate answer path.

Dependency-aware runtime flowINPUT CONTRACT → OWNER → EXECUTION → OUTPUT CONTRACT
01 · LEARNER STATEUnifiedContextMessage, history, KBs, attachments, language, memory, persona, skills, sources, metadata.SOURCE S03
02 · TURN OWNERChatOrchestratorValidates, resolves one capability, creates the turn bus, and owns completion.SOURCE S02
03 · THINK + ACTCapability + loop + toolsProtocol labels, scoped schemas, bounded dispatch, pause/resume, deterministic gates.S04–S07
04 · OBSERVABLE RESULTStreamBus + safe envelopeTyped events reach consumers; explicit metadata is published; evidence may later consolidate.S08–S09
SEVEN-STAGE RUNTIME WALKTHROUGH

Package the learner’s world

FRAME 1 / 7AUTO PLAYING
03 · Component deep dive

Read every component as an I/O contract.

Each card states what must be true before the component runs, what it guarantees afterward, and the internal mechanism that transforms one into the other. Switch between algorithm and software views, then open a card to walk the transformation step by step.

A1 · TURN ROUTING

Single-owner selection

Generate a session ID, resolve active_capability or "chat", reject unknown names as terminal events, then run one owner asynchronously.

cap_name = context.active_capability or "chat" capability = registry.get(cap_name) await capability.run(context, bus)
INVALIDATED IF · another entrypoint bypasses the orchestrator and implements different turn semantics.
A2 · PROTOCOL LOOP

Label, validate, repair, repeat

Each iteration obtains a labeled step, checks protocol violations, repairs malformed outputs, dispatches tools, handles intermediate labels, or terminates.

for iteration in range(max_iter): step = await run_labeled_step(...) if violation: repair_and_continue() elif terminal: break elif tool: await dispatch()
FAILURE MODE · a provider that does not preserve labels or tool-call structure spends iterations on repair.
A3 · BOUNDED TOOL DISPATCH

Act, pause, terminate, or continue

Tool results return content, sources, UI metadata, success state, and explicit control signals. ask_user pauses the same turn and resumes with the reply.

if outcome.pause: resumed = await host.resolve_pause(outcome) elif outcome.terminate: await host.emit_terminator(payload) else: continue
TESTED BY · tool-dispatch pause ordering and event tests under tests/core/agentic/.
A4 · PROGRESSIVE TOOL SURFACE

Mount context, defer the long tail

Context flags mount RAG, source, memory, notebook, execution, and mastery tools only when relevant. Deferred tools expose compact manifests and load schemas into the live list on demand.

manifest → load_tools(names) → validate allowed + deferred → append OpenAI schema → persist session-loaded set
TRADE-OFF · smaller prompts depend on the model recognizing when a deferred capability is needed.
A5 · DETERMINISTIC LEARNING GATES

Intelligence at the loop; certainty at the exit

Deep Solve stores a committed plan and bounded replan budget. Mastery Path binds persisted paths, grades questions, and uses a hard per-type gate plus spaced review.

model: choose how to teach engine: decide whether state may advance tool: read/write the bounded state
INVALIDATED IF · progression can occur from prose alone without a corresponding engine-state transition.
A6 · EVIDENCE CONDENSATION

L1 → L2 → L3 memory

Append raw surface traces, consolidate readable per-surface facts, then synthesize recent/profile/scope knowledge across surfaces. Preferences remain an explicit write path.

L1 trace/<surface>/<date>.jsonl → L2 <surface>.md → L3 recent | profile | scope + explicit preferences
BOUNDARY · consolidation can improve continuity, but it does not prove every learner-model claim is correct.
S1 · CONTROL PLANE

ChatOrchestrator

Routes a UnifiedContext, owns the StreamBus lifecycle, normalizes errors into terminal events, and publishes a safe completion envelope.

deeptutor/runtime/orchestrator.py ↗
S2 · STATE CONTRACT

UnifiedContext

The canonical request envelope for every tool, capability, and plugin invocation. Its metadata field is a scratchpad—not automatically public wire data.

deeptutor/core/context.py ↗
S4 · DISCOVERY

Tool + Capability registries

Load built-ins, discover plugins, resolve names and aliases, build model-provider schemas, and expose manifests without coupling the orchestrator to each implementation.

deeptutor/runtime/registry/ ↗
S5 · SHARED INTELLIGENCE LOOP

AgenticChatPipeline

Composes prompt blocks, contextual tools, provider-scoped views, usage tracking, context budgets, and the capability-neutral agent loop.

agents/chat/agentic_pipeline.py ↗
S6 · LOOP KERNEL

run_agentic_loop

Owns iteration, label validation, repair, terminal handling, intermediate hooks, tool dispatch, pause/resume, forced finalization, and aggregated sources.

core/agentic/loop.py ↗
S7 · EVENT FABRIC

StreamBus

Turn-scoped async fan-out with bounded optional history, late-subscriber replay, cross-loop wake-up, typed convenience helpers, and close sentinels.

core/stream_bus.py ↗
S8 · DURABLE LEARNER MODEL

MemoryStore

A stateless facade over per-user paths, atomic Markdown writes, L2/L3 consolidation, explicit preferences, audits, and trace provenance.

services/memory/store.py ↗
04 · Implementation path

Trace the control boundaries in code.

These excerpts are simplified from the checked-out source. They preserve the governing behavior while omitting defensive branches, trace metadata, and provider-specific plumbing.

R1 · SAFE TURN OWNER

The orchestrator never publishes the scratchpad wholesale.

Capabilities may opt values into a publishable sub-dictionary. Capability, session, and turn identifiers always win.

orchestrator.py ↗
meta = context.metadata or {} agent_output = str(meta.get(AGENT_OUTPUT) or "") published = meta.get(EVENT_METADATA) extras = dict(published) if isinstance(published, dict) else {} return agent_output, { **extras, "capability": cap_name, "session_id": context.session_id, "turn_id": str(meta.get("turn_id") or ""), }

Why this boundary exists

  • Metadata can hold live callbacks such as wait_for_user_reply.
  • It may contain the learner’s ask_user answers.
  • Arbitrary scratchpad objects may not serialize.
  • Global listeners include external partner channels.
R2 · REPAIRABLE AGENT LOOP

Malformed model actions become feedback, not silent control flow.

Protocol violations are classified, emitted as warnings, appended as repair messages, and retried within a bounded iteration budget.

core/agentic/loop.py ↗
step = await run_labeled_step(...) violation = _protocol_violation(step, protocol) if violation: await _emit_retry_notice(...) _append_repair_messages(...) continue if step.label in protocol.terminal: completed = True break
01Guard contextCompact or stop before the provider window is exceeded.
02Request a labeled stepThink, tool, intermediate, or terminal.
03ValidateReject missing, multiple, or mismatched tool labels.
04Repair or advanceFeed observable protocol feedback into the next bounded iteration.
R3 · PAUSE WITHOUT ENDING THE TURN

Human clarification resumes the same loop.

A ToolResult can carry a structured pause payload. The host awaits the learner’s reply, substitutes it into the tool message, and continues the iteration.

core/tool_protocol.py ↗
@dataclass class ToolResult: content: str = "" sources: list[dict] = field(default_factory=list) success: bool = True terminate_turn: bool = False pause_for_user: dict | None = None

Operational effect

ask_user no longer fakes a completed turn and starts another. The in-flight loop remains the owner, preserving its capability mode, tool results, trace, and iteration state.

BEFORE PAUSEQuestion payload + active loop
AFTER REPLYTool message + same loop resumes
R4 · AUDITABLE MEMORY WRITE

Preferences are explicit; consolidation remains reviewable.

MemoryStore prevents duplicate explicit preferences, writes atomically, and separates direct preference writes from automatically consolidated recent/profile/scope documents.

services/memory/store.py ↗
async def update_l3(slot, ...): if slot == "preferences": raise ValueError("preferences.md is not auto-consolidated") async with self._lock_for(path): return await consolidator.consolidate_l3(...)

What this proves—and does not

  • Proves: different memory layers have distinct write authority and file-backed provenance.
  • Does not prove: every LLM-extracted learner fact is semantically correct.
  • Control: workbench preview/apply, audit, deduplication, and human-editable Markdown.
05 · Why it works

Design lessons, failure modes, and invalidation tests.

The repository’s strongest lessons are not “use agents” or “add memory.” They are about where to place ownership, evidence, and deterministic authority around probabilistic behavior.

P1

One semantic turn

Unify interfaces at the request and event contracts so new clients do not fork tutor behavior.

P2

Two plugin levels

Keep bounded actions composable and let purpose-built workflows own control.

P3

Repair the protocol

Convert malformed model behavior into bounded, observable feedback rather than undefined execution.

P4

Gate progression in state

Let the model teach flexibly while the engine enforces plan and mastery invariants.

P5

Disclose capability progressively

Keep prompt surfaces small with manifests, then load full tools, skills, and sources on demand.

P6

Make personalization inspectable

File-backed evidence, summaries, and synthesis allow correction that hidden memory cannot.

Use this architecture when

01
Many learning modes share contextChat, solve, research, mastery, and visualization need the same learner state.
02
Interfaces must remain consistentCLI, browser, and embedded SDK consumers need one event vocabulary.
03
Human pauses must preserve workClarification should resume the same turn rather than reconstructing state.

Do not overclaim it when

01
A plugin is registered but unreachableRegistry presence alone does not prove correct prompt mounting or runtime activation.
02
Memory exists without auditFile-backed provenance reduces opacity; it does not eliminate extraction error.
03
Provider behavior breaks the protocolRepair loops help only within bounded budgets and available model competence.
DeepTutor’s architecture treats learning behavior as a probabilistic process inside explicit software contracts—not as a prompt that happens to call tools.

Invalidation test: this conclusion weakens if major entrypoints bypass UnifiedContext or ChatOrchestrator, if mastery progresses without engine-state evidence, or if consumers depend on capability-specific private metadata rather than the shared event contract.

06 · Source index

Every major claim has a code path.

Source groups are stable evidence handles for this artifact. Documentation-only claims are labeled separately from behavior verified in implementation.

S10 · VALIDATIONOrchestrator, stream, tool dispatch, mastery, deferred-tool testsDeepTutor/tests/ ↗