# How to Debug the AI Agent Built Using learn-claude-code: A Layer-by-Layer Guide

> Debug your learn-claude-code AI agent effectively. Inspect conversation history, tool outcomes, and subsystem states with REPL shortcuts. Trace failures layer by layer through the progressive session architecture.

- Repository: [shareAI-Lab/learn-claude-code](https://github.com/shareAI-lab/learn-claude-code)
- Tags: how-to-guide
- Published: 2026-03-08

---

**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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s01_agent_loop.py)** – The core `while` loop that calls the LLM and feeds back tool results. Failures here manifest as infinite loops or premature stops.
- **[`agents/s02_tool_use.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s02_tool_use.py)** – Defines `TOOL_HANDLERS`, mapping tool names to Python functions. Signature mismatches between the schema and handler cause dispatch errors.
- **[`agents/s03_todo_write.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s03_todo_write.py)** – Implements `TodoManager` with `has_open_items()` checks. Debugging todo nag issues requires inspecting `rounds_without_todo` counters.
- **[`agents/s04_subagent.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s04_subagent.py)** – Contains `run_subagent()` for spawning child agents. Failures here involve message history isolation and summary extraction.
- **[`agents/s05_skill_loading.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s05_skill_loading.py)** – `SkillLoader` dynamically loads markdown skills. Path resolution errors occur when [`SKILL.md`](https://github.com/shareAI-lab/learn-claude-code/blob/main/SKILL.md) files are missing.
- **[`agents/s06_context_compact.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s06_context_compact.py)** – Implements `microcompact` and `auto_compact` for token management. `TOKEN_THRESHOLD` breaches trigger aggressive history truncation.
- **[`agents/s07_task_system.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s07_task_system.py)** – `TaskManager` provides persistent file-based CRUD for tasks. Debugging involves checking task status and dependency resolution.
- **[`agents/s08_background_tasks.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s08_background_tasks.py)** – `BackgroundManager` runs shell commands in daemon threads. Thread-safety issues appear in the `notifications` queue.
- **[`agents/s09_agent_teams.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s09_agent_teams.py)** – `MessageBus` handles JSONL inbox files in `INBOX_DIR`. Silent message failures usually involve `safe_path` validation.
- **[`agents/s10_team_protocols.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s10_team_protocols.py)** – Broadcast and shutdown coordination. Debugging requires inspecting protocol state machines.
- **[`agents/s11_autonomous_agents.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s11_autonomous_agents.py)** – `TeammateManager._loop` runs autonomous teammate loops. Idle detection and auto-claim logic require tracing the `_loop` implementation.
- **[`agents/s12_worktree_task_isolation.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s12_worktree_task_isolation.py)** – Git work-tree isolation for task directories. Failures involve `git worktree add` permissions and cleanup.

### The Capstone Integration (s_full.py)

[`agents/s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s01_agent_loop.py).

Check `response.stop_reason` after the LLM call:

- If `"max_tokens"` – The conversation hit the token limit. Use `/compact` to force `microcompact` or increase `TOKEN_THRESHOLD` in [`agents/s06_context_compact.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s06_context_compact.py).
- If `"error"` – The API request failed. Verify your `ANTHROPIC_API_KEY` and model ID in `.env`.

### Tool Handler Exceptions and Dispatch Failures

In [`agents/s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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:

1. Locate the handler in [`agents/s02_tool_use.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s02_tool_use.py) or [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s_full.py).
2. Add a temporary print inside the handler:

```python
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

```

3. 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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s03_todo_write.py) and is integrated in [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s_full.py).

Check these conditions:

- `TodoManager.has_open_items()` returns `True` (there are incomplete todos).
- `used_todo` flag is `False` for the current round (the model didn't update todos this turn).
- `rounds_without_todo` counter exceeds the threshold (typically 3).

If the nag never appears, print these variables in the main loop:

```python
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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s08_background_tasks.py).

If results don't appear:

1. Verify the daemon thread started by checking `threading.enumerate()`:

```python
import threading
print([t.name for t in threading.enumerate()])

```

2. Check the `notifications` queue in `BackgroundManager`. The `drain()` method retrieves results:

```python
from agents.s_full import BG
print(BG.drain())

```

3. 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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s09_agent_teams.py) with JSONL files in `INBOX_DIR`.

Debug steps:

1. Check if the inbox file exists:

```bash
cat .team/inbox/lead.jsonl

```

2. Verify `MessageBus.send` was called with the correct target name.

3. Inspect `safe_path` validation in [`agents/s09_agent_teams.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s09_agent_teams.py)—path escape attempts raise `ValueError` silently in some implementations.

4. Ensure the lead's inbox is being read in the main loop (`BUS.read_inbox("lead")` in [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s_full.py)).

### Token Budget Overflow and Context Compaction

Context management lives in [`agents/s06_context_compact.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s06_context_compact.py) with `microcompact` and `auto_compact`.

Symptoms: Agent forgets recent context or hits token limits frequently.

Solutions:

1. Force manual compaction with the `/compact` REPL command.

2. Check the transcript directory (`TRANSCRIPT_DIR`) for offloaded summaries.

3. Adjust `TOKEN_THRESHOLD` in the source if you consistently hit limits (default is usually around 100k tokens).

4. Inspect `estimate_tokens` implementation—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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s_full.py) provides interactive debugging commands while running:

