Debugging Agent Execution Flow in Codebuff: Recommended Strategies

To debug agent execution flow in Codebuff, enable the CACHE_DEBUG_FULL_LOGGING flag, use the structured logger utility with context-aware logging, and inspect the JSONL debug logs and cache snapshots using built-in comparison scripts.

Codebuff’s agents execute through a tightly-coupled loop that builds prompts, streams LLM responses, processes tool calls, and persists state. Because this flow is highly dynamic, the repository provides several built-in mechanisms to make debugging transparent and reproducible. This guide covers the architectural hooks and practical workflows for debugging agent execution flow in Codebuff.

Core Debugging Architecture

The debugging system centers on a Pino-based logger that writes structured JSON lines to debug/web.jsonl during local development. This logger is configured in web/src/util/logger.ts (lines 18-49), where it creates the debug folder and sets up the destination stream. When running in development mode (IS_DEV && !IS_CI), logs also fall back to console output for real-time monitoring.

For correlating messages across asynchronous steps, the loggerWithContext function (lines 71-88 in the same file) injects static context—such as runId and agentId—into every log entry. This makes it trivial to grep for a specific execution trace across thousands of log lines.

Enabling Full Request Logging

The most powerful switch for debugging agent execution flow is CACHE_DEBUG_FULL_LOGGING, defined in packages/agent-runtime/src/constants.ts (lines 5-12). When set to true, the runtime persists the complete LLM request—including the system prompt, tool definitions, and message history—to debug/cache-debug/<runId>-<iteration>.json.

This is the only mechanism that provides a per-prompt snapshot of exactly what the runtime sends to the provider, making it essential for diagnosing prompt-cache misses or unexpected token counts.

To enable it:

// packages/agent-runtime/src/constants.ts
export const CACHE_DEBUG_FULL_LOGGING = true; // <-- enable full request logging

Structured Logging in the Execution Loop

The core agent execution logic resides in packages/agent-runtime/src/run-agent-step.ts, which contains granular logger.debug statements at critical junctures:

  • Iteration start (lines 310-327): Logs the iteration number, model configuration, token counts, and the compiled prompt.
  • Compact-command handling (lines 430-444): Emits debug entries when the /compact command truncates message history.
  • End-of-turn decision (lines 470-485): Records why the agent decided to end the turn (e.g., task_completed tool called, no tool calls present, or think-only response).

These logs flow through the Pino pipeline and appear in debug/web.jsonl with full context attached.

Analyzing Cache Snapshots

When debugging prompt-cache behavior, use the scripts/compare-cache-debug.ts utility. This script reads the cached request snapshots from debug/cache-debug/ and prints a unified diff between successive prompts.

This is the definitive tool for locating why a prompt-cache miss occurred—whether due to a new tool being added, a timestamp in the system prompt, or message ordering changes.

To compare two snapshots:

bun scripts/compare-cache-debug.ts \
  debug/cache-debug/run-123-1.json \
  debug/cache-debug/run-123-2.json

Debugging Tool Call Processing

Tool call parsing happens in packages/agent-runtime/src/tools/stream-parser.ts within the processStream function. This module emits logger.debug statements that surface:

  • Raw tool call chunks from the LLM stream
  • Parsing errors or malformed JSON
  • Final ToolMessage construction

If an agent fails to execute a tool or appears to ignore a tool result, inspect the logs from this module to verify that the stream was parsed correctly.

Environment-Level Debug Toggles

Additional granular control is available through environment flags defined in common/src/env.ts. The most relevant is DEBUG_ANALYTICS (line 23), which logs raw analytics payloads to the console before they are sent to the telemetry endpoint.

Other modules, such as packages/agent-runtime/src/system-prompt/truncate-file-tree.ts, check a generic DEBUG flag to emit additional console output without affecting the structured production logs.

Practical Debugging Workflow

Follow this sequence to diagnose issues in agent execution flow:

  1. Enable full cache logging by setting CACHE_DEBUG_FULL_LOGGING = true in packages/agent-runtime/src/constants.ts.

  2. Run the agent in debug mode:

    bun dev -- --debug

    This forces IS_DEV mode, creating the debug/ folder and enabling console output.

  3. Inspect iteration logs to verify prompt composition:

    cat debug/web.jsonl | jq -c 'select(.level=="DEBUG")' | less

    Search for "Start agent" entries to confirm the correct prompt and tool set were assembled.

  4. Diff cache snapshots if experiencing cache misses:

    bun scripts/compare-cache-debug.ts

    This reveals exactly which fields changed between iterations.

  5. Trace tool call flow by grepping for "toolCalls" or "toolResults" in debug/web.jsonl. Check packages/agent-runtime/src/tools/stream-parser.ts debug statements for parsing errors.

  6. Use contextual logging in custom agents:

    const log = loggerWithContext({ runId, agentId });
    log.debug({ step: 1 }, 'Custom agent step started');
  7. Enable analytics debugging by setting DEBUG_ANALYTICS=true in your environment to see raw telemetry payloads.

This workflow provides end-to-end visibility into prompt construction, token counting, LLM streaming, tool-call handling, and turn-ending logic.

Summary

  • Enable CACHE_DEBUG_FULL_LOGGING in packages/agent-runtime/src/constants.ts to capture complete LLM request snapshots for every iteration.
  • Use the Pino-based logger in web/src/util/logger.ts with loggerWithContext to correlate logs across asynchronous agent steps using runId and agentId.
  • Inspect run-agent-step.ts debug statements (lines 310-327, 430-444, 470-485) to verify iteration starts, compact commands, and turn-ending decisions.
  • Run compare-cache-debug.ts to diff cached request snapshots and diagnose prompt-cache misses.
  • Check stream-parser.ts debug logs to trace tool call parsing and identify malformed LLM outputs.
  • Toggle environment flags like DEBUG_ANALYTICS in common/src/env.ts for additional console visibility without affecting production logs.

Frequently Asked Questions

How do I enable detailed logging for a specific agent run?

Set CACHE_DEBUG_FULL_LOGGING to true in packages/agent-runtime/src/constants.ts and run the agent with the --debug flag. This writes complete LLM request snapshots to debug/cache-debug/ and streams structured logs to debug/web.jsonl. Use loggerWithContext({ runId, agentId }) in your agent code to ensure every log entry is tagged with identifiers for easy filtering.

Why is my prompt cache missing even though the prompt looks identical?

Prompt-cache misses usually occur due to non-obvious differences in the request payload. Use the scripts/compare-cache-debug.ts utility to diff successive snapshots from debug/cache-debug/. This script reveals exact changes in system prompts, tool definitions, or message ordering that invalidate the cache. Even minor changes like timestamps in metadata or different tool ordering can cause misses.

How can I trace why a tool call failed to execute?

Tool call execution issues are typically logged in packages/agent-runtime/src/tools/stream-parser.ts. Search your debug/web.jsonl for entries containing "toolCalls" or "toolResults" to see the raw LLM output and parsed results. The processStream function emits debug statements when it encounters malformed JSON or parsing errors. Additionally, check run-agent-step.ts (lines 430-444) to verify if the compact command or message truncation affected the tool call context.

What is the difference between the logger and console output in development?

In development mode (IS_DEV && !IS_CI), the logger configured in web/src/util/logger.ts writes structured JSON lines to both debug/web.jsonl and the console. The file output preserves the full structured data for programmatic analysis with tools like jq, while the console output provides immediate visual feedback. Production mode only writes to rotating files or analytics endpoints, omitting console output entirely. Use DEBUG_ANALYTICS in common/src/env.ts to see raw analytics payloads in the console without affecting the structured log stream.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →