mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 22:11:14 +02:00
style: fix E501 line-too-long errors in gns3_copilot
Fix all 423 E501 line length violations across 26 files to comply with
PEP 8 88-character line limit.
Changes:
- Split long f-strings across multiple lines
- Break long docstring descriptions and parameter lists
- Split markdown table rows and list examples
- Break long URL construction f-strings
- Split long logger messages and comments
- Add noqa: E501 for SVG strings (cannot be split)
Modified files:
- agent/: context_manager.py, gns3_copilot.py, model_factory.py
- gns3_client/: connector_factory.py, context_helpers.py, custom_gns3fy.py,
gns3_project_info.py, gns3_topology_reader.py
- prompts/: __init__.py, lab_automation_assistant_prompt.py,
prompt_loader.py, teaching_assistant_prompt.py
- tools_v2/: __init__.py, config_tools_nornir.py, display_tools_nornir.py,
gns3_create_link.py, gns3_create_node.py, gns3_get_node_temp.py,
gns3_start_node.py, gns3_update_node_name.py,
vpcs_tools_telnetlib3.py
- utils/: __init__.py, command_filter.py, get_gns3_device_port.py,
gns3_drawing_utils.py, llm_config_helper.py, message_converters.py,
parse_tool_content.py, tool_call_stream.py
All files now pass ruff E501 checks.
Co-Authored-By: Yue Guobin <yueguobin@outlook.com>
This commit is contained in:
1 parent
25f2d1b56b
commit
7c3b832bca
32 files changed
+1967
-762
No files matched your search
@@ -85,12 +85,14 @@ def parse_tool_content(
|
||||
by json.dumps.
|
||||
|
||||
Args:
|
||||
content: Content returned by tools (can be str, dict, list, int, float, bool, or None)
|
||||
content: Content returned by tools (can be str, dict, list, int, float, bool,
|
||||
or None)
|
||||
fallback_to_raw: Whether to return raw content when parsing fails, default True
|
||||
strict_mode: Strict mode, raises exceptions when parsing fails, default False
|
||||
|
||||
Returns:
|
||||
Union[Dict[str, Any], List[Any], Any]: Parsed data that can be serialized by json.dumps:
|
||||
Union[Dict[str, Any], List[Any], Any]: Parsed data that can be serialized by
|
||||
json.dumps:
|
||||
- Successfully parsed JSON/Python literal data
|
||||
- Original dict/list objects (passed through)
|
||||
- Primitive types (int, float, bool, str)
|
||||
@@ -158,7 +160,9 @@ def parse_tool_content(
|
||||
# Empty string handling
|
||||
if not content.strip():
|
||||
result = {}
|
||||
logger.info("Content is empty or whitespace, returning: %s", result)
|
||||
logger.info(
|
||||
"Content is empty or whitespace, returning: %s", result
|
||||
)
|
||||
return result
|
||||
|
||||
s = content.strip()
|
||||
@@ -166,14 +170,19 @@ def parse_tool_content(
|
||||
# Handle empty dictionary case
|
||||
if s == "{}":
|
||||
result = {}
|
||||
logger.info("Content is empty dictionary, returning: %s", result)
|
||||
logger.info(
|
||||
"Content is empty dictionary, returning: %s", result
|
||||
)
|
||||
return result
|
||||
|
||||
# Try to parse as Python literal
|
||||
# (higher priority as many tools return Python format strings)
|
||||
try:
|
||||
result = ast.literal_eval(s)
|
||||
logger.info("Successfully parsed as Python literal, returning: %s", result)
|
||||
logger.info(
|
||||
"Successfully parsed as Python literal, returning: %s",
|
||||
result,
|
||||
)
|
||||
return result
|
||||
except (ValueError, SyntaxError):
|
||||
pass
|
||||
@@ -181,7 +190,9 @@ def parse_tool_content(
|
||||
# Try to parse as JSON
|
||||
try:
|
||||
result = json.loads(s)
|
||||
logger.info("Successfully parsed as JSON, returning: %s", result)
|
||||
logger.info(
|
||||
"Successfully parsed as JSON, returning: %s", result
|
||||
)
|
||||
return result
|
||||
except json.JSONDecodeError:
|
||||
pass
|
||||
@@ -210,7 +221,8 @@ def parse_tool_content(
|
||||
|
||||
# Handle unsupported types
|
||||
error_msg = ( # type: ignore[unreachable]
|
||||
"Content must be str, dict, list, int, float, bool, or None, got " f"{type(content).__name__}"
|
||||
"Content must be str, dict, list, int, float, bool, or None, got "
|
||||
f"{type(content).__name__}"
|
||||
)
|
||||
logger.error(error_msg)
|
||||
|
||||
@@ -226,7 +238,9 @@ def parse_tool_content(
|
||||
return result
|
||||
|
||||
|
||||
def format_tool_response(content: str | dict | list | int | float | bool | None, indent: int = 2) -> str:
|
||||
def format_tool_response(
|
||||
content: str | dict | list | int | float | bool | None, indent: int = 2
|
||||
) -> str:
|
||||
"""
|
||||
Format tool response as a beautiful JSON string for UI display.
|
||||
|
||||
@@ -234,7 +248,8 @@ def format_tool_response(content: str | dict | list | int | float | bool | None,
|
||||
properly displayed in UI interfaces.
|
||||
|
||||
Args:
|
||||
content: Content returned by tools (can be str, dict, list, int, float, bool, or None)
|
||||
content: Content returned by tools (can be str, dict, list, int, float, bool,
|
||||
or None)
|
||||
indent: JSON indentation spaces, default 2
|
||||
|
||||
Returns:
|
||||
@@ -244,7 +259,9 @@ def format_tool_response(content: str | dict | list | int | float | bool | None,
|
||||
logger.info("format_tool_response parameter indent: %s", indent)
|
||||
|
||||
try:
|
||||
parsed = parse_tool_content(content, fallback_to_raw=True, strict_mode=False)
|
||||
parsed = parse_tool_content(
|
||||
content, fallback_to_raw=True, strict_mode=False
|
||||
)
|
||||
# Ensure the result can be serialized to JSON
|
||||
result = json.dumps(parsed, ensure_ascii=False, indent=indent)
|
||||
logger.info("format_tool_response returning: %s", result)
|
||||
@@ -253,7 +270,9 @@ def format_tool_response(content: str | dict | list | int | float | bool | None,
|
||||
# If the parsed result cannot be serialized, convert to string and wrap
|
||||
logger.error("Cannot serialize parsed result to JSON: %s", e)
|
||||
try:
|
||||
result = json.dumps({"raw": str(content)}, ensure_ascii=False, indent=indent)
|
||||
result = json.dumps(
|
||||
{"raw": str(content)}, ensure_ascii=False, indent=indent
|
||||
)
|
||||
logger.info("format_tool_response returning fallback: %s", result)
|
||||
return result
|
||||
except Exception:
|
||||
@@ -267,12 +286,16 @@ def format_tool_response(content: str | dict | list | int | float | bool | None,
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.error("Error formatting tool response: %s", e)
|
||||
result = json.dumps({"error": str(e)}, ensure_ascii=False, indent=indent)
|
||||
result = json.dumps(
|
||||
{"error": str(e)}, ensure_ascii=False, indent=indent
|
||||
)
|
||||
logger.info("format_tool_response returning error: %s", result)
|
||||
return result
|
||||
|
||||
|
||||
def normalize_tool_response(response: dict | list | str, tool_name: str = "unknown") -> dict:
|
||||
def normalize_tool_response(
|
||||
response: dict | list | str, tool_name: str = "unknown"
|
||||
) -> dict:
|
||||
"""
|
||||
Normalize tool response to standard format for consistent frontend display.
|
||||
|
||||
@@ -298,15 +321,24 @@ def normalize_tool_response(response: dict | list | str, tool_name: str = "unkno
|
||||
|
||||
Examples:
|
||||
>>> normalize_tool_response({"status": "success", "output": "OK"})
|
||||
{'success': True, 'total': 1, 'successful': 1, 'failed': 0, 'data': [{'status': 'success', 'result': 'OK'}], 'metadata': {}}
|
||||
{'success': True, 'total': 1, 'successful': 1, 'failed': 0,
|
||||
'data': [{'status': 'success', 'result': 'OK'}], 'metadata': {}}
|
||||
|
||||
>>> normalize_tool_response([{"device_name": "R1", "status": "success"}])
|
||||
{'success': True, 'total': 1, 'successful': 1, 'failed': 0, 'data': [...], 'metadata': {}}
|
||||
{'success': True, 'total': 1, 'successful': 1, 'failed': 0,
|
||||
'data': [...], 'metadata': {}}
|
||||
"""
|
||||
metadata = {"tool_name": tool_name, "normalized_at": datetime.utcnow().isoformat()}
|
||||
metadata = {
|
||||
"tool_name": tool_name,
|
||||
"normalized_at": datetime.utcnow().isoformat(),
|
||||
}
|
||||
|
||||
# Handle error responses
|
||||
if isinstance(response, dict) and "error" in response and len(response) == 1:
|
||||
if (
|
||||
isinstance(response, dict)
|
||||
and "error" in response
|
||||
and len(response) == 1
|
||||
):
|
||||
return {
|
||||
"success": False,
|
||||
"total": 0,
|
||||
@@ -319,29 +351,56 @@ def normalize_tool_response(response: dict | list | str, tool_name: str = "unkno
|
||||
|
||||
# Handle empty responses
|
||||
if not response:
|
||||
return {"success": True, "total": 0, "successful": 0, "failed": 0, "data": [], "metadata": metadata}
|
||||
return {
|
||||
"success": True,
|
||||
"total": 0,
|
||||
"successful": 0,
|
||||
"failed": 0,
|
||||
"data": [],
|
||||
"metadata": metadata,
|
||||
}
|
||||
|
||||
# Handle list responses (most tools return list of device results)
|
||||
if isinstance(response, list):
|
||||
successful = sum(1 for item in response if isinstance(item, dict) and item.get("status") == "success")
|
||||
successful = sum(
|
||||
1
|
||||
for item in response
|
||||
if isinstance(item, dict) and item.get("status") == "success"
|
||||
)
|
||||
failed = len(response) - successful
|
||||
|
||||
normalized_data = []
|
||||
for item in response:
|
||||
if isinstance(item, dict):
|
||||
normalized_item = {
|
||||
"id": item.get("device_id") or item.get("node_id") or item.get("id") or "",
|
||||
"id": item.get("device_id")
|
||||
or item.get("node_id")
|
||||
or item.get("id")
|
||||
or "",
|
||||
"name": item.get("device_name") or item.get("name") or "",
|
||||
"status": item.get("status", "unknown"),
|
||||
}
|
||||
if normalized_item["status"] == "success":
|
||||
normalized_item["result"] = item.get("output") or item.get("result") or ""
|
||||
normalized_item["result"] = (
|
||||
item.get("output") or item.get("result") or ""
|
||||
)
|
||||
else:
|
||||
normalized_item["error"] = item.get("error") or item.get("output") or "Unknown error"
|
||||
normalized_item["error"] = (
|
||||
item.get("error")
|
||||
or item.get("output")
|
||||
or "Unknown error"
|
||||
)
|
||||
normalized_data.append(normalized_item)
|
||||
else:
|
||||
# Non-dict items in list
|
||||
normalized_data.append({"id": "", "name": "", "status": "unknown", "result": str(item)})
|
||||
normalized_data.append(
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"status": "unknown",
|
||||
"result": str(item),
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
"success": failed == 0,
|
||||
@@ -367,8 +426,14 @@ def normalize_tool_response(response: dict | list | str, tool_name: str = "unkno
|
||||
}
|
||||
|
||||
# Legacy format: extract common fields
|
||||
total = response.get("total_nodes") or response.get("total") or response.get("count", 1)
|
||||
successful = response.get("successful_nodes") or response.get("successful") or 0
|
||||
total = (
|
||||
response.get("total_nodes")
|
||||
or response.get("total")
|
||||
or response.get("count", 1)
|
||||
)
|
||||
successful = (
|
||||
response.get("successful_nodes") or response.get("successful") or 0
|
||||
)
|
||||
failed = response.get("failed_nodes") or response.get("failed") or 0
|
||||
|
||||
# Extract data from various possible locations
|
||||
@@ -393,9 +458,13 @@ def normalize_tool_response(response: dict | list | str, tool_name: str = "unkno
|
||||
if not data and "status" in response:
|
||||
data = [
|
||||
{
|
||||
"name": response.get("device_name") or response.get("name") or "",
|
||||
"name": response.get("device_name")
|
||||
or response.get("name")
|
||||
or "",
|
||||
"status": response["status"],
|
||||
"result": response.get("output") or response.get("result") or "",
|
||||
"result": response.get("output")
|
||||
or response.get("result")
|
||||
or "",
|
||||
"error": response.get("error") or "",
|
||||
}
|
||||
]
|
||||
@@ -425,14 +494,23 @@ def normalize_tool_response(response: dict | list | str, tool_name: str = "unkno
|
||||
"total": 1,
|
||||
"successful": 1,
|
||||
"failed": 0,
|
||||
"data": [{"id": "", "name": "", "status": "unknown", "result": str(response)}],
|
||||
"data": [
|
||||
{
|
||||
"id": "",
|
||||
"name": "",
|
||||
"status": "unknown",
|
||||
"result": str(response),
|
||||
}
|
||||
],
|
||||
"metadata": metadata,
|
||||
}
|
||||
|
||||
|
||||
# Test function to verify the implementation
|
||||
def _test_parse_tool_content() -> None:
|
||||
"""Test function to verify parse_tool_content works correctly with all input types"""
|
||||
"""Test function to verify parse_tool_content works correctly with all input
|
||||
types
|
||||
"""
|
||||
test_cases: list[tuple[Any, Any]] = [
|
||||
# String inputs
|
||||
(
|
||||
@@ -486,7 +564,9 @@ def _test_parse_tool_content() -> None:
|
||||
valid = "✓"
|
||||
except Exception:
|
||||
valid = "✗"
|
||||
print(f"Format Test {i + 1}: {valid} Input: {repr(input_data)} -> {result}")
|
||||
print(
|
||||
f"Format Test {i + 1}: {valid} Input: {repr(input_data)} -> {result}"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in new issue
Block a user