139 Commits

Author SHA1 Message Date
YueGuobin
641d10177a
refactor: move MCP service from api/routes to agent package
MCP is an optional AI feature that already depends on
agent.gns3_copilot (Gns3Connector, nornir/netmiko tools) and whose
MCP_AVAILABLE feature flag lives in gns3server/agent. Moving it there
collocates all AI features under one tree and removes AI code from the
core REST routes.

- git mv gns3server/api/routes/mcp -> gns3server/agent/mcp (no content changes)
- api/server.py, core/tasks.py: update import paths
- tests: tests/api/routes/mcp -> tests/agent/mcp, rewrite patch BASE and
  handler imports; fix MCP_DIR depth in test_tool_params.py
- agent/__init__.py: probe the SDK via importlib.import_module so the
  top-level name "mcp" is not bound in the agent namespace (it would
  shadow the new gns3server.agent.mcp subpackage and break
  'from gns3server.agent import mcp')
- docs: update source file paths

Verified: full suite 1567 passed; 82 MCP tools registered, SSE mounted
at /v3/mcp/transport.
2026-08-22 19:32:13 +08:00
YueGuobin
6aeb5dbda5
feat(copilot): device skills per-topic split layout and topic retrieval
SkillsLoader.load_device_skills() now supports two device layouts: the
existing single file and a split directory (device/<device>/_base.yaml +
one YAML per protocol topic). Topic files are merged into the device
skill under 'topics', keyed by their 'topic' field; mismatched
device_type, missing _base.yaml and duplicate topics are handled with
explicit log-and-skip.

get_skill() and DeviceSkillsTool gain a 'topic' parameter following the
injection list -> index -> issue pattern. Topic bodies are never
returned without an explicit topic request - index/summary/full all
serve a topic index instead - so growing a device with new protocol
topics no longer grows the token cost of device-level lookups.

Also fix reload_skills() to actually drop injection skills that fail
validate_skill_format() instead of logging 'skipping' and merging them
anyway.
2026-08-21 21:41:51 +08:00
YueGuobin
19f20e8d75
copilot: log into devices using the node default credentials
The vendored gns3fy Node model dropped default_username/default_password
from the API response, and the nornir groups hardcoded empty
credentials, so drivers that require authentication (gns3_ruijie_telnet,
stock netmiko SSH/telnet) could not log in.

Carry the per-node credentials through nodes_inventory() into the
nornir hosts data at host level, where they override the group's empty
fallback. Missing or cleared ("") values keep inheriting from the
group, so no-auth drivers are unaffected.
2026-08-21 21:41:42 +08:00
YueGuobin
435aa4c257
copilot: prefer netmiko_device_type over the device_type:<type> tag
The vendored gns3fy Node model and its nodes_inventory() now carry the
node's netmiko_device_type field, and get_device_ports_from_topology()
resolves the Netmiko device type from it first, falling back to the
device_type:<type> tag. Nodes created from a template inherit the value
from the template automatically, so automation tooling gets the correct
Netmiko driver without tags.
2026-08-21 21:41:35 +08:00
YueGuobin
f43a717b20
copilot: sync CONSOLE_TYPES with the server ConsoleType enum
The vendored gns3fy copy keeps its type lists as literals (the module is
shared with the standalone MCP service and cannot import server enums),
and CONSOLE_TYPES had drifted: 'ssh' and 'docker_exec' were missing while
both are valid server-side. Impact: the copilot topology reader validates
the whole node list in one pydantic pass, so a single vendor NOS node
(console_type 'docker_exec') made it drop the entire project and return
zero devices to every copilot device tool.

Add the missing values plus drift tests asserting the vendored lists
cover the server enums (skipped when ai-features extras are absent).
2026-08-15 23:32:24 +08:00
Guobin Yue
277640a335
Merge branch '3.1' into fix-web-wireshark-docker-xpra6.x 2026-07-06 13:35:44 +08:00
YueGuobin
f5a72532ac
Fix web-wireshark docker build broken by xpra 6.5 release
Replace the `xpra=6.4*` version clamp on the apt-get install command
line with APT pinning via /etc/apt/preferences.d/pin-xpra.

