mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-09-27 22:30:11 +03:00
Add compact array format for link node entries to reduce token usage
Supports both standard and compact formats:
Standard: [{"node_id": "uuid", "adapter_number": 0, "port_number": 0}]
Compact: ["uuid", 0, 0, "uuid", 0, 0] - 3x less tokens
This commit is contained in:
parent
27a489a3fd
commit
a8a83051ff
@ -596,10 +596,10 @@ async def link_get(
|
|||||||
@mcp.tool()
|
@mcp.tool()
|
||||||
async def link_create(
|
async def link_create(
|
||||||
project_id: Annotated[str, Field(description="UUID of the project")],
|
project_id: Annotated[str, Field(description="UUID of the project")],
|
||||||
nodes: Annotated[list | None, Field(description="Single mode: [{node_id, adapter_number, port_number}]")] = None,
|
nodes: Annotated[list | None, Field(description="Single mode: [{node_id, adapter_number, port_number}] or compact [id, ad, pt, id, ad, pt]")] = None,
|
||||||
link_type: Annotated[str, Field(description="Link type - ethernet or serial")] = "ethernet",
|
link_type: Annotated[str, Field(description="Link type - ethernet or serial")] = "ethernet",
|
||||||
filters: Annotated[dict | None, Field(description="Optional packet filters")] = None,
|
filters: Annotated[dict | None, Field(description="Optional packet filters")] = None,
|
||||||
links: Annotated[list | None, Field(description="Batch mode: [{nodes, link_type?, filters?}] — creates multiple links in parallel")] = None,
|
links: Annotated[list | None, Field(description="Batch mode: [{nodes, link_type?, filters?}] — nodes supports compact [id, ad, pt, id, ad, pt] format")] = None,
|
||||||
fields: Annotated[list[str] | None, Field(description="Response fields to include (default: [link_id, link_type, nodes]). "
|
fields: Annotated[list[str] | None, Field(description="Response fields to include (default: [link_id, link_type, nodes]). "
|
||||||
"Available: link_id, project_id, link_type, nodes, suspend, "
|
"Available: link_id, project_id, link_type, nodes, suspend, "
|
||||||
"link_style, filters, show_filters_icon, capturing, "
|
"link_style, filters, show_filters_icon, capturing, "
|
||||||
|
|||||||
@ -46,6 +46,26 @@ def _get_connector(gns3_ctx: dict[str, Any]):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _normalize_link_nodes(nodes) -> list[dict[str, Any]]:
|
||||||
|
"""
|
||||||
|
Normalize link node entries, accepting both standard object format and
|
||||||
|
compact array format to reduce token usage.
|
||||||
|
|
||||||
|
Standard: [{"node_id": "uuid", "adapter_number": 0, "port_number": 0}]
|
||||||
|
Compact: ["uuid", 0, 0, "uuid", 0, 0]
|
||||||
|
"""
|
||||||
|
if not nodes:
|
||||||
|
return nodes
|
||||||
|
if isinstance(nodes[0], dict):
|
||||||
|
return nodes
|
||||||
|
if isinstance(nodes, list) and len(nodes) == 6:
|
||||||
|
return [
|
||||||
|
{"node_id": nodes[0], "adapter_number": nodes[1], "port_number": nodes[2]},
|
||||||
|
{"node_id": nodes[3], "adapter_number": nodes[4], "port_number": nodes[5]},
|
||||||
|
]
|
||||||
|
return nodes
|
||||||
|
|
||||||
|
|
||||||
# ── Tool handlers ──────────────────────────────────────────────────────────
|
# ── Tool handlers ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
VALID_LINK_FIELDS = {
|
VALID_LINK_FIELDS = {
|
||||||
@ -100,10 +120,11 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic
|
|||||||
results = []
|
results = []
|
||||||
conn = _get_connector(gns3_ctx)
|
conn = _get_connector(gns3_ctx)
|
||||||
def _create_one(link_data):
|
def _create_one(link_data):
|
||||||
if not link_data.get("nodes"):
|
raw_nodes = link_data.get("nodes")
|
||||||
|
if not raw_nodes:
|
||||||
return {"status": "error", "error": "nodes is required for each link"}
|
return {"status": "error", "error": "nodes is required for each link"}
|
||||||
try:
|
try:
|
||||||
body = {"nodes": link_data["nodes"]}
|
body = {"nodes": _normalize_link_nodes(raw_nodes)}
|
||||||
if link_data.get("link_type"):
|
if link_data.get("link_type"):
|
||||||
body["link_type"] = link_data["link_type"]
|
body["link_type"] = link_data["link_type"]
|
||||||
if link_data.get("filters"):
|
if link_data.get("filters"):
|
||||||
@ -126,7 +147,7 @@ def create_link_handler(params: dict[str, Any], gns3_ctx: dict[str, Any]) -> dic
|
|||||||
if not nodes:
|
if not nodes:
|
||||||
return {"error": "nodes is required"}
|
return {"error": "nodes is required"}
|
||||||
conn = _get_connector(gns3_ctx)
|
conn = _get_connector(gns3_ctx)
|
||||||
data = {"nodes": nodes}
|
data = {"nodes": _normalize_link_nodes(nodes)}
|
||||||
if "link_type" in params:
|
if "link_type" in params:
|
||||||
data["link_type"] = params["link_type"]
|
data["link_type"] = params["link_type"]
|
||||||
if "filters" in params:
|
if "filters" in params:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user