How to Debug the AI Agent Built Using learn-claude-code: A Layer-by-Layer Guide
To debug the learn-claude-code AI agent, inspect the conversation history, tool dispatch outcomes, and subsystem states using built-in REPL shortcuts like /compact and /tasks, while tracing failures through the progressive session architecture from s01 to s_full.py.
The shareAI-lab/learn-claude-code repository implements a Claude‑Code‑style AI agent through a progressive learning path. When you need to debug the AI agent built using learn-claude-code, understanding its layered architecture—from the minimal loop in s01 to the full orchestration in s_full.py—allows you to pinpoint exactly where behavior diverges from expectations.
Understanding the Agent Architecture for Debugging
The Progressive Session Model (s01-s12)
The repository organizes capabilities into incremental sessions. Each layer adds complexity and potential failure points:
agents/s01_agent_loop.py– The corewhileloop that calls the LLM and feeds back tool results. Failures here manifest as infinite loops or premature stops.agents/s02_tool_use.py– DefinesTOOL_HANDLERS, mapping tool names to Python functions. Signature mismatches between the schema and handler cause dispatch errors.agents/s03_todo_write.py– ImplementsTodoManagerwithhas_open_items()checks. Debugging todo nag issues requires inspectingrounds_without_todocounters.agents/s04_subagent.py– Containsrun_subagent()for spawning child agents. Failures here involve message history isolation and summary extraction.agents/s05_skill_loading.py–SkillLoaderdynamically loads markdown skills. Path resolution errors occur whenSKILL.mdfiles are missing.agents/s06_context_compact.py– Implementsmicrocompactandauto_compactfor token management.TOKEN_THRESHOLDbreaches trigger aggressive history truncation.agents/s07_task_system.py–TaskManagerprovides persistent file-based CRUD for tasks. Debugging involves checking task status and dependency resolution.agents/s08_background_tasks.py–BackgroundManagerruns shell commands in daemon threads. Thread-safety issues appear in thenotificationsqueue.agents/s09_agent_teams.py–MessageBushandles JSONL inbox files inINBOX_DIR. Silent message failures usually involvesafe_pathvalidation.agents/s10_team_protocols.py– Broadcast and shutdown coordination. Debugging requires inspecting protocol state machines.agents/s11_autonomous_agents.py–TeammateManager._loopruns autonomous teammate loops. Idle detection and auto-claim logic require tracing the_loopimplementation.agents/s12_worktree_task_isolation.py– Git work-tree isolation for task directories. Failures involvegit worktree addpermissions and cleanup.
The Capstone Integration (s_full.py)
agents/s_full.py composes all sessions into a unified agent. It adds REPL shortcuts and orchestrates compression, background drainage, and inbox processing. Most debugging occurs here because it integrates all subsystems.
Common Debugging Scenarios and Solutions
LLM Stops Unexpectedly Without Tool Use
When the model returns normal text instead of tool calls, inspect the core loop in agents/s01_agent_loop.py.
Check response.stop_reason after the LLM call:
- If
"max_tokens"– The conversation hit the token limit. Use/compactto forcemicrocompactor increaseTOKEN_THRESHOLDinagents/s06_context_compact.py. - If
"error"– The API request failed. Verify yourANTHROPIC_API_KEYand model ID in.env.
Tool Handler Exceptions and Dispatch Failures
In agents/s_full.py, the TOOL_HANDLERS dictionary maps tool names to functions. If a tool call throws an exception, the wrapper catches it and returns "Error: …" to the model.
To debug:
- Locate the handler in
agents/s02_tool_use.pyors_full.py. - Add a temporary print inside the handler:
def run_bash(command: str, timeout: int = 120):
print(f"DEBUG: Running command: {command}")
result = subprocess.run(...)
print(f"DEBUG: Result: {result}")
return result.stdout
- Re-run the agent and watch the console for the debug output.
Todo Nag Reminder Not Appearing
The todo nag logic resides in agents/s03_todo_write.py and is integrated in s_full.py.
Check these conditions:
TodoManager.has_open_items()returnsTrue(there are incomplete todos).used_todoflag isFalsefor the current round (the model didn't update todos this turn).rounds_without_todocounter exceeds the threshold (typically 3).
If the nag never appears, print these variables in the main loop:
print(f"Has open items: {todo_mgr.has_open_items()}")
print(f"Rounds without todo: {rounds_without_todo}")
print(f"Used todo this round: {used_todo}")
Background Task Results Missing
Background execution is handled by BackgroundManager in agents/s08_background_tasks.py.
If results don't appear:
- Verify the daemon thread started by checking
threading.enumerate():
import threading
print([t.name for t in threading.enumerate()])
- Check the
notificationsqueue inBackgroundManager. Thedrain()method retrieves results:
from agents.s_full import BG
print(BG.drain())
- Ensure the command didn't hit the timeout (default 120s) or the dangerous-command filter.
Teammate Message Delivery Failures
Team messaging uses MessageBus in agents/s09_agent_teams.py with JSONL files in INBOX_DIR.
Debug steps:
- Check if the inbox file exists:
cat .team/inbox/lead.jsonl
-
Verify
MessageBus.sendwas called with the correct target name. -
Inspect
safe_pathvalidation inagents/s09_agent_teams.py—path escape attempts raiseValueErrorsilently in some implementations. -
Ensure the lead's inbox is being read in the main loop (
BUS.read_inbox("lead")ins_full.py).
Token Budget Overflow and Context Compaction
Context management lives in agents/s06_context_compact.py with microcompact and auto_compact.
Symptoms: Agent forgets recent context or hits token limits frequently.
Solutions:
-
Force manual compaction with the
/compactREPL command. -
Check the transcript directory (
TRANSCRIPT_DIR) for offloaded summaries. -
Adjust
TOKEN_THRESHOLDin the source if you consistently hit limits (default is usually around 100k tokens). -
Inspect
estimate_tokensimplementation—if using a simple character count, verify it aligns with your model's actual tokenization.
Using Built-in Debug Hooks and REPL Commands
Available REPL Shortcuts
The full agent in agents/s_full.py provides interactive debugging commands while running:
/compact– Forces immediate context compression viamicrocompact, clearing old tool-result payloads./tasks– Prints the current task board state fromTaskManager./team– Lists all teammates and their current status fromTeammateManager./inbox– Dumps the lead's inbox JSONL contents viaMessageBus.
These commands interrupt the normal agent loop temporarily to surface internal state without stopping the process.
Inspecting Internal State
Beyond REPL commands, you can attach to running state:
Check background thread status:
import threading
print([t.name for t in threading.enumerate()])
Drain the background notification queue:
from agents.s_full import BG
notifications = BG.drain()
print(f"Pending notifications: {notifications}")
Inspect todo state:
from agents.s_full import TODO
print(f"Open items: {TODO.has_open_items()}")
print(f"All todos: {TODO.list_todos()}")
Step-by-Step Debugging Workflow
-
Launch the full agent to establish your baseline:
python agents/s_full.py -
Reproduce the issue with a minimal prompt (e.g., "Create a todo list for refactoring").
-
Observe the tool execution flow in the console output. Each tool prints a truncated result prefixed with
> tool_name:. -
Identify the failure layer:
- If the model stops without tools → Check
response.stop_reasonand token counts (Layer s01/s06). - If a tool throws → Check
TOOL_HANDLERSins_full.pyors02_tool_use.py. - If todos/background/team features fail → Inspect the respective managers (s03, s08, s09).
- If the model stops without tools → Check
-
Insert temporary debug prints in the suspect handler or manager:
print(f"DEBUG: Input params: {params}") print(f"DEBUG: Current state: {self.state}") -
Use REPL shortcuts to manipulate state:
/compactif you suspect token limits./tasksor/inboxto verify subsystem state.
-
Verify fixes by re-running the same prompt and confirming the console output shows correct execution.
-
Clean up debug prints before committing changes.
Summary
- Architecture awareness is critical: the agent builds from
s01_agent_loop.pythroughs12_worktree_task_isolation.py, withs_full.pyintegrating everything. - Common failure points include token budget overflows (fixed via
/compactorauto_compact), tool handler exceptions (caught inTOOL_HANDLERS), and message bus failures (checkINBOX_DIRJSONL files). - Built-in debugging tools include REPL commands (
/compact,/tasks,/team,/inbox), round counters for todo tracking, and exception capture that feeds errors back to the model. - Systematic debugging involves reproducing the issue, identifying the architectural layer, inserting temporary prints, and using REPL shortcuts to inspect state without stopping the agent.
Frequently Asked Questions
How do I enable verbose logging in learn-claude-code?
The repository does not use a traditional logging framework; instead, it relies on print statements embedded in tool handlers and the REPL. To increase verbosity, add print() statements inside the specific handler or manager you are debugging (e.g., inside run_bash in agents/s02_tool_use.py or TodoManager.update in agents/s03_todo_write.py). The s_full.py agent already prints truncated tool results prefixed with > tool_name: after each execution.
Why does my agent stop responding after several tool calls?
This typically indicates a token budget overflow or a context window limit. The agent stops when response.stop_reason equals "max_tokens" or when the internal estimate_tokens count exceeds TOKEN_THRESHOLD. To resolve this, use the /compact REPL command to force immediate context compression via microcompact, or check the auto_compact logic in agents/s06_context_compact.py to ensure it is triggering correctly. If the issue persists, consider increasing TOKEN_THRESHOLD or simplifying the system prompt.
How can I inspect what a sub-agent is doing in real-time?
Sub-agents are spawned via run_subagent in agents/s04_subagent.py with a fresh message history, and only the final summary is returned to the parent. To see the intermediate steps, temporarily edit the run_subagent function to insert debug prints before the LLM call:
def run_subagent(prompt: str, agent_type: str = "Explore") -> str:
sub_msgs = [{"role": "user", "content": prompt}]
print("\n--- Subagent start ---")
print("Messages:", sub_msgs)
# ... rest of function
Re-run the parent agent, and the console will display the sub-agent's internal dialogue before the summary is returned.
What should I do if the token threshold keeps triggering?
Frequent token threshold triggers indicate that the conversation history is growing faster than the compaction mechanisms can handle. First, verify that auto_compact in agents/s06_context_compact.py is actually executing by checking for transcript files in TRANSCRIPT_DIR. If compaction is working but you still hit limits, you can:
- Lower the history retention by modifying the
microcompactlogic to be more aggressive about removing old tool results. - Increase
TOKEN_THRESHOLDin the source code to match your model's actual context window. - Use
/compactmanually before complex multi-step operations to reset the context window proactively.
Check the estimate_tokens implementation as well—if it uses character count instead of actual tokenization, it may underestimate usage for code-heavy conversations.
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 →