feat: add PacketAnalysisSkillsTool

- Register packet_analysis_skills as a LangChain tool for LLM
- LLM can query protocol field definitions before calling packet_analysis
- Follows the same pattern as DeviceSkillsTool and InjectionSkillsTool
This commit is contained in:
YueGuobin 2026-05-12 13:37:59 +08:00
parent 2a38816d3d
commit 67b3b778b8
No known key found for this signature in database
3 changed files with 72 additions and 0 deletions

View File

@ -97,6 +97,7 @@ from gns3server.agent.gns3_copilot.tools_v2.vpcs_tools_netmiko import VPCSComman
from gns3server.agent.gns3_copilot.tools_v2 import PacketAnalysisTool
from gns3server.agent.gns3_copilot.skills import DeviceSkillsTool
from gns3server.agent.gns3_copilot.skills import InjectionSkillsTool
from gns3server.agent.gns3_copilot.skills import PacketAnalysisSkillsTool
# Set up logger for GNS3-Copilot
logger = logging.getLogger(__name__)
@ -116,6 +117,7 @@ TEACHING_ASSISTANT_MODE_TOOLS = [
ExecuteMultipleDeviceCommands(), # Execute show/display/debug commands
# (READ-ONLY)
PacketAnalysisTool(), # Protocol-oriented packet analysis with tshark
PacketAnalysisSkillsTool(), # Query packet analysis protocol definitions
DeviceSkillsTool(), # Get device-specific skills and command knowledge
]
@ -133,6 +135,7 @@ LAB_AUTOMATION_ASSISTANT_MODE_TOOLS = [
ExecuteMultipleDeviceConfigCommands(), # Execute configuration commands
VPCSCommands(), # Execute VPCS commands using Netmiko
PacketAnalysisTool(), # Protocol-oriented packet analysis with tshark
PacketAnalysisSkillsTool(), # Query packet analysis protocol definitions
DeviceSkillsTool(), # Get device-specific skills and command knowledge
]

View File

@ -43,6 +43,7 @@ from .registry import (
get_injection_skill,
DeviceSkillsTool,
InjectionSkillsTool,
PacketAnalysisSkillsTool,
set_skills_manager,
get_skills_manager,
reload_injection_skills,
@ -60,6 +61,7 @@ __all__ = [
"get_injection_skill",
"DeviceSkillsTool",
"InjectionSkillsTool",
"PacketAnalysisSkillsTool",
"SkillsManager",
"SkillsLoader",
"set_skills_manager",

View File

@ -783,3 +783,70 @@ class InjectionSkillsTool(BaseTool):
skill = get_injection_skill(device_type, detail=detail, issue=issue)
return json.dumps(skill, ensure_ascii=False, indent=2)
class PacketAnalysisSkillsTool(BaseTool):
"""
LangChain tool for querying packet analysis protocol definitions.
Use this tool to list available protocols and get protocol-specific
tshark fields, display filters, and check rules.
"""
name: str = "packet_analysis_skills"
description: str = """
Get or list packet analysis protocol definitions.
Before calling packet_analysis tool, use this to query the protocol's
available tshark fields, display filters, and check rules.
USAGE:
- List available protocols:
{"action": "list"}
- Get protocol definition with fields:
{"action": "get", "protocol": "ospf"}
PARAMETERS:
- action: "list" or "get" (required)
- protocol: Protocol key for action="get" (e.g., "ospf", "bgp", "arp", "icmp")
"""
def _run(
self,
tool_input: str | dict[str, Any],
run_manager: CallbackManagerForToolRun | None = None,
**kwargs: Any,
) -> str:
"""Execute the packet analysis skills lookup."""
logger.debug("PacketAnalysisSkillsTool invoked with input: %s", tool_input)
if isinstance(tool_input, str):
try:
params = json.loads(tool_input)
except json.JSONDecodeError as e:
return json.dumps({
"error": f"Invalid JSON input: {e}",
"hint": 'Expected format: {"action": "get", "protocol": "ospf"}'
}, ensure_ascii=False, indent=2)
else:
params = tool_input
action = params.get("action", "get")
if action == "list":
protocols = list_available_packet_analysis_protocols()
return json.dumps({
"count": len(protocols),
"protocols": protocols
}, ensure_ascii=False, indent=2)
protocol = params.get("protocol")
if not protocol:
return json.dumps({
"error": "Missing required field: protocol",
"available_protocols": list(PACKET_ANALYSIS_REGISTRY.keys()),
}, ensure_ascii=False, indent=2)
result = get_packet_analysis_protocol(protocol)
return json.dumps(result, ensure_ascii=False, indent=2)