How to Debug Agent Execution Using Activity Events and Logging in Page Agent

Debug agent execution in alibaba/page-agent by listening to activity events emitted from PageAgentCore and correlating them with built-in console logs that trace every state transition from observation through tool execution.

Page Agent is an open-source browser automation library that separates transient activity events from persistent history events. Understanding how to intercept these real-time signals and console logs is essential for troubleshooting agent behavior and diagnosing performance bottlenecks. This guide explains the debugging architecture implemented in @page-agent/core and practical techniques for monitoring execution flow.

Understanding Activity Events and History Events

Page Agent maintains two distinct event systems. History events such as AgentStepEvent and ObservationEvent are persisted for later analysis, while activity events defined by the AgentActivity type in packages/core/src/types.ts (lines 64-71) provide ephemeral, real-time signals. These activities include states like thinking, executing, executed, retrying, and error, allowing you to observe the agent's immediate state without cluttering the permanent history log.

This separation of concerns ensures that UI components remain responsive by consuming lightweight activity signals, while the core logic maintains a complete audit trail of steps and observations.

Listening to Real-Time Activity Events

The core engine emits activity events via the private #emitActivity helper method located in packages/core/src/PageAgentCore.ts (lines 162-168). Every state transition—whether the agent is invoking the LLM, starting a tool, or handling an error—triggers a CustomEvent('activity', ...) that bubbles up through the PageAgent instance.

Attach an event listener to capture these payloads for custom telemetry or debugging:

import { PageAgent } from '@page-agent/core'

const agent = new PageAgent(/* config */)

agent.addEventListener('activity', (e) => {
  const activity = (e as CustomEvent).detail
  console.info('🟢 Activity:', activity)

  // Capture tool execution metrics
  if (activity.type === 'executed') {
    console.info(`Tool ${activity.tool} ran for ${activity.duration}ms, output length=${activity.output?.length}`)
  }
})

agent.execute('Search for the latest Alibaba news and summarize it')

The listener receives the full AgentActivity payload, enabling you to log timing data, track retry attempts, or forward events to external monitoring systems.

Correlating Events with Console Logging

Synchronous console.log statements embedded throughout packages/core/src/PageAgentCore.ts provide immediate visibility into the execution loop. Key diagnostic markers include:

  • "👀 Observing…" – Emitted when the agent begins scanning the current page state
  • "🧠 Thinking…" – Indicates the LLM is being invoked for reasoning or planning
  • "Executing tool" – Logs the toolName and toolInput before invocation
  • "Tool … executed for …ms" – Records the duration and result size immediately after completion

Because these logs execute before the corresponding activity events are dispatched, you can inspect raw payloads in the browser console before they reach your custom listeners or UI components. This synchronous logging is invaluable for catching serialization errors or malformed tool inputs before they propagate.

Visual Debugging with the UI Panel

For browser-based debugging, the built-in Panel class in packages/ui/src/panel/Panel.ts (lines 43-68) consumes activity events to update a floating header bar. When running the demo from packages/page-agent/src/demo.ts, this panel appears automatically and displays real-time status such as "Thinking…" or "Executing click_element_by_index".

Toggle the panel programmatically to inspect agent state without opening DevTools:

// Assuming panel reference from the demo setup
panel.show()  // Expands the debugging interface
panel.hide()  // Collapses to minimal indicator

The panel's internal activity handler processes the same event payload as custom listeners, providing a visual correlation between console logs and UI state.

Instrumenting Custom Tools

When extending Page Agent with custom tools, insert strategic logging inside the tool's execute function to trace internal logic. Because PageAgentCore emits an executing activity before the tool runs and an executed activity after, your internal logs create a clear before-and-after trace.

// Example inside packages/core/src/tools/index.ts
this.tools.set('scrape_page', {
  description: 'Scrape the current page',
  async execute(input) {
    console.debug('🔍 scrape_page called with', input)
    const html = await this.pageController.getSimplifiedHTML()
    console.debug('🔍 html length:', html.length)
    // ... tool logic ...
    return { html }
  },
})

This pattern allows you to verify that custom tools receive correct parameters and return expected data structures before the core engine wraps them in history events.

Summary

  • Activity events provide transient, real-time state signals distinct from persistent history logs, defined in packages/core/src/types.ts.
  • The #emitActivity helper in packages/core/src/PageAgentCore.ts broadcasts thinking, executing, executed, retrying, and error events as CustomEvent instances.
  • Attach listeners via agent.addEventListener('activity', ...) to capture execution metrics and performance data.
  • Built-in console logs in PageAgentCore.ts offer synchronous, immediate visibility into observation, reasoning, and tool execution phases.
  • The Panel class in packages/ui/src/panel/Panel.ts provides a visual debugging surface that consumes the same activity events, toggleable via show() and hide().
  • Instrument custom tools with console.debug statements to trace inputs and outputs, correlating with the core's built-in activity emissions.

Frequently Asked Questions

How do I distinguish between activity events and history events in Page Agent?

Activity events are transient signals representing momentary states like thinking or executed, defined by the AgentActivity type in packages/core/src/types.ts. They are emitted via CustomEvent and consumed by UI components or debuggers in real-time, then discarded. History events such as AgentStepEvent are persisted data structures that record the complete sequence of observations, thoughts, and actions for later analysis or serialization.

Where are activity events emitted in the source code?

Activity events are emitted from packages/core/src/PageAgentCore.ts via the private #emitActivity method (lines 162-168). Specific emission points include line 256 for thinking, line 409 for executing, and line 420 for executed, as well as locations handling retrying and error states. Each emission corresponds to a distinct phase in the agent's execution loop.

Can I disable the built-in console logs in production?

The built-in console.log statements in PageAgentCore.ts are static and execute unconditionally during the observation, thinking, and tool execution phases. To suppress them in production builds, you would need to modify the source tree to remove or wrap these statements in conditional checks, or configure your build pipeline to strip console.* calls during minification.

How does the UI panel correlate with console debugging?

The Panel class in packages/ui/src/panel/Panel.ts registers an activity event listener that receives the identical payload dispatched to custom listeners or the console. When the panel header displays "Thinking…" or "Executing tool...", it reflects the same AgentActivity object you can intercept programmatically or see in DevTools logs, ensuring visual and textual debugging outputs remain synchronized.

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 →