The previous specifier stopped resolving once xpra 6.5 was released:
the xpra metapackage was pinned to 6.4 while its sub-packages
(xpra-client, xpra-server, xpra-codecs, ...) were unconstrained and
defaulted to 6.5, so apt could not satisfy the dependency graph and
the "Build Docker images" action failed.

Pinning all xpra* packages at the preferences level constrains the
whole set consistently (xpra-html5 is handled separately since it
follows a different version scheme, locked to v19). Blocking every
other version with priority -1 ensures that, if the pinned version
ever disappears from the repository, apt fails loudly instead of
silently upgrading to the latest release.

Fixes GNS3/gns3-registry#1044
2026-07-06 13:31:07 +08:00
YueGuobin
292b60efaa
Make AI features (AI Copilot + MCP) optional via [ai-features] extra
- Move fastmcp from core requirements.txt to mcp-requirements.txt
- Add MCP_AVAILABLE feature flag in agent/__init__.py (graceful degradation)
- Guard MCP imports/registration in server.py and tasks.py
- Replace ai-copilot/mcp/ai-support extras with single ai-features extra
- Add stub MCP routes returning 501 when MCP is not installed
- Add gns3server-uninstall-ai-features CLI command
- Remove old gns3server-uninstall-ai-copilot command
- Update all error messages and docs to reference ai-features

Closes #2794
2026-06-27 10:14:43 +08:00
YueGuobin
59e5f8dd2f
Fix review issues: key_prefix length, count validation, WAL log, timeout comment, pointless temp var 2026-06-16 22:50:22 +08:00
YueGuobin
d407b29fe9
Increase HTTP connection pool to 500/1000 2026-06-16 00:58:12 +08:00
YueGuobin
ccb629f48f
Clean up all timing/debug logs
Remove all [MCP-TIMING] and [CTRL-TIMING] log lines, timing middleware,
and related import time statements across 11 files.
2026-06-16 00:34:11 +08:00
YueGuobin
cef6dc6bd2
Add detailed timing logs to MCP node creation and HTTP client
Logs with [MCP-TIMING] prefix at:
- create_node_handler entry, setup, http_call start/end, total
- http_call entry, auth, response
- _authenticate_v3 entry, done, fail
2026-06-15 22:51:43 +08:00
YueGuobin
6cbe676b18
Increase MCP HTTP client timeout from 10s to 30s
Dynamips node creation (e.g., Cisco 7200 with multiple adapters)
can exceed the previous 10-second timeout, causing MCP tools to
fail with Read timed out errors.
2026-06-15 13:14:11 +08:00
YueGuobin
f0b0de2a91
docs: Add MCP sharing warnings to shared gns3_copilot modules 2026-06-11 12:11:13 +08:00
YueGuobin
e7038f1ae3
feat: Add device configuration MCP tools (config_send, command_run, vpcs_config_set)
- Add jwt_token/url parameters to get_device_ports_from_topology() and GNS3TopologyTool
  for MCP handler compatibility (backward compatible, auto-detection fallback)
- Add jwt_token/url pass-through to ExecuteMultipleDeviceConfigCommands,
  ExecuteMultipleDeviceCommands, and VPCSCommands _run() methods
- Create MCP handler device_config.py wrapping the 3 device config tools
- Register as device_config_send, device_command_run, vpcs_config_set
2026-06-10 14:34:35 +08:00
YueGuobin
acce79d243
refactor: unify MCP handlers to use http_call directly, relocate node file ops to Node class
- Move node file operations (list_files, delete_file) from Gns3Connector to Node class
- Add link capture/reset operations (reset, start_capture, stop_capture) to Link class
- Convert all MCP handlers to use conn.http_call() directly instead of
  Gns3Connector/Node/Link abstraction methods
- Register 4 new MCP tools: reset_link, start_capture, stop_capture,
  download_capture_file
