-
Notifications
You must be signed in to change notification settings - Fork 0
feat: improve UI and add agent-to-agent chat #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,4 +1,8 @@ | ||||||||||||||||||||
| """OpenCLAW Bot Chat Backend""" | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import subprocess | ||||||||||||||||||||
| import re | ||||||||||||||||||||
|
|
||||||||||||||||||||
| from fastapi import FastAPI, HTTPException | ||||||||||||||||||||
| from pydantic import BaseModel | ||||||||||||||||||||
| from openclaw_client import OpenCLAWClient | ||||||||||||||||||||
|
|
@@ -20,25 +24,64 @@ def root(): | |||||||||||||||||||
| return {"message": "OpenCLAW Bot Chat API"} | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| def get_agents_from_openclaw() -> list[dict]: | ||||||||||||||||||||
| """Get agents from OpenCLAW CLI.""" | ||||||||||||||||||||
| try: | ||||||||||||||||||||
| output = subprocess.check_output( | ||||||||||||||||||||
| ["openclaw", "agents", "list"], timeout=10, text=True | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| agents = [] | ||||||||||||||||||||
| for line in output.split("\n"): | ||||||||||||||||||||
| # Match "- agentName" or "- agentName (default)" format | ||||||||||||||||||||
| match = re.match(r"^- (\w+)", line) | ||||||||||||||||||||
|
||||||||||||||||||||
| match = re.match(r"^- (\w+)", line) | |
| match = re.match(r"^- ([^(\s]+)", line) |
Copilot
AI
Mar 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring says this endpoint gets agents "from OpenCLAW Gateway", but the implementation now shells out to the OpenCLAW CLI (with a fallback list). Update the docstring (and any related docs) so it reflects the real source of truth and failure behavior.
| """Get list of agents from OpenCLAW Gateway.""" | |
| """Get list of agents using the OpenCLAW CLI, with a fallback to default agents. | |
| This endpoint invokes `get_agents_from_openclaw`, which shells out to the | |
| `openclaw agents list` CLI command to discover available agents. If the CLI | |
| invocation fails or returns no agents, a predefined set of default agents is | |
| returned instead. Only unexpected errors in this process result in a 503 | |
| Service Unavailable response. | |
| """ |
Copilot
AI
Mar 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/api/agents now calls get_agents_from_openclaw() which catches all exceptions and returns [], causing this endpoint to return 200 with fallback agents even when OpenCLAW is unavailable. The existing test suite expects a 503 on upstream failure (see backend/tests/test_routes.py::test_get_agents_gateway_unavailable). Either update the endpoint contract/tests, or let failures propagate so the route can return a 503 consistently.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| """WebSocket Manager for real-time chat.""" | ||
|
|
||
| from typing import Dict | ||
| from fastapi import WebSocket | ||
|
|
||
|
|
@@ -28,3 +29,11 @@ async def broadcast(self, message: dict, exclude: str | None = None): | |
| except Exception: | ||
| # Handle disconnection gracefully | ||
| self.disconnect(client_id) | ||
|
|
||
| async def send_to(self, client_id: str, message: dict): | ||
| """Send a message to a specific client.""" | ||
| if client_id in self.active_connections: | ||
| try: | ||
| await self.active_connections[client_id].send_json(message) | ||
| except Exception: | ||
| self.disconnect(client_id) | ||
|
Comment on lines
+33
to
+39
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
subprocess.check_output(...)is called from within an async request path (/api/agents). Because it’s synchronous, it will block the event loop while the CLI runs (up to the 10s timeout), reducing throughput for all requests. Run the CLI call in a thread (asyncio.to_thread) or use an async subprocess API, and consider caching results to avoid running the CLI on every request.