How to Check if an AgentSession Is Currently Running in Pi-Web

You can verify an AgentSession's execution status via the REST API endpoint GET /api/agent/[id]/state, inspect the in-process AgentSessionWrapper.isRunning() method, or subscribe to real-time updates using the global broadcast mechanism.

The pi-web repository provides three distinct mechanisms to determine whether an AgentSession is actively processing prompts or executing tasks. Depending on your architecture—whether you're integrating with the Next.js backend, debugging internal Node.js state, or building a React frontend—you can access real-time execution status through specific endpoints and wrapper methods.

Server-Side API Endpoint

The primary HTTP interface for checking session status resides in app/api/agent/[id]/state/route.ts. This Next.js API route returns a JSON payload containing a boolean running flag and detailed state information.

The handler validates the session through the RPC wrapper's isAlive() method before reporting the status. When the session exists and the RPC connection is active, the endpoint returns running: true if the agent is currently processing.

{
  "running": true,
  "state": { ... }
}
// Server-side check (Node/Next.js)
import fetch from 'node-fetch';

async function isSessionRunning(sessionId: string): Promise<boolean> {
  const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/agent/${sessionId}/state`);
  const { running } = await res.json();
  return running;
}

In-Process Status Detection

For internal logic within the Node.js process, inspect the AgentSessionWrapper class defined in lib/rpc-manager.ts. The isRunning() method (lines 39-41) aggregates multiple execution flags to determine if the session is busy.

According to the source code, isRunning() combines promptRunning, inner.isStreaming, inner.isCompacting, and inner.isBashRunning. When any of these flags are true, the session is considered active.

Direct Registry Access

Access the global session registry to check status programmatically without HTTP overhead:

import { getRegistry } from '@/lib/rpc-manager';

function logRunningSessions() {
  for (const [id, wrapper] of getRegistry()) {
    if (wrapper.isRunning()) {
      console.log(`Session ${id} is busy`);
    }
  }
}

Real-Time Client Subscriptions

Frontend components receive live updates through two mechanisms in lib/rpc-manager.ts. The subscribeRunningSessions() function (lines 1010-1015) registers callbacks that receive arrays of currently running session IDs whenever the global state changes.

Additionally, the Server-Sent Events (SSE) endpoint GET /api/agent/running/events pushes updates whenever any session starts or stops running. The React frontend typically consumes this through the useAgentSession hook, though you can implement manual subscription for custom components (refer to AGENTS.md for the data flow diagram).

React Hook Implementation

import useSWR from 'swr';

function RunningIndicator({ sessionId }: { sessionId: string }) {
  const { data } = useSWR(
    `/api/agent/${sessionId}/state`,
    url => fetch(url).then(r => r.json())
  );

  if (!data) return null;
  return data.running ? '🟢 Agent is running' : '⚪️ Agent idle';
}

Global Subscription Pattern

import { subscribeRunningSessions } from '@/lib/rpc-manager';

const unsubscribe = subscribeRunningSessions((runningSessionIds) => {
  console.log('Currently running session IDs:', runningSessionIds);
});

// Cleanup when component unmounts or updates are no longer needed
unsubscribe();

Practical Implementation Examples

When building integrations, choose the appropriate check based on your execution context:

  • Backend services: Use the HTTP API endpoint for cross-process communication or getRegistry() for co-located checks
  • Internal debugging: Call wrapper.isRunning() directly on the AgentSessionWrapper instance
  • React UI components: Consume the SWR-based hook or subscribe to the SSE stream for real-time indicators

The three-tier architecture ensures you can check status from external services (REST), within the same Node process (direct method calls), or from browser clients (subscriptions).

Summary

  • GET /api/agent/[id]/state in app/api/agent/[id]/state/route.ts returns the canonical running boolean for HTTP clients
  • AgentSessionWrapper.isRunning() in lib/rpc-manager.ts (lines 39-41) aggregates promptRunning, isStreaming, isCompacting, and isBashRunning flags for in-process checks
  • subscribeRunningSessions() in lib/rpc-manager.ts (lines 1010-1015) provides a callback-based API for real-time updates in the frontend
  • GET /api/agent/running/events exposes an SSE stream for push-based status monitoring

Frequently Asked Questions

What is the difference between isRunning() and the /state API endpoint?

The isRunning() method is an in-process function available within the Node.js runtime that checks internal flags directly on the AgentSessionWrapper instance. The /state endpoint is an HTTP interface that encapsulates this logic for external clients, returning a JSON payload after validating the RPC connection via isAlive(). Use isRunning() for internal logic and the API endpoint for cross-service communication.

How do I listen for running state changes from a React component?

Import subscribeRunningSessions from @/lib/rpc-manager to register a callback that receives an array of currently running session IDs. Alternatively, use the useAgentSession hook (defined in hooks/useAgentSession.ts) which wraps this subscription logic with React state management. For server-sent events directly, connect to GET /api/agent/running/events.

What internal flags determine if AgentSessionWrapper.isRunning() returns true?

According to the source code in lib/rpc-manager.ts, the method returns true if any of the following are active: promptRunning, inner.isStreaming, inner.isCompacting, or inner.isBashRunning. These flags track distinct execution phases including prompt processing, response streaming, memory compaction, and bash command execution.

Can I check the running status of multiple sessions at once?

Yes. Use getRegistry() from lib/rpc-manager.ts to iterate over all active session wrappers and filter by isRunning(). For client-side applications, subscribe to subscribeRunningSessions() which broadcasts the complete set of running session IDs whenever any session's status changes, eliminating the need to poll individual endpoints.

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 →