2026-06-10 13:47:10 +08:00
YueGuobin
28b06f37c4
feat: Add node file operations as MCP tools (list, get, write, delete)
- Add list_node_files, get_node_file, write_node_file, delete_node_file methods to Gns3Connector
- Add MCP handlers with offset/limit line-based reading for get_node_file
- Auto-truncate files >50KB with truncated flag in response
- Rich metadata returned (total_lines, total_bytes, has_more, etc.)
- Tool docstrings guide AI to check file sizes before reading chunked
2026-06-10 12:16:35 +08:00
YueGuobin
4921b98948
Add MCP project tools: update, duplicate, and README operations
- Add update_project and duplicate_project MCP tools
- Add get_project_readme and update_project_readme tools
- Add Gns3Connector methods: update_project, duplicate_project,
  get_project_file, write_project_file
2026-06-07 23:14:07 +08:00
YueGuobin
e76f3970ca
fix: add load_feature_skills() to properly load network planning features
The feature directory contains network planning and design functionalities
(e.g., topology_planner), not device-specific features. These were not being
loaded because load_device_skills() only scanned the device directory.

Changes:
- Added new load_feature_skills() method in SkillsLoader
- Modified reload_skills() to load both device and feature directories
- Device skills: device-specific configurations (e.g., VPCS)
- Feature skills: network planning functionalities (e.g., topology planner)
- Both are now properly loaded into SKILLS_REGISTRY

This ensures that network planning features like topology_planner are available
via the device_skills tool with proper category classification.
2026-06-05 22:25:17 +08:00
YueGuobin
64471575f7
chore: update GNS3 skills repository to official organization
Update the default download repository address for GNS3 skills from
yueguobin/GNS3-Skills to gns3/gns3-skills to use the official
organization repository.

This affects:
- Default skills_repo_url in server configuration schema
- Skills manager default repository URL
- Skills configuration defaults
- All documentation references
2026-05-29 22:04:48 +08:00
YueGuobin
045db5bdd8
fix: clean BPF syntax error message and specify loopback interface
- Add -i lo to tshark command to avoid "(null)" interface in errors
- Strip "for interface" suffix from error message for cleaner output
2026-05-24 23:00:41 +08:00
YueGuobin
ce58e9adc8
feat: add BPF syntax validation using tshark
- Add _validate_bpf_syntax() method to validate BPF expressions
- Use tshark with 1-second timeout for syntax checking
- Check for "Invalid" in output to detect syntax errors
- Validate BPF filters before applying them to links
- Handle tshark not installed scenario gracefully
- Support both single and multiple BPF expressions
- Return detailed error messages for syntax validation failures
2026-05-24 22:49:59 +08:00
YueGuobin
e71931d096
feat: add show_filters_icon parameter to packet filter tool
- Add show_filters_icon parameter with default value False
- Pass show_filters_icon to link.update() in set and clear operations
- Update tool description to explain default behavior
- Remove "clear" action from description to simplify interface
- Hide filter icon in GNS3 Web UI by default for cleaner UI during fault injection
2026-05-24 22:46:52 +08:00
YueGuobin
8ba1f064d2
feat: add packet filter management tool for GNS3-Copilot fault injection
Add comprehensive packet filter management functionality to GNS3-Copilot,
enabling AI-powered fault injection scenarios with network simulation
capabilities like latency, packet loss, and corruption.

## Changes

### New Features
- **GNS3PacketFilterTool**: New LangChain tool for managing packet filters
  on GNS3 links with support for delay, packet loss, corruption,
  frequency_drop, and BPF filtering
  - Actions: get_available, set, get, clear
  - Integrated into troubleshooting_injection mode for fault scenarios

### API Integration
- **Link.available_filters()**: Added method to custom_gns3fy.py Link class
  - Queries available filter types for specific links
  - API v3+ only (raises ValueError for v2 connectors)
  - Returns filter definitions with parameters and constraints

### Tool Integration
- Added GNS3PacketFilterTool to TROUBLESHOOTING_INJECTION_MODE_TOOLS
- Positioned as 3rd tool in fault injection workflow
- Optimized for troubleshooting practice scenarios

## Files Modified
- gns3server/agent/gns3_copilot/agent/gns3_copilot.py
- gns3server/agent/gns3_copilot/gns3_client/custom_gns3fy.py
- gns3server/agent/gns3_copilot/tools_v2/__init__.py

