refactor: consolidate get_pin_net into get_wire_connections
get_pin_net was a superset of get_wire_connections with the same coordinate-based flood-fill but two extra response fields (net, query_point) and a reference+pin input mode. Having both tools confused LLM tool selection. get_wire_connections now: - Returns net (label name or null) and query_point in all response paths - Accepts reference+pin input in addition to x/y coordinates, resolving the pin endpoint via PinLocator internally get_pin_net tool, handler, schema, TS registration, and tests removed. test_wire_connectivity.py updated with coverage for all new behaviour. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -383,7 +383,6 @@ class KiCADInterface:
|
||||
"get_net_connections": self._handle_get_net_connections,
|
||||
"get_wire_connections": self._handle_get_wire_connections,
|
||||
"get_net_at_point": self._handle_get_net_at_point,
|
||||
"get_pin_net": self._handle_get_pin_net,
|
||||
"run_erc": self._handle_run_erc,
|
||||
"generate_netlist": self._handle_generate_netlist,
|
||||
"sync_schematic_to_board": self._handle_sync_schematic_to_board,
|
||||
@@ -2515,29 +2514,57 @@ class KiCADInterface:
|
||||
return {"success": False, "message": str(e)}
|
||||
|
||||
def _handle_get_wire_connections(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Find all component pins reachable from a point via connected wires"""
|
||||
"""Find net name and all component pins reachable from a point or component pin."""
|
||||
logger.info("Getting wire connections")
|
||||
try:
|
||||
from pathlib import Path
|
||||
|
||||
from commands.pin_locator import PinLocator
|
||||
from commands.wire_connectivity import get_wire_connections
|
||||
|
||||
schematic_path = params.get("schematicPath")
|
||||
if not schematic_path:
|
||||
return {"success": False, "message": "Missing required parameter: schematicPath"}
|
||||
|
||||
reference = params.get("reference")
|
||||
pin = params.get("pin")
|
||||
x = params.get("x")
|
||||
y = params.get("y")
|
||||
|
||||
if not (schematic_path and x is not None and y is not None):
|
||||
has_ref_pin = reference is not None and pin is not None
|
||||
has_coords = x is not None and y is not None
|
||||
|
||||
if has_ref_pin and has_coords:
|
||||
return {
|
||||
"success": False,
|
||||
"message": "Missing required parameters: schematicPath, x, y",
|
||||
"message": "Supply either {reference, pin} or {x, y}, not both",
|
||||
}
|
||||
|
||||
try:
|
||||
x, y = float(x), float(y)
|
||||
except (TypeError, ValueError):
|
||||
if not has_ref_pin and not has_coords:
|
||||
if reference is not None or pin is not None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": "Both reference and pin are required together",
|
||||
}
|
||||
return {
|
||||
"success": False,
|
||||
"message": "Parameters x and y must be numeric",
|
||||
"message": "Must supply either {reference, pin} or {x, y}",
|
||||
}
|
||||
|
||||
if has_ref_pin:
|
||||
location = PinLocator().get_pin_location(Path(schematic_path), reference, str(pin))
|
||||
if location is None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"Pin {pin} not found on {reference}",
|
||||
}
|
||||
x, y = location[0], location[1]
|
||||
else:
|
||||
try:
|
||||
x, y = float(x), float(y)
|
||||
except (TypeError, ValueError):
|
||||
return {"success": False, "message": "Parameters x and y must be numeric"}
|
||||
|
||||
schematic = SchematicManager.load_schematic(schematic_path)
|
||||
if not schematic:
|
||||
return {"success": False, "message": "Failed to load schematic"}
|
||||
@@ -2549,7 +2576,7 @@ class KiCADInterface:
|
||||
if result is None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"No wire found at ({x},{y}) within tolerance",
|
||||
"message": f"No wire found at ({x},{y}) — point may not be connected",
|
||||
}
|
||||
|
||||
return {"success": True, **result}
|
||||
@@ -2595,70 +2622,6 @@ class KiCADInterface:
|
||||
logger.error(traceback.format_exc())
|
||||
return {"success": False, "message": str(e)}
|
||||
|
||||
def _handle_get_pin_net(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Find net name and all connected pins for a reference+pin or coordinate query"""
|
||||
logger.info("Getting pin net")
|
||||
try:
|
||||
from pathlib import Path
|
||||
|
||||
from commands.pin_locator import PinLocator
|
||||
from commands.wire_connectivity import get_pin_net
|
||||
|
||||
schematic_path = params.get("schematicPath")
|
||||
if not schematic_path:
|
||||
return {"success": False, "message": "Missing required parameter: schematicPath"}
|
||||
|
||||
reference = params.get("reference")
|
||||
pin = params.get("pin")
|
||||
x = params.get("x")
|
||||
y = params.get("y")
|
||||
|
||||
has_ref_pin = reference is not None and pin is not None
|
||||
has_coords = x is not None and y is not None
|
||||
|
||||
if not has_ref_pin and not has_coords:
|
||||
return {
|
||||
"success": False,
|
||||
"message": "Must supply either {reference, pin} or {x, y}",
|
||||
}
|
||||
|
||||
if has_ref_pin:
|
||||
location = PinLocator().get_pin_location(Path(schematic_path), reference, str(pin))
|
||||
if location is None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"Pin {pin} not found on {reference}",
|
||||
}
|
||||
x, y = location[0], location[1]
|
||||
else:
|
||||
try:
|
||||
x, y = float(x), float(y)
|
||||
except (TypeError, ValueError):
|
||||
return {"success": False, "message": "Parameters x and y must be numeric"}
|
||||
|
||||
schematic = SchematicManager.load_schematic(schematic_path)
|
||||
if not schematic:
|
||||
return {"success": False, "message": "Failed to load schematic"}
|
||||
|
||||
if not hasattr(schematic, "wire"):
|
||||
return {"success": False, "message": "Schematic has no wires"}
|
||||
|
||||
result = get_pin_net(schematic, schematic_path, x, y)
|
||||
if result is None:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"No wire found at ({x},{y}) — pin may not be connected",
|
||||
}
|
||||
|
||||
return {"success": True, **result}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting pin net: {str(e)}")
|
||||
import traceback
|
||||
|
||||
logger.error(traceback.format_exc())
|
||||
return {"success": False, "message": str(e)}
|
||||
|
||||
def _handle_run_erc(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Run Electrical Rules Check on a schematic via kicad-cli"""
|
||||
logger.info("Running ERC on schematic")
|
||||
|
||||
Reference in New Issue
Block a user