- Add AgentStatusHub with typed IAgentStatusClient interface
- Hub at /hubs/agent-status (matches design spec)
- Fleet group + per-agent group subscription
- AgentStatusChanged and AgentTaskProgress push events
- Extension methods for server-side push via IHubContext
- Add GatewayEventBridgeService background service
- Connects to OpenClaw Gateway WebSocket (v3 protocol)
- Handles challenge → connect → hello-ok handshake
- Bridges sessions.changed, session.message, session.tool events
- Translates Gateway session status to AgentStatus enum
- Maintains in-memory fleet state for snapshot queries
- Add REST API controllers
- GET /api/agents — fleet status snapshot
- GET /api/agents/{agentId} — single agent status
- GET /api/logs/{agentId} — agent session logs (stub)
- POST /api/command/stop/{agentId} — stop agent
- POST /api/command/restart/{agentId} — restart agent
- POST /api/command/steer/{agentId} — inject message
- Add models matching TypeScript spec interfaces
- AgentStatusUpdate, TaskProgressUpdate, AgentCardData
- AgentStatus enum (active/idle/thinking/error)
- Configure CORS with credentials for SignalR WebSocket
- Configure Swagger/OpenAPI with XML doc comments
- Agent role map matching frontend AGENT_ROLES constant
87 lines
3.4 KiB
C#
87 lines
3.4 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
|
|
namespace ControlCenter.Controllers;
|
|
|
|
/// <summary>
|
|
/// REST API for querying agent session logs.
|
|
/// Provides historical message and tool call logs for a specific agent.
|
|
///
|
|
/// <para>API contract for Rex (Frontend):</para>
|
|
/// <list type="bullet">
|
|
/// <item><c>GET /api/logs/{agentId}</c> — Returns recent logs for an agent</item>
|
|
/// <item><c>GET /api/logs/{agentId}/tools</c> — Returns recent tool calls for an agent</item>
|
|
/// </list>
|
|
///
|
|
/// <para>Log data is sourced from the OpenClaw Gateway's transcript files.
|
|
/// The Gateway's <c>logs.tail</c> RPC provides the raw data, and this
|
|
/// controller formats it for the frontend.</para>
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
public class LogsController : ControllerBase
|
|
{
|
|
private readonly ILogger<LogsController> _logger;
|
|
|
|
public LogsController(ILogger<LogsController> logger)
|
|
{
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets recent session logs for a specific agent.
|
|
/// Returns the last N messages from the agent's active session transcript.
|
|
/// </summary>
|
|
/// <param name="agentId">The agent identifier, e.g. "otto", "dex".</param>
|
|
/// <param name="limit">Maximum number of log entries to return (default: 50, max: 200).</param>
|
|
/// <returns>An array of log entries for the agent.</returns>
|
|
/// <response code="200">Returns the agent's recent logs.</response>
|
|
/// <response code="404">No active session found for the agent.</response>
|
|
[HttpGet("{agentId}")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public IActionResult GetLogs(string agentId, [FromQuery] int limit = 50)
|
|
{
|
|
limit = Math.Clamp(limit, 1, 200);
|
|
|
|
_logger.LogDebug("Logs requested for agent {AgentId}, limit {Limit}", agentId, limit);
|
|
|
|
// TODO: Implement log retrieval by calling the Gateway's logs.tail RPC
|
|
// or reading transcript files. For now, return an empty array as the
|
|
// bridge service will provide this data when fully integrated.
|
|
return Ok(new
|
|
{
|
|
agentId,
|
|
logs = Array.Empty<object>(),
|
|
count = 0,
|
|
hasMore = false
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets recent tool call logs for a specific agent.
|
|
/// Returns the last N tool invocations from the agent's session.
|
|
/// </summary>
|
|
/// <param name="agentId">The agent identifier.</param>
|
|
/// <param name="limit">Maximum number of tool entries to return (default: 20, max: 100).</param>
|
|
/// <returns>An array of tool call entries for the agent.</returns>
|
|
/// <response code="200">Returns the agent's recent tool calls.</response>
|
|
/// <response code="404">No active session found for the agent.</response>
|
|
[HttpGet("{agentId}/tools")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
|
public IActionResult GetToolLogs(string agentId, [FromQuery] int limit = 20)
|
|
{
|
|
limit = Math.Clamp(limit, 1, 100);
|
|
|
|
_logger.LogDebug("Tool logs requested for agent {AgentId}, limit {Limit}", agentId, limit);
|
|
|
|
// TODO: Implement tool log retrieval. Return empty for now.
|
|
return Ok(new
|
|
{
|
|
agentId,
|
|
tools = Array.Empty<object>(),
|
|
count = 0,
|
|
hasMore = false
|
|
});
|
|
}
|
|
} |