-
Notifications
You must be signed in to change notification settings - Fork 181
Fix network list --status command to detect running networks #152
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
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Co-authored-by: zomux <1029280+zomux@users.noreply.github.com>
Co-authored-by: zomux <1029280+zomux@users.noreply.github.com>
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.
Pull request overview
This PR fixes the openagents network list --status command which previously showed "No networks found" regardless of whether networks were actually running. The fix adds real network discovery functionality by scanning common OpenAgents ports for running network instances.
- Implements
discover_running_networks()function to scan for active networks via HTTP health checks - Adds PID detection for discovered networks using platform-specific commands (
ssfor Linux,lsoffor macOS) - Includes comprehensive test suite covering various scenarios (connection errors, timeouts, deduplication, etc.)
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 16 comments.
| File | Description |
|---|---|
| src/openagents/cli.py | Adds discover_running_networks() function and integrates it into network_list command to detect and display running networks |
| tests/network/test_network_discovery.py | Comprehensive test suite for network discovery functionality covering edge cases, error handling, and deduplication |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if result.returncode == 0 and result.stdout: | ||
| # Find lines containing the port and extract PID | ||
| for line in result.stdout.split("\n"): | ||
| if f":{port}" in line: |
Copilot
AI
Dec 1, 2025
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 port search pattern f":{port}" in line 1867 could produce false positives. For example, when searching for port 8700, it would also match port 18700 or 28700.
Consider using a more precise pattern with word boundaries or specific delimiters:
if f":{port} " in line or f":{port}\t" in line or line.rstrip().endswith(f":{port}"):| if f":{port}" in line: | |
| if ( | |
| f":{port} " in line | |
| or f":{port}\t" in line | |
| or line.rstrip().endswith(f":{port}") | |
| ): |
| import requests | ||
|
|
||
| with patch('requests.get', side_effect=requests.exceptions.Timeout()): |
Copilot
AI
Dec 1, 2025
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 import statement is inside the test function. While this works, it's better practice to import at the module level or use proper mocking. Since requests is already being patched with patch('requests.get', ...), the import is unnecessary here.
Consider removing the import statement:
def test_discover_handles_timeout(self):
"""Test that timeouts are handled gracefully."""
from requests.exceptions import Timeout
with patch('requests.get', side_effect=Timeout()):
networks = discover_running_networks(
ports=[8700],
hosts=["localhost"],
timeout=1.0
)
assert networks == []| import requests | ||
|
|
||
| with patch('requests.get', side_effect=requests.exceptions.ConnectionError("No network")): |
Copilot
AI
Dec 1, 2025
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 import statement is inside the test function. While this works, it's better practice to import at the module level. Since you're only using the module to reference the exception, consider importing at the top.
Consider removing the import statement:
def test_discover_with_default_ports(self):
"""Test discovery uses reasonable default ports."""
from requests.exceptions import ConnectionError
with patch('requests.get', side_effect=ConnectionError("No network")):
# Just verify it runs without error using defaults
networks = discover_running_networks(timeout=0.1)
assert networks == []| } | ||
| } | ||
|
|
||
| with patch('requests.get', return_value=mock_response): |
Copilot
AI
Dec 1, 2025
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.
[nitpick] The patch target 'requests.get' patches the requests module globally. Since discover_running_networks imports requests inside the function, the patch target should be 'openagents.cli.requests.get' to patch it where it's used, not where it's defined.
However, since requests is imported inside the function, the current approach happens to work. For better practice and clarity, consider either:
- Moving the
import requeststo the top of cli.py - Or updating the patch target to
'openagents.cli.requests.get'
Current approach works but may be fragile if the import location changes.
| import requests | ||
| import re |
Copilot
AI
Dec 1, 2025
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 requests and re modules are imported inside the function. While this works, it's better practice to import them at the module level for consistency with the rest of the file and to avoid repeated import overhead if the function is called multiple times.
Consider moving these imports to the top of the file:
import re
import requests| import requests | ||
|
|
||
| with patch('requests.get', side_effect=requests.exceptions.ConnectionError()): |
Copilot
AI
Dec 1, 2025
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 import statement is inside the test function. While this works, it's better practice to import at the module level or use proper mocking. Since requests is already being patched with patch('requests.get', ...), the import is unnecessary here.
Consider removing the import statement:
def test_discover_handles_connection_error(self):
"""Test that connection errors are handled gracefully."""
from requests.exceptions import ConnectionError
with patch('requests.get', side_effect=ConnectionError()):
networks = discover_running_networks(
ports=[8700],
hosts=["localhost"],
timeout=1.0
)
assert networks == []|
|
||
| if status: | ||
| table.add_column("Name", style="cyan") | ||
| table.add_column("Status", style="green") |
Copilot
AI
Dec 1, 2025
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.
[nitpick] The status_text contains Rich markup ([green]Running[/green] or [red]Stopped[/red]), but when the status is "Stopped", the table column header is styled as "green". This creates a visual inconsistency where the column is labeled with green styling but may contain red-colored "Stopped" text.
Consider using a neutral style for the Status column header or using a style like "bold" that doesn't imply a specific state:
table.add_column("Status", style="bold")| table.add_column("Status", style="green") | |
| table.add_column("Status", style="bold") |
| timeout=2, | ||
| ) | ||
| if result.returncode == 0 and result.stdout: | ||
| pid = result.stdout.strip().split("\n")[0] |
Copilot
AI
Dec 1, 2025
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.
[nitpick] The PID detection only handles Linux (sys.platform.startswith("linux")) and macOS (sys.platform == "darwin"), but doesn't handle Windows or other platforms. While the pid variable defaults to None, it would be clearer to have an explicit comment or log message indicating that PID detection is not supported on other platforms.
Consider adding a comment or else clause:
elif sys.platform == "darwin":
# macOS PID detection
...
# Note: PID detection not supported on Windows and other platforms| pid = result.stdout.strip().split("\n")[0] | |
| pid = result.stdout.strip().split("\n")[0] | |
| else: | |
| # PID detection not supported on Windows and other platforms | |
| logging.debug(f"PID detection is not supported on platform: {sys.platform}") |
| # Skip if we've already found this network | ||
| if network_id in seen_networks: | ||
| continue | ||
| seen_networks.add(network_id) |
Copilot
AI
Dec 1, 2025
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.
If multiple networks return no network_id field, they will all be assigned the default value "unknown" and subsequently deduplicated as if they were the same network. This could hide multiple distinct networks that lack IDs.
Consider using a combination of host, port, and network_name for deduplication when network_id is "unknown":
network_id = network_data.get("network_id", "unknown")
# Create a unique identifier for deduplication
if network_id == "unknown":
dedup_key = f"{host}:{port}:{network_data.get('network_name', 'Unknown')}"
else:
dedup_key = network_id
if dedup_key in seen_networks:
continue
seen_networks.add(dedup_key)| # Skip if we've already found this network | |
| if network_id in seen_networks: | |
| continue | |
| seen_networks.add(network_id) | |
| # Create a unique deduplication key | |
| if network_id == "unknown": | |
| dedup_key = f"{host}:{port}:{network_data.get('network_name', 'Unknown')}" | |
| else: | |
| dedup_key = network_id | |
| # Skip if we've already found this network | |
| if dedup_key in seen_networks: | |
| continue | |
| seen_networks.add(dedup_key) |
| used by the `openagents network list --status` command. | ||
| """ | ||
|
|
||
| import pytest |
Copilot
AI
Dec 1, 2025
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.
Import of 'pytest' is not used.
| import pytest |
The
openagents network list --statuscommand always showed "No networks found" regardless of whether networks were running. The command was a static placeholder with no actual discovery logic.Changes
discover_running_networks()function - Scans common OpenAgents ports (8700, 8570, 8050, etc.) via/api/healthendpoint to identify running networkssson Linux,lsofon macOS)Example
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
api.openai.com/usr/bin/python python -m pytest tests/ -x -q(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.