## Files Added
- gns3server/agent/gns3_copilot/tools_v2/gns3_packet_filter.py

## Testing
- All validation tests passed
- Version checking verified (v3+ only)
- Tool integration confirmed in troubleshooting mode
2026-05-24 22:31:28 +08:00
YueGuobin
30a140a9e3
fix: surface tshark stderr errors to LLM, not just log them 2026-05-12 15:10:27 +08:00
YueGuobin
b79fea918d
fix: hint LLM about -c behavior when tshark returns empty with -c 2026-05-12 14:54:50 +08:00
YueGuobin
09b0fbcfea
fix: update search_fields examples to use existing field names 2026-05-12 14:48:37 +08:00
YueGuobin
73e0de7706
fix: reject multi-keyword search_fields, single keyword only 2026-05-12 14:47:00 +08:00
YueGuobin
c357d52fbf
fix: document action/query params in PacketAnalysisTool description 2026-05-12 14:36:21 +08:00
YueGuobin
2a34d0ef58
feat: add search_fields action to PacketAnalysisTool for real-time field lookup 2026-05-12 14:33:13 +08:00
YueGuobin
32c3b4cd35
feat: validate tshark -e field names before running analysis 2026-05-12 14:27:16 +08:00
YueGuobin
9c23f9037c
fix: document -c behavior caveat in PacketAnalysisTool description 2026-05-12 14:00:58 +08:00
YueGuobin
b7a0b611df
fix: demote loader-level load logs to DEBUG, info already reported by manager
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:52:05 +08:00
YueGuobin
89da58fe1b
fix: promote skills/prompts load logs to INFO level
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-12 13:46:36 +08:00
YueGuobin
c5af9ce389
fix: load packet analysis protocols during skills initialization
- Add reload_packet_analysis_protocols() call in _ensure_skills_manager()
- PACKET_ANALYSIS_REGISTRY was empty because it was never loaded
2026-05-12 13:41:52 +08:00
YueGuobin
67b3b778b8
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
2026-05-12 13:37:59 +08:00
YueGuobin
2a38816d3d
fix: remove remaining quoted example from tool input docstring 2026-05-12 13:30:18 +08:00
YueGuobin
b991125c6c
fix: use shlex.split for tshark_args parsing
- Replace str.split() with shlex.split() to handle quoted arguments
- LLM may pass args with or without quotes, both work correctly now
2026-05-12 13:29:31 +08:00
YueGuobin
e0c2d64b7c
feat: add packet analysis workflow to tool description
- Update PacketAnalysisTool.description with step-by-step workflow
- Instruct LLM to query packet_analysis skills first, then construct tshark_args
2026-05-12 13:13:24 +08:00
YueGuobin
2c5cfdbee8
refactor: remove old PacketCaptureTool, replaced by PacketAnalysisTool
- Delete packet_capture_tools.py (analyze_packets with packet_number)
- PacketAnalysisTool is more flexible and can do everything the old tool could
- Update tool registration to use only PacketAnalysisTool
- Cleaner, more unified packet analysis interface
2026-05-12 10:19:25 +08:00
YueGuobin
84b9742045
feat: add protocol-oriented packet analysis tool
- Add PacketAnalysisTool that accepts user-provided tshark arguments
- LLM constructs tshark commands based on protocol knowledge from skills
- Add PACKET_ANALYSIS_REGISTRY for protocol definitions
- Add load_packet_analysis_protocols() to SkillsLoader
- Add get_packet_analysis_protocol() and list functions to registry
- Register PacketAnalysisTool in teaching and lab automation modes
- Update SkillsManager to reload packet analysis protocols

Related: GNS3-Skills commit 7bc45d2
2026-05-12 09:59:10 +08:00
YueGuobin
ae1a444677
fix: remove background init timeout and allow skills reload retry
- Remove 5s thread.join() timeout so git clone/pull is not truncated
- Remove _init_complete flag, reset _init_in_progress on failure instead
- Let /reload/skills API retry initialization after network failure
- Raise GIT_HTTP_LOW_SPEED_LIMIT from 1 KB/s to 10 KB/s

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 22:51:57 +08:00
YueGuobin
e68cc17ed5
feat: add fault injection system and external skills repository
## Summary

Add a complete fault injection system for GNS3 Copilot, migrate all
skills from local Python files to an external Git repository with
hot reload support, and restructure Copilot API under /copilot/.

## Key Changes

### Fault Injection
- New troubleshooting_injection mode with InjectionSkillsTool
- 368 fault scenarios across 39 protocol categories
- Context-based filtering (LLM must pass topology protocols)

### External Skills Repository
- SkillsManager: Git clone/pull, version tracking, smart updates
- SkillsLoader: YAML skills + Markdown prompts from external repo
- Hot reload via POST /copilot/reload/skills
- Configurable via gns3_server.conf

### Architecture
- API unified under /copilot/ prefix
- SkillsManager moved from Controller to agent module
- Lazy initialization with startup background preload
- Per-command Git timeout, smart update checks
- Forbidden commands hot-reloadable from external repo
- 32 INFO logs downgraded to DEBUG
2026-05-11 01:24:55 +08:00
YueGuobin
156072118f
fix: Disable DeepSeek thinking mode to avoid reasoning_content errors
DeepSeek models (deepseek-v4-flash/pro) enable thinking mode by default,
which returns reasoning_content that must be passed back to the API in
subsequent requests. This causes 400 errors in multi-turn conversations
when the reasoning_content is not properly handled.

This commit disables thinking mode by passing extra_body={"thinking": {"type": "disabled"}}
as an explicit parameter to DeepSeek models, preventing the reasoning_content
field from being generated.

Modified:
- create_base_model(): Add extra_body parameter with thinking mode disabled
- create_title_model(): Add extra_body parameter with thinking mode disabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-09 22:31:50 +08:00
grossmj
640910ec8e
Use gns3server-web-wireshark-setup in docs 2026-04-24 00:48:00 +08:00
YueGuobin
0b7c40a14a
fix: rename wireshark CLI to gns3-wireshark to avoid conflict
The wireshark CLI entry point creates /usr/bin/wireshark which conflicts
with the system wireshark package on Arch Linux (owned by wireshark-qt),
causing package installation to fail.

Rename to gns3-wireshark to follow the same naming convention as other
GNS3 CLI tools (gns3server, gns3vmnet).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-24 00:04:21 +08:00
YueGuobin
d6d4f7262e
fix(copilot): add verify=False for HTTPS with self-signed certs
Add verify=False to requests.get() when capture_url uses HTTPS protocol,
to skip SSL certificate validation. This allows PacketCaptureTool to
work with GNS3 servers using self-signed certificates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 23:20:41 +08:00
YueGuobin
fd6868efce
fix(web-wireshark): add -k flag to curl for HTTPS with self-signed certs
Add -k flag to curl command when capture_stream_url uses HTTPS protocol,
to skip SSL certificate validation. This allows Web Wireshark to work
with GNS3 servers using self-signed certificates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-23 22:52:51 +08:00
YueGuobin
117025a8a2
fix(web-wireshark): improve Docker API version compatibility with fallback mechanism
- Change initial API version from 1.40 to 1.44 to support Docker 29.3+ (API 1.54)
- Add automatic fallback to API 1.40 for older Docker versions (20.10, API 1.41)
- Fixes "client version 1.40 is too old. Minimum supported API version is 1.44" error
- Ensures compatibility across Docker versions 20.10 (API 1.41) to 29.3+ (API 1.54+)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 23:12:56 +08:00
YueGuobin
6c96e7493f
feat(web-wireshark): add method to retrieve container IP and refactor websocket endpoint
- Add `get_container_ip` method to WebWiresharkManager for retrieving container IP addresses in wireshark network
- Method uses Docker API as primary approach with container command execution as fallback
- Refactor web_wireshark_websocket endpoint to use new method instead of direct Docker queries
- Improve error handling and logging for container IP retrieval failures
2026-04-22 22:35:50 +08:00