- `/compact` – Forces immediate context compression via `microcompact`, clearing old tool-result payloads.
- `/tasks` – Prints the current task board state from `TaskManager`.
- `/team` – Lists all teammates and their current status from `TeammateManager`.
- `/inbox` – Dumps the lead's inbox JSONL contents via `MessageBus`.

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:**

```python
import threading
print([t.name for t in threading.enumerate()])

```

**Drain the background notification queue:**

```python
from agents.s_full import BG
notifications = BG.drain()
print(f"Pending notifications: {notifications}")

```

**Inspect todo state:**

```python
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

1. **Launch the full agent** to establish your baseline:

   ```bash
   python agents/s_full.py
   ```

2. **Reproduce the issue** with a minimal prompt (e.g., "Create a todo list for refactoring").

3. **Observe the tool execution flow** in the console output. Each tool prints a truncated result prefixed with `> tool_name:`.

4. **Identify the failure layer**:
   - If the model stops without tools → Check `response.stop_reason` and token counts (Layer s01/s06).
   - If a tool throws → Check `TOOL_HANDLERS` in [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s_full.py) or [`s02_tool_use.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s02_tool_use.py).
   - If todos/background/team features fail → Inspect the respective managers (s03, s08, s09).

5. **Insert temporary debug prints** in the suspect handler or manager:

   ```python
   print(f"DEBUG: Input params: {params}")
   print(f"DEBUG: Current state: {self.state}")
   ```

6. **Use REPL shortcuts** to manipulate state:
   - `/compact` if you suspect token limits.
   - `/tasks` or `/inbox` to verify subsystem state.

7. **Verify fixes** by re-running the same prompt and confirming the console output shows correct execution.

8. **Clean up** debug prints before committing changes.

## Summary

- **Architecture awareness** is critical: the agent builds from [`s01_agent_loop.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s01_agent_loop.py) through [`s12_worktree_task_isolation.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s12_worktree_task_isolation.py), with [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/s_full.py) integrating everything.
- **Common failure points** include token budget overflows (fixed via `/compact` or `auto_compact`), tool handler exceptions (caught in `TOOL_HANDLERS`), and message bus failures (check `INBOX_DIR` JSONL 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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s02_tool_use.py) or `TodoManager.update` in [`agents/s03_todo_write.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/agents/s03_todo_write.py)). The [`s_full.py`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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:

```python
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`](https://github.com/shareAI-lab/learn-claude-code/blob/main/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:

1. **Lower the history retention** by modifying the `microcompact` logic to be more aggressive about removing old tool results.
2. **Increase `TOKEN_THRESHOLD`** in the source code to match your model's actual context window.
3. **Use `/compact` manually** 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.