feat(CUB-19): implement AgentStatus SignalR hub for real-time updates
- 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
This commit is contained in:
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter
Executable file
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter
Executable file
Binary file not shown.
126
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.deps.json
Normal file
126
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.deps.json
Normal file
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v9.0",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v9.0": {
|
||||
"ControlCenter/1.0.0": {
|
||||
"dependencies": {
|
||||
"Swashbuckle.AspNetCore": "10.1.7"
|
||||
},
|
||||
"runtime": {
|
||||
"ControlCenter.dll": {}
|
||||
}
|
||||
},
|
||||
"Microsoft.Extensions.ApiDescription.Server/9.0.0": {},
|
||||
"Microsoft.OpenApi/2.4.1": {
|
||||
"dependencies": {
|
||||
"System.Text.Json": "8.0.5"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net8.0/Microsoft.OpenApi.dll": {
|
||||
"assemblyVersion": "2.4.1.0",
|
||||
"fileVersion": "2.4.1.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Swashbuckle.AspNetCore/10.1.7": {
|
||||
"dependencies": {
|
||||
"Microsoft.Extensions.ApiDescription.Server": "9.0.0",
|
||||
"Swashbuckle.AspNetCore.Swagger": "10.1.7",
|
||||
"Swashbuckle.AspNetCore.SwaggerGen": "10.1.7",
|
||||
"Swashbuckle.AspNetCore.SwaggerUI": "10.1.7"
|
||||
}
|
||||
},
|
||||
"Swashbuckle.AspNetCore.Swagger/10.1.7": {
|
||||
"dependencies": {
|
||||
"Microsoft.OpenApi": "2.4.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Swashbuckle.AspNetCore.Swagger.dll": {
|
||||
"assemblyVersion": "10.1.7.0",
|
||||
"fileVersion": "10.1.7.2427"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Swashbuckle.AspNetCore.SwaggerGen/10.1.7": {
|
||||
"dependencies": {
|
||||
"Swashbuckle.AspNetCore.Swagger": "10.1.7"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll": {
|
||||
"assemblyVersion": "10.1.7.0",
|
||||
"fileVersion": "10.1.7.2427"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Swashbuckle.AspNetCore.SwaggerUI/10.1.7": {
|
||||
"runtime": {
|
||||
"lib/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll": {
|
||||
"assemblyVersion": "10.1.7.0",
|
||||
"fileVersion": "10.1.7.2427"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Text.Json/8.0.5": {}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"ControlCenter/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Microsoft.Extensions.ApiDescription.Server/9.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-1Kzzf7pRey40VaUkHN9/uWxrKVkLu2AQjt+GVeeKLLpiEHAJ1xZRsLSh4ZZYEnyS7Kt2OBOPmsXNdU+wbcOl5w==",
|
||||
"path": "microsoft.extensions.apidescription.server/9.0.0",
|
||||
"hashPath": "microsoft.extensions.apidescription.server.9.0.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.OpenApi/2.4.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-u7QhXCISMQuab3flasb1hoaiERmUqyWsW7tmQODyILoQ7mJV5IRGM+2KKZYo0QUfC13evEOcHAb6TPWgqEQtrw==",
|
||||
"path": "microsoft.openapi/2.4.1",
|
||||
"hashPath": "microsoft.openapi.2.4.1.nupkg.sha512"
|
||||
},
|
||||
"Swashbuckle.AspNetCore/10.1.7": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-vgef8DPT411JU5JjHiDbr0WOxsIVuAvegPGtqmm4Na4JRl/264dfBJcGkiPHsAr5P+Vda+qN1rZKRtBl1rF9aA==",
|
||||
"path": "swashbuckle.aspnetcore/10.1.7",
|
||||
"hashPath": "swashbuckle.aspnetcore.10.1.7.nupkg.sha512"
|
||||
},
|
||||
"Swashbuckle.AspNetCore.Swagger/10.1.7": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-EjLibt/d/QuRv170GoihTbcPUpgzSFm2WKHhnGJFZQ03JYzfuitsM79azaAR8NBwRunU7yScSX6HRE5JUlrEMQ==",
|
||||
"path": "swashbuckle.aspnetcore.swagger/10.1.7",
|
||||
"hashPath": "swashbuckle.aspnetcore.swagger.10.1.7.nupkg.sha512"
|
||||
},
|
||||
"Swashbuckle.AspNetCore.SwaggerGen/10.1.7": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-PuubO9BjvNn6U3D9kLpuWKY1JtziWw7SsGBq0age1E50uQjQ8Fzl8s0EwzrLfANqYJNgDnJi9l7N1QxcGVB2Zw==",
|
||||
"path": "swashbuckle.aspnetcore.swaggergen/10.1.7",
|
||||
"hashPath": "swashbuckle.aspnetcore.swaggergen.10.1.7.nupkg.sha512"
|
||||
},
|
||||
"Swashbuckle.AspNetCore.SwaggerUI/10.1.7": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-iJo3ODyUb/M8Vm8AH1r9y9iAba0w95xsCn3zFVl96ISRHbTDWxi+l7oFVCZqUEdjd97B8VMDPnMliWAdomR8uw==",
|
||||
"path": "swashbuckle.aspnetcore.swaggerui/10.1.7",
|
||||
"hashPath": "swashbuckle.aspnetcore.swaggerui.10.1.7.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Json/8.0.5": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-0f1B50Ss7rqxXiaBJyzUu9bWFOO2/zSlifZ/UNMdiIpDYe4cY4LQQicP4nirK1OS31I43rn062UIJ1Q9bpmHpg==",
|
||||
"path": "system.text.json/8.0.5",
|
||||
"hashPath": "system.text.json.8.0.5.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.dll
Normal file
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.dll
Normal file
Binary file not shown.
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.pdb
Normal file
BIN
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.pdb
Normal file
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net9.0",
|
||||
"frameworks": [
|
||||
{
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "9.0.0"
|
||||
},
|
||||
{
|
||||
"name": "Microsoft.AspNetCore.App",
|
||||
"version": "9.0.0"
|
||||
}
|
||||
],
|
||||
"configProperties": {
|
||||
"System.GC.Server": true,
|
||||
"System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"Version":1,"ManifestType":"Build","Endpoints":[]}
|
||||
525
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.xml
Normal file
525
backend/ControlCenter/bin/Debug/net9.0/ControlCenter.xml
Normal file
@@ -0,0 +1,525 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>ControlCenter</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:ControlCenter.Controllers.AgentsController">
|
||||
<summary>
|
||||
REST API for querying agent fleet status.
|
||||
Provides the initial data load for the Command Hub,
|
||||
while real-time updates flow through the AgentStatus SignalR hub.
|
||||
|
||||
<para>API contract for Rex (Frontend):</para>
|
||||
<list type="bullet">
|
||||
<item><c>GET /api/agents</c> — Returns all known agents with current status</item>
|
||||
<item><c>GET /api/agents/{agentId}</c> — Returns a specific agent's status</item>
|
||||
</list>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.AgentsController.GetAgents">
|
||||
<summary>
|
||||
Gets the current fleet status — all known agents with their latest state.
|
||||
This is the initial load endpoint; subsequent updates arrive via SignalR.
|
||||
</summary>
|
||||
<returns>An array of agent card data for the entire fleet.</returns>
|
||||
<response code="200">Returns the fleet snapshot.</response>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.AgentsController.GetAgent(System.String)">
|
||||
<summary>
|
||||
Gets the current status of a specific agent.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier, e.g. "otto", "dex".</param>
|
||||
<returns>The agent's current card data.</returns>
|
||||
<response code="200">Returns the agent's status.</response>
|
||||
<response code="404">Agent not found in the fleet state.</response>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Controllers.CommandController">
|
||||
<summary>
|
||||
REST API for sending control commands to agents.
|
||||
Provides the Command Hub's action endpoints for agent lifecycle control.
|
||||
|
||||
<para>API contract for Rex (Frontend):</para>
|
||||
<list type="bullet">
|
||||
<item><c>POST /api/command/stop/{agentId}</c> — Stop/abort an agent's active session</item>
|
||||
<item><c>POST /api/command/restart/{agentId}</c> — Restart an agent</item>
|
||||
<item><c>POST /api/command/steer/{agentId}</c> — Inject a message into an agent's session</item>
|
||||
</list>
|
||||
|
||||
<para>Commands are forwarded to the OpenClaw Gateway via the
|
||||
WebSocket bridge service. The Gateway handles the actual execution.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.CommandController.StopAgent(System.String)">
|
||||
<summary>
|
||||
Stops (aborts) an agent's active session.
|
||||
Sends an abort command to the OpenClaw Gateway.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier to stop.</param>
|
||||
<returns>Confirmation of the stop command.</returns>
|
||||
<response code="200">Stop command sent successfully.</response>
|
||||
<response code="404">No active session found for the agent.</response>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.CommandController.RestartAgent(System.String)">
|
||||
<summary>
|
||||
Restarts an agent by aborting the current session and allowing
|
||||
a new one to start on the next incoming message.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier to restart.</param>
|
||||
<returns>Confirmation of the restart command.</returns>
|
||||
<response code="200">Restart command sent successfully.</response>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.CommandController.SteerAgent(System.String,ControlCenter.Controllers.SteerRequest)">
|
||||
<summary>
|
||||
Steers (injects a message into) an agent's active session.
|
||||
Used by operators to redirect an agent's task mid-execution.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier to steer.</param>
|
||||
<param name="request">The steering message to inject.</param>
|
||||
<returns>Confirmation of the steer command.</returns>
|
||||
<response code="200">Steer command sent successfully.</response>
|
||||
<response code="400">Missing or empty message.</response>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Controllers.SteerRequest">
|
||||
<summary>
|
||||
Request body for the steer command.
|
||||
</summary>
|
||||
<param name="Message">The message to inject into the agent's session.</param>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.SteerRequest.#ctor(System.String)">
|
||||
<summary>
|
||||
Request body for the steer command.
|
||||
</summary>
|
||||
<param name="Message">The message to inject into the agent's session.</param>
|
||||
</member>
|
||||
<member name="P:ControlCenter.Controllers.SteerRequest.Message">
|
||||
<summary>The message to inject into the agent's session.</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Controllers.LogsController">
|
||||
<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>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.LogsController.GetLogs(System.String,System.Int32)">
|
||||
<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>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Controllers.LogsController.GetToolLogs(System.String,System.Int32)">
|
||||
<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>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Hubs.AgentStatusHub">
|
||||
<summary>
|
||||
SignalR hub for real-time agent status updates in the Command Hub.
|
||||
|
||||
<para>Usage flow:</para>
|
||||
<list type="number">
|
||||
<item>Client connects to <c>/hubs/agent-status</c></item>
|
||||
<item>Client calls <see cref="M:ControlCenter.Hubs.AgentStatusHub.JoinFleet"/> to subscribe to all agent updates</item>
|
||||
<item>Client calls <see cref="M:ControlCenter.Hubs.AgentStatusHub.JoinAgentGroup(System.String)"/> to subscribe to a specific agent</item>
|
||||
<item>Server pushes <see cref="M:ControlCenter.Hubs.IAgentStatusClient.AgentStatusChanged(ControlCenter.AgentStatusUpdate)"/>
|
||||
and <see cref="M:ControlCenter.Hubs.IAgentStatusClient.AgentTaskProgress(ControlCenter.TaskProgressUpdate)"/> events</item>
|
||||
<item>Client calls <see cref="M:ControlCenter.Hubs.AgentStatusHub.GetFleetSnapshot"/> for initial state on connect</item>
|
||||
</list>
|
||||
|
||||
<para>Group naming:</para>
|
||||
<list type="bullet">
|
||||
<item>Fleet group: <c>fleet</c> — receives all agent updates</item>
|
||||
<item>Agent group: <c>agent:{agentId}</c> — receives updates for one agent</item>
|
||||
</list>
|
||||
|
||||
<para>Typed client: <see cref="T:ControlCenter.Hubs.IAgentStatusClient"/> — all server-to-client
|
||||
calls go through this interface for compile-time safety.</para>
|
||||
|
||||
<para>Architecture note: This hub bridges OpenClaw Gateway WebSocket events
|
||||
to SignalR clients. A background service (<see cref="T:ControlCenter.Services.GatewayEventBridgeService"/>)
|
||||
subscribes to Gateway events and pushes them through this hub's extension methods.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.JoinFleet">
|
||||
<summary>
|
||||
Adds the calling connection to the fleet group.
|
||||
Once joined, the client will receive all agent status changes
|
||||
and task progress updates across the entire fleet.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.LeaveFleet">
|
||||
<summary>
|
||||
Removes the calling connection from the fleet group.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.JoinAgentGroup(System.String)">
|
||||
<summary>
|
||||
Adds the calling connection to a specific agent's group.
|
||||
Once joined, the client will receive updates only for that agent.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier, e.g. "otto", "dex".</param>
|
||||
<exception cref="T:Microsoft.AspNetCore.SignalR.HubException">Thrown if agentId is null or empty.</exception>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.LeaveAgentGroup(System.String)">
|
||||
<summary>
|
||||
Removes the calling connection from a specific agent's group.
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier.</param>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.GetFleetSnapshot">
|
||||
<summary>
|
||||
Returns a snapshot of the current fleet state.
|
||||
Called by clients on initial connection to get the full picture
|
||||
before incremental updates begin arriving.
|
||||
</summary>
|
||||
<returns>An array of <see cref="T:ControlCenter.AgentCardData"/> representing all known agents.</returns>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.OnDisconnectedAsync(System.Exception)">
|
||||
<summary>
|
||||
Overrides <see cref="M:Microsoft.AspNetCore.SignalR.Hub.OnDisconnectedAsync(System.Exception)"/> to perform cleanup.
|
||||
SignalR automatically removes disconnected connections from all groups.
|
||||
</summary>
|
||||
<param name="exception">Exception that caused the disconnection, if any.</param>
|
||||
</member>
|
||||
<member name="F:ControlCenter.Hubs.AgentStatusHub.FleetGroupName">
|
||||
<summary>
|
||||
The SignalR group name for the entire fleet (all agents).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHub.AgentGroupName(System.String)">
|
||||
<summary>
|
||||
Returns the SignalR group name for a specific agent.
|
||||
Format: <c>agent:{agentId}</c> (lowercase for consistency).
|
||||
</summary>
|
||||
<param name="agentId">The agent identifier.</param>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Hubs.AgentStatusHubExtensions">
|
||||
<summary>
|
||||
Extension methods for pushing real-time agent updates through
|
||||
the <see cref="T:Microsoft.AspNetCore.SignalR.IHubContext`1"/> of <see cref="T:ControlCenter.Hubs.AgentStatusHub"/>.
|
||||
|
||||
<para>These methods are intended to be called from background services
|
||||
(e.g., <see cref="T:ControlCenter.Services.GatewayEventBridgeService"/>) or other
|
||||
server-side code that detects an agent state change.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHubExtensions.PushAgentStatusAsync(Microsoft.AspNetCore.SignalR.IHubContext{ControlCenter.Hubs.AgentStatusHub,ControlCenter.Hubs.IAgentStatusClient},ControlCenter.AgentStatusUpdate)">
|
||||
<summary>
|
||||
Pushes an agent status change to all clients subscribed to
|
||||
the fleet group and the specific agent's group.
|
||||
|
||||
<para>Call this from any background service when an agent's
|
||||
operational status changes (e.g., the Gateway reports a
|
||||
session transition from "running" to "done").</para>
|
||||
</summary>
|
||||
<param name="hubContext">The hub context injected via DI.</param>
|
||||
<param name="update">The agent status update payload.</param>
|
||||
<returns>A Task that completes when the message has been sent to all group members.</returns>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.AgentStatusHubExtensions.PushTaskProgressAsync(Microsoft.AspNetCore.SignalR.IHubContext{ControlCenter.Hubs.AgentStatusHub,ControlCenter.Hubs.IAgentStatusClient},ControlCenter.TaskProgressUpdate)">
|
||||
<summary>
|
||||
Pushes a task progress update to all clients subscribed to
|
||||
the fleet group and the specific agent's group.
|
||||
</summary>
|
||||
<param name="hubContext">The hub context injected via DI.</param>
|
||||
<param name="progress">The task progress update payload.</param>
|
||||
<returns>A Task that completes when the message has been sent to all group members.</returns>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Hubs.IAgentStatusClient">
|
||||
<summary>
|
||||
Strongly-typed client interface for the AgentStatus SignalR hub.
|
||||
Defines the methods the server can invoke on connected clients
|
||||
to push real-time agent status and task progress updates.
|
||||
|
||||
<para>All server-to-client calls go through this interface for
|
||||
compile-time safety — matching the pattern used by the
|
||||
Extrudex PrinterHub.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.IAgentStatusClient.AgentStatusChanged(ControlCenter.AgentStatusUpdate)">
|
||||
<summary>
|
||||
Pushes an agent status change to all subscribed clients.
|
||||
Fired whenever an agent's operational status changes
|
||||
(e.g., idle → active, active → thinking, active → error).
|
||||
</summary>
|
||||
<param name="update">The full status update payload.</param>
|
||||
<returns>A Task that completes when the client has processed the update.</returns>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Hubs.IAgentStatusClient.AgentTaskProgress(ControlCenter.TaskProgressUpdate)">
|
||||
<summary>
|
||||
Pushes a task progress update to all subscribed clients.
|
||||
Fired when an agent reports progress on its current task.
|
||||
</summary>
|
||||
<param name="progress">The task progress update payload.</param>
|
||||
<returns>A Task that completes when the client has processed the update.</returns>
|
||||
</member>
|
||||
<member name="T:ControlCenter.AgentStatus">
|
||||
<summary>
|
||||
Agent operational status derived from OpenClaw Gateway session activity.
|
||||
Maps to the frontend AgentStatus type: 'active' | 'idle' | 'thinking' | 'error'.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.AgentStatus.Active">
|
||||
<summary>Agent is currently processing a turn.</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.AgentStatus.Idle">
|
||||
<summary>Agent completed its last turn; no active work.</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.AgentStatus.Thinking">
|
||||
<summary>LLM call in flight; tokens streaming.</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.AgentStatus.Error">
|
||||
<summary>Agent encountered an unhandled error.</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.AgentLifecycleStatus">
|
||||
<summary>
|
||||
Extended lifecycle status including offline — not all agents have active sessions.
|
||||
Used internally; clients only see <see cref="T:ControlCenter.AgentStatus"/> (offline maps to idle).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.AgentStatusUpdate">
|
||||
<summary>
|
||||
Pushed to SignalR clients when an agent's status changes.
|
||||
Matches the TypeScript <c>AgentStatusUpdate</c> interface from the design spec.
|
||||
</summary>
|
||||
<param name="AgentId">Agent identifier, e.g. "otto", "dex".</param>
|
||||
<param name="DisplayName">Human-readable name, e.g. "Otto".</param>
|
||||
<param name="Role">Role description, e.g. "Orchestrator Agent".</param>
|
||||
<param name="Status">Current operational status.</param>
|
||||
<param name="CurrentTask">Description of the current task, if any.</param>
|
||||
<param name="SessionKey">Full session key, e.g. "agent:otto:telegram:direct:8787451565".</param>
|
||||
<param name="Channel">Channel the agent is operating on, e.g. "telegram".</param>
|
||||
<param name="LastActivity">ISO 8601 timestamp of last activity.</param>
|
||||
<param name="ErrorMessage">Error message when status is 'error'.</param>
|
||||
</member>
|
||||
<member name="M:ControlCenter.AgentStatusUpdate.#ctor(System.String,System.String,System.String,System.String,System.String,System.String,System.String,System.String,System.String)">
|
||||
<summary>
|
||||
Pushed to SignalR clients when an agent's status changes.
|
||||
Matches the TypeScript <c>AgentStatusUpdate</c> interface from the design spec.
|
||||
</summary>
|
||||
<param name="AgentId">Agent identifier, e.g. "otto", "dex".</param>
|
||||
<param name="DisplayName">Human-readable name, e.g. "Otto".</param>
|
||||
<param name="Role">Role description, e.g. "Orchestrator Agent".</param>
|
||||
<param name="Status">Current operational status.</param>
|
||||
<param name="CurrentTask">Description of the current task, if any.</param>
|
||||
<param name="SessionKey">Full session key, e.g. "agent:otto:telegram:direct:8787451565".</param>
|
||||
<param name="Channel">Channel the agent is operating on, e.g. "telegram".</param>
|
||||
<param name="LastActivity">ISO 8601 timestamp of last activity.</param>
|
||||
<param name="ErrorMessage">Error message when status is 'error'.</param>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.AgentId">
|
||||
<summary>Agent identifier, e.g. "otto", "dex".</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.DisplayName">
|
||||
<summary>Human-readable name, e.g. "Otto".</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.Role">
|
||||
<summary>Role description, e.g. "Orchestrator Agent".</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.Status">
|
||||
<summary>Current operational status.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.CurrentTask">
|
||||
<summary>Description of the current task, if any.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.SessionKey">
|
||||
<summary>Full session key, e.g. "agent:otto:telegram:direct:8787451565".</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.Channel">
|
||||
<summary>Channel the agent is operating on, e.g. "telegram".</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.LastActivity">
|
||||
<summary>ISO 8601 timestamp of last activity.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.AgentStatusUpdate.ErrorMessage">
|
||||
<summary>Error message when status is 'error'.</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.TaskProgressUpdate">
|
||||
<summary>
|
||||
Pushed to SignalR clients when an agent's task progress updates.
|
||||
Matches the TypeScript <c>TaskProgressUpdate</c> interface from the design spec.
|
||||
</summary>
|
||||
<param name="AgentId">Agent identifier.</param>
|
||||
<param name="TaskDescription">Description of the current task.</param>
|
||||
<param name="Progress">Task progress percentage (0–100), if trackable.</param>
|
||||
<param name="Elapsed">Elapsed time string, e.g. "04m 12s".</param>
|
||||
</member>
|
||||
<member name="M:ControlCenter.TaskProgressUpdate.#ctor(System.String,System.String,System.Nullable{System.Int32},System.String)">
|
||||
<summary>
|
||||
Pushed to SignalR clients when an agent's task progress updates.
|
||||
Matches the TypeScript <c>TaskProgressUpdate</c> interface from the design spec.
|
||||
</summary>
|
||||
<param name="AgentId">Agent identifier.</param>
|
||||
<param name="TaskDescription">Description of the current task.</param>
|
||||
<param name="Progress">Task progress percentage (0–100), if trackable.</param>
|
||||
<param name="Elapsed">Elapsed time string, e.g. "04m 12s".</param>
|
||||
</member>
|
||||
<member name="P:ControlCenter.TaskProgressUpdate.AgentId">
|
||||
<summary>Agent identifier.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.TaskProgressUpdate.TaskDescription">
|
||||
<summary>Description of the current task.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.TaskProgressUpdate.Progress">
|
||||
<summary>Task progress percentage (0–100), if trackable.</summary>
|
||||
</member>
|
||||
<member name="P:ControlCenter.TaskProgressUpdate.Elapsed">
|
||||
<summary>Elapsed time string, e.g. "04m 12s".</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.AgentCardData">
|
||||
<summary>
|
||||
Snapshot of an agent's full card data, sent on initial connection
|
||||
or when the fleet state is requested.
|
||||
Matches the TypeScript <c>AgentCardData</c> interface from the design spec.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.AgentCardData.#ctor(System.String,System.String,System.String,System.String,System.String,System.Nullable{System.Int32},System.String,System.String,System.String,System.String,System.String)">
|
||||
<summary>
|
||||
Snapshot of an agent's full card data, sent on initial connection
|
||||
or when the fleet state is requested.
|
||||
Matches the TypeScript <c>AgentCardData</c> interface from the design spec.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:ControlCenter.Services.GatewayEventBridgeService">
|
||||
<summary>
|
||||
Background service that connects to the OpenClaw Gateway WebSocket
|
||||
and bridges Gateway events to the <see cref="T:ControlCenter.Hubs.AgentStatusHub"/>.
|
||||
|
||||
<para>Architecture:</para>
|
||||
<list type="number">
|
||||
<item>Connects to the Gateway WS endpoint (configurable via appsettings)</item>
|
||||
<item>Handles the v3 protocol handshake (challenge → connect → hello-ok)</item>
|
||||
<item>Subscribes to <c>sessions.changed</c> and related events</item>
|
||||
<item>Translates session state changes into <see cref="T:ControlCenter.AgentStatusUpdate"/>
|
||||
and <see cref="T:ControlCenter.TaskProgressUpdate"/> objects</item>
|
||||
<item>Pushes updates through the <see cref="T:ControlCenter.Hubs.AgentStatusHub"/> SignalR hub</item>
|
||||
</list>
|
||||
|
||||
<para>This is the server-side bridge that allows Angular clients to
|
||||
receive real-time updates via SignalR instead of connecting directly
|
||||
to the Gateway WebSocket.</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.Services.GatewayEventBridgeService._fleetState">
|
||||
<summary>
|
||||
In-memory fleet state — maps agent IDs to their latest card data.
|
||||
Updated on every <c>sessions.changed</c> event from the Gateway.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:ControlCenter.Services.GatewayEventBridgeService.AgentRoles">
|
||||
<summary>
|
||||
Known agent roles for display in the Command Hub.
|
||||
Maps agent IDs to their functional descriptions.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.MapSessionStatus(System.String)">
|
||||
<summary>
|
||||
Maps OpenClaw session status to <see cref="T:ControlCenter.AgentStatus"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.GetFleetSnapshot">
|
||||
<summary>
|
||||
Returns the current fleet state snapshot.
|
||||
Used by the hub's <c>GetFleetSnapshot</c> method and by the
|
||||
<c>AgentsController</c> REST endpoint.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.ConnectAndListenAsync(System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Connects to the OpenClaw Gateway WebSocket and processes events
|
||||
until the connection is lost or cancellation is requested.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.ReceiveMessagesAsync(System.Net.WebSockets.ClientWebSocket,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Receives and processes WebSocket messages from the Gateway.
|
||||
Handles the v3 protocol handshake and dispatches events.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.ProcessMessageAsync(System.Net.WebSockets.ClientWebSocket,System.String,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Processes a single WebSocket message from the Gateway.
|
||||
Routes based on the message type: event, response, or challenge.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleConnectChallengeAsync(System.Net.WebSockets.ClientWebSocket,System.Text.Json.JsonElement,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Handles the Gateway connect.challenge event by sending
|
||||
a connect request with authentication credentials.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleGatewayEventAsync(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a Gateway event message by dispatching to the
|
||||
appropriate handler based on event name.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleSessionsChangedAsync(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a sessions.changed event from the Gateway.
|
||||
Updates the fleet state and pushes status changes through SignalR.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleSessionMessage(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a session.message event. Updates the agent's last activity
|
||||
and pushes a status update if the status changed.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleSessionTool(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a session.tool event. Extracts tool progress information
|
||||
and pushes a <see cref="T:ControlCenter.TaskProgressUpdate"/> through SignalR.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleHealthEvent(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a health event from the Gateway.
|
||||
Logs the health status for diagnostics.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.HandleGatewayResponse(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Handles a Gateway response message. Currently only logs for diagnostics.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.SessionToCardData(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Converts a raw Gateway session JSON element into an
|
||||
<see cref="T:ControlCenter.AgentCardData"/> record.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.ExtractAgentId(System.String)">
|
||||
<summary>
|
||||
Extracts the agent ID from a session key.
|
||||
Session key format: "agent:{agentId}:{channel}:..."
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:ControlCenter.Services.GatewayEventBridgeService.ExtractChannel(System.Text.Json.JsonElement)">
|
||||
<summary>
|
||||
Extracts the channel from a session element.
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
BIN
backend/ControlCenter/bin/Debug/net9.0/Microsoft.OpenApi.dll
Executable file
BIN
backend/ControlCenter/bin/Debug/net9.0/Microsoft.OpenApi.dll
Executable file
Binary file not shown.
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.Swagger.dll
Executable file
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.Swagger.dll
Executable file
Binary file not shown.
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll
Executable file
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerGen.dll
Executable file
Binary file not shown.
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll
Executable file
BIN
backend/ControlCenter/bin/Debug/net9.0/Swashbuckle.AspNetCore.SwaggerUI.dll
Executable file
Binary file not shown.
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"Microsoft.AspNetCore": "Information",
|
||||
"ControlCenter": "Debug"
|
||||
}
|
||||
},
|
||||
"Gateway": {
|
||||
"WebSocketUrl": "ws://localhost:3271/ws",
|
||||
"AuthToken": ""
|
||||
},
|
||||
"Cors": {
|
||||
"AllowedOrigins": [
|
||||
"http://localhost:4200",
|
||||
"http://localhost:5000"
|
||||
]
|
||||
}
|
||||
}
|
||||
22
backend/ControlCenter/bin/Debug/net9.0/appsettings.json
Normal file
22
backend/ControlCenter/bin/Debug/net9.0/appsettings.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning",
|
||||
"ControlCenter": "Debug"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
|
||||
"Gateway": {
|
||||
"WebSocketUrl": "ws://localhost:3271/ws",
|
||||
"AuthToken": ""
|
||||
},
|
||||
|
||||
"Cors": {
|
||||
"AllowedOrigins": [
|
||||
"http://localhost:4200",
|
||||
"http://localhost:5000"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user