Skip to content

Comments

Claude/gateway rpc refactor z6 uu1#1

Merged
burnshall-ui merged 2 commits intomainfrom
claude/gateway-rpc-refactor-z6Uu1
Feb 17, 2026
Merged

Claude/gateway rpc refactor z6 uu1#1
burnshall-ui merged 2 commits intomainfrom
claude/gateway-rpc-refactor-z6Uu1

Conversation

@burnshall-ui
Copy link
Owner

@burnshall-ui burnshall-ui commented Feb 17, 2026

Note

Medium Risk
Moderate risk: replaces CLI/config-file based backend paths with Gateway RPC + a persistent WebSocket→SSE bridge, which could impact core dashboard data loading and realtime updates if the Gateway protocol/availability differs.

Overview
Migrates agent and model backend endpoints off local openclaw CLI / filesystem reads and onto callGatewayRpc (agents.list/add/delete/update, models.list with status fallback), including a new PATCH /api/agents/[id] for updates.

Adds realtime plumbing by introducing a persistent Gateway WebSocket event singleton (gatewayEvents), exposing it via a new SSE endpoint GET /api/events, and wiring the dashboard to display Gateway connection status plus apply live agent status/task/log updates with periodic list refresh.

Updates SSR (app/page.tsx) to call the Gateway directly (no self-fetch), extends agent typing/mapping (GatewayAgentEntry + gatewayEntryToAgent), adds GET /api/status health/presence probe, and pins typescript to 5.9.3.

Written by Cursor Bugbot for commit 366340e. This will update automatically on new commits. Configure here.

Replace all child_process.exec("openclaw agents ...") calls with
callGatewayRpc() WebSocket calls. Add persistent event streaming via
GatewayEventManager singleton, SSE endpoint (/api/events), status
endpoint (/api/status), and useGatewayEvents React hook for live
dashboard updates. Server component now calls Gateway directly
instead of self-fetching localhost.

https://claude.ai/code/session_01XLFgYizVSscsWXY3FF724r
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

This PR is being reviewed by Cursor Bugbot

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

cancel() {
// Client disconnected — cleanup happens via the Proxy above
// or we can do additional cleanup here if needed
},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SSE event listener cleanup never executes on disconnect

High Severity

The cleanup function (which removes event listeners from the singleton gatewayEvents and clears the heartbeat interval) is only reachable via a Proxy on controller.close. However, when a client disconnects from an SSE stream, the runtime invokes the cancel() callback on the underlying source — not controller.close(). The cancel() body is empty, so cleanup never runs. Every client connection permanently adds four event listeners to gatewayEvents and leaks a setInterval, causing unbounded resource growth.

Fix in Cursor Fix in Web

return updatedAgent;
}),
);
}, [getAgentUpdate]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Log entries duplicated on every agent update event

Medium Severity

The useEffect depends on getAgentUpdate, which gets a new identity every time the agentUpdates map changes (any agent update). Updates are never cleared from the map after being applied. So when agent B receives an event, the effect re-runs for all agents — and agent A's previously-applied update.log is appended again to its logs array. This causes the same log entry to be duplicated with every subsequent gateway event from any agent.

Fix in Cursor Fix in Web


await callGatewayRpc<unknown>("agents.update", {
id,
...body,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request body can override URL-derived agent ID

Medium Severity

In the PATCH handler, the RPC params are built as { id, ...body }. Since AgentUpdateParams includes an id field, and body is spread after the URL-derived id, a client can send { "id": "other-agent" } in the request body to update a different agent than the one in the URL path. The response still returns agentId: id from the URL, masking the mismatch.

Fix in Cursor Fix in Web

@burnshall-ui burnshall-ui merged commit 1f7eb06 into main Feb 17, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants