gns3-server/docs/gns3-copilot/template-based-configuration-roadmap.md
Guobin Yue f07d21c511
feat(web-wireshark): add implementation plan for script-driven (#2666)
* feat(web-wireshark): add implementation plan for script-driven integration

Add comprehensive implementation plan for Web Wireshark integration using script-driven approach. The plan outlines:

- Background and motivation for script-based Web Wireshark integration
- Core workflow from API request to WebSocket proxy connection
- Management script architecture with WebWiresharkManager class
- Docker container configuration and resource management
- Performance analysis and optimization recommendations
- Network setup and management procedures

Key features include:
- JWT token extraction from Authorization header
- Automatic GNS3 server URL detection
- Container lifecycle management per project
- Xpra session isolation per link
- WebSocket proxy integration through gns3server
- Resource monitoring and scaling guidelines

The implementation enables users to start Web Wireshark sessions via POST requests with `wireshark: true` parameter, providing a unified web-based packet capture interface.

* feat(web-wireshark): implement script-driven Web Wireshark integration

Add complete Web Wireshark container integration with script-driven architecture:

- Create manage_wireshark.py script for Docker container management
- Add LinkCapture schema with wireshark boolean field
- Update Link class with wireshark and jwt_token parameters
- Implement WebSocket proxy endpoint for xpra HTML5 client
- Add cleanup logic in Project class for container lifecycle

Key features:
- Script-driven container and xpra session management
- JWT token extraction from Authorization header
- GNS3 URL auto-detection with Controller/Config fallback
- WebSocket proxy for unified access through gns3server
- Proper cleanup on project close/delete

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): use aiohttp instead of docker SDK

Replace docker-py SDK with direct Docker HTTP API calls using aiohttp,
following GNS3's existing architecture pattern in gns3server/compute/docker/.

Changes:
- Create DockerHTTPClient class using aiohttp + Unix socket
- Implement all Docker operations as async methods
- Remove dependency on docker Python SDK
- Use Docker API v1.44 via /var/run/docker.sock

Benefits:
- No additional dependencies required
- Consistent with GNS3's async architecture
- Better integration with existing codebase

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): add dynamic Docker API version detection

Implement dynamic Docker API version detection following GNS3's pattern
in gns3server/compute/docker/__init__.py.

Changes:
- Add DOCKER_MINIMUM_API_VERSION and DOCKER_PREFERRED_API_VERSION constants
- Remove hardcoded "v1.44" prefix (now using "1.44" format)
- Add _check_connection() method to detect Docker daemon version
- Dynamically select API version based on daemon capabilities
- Add proper error handling for version mismatches

Behavior:
- Initialize with minimum API version (1.40)
- On first connection, detect Docker daemon API version
- Use preferred API version (1.44) if supported
- Fall back to daemon's minimum API version if needed
- Raise error if daemon version is too old

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): add optional --verbose logging parameter

Remove hardcoded logging.basicConfig() and add --verbose parameter
to control log output, following GNS3's logging pattern.

Changes:
- Remove logging.basicConfig(level=logging.INFO) from module level
- Add --verbose/-v command line parameter
- Configure logging only when --verbose is specified
- Use structured log format with timestamp when verbose

Behavior:
- When called by GNS3: uses GNS3's logging configuration (default)
- When run standalone: no output unless --verbose is specified
- With --verbose: shows detailed logs with timestamps

This prevents the script from interfering with GNS3's logging
configuration while still allowing debug output when needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): fix code quality issues from static analysis

Fix issues identified by flake8 and pylint static analysis:

Import and formatting fixes:
- Remove unused 'time' import
- Fix import order (stdlib before third-party)
- Remove unnecessary f-strings without placeholders
- Split long line to comply with flake8 (max line length: 127)

Code structure improvements:
- Remove unnecessary 'else' after 'return'
- Add 'from e' to exception re-raising for better tracebacks

Code quality metrics:
- pylint score: 8.11/10 → 9.97/10 (+1.86)
- flake8: 0 errors (max line length: 127, per CI/CD standard)
- All critical issues resolved

Note: R0914 (too-many-locals) warning is informational only,
code remains clear and maintainable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): export LinkCapture schema in schemas module

Add LinkCapture to the schemas module exports in __init__.py to fix
the AttributeError when starting the GNS3 server.

Error was:
  AttributeError: module 'gns3server.schemas' has no attribute 'LinkCapture'

This was caused by adding the LinkCapture class to controller/links.py
but forgetting to export it in the schemas __init__.py.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add --image parameter for custom Docker images

Add optional --image parameter to allow using custom Docker images
for testing, instead of requiring gns3/web-wireshark:latest.

Changes:
- Add --image parameter to start command (default: gns3/web-wireshark:latest)
- Update get_or_create_container() to accept image parameter
- Update start_wireshark_session() to accept and pass image parameter
- Update TEST.md with examples of using custom images

Usage:
  # Using default image
  python3 manage_wireshark.py start --project-id x --link-id y --jwt-token z

  # Using custom image (for testing)
  python3 manage_wireshark.py start --project-id x --link-id y --jwt-token z --image ubuntu:latest

This makes it easier to test the script without having the official
gns3/web-wireshark image available.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add configurable resource limits and increase session capacity

Add configurable resource parameters and increase session support from 10 to 100.

Resource parameters:
- --memory: Memory limit (default: 2g)
- --memory-swap: Memory swap limit (default: same as memory)
- --cpus: CPU cores (default: 1.0)
- --pids-limit: Process limit (default: 1000)

Other improvements:
- Fix CPU quota calculation: 1000000 microseconds = 1.0 CPU core
  (was incorrectly 100000 = 0.1 CPU core)
- Add health check: xpra list command
- Add log configuration: json-file, max-size=10m, max-file=3
- Increase session capacity: 10 → 100 concurrent sessions
- Port range: 12300-12399 (was 12300-12309)
- Display range: :100-:199 (was :100-:109)

This matches the docker run command parameters and provides
better resource management and monitoring capabilities.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): update UDPLink.start_capture() to accept new parameters

Update UDPLink.start_capture() to accept the new wireshark and jwt_token
parameters and pass them to the parent Link class.

This fixes the TypeError when starting capture on UDP links:
  TypeError: UDPLink.start_capture() got an unexpected keyword argument 'wireshark'

The UDPLink class overrides start_capture() but didn't include the new
parameters added for Web Wireshark support.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: add project memory infrastructure and JWT token flow documentation

- Add memory skill for recording project knowledge
- Document JWT token flow in Web Wireshark integration
- Update .gitignore to track skills and memory directories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): fix Docker API URL format and use docker exec CLI

- Add "v" prefix to Docker API URL (http://docker/v{version}/...)
- Remove unused exec_create/exec_start API methods
- Fix Healthcheck.Test format to ["CMD-SHELL", "command"]
- Use docker exec CLI instead of Docker API for command execution
- This aligns with GNS3 docker_vm pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): improve xpra session management and error handling

- Check and clean up existing sessions before starting new xpra session
- Add verification that xpra session started successfully
- Use docker exec CLI consistently instead of Docker API
- Improve error logging and diagnostics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add timeout handling and container health checks

- Add REQUEST_TIMEOUT constant for Docker HTTP API requests
- Add asyncio.timeout wrapper for Docker API calls to prevent hanging
- Add _is_container_healthy() to check container responsiveness
- Add _exec_in_container() helper with timeout support
- Improve unhealthy container handling with force remove
- Add detailed logging for container health state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): split monolithic file into modules

Split manage_wireshark.py into:
- docker_client.py: Docker HTTP API client
- manager.py: WebWiresharkManager with session management
- manage_wireshark.py: CLI entry point

This improves code organization and maintainability.
Keep all timeout handling and health check logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): correct NanoCpus calculation to use nanoseconds

NanoCpus in Docker API requires nanoseconds (1 CPU = 1000000000),
not the previous incorrect multiplier of 100000.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): fix xpra command quoting and session verification

- Add quotes around --xvfb parameter value to preserve spaces
- Fix session verification to check display number instead of session name
  (xpra list shows "LIVE session at :185" not session name)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): run wireshark in background with &

Wireshark with curl pipeline runs continuously, so it must run
in background to avoid blocking. Also reduced timeout since we
don't wait for completion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add deterministic hash for display/port allocation

Use MD5-based hash instead of Python's hash() which is randomized
across process restarts. This ensures display and port numbers are
stable when the GNS3 server restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor: extract link_id_to_port to shared utils module

Move deterministic hash functions to gns3server/utils/port_allocator.py
to avoid code duplication and ensure consistent algorithm across
manager.py and links.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(links): move import to top of file

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web-wireshark): use correct Config access pattern like gns3-copilot

The Server config is an object with .protocol.value, .host, .port
attributes, not a dict. Fixes URL detection failing and falling back
to 127.0.0.1:3080 which doesn't work from inside containers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add UUID validation utility and use in manage_wireshark

Create gns3server/utils/uuid_validator.py with validate_uuid function
to validate UUID format and catch typos early with clear error messages.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: use argparse.ArgumentTypeError for proper error message display

Previously ValueError was used which only showed 'invalid validate_uuid value'.
Now shows the full helpful message about expected format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add --dpi=96 to xpra start parameters

Set standard DPI for better display scaling in web Wireshark.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: update TEST.md with correct project-id format

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web-wireshark): hide xpra shutdown menu via XPRA_CLIENT_CAN_SHUTDOWN

Prevents users from accidentally shutting down the xpra server
through the HTML5 client menu.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(memory): add xpra-html5-client configuration reference

Document xpra HTML5 client configuration including:
- URL parameters for toolbar menu control
- default-settings.txt parameters (Features, Connection, Advanced)
- Server-controlled submenu items
- XPRA_CLIENT_CAN_SHUTDOWN environment variable
- Background image customization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web-wireshark): remove xpra stop cleanup to avoid zombie processes

xpra stop can leave zombie processes and timeout. Instead, let xpra start
reuse the display directly (it will overwrite existing session).

Also added --file-transfer=no, --printing=no, --sound=no to disable
unneeded features.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web-wireshark): add fullscreen_button=false to default-settings.txt

Also remove --file-transfer/--printing/--sound from command line since
xpra doesn't support these options. Configure in default-settings.txt instead.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web-wireshark): update xpra background with GNS3 branding

- Replace default xpra background with GNS3 icon and modern gradient
- Update CSS to use SVG background image with cover sizing
- Change background color to gradient from #021d3a to linear gradient
- Improves visual integration with GNS3 web interface

* style: add GPLv3 headers with copyright to web_wireshark modules

Co-Authored-By: YueGuobin <yueguobin@gmail.com>

* feat(docker): use Alibaba Cloud Debian mirror for faster builds in China

Use mirrors.aliyun.com for Debian packages with correct paths for
both main repo (/debian) and security repo (/debian-security).

Co-Authored-By: YueGuobin <yueguobin@gmail.com>

* feat(web-wireshark): update xpra background styling and echo command

- Replace `echo -e` with `printf` for better POSIX compatibility in Dockerfile
- Update xpra HTML5 client background to use GNS3 icon with light gradient
- Change background color from dark blue to light gray for improved visibility

* fix(web-wireshark): use pkill to stop xpra sessions

Replace 'xpra stop :{display}' with 'pkill -f "xpra.*:{display}"' for more reliable session termination.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): start Wireshark in fullscreen mode

Add --fullscreen flag to Wireshark startup command to prevent window decorations and improve user experience.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): use carrier-grade NAT subnet to avoid conflicts

Change Docker network subnet from 172.28.0.0/16 to 100.64.1.0/24 to avoid conflicts with common private networks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(web-wireshark): update subnet to /22 for 1000+ projects

Change Docker network subnet from 100.64.1.0/24 to 100.64.0.0/22 to support 1000+ projects (1022 available IPs). Update all documentation to reflect the new subnet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): replace CGNAT subnet with configurable private subnet

Replace the CGNAT address block (100.64.0.0/22) with a standard private
subnet (172.31.0.0/22) to avoid network access issues. Many networks and
ISPs block or cannot route CGNAT addresses.

Changes:
- Add WebWiresharkSettings to config schema with configurable subnet
- Read network_subnet from config, default to 172.31.0.0/22
- Add Web Wireshark configuration section to sample config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): comment out dpi setting

Allow xpra to use default DPI settings for better display scaling.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): set DPI in Xvfb to prevent scaling warnings

Add -dpi 96 to Xvfb startup command to match xpra's expected DPI
and avoid "scaling problems" warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): remove custom Xvfb to use default Xorg-dummy

Remove --xvfb parameter to let xpra use the default Xorg-dummy driver,
which properly handles DPI changes when resize-display is enabled and
prevents DPI mismatch warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* revert(web-wireshark): restore Xvfb configuration

Restore the Xvfb display server configuration for xpra sessions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): enhance xpra HTML5 default settings

Update xpra HTML5 configuration to disable additional unused features:
- audio, keyboard, mediasource, aurora, http-stream
- Improve readability using heredoc format instead of printf

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(api): add RBAC authentication to web wireshark WebSocket endpoint

- Add `has_privilege_on_websocket` dependency to enforce Link.Capture privilege
- Include current_user parameter in endpoint for user identification and logging
- Update endpoint documentation to reflect token requirement and privilege
- Add test example WebSocket URL in TEST.md for reference

* refactor(web-wireshark): add generic WebSocket proxy and disable xpra HTML

- Add websocket_to_websocket.py utility for binary WebSocket proxy
- Disable xpra HTML server with --html=no flag
- Update manager return value: url -> ws_url
- Simplify WebSocket proxy implementation in links.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web-wireshark): remove unnecessary sleep delays

Remove 2-second sleep delays after container start and xpra initialization.
Health checks and verification happen immediately, improving startup time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(agent): prevent blocking during project close

- Add 5s timeout for AgentService.checkpointer_conn.close()
- Optimize stop_all_sessions: single command instead of 100 docker exec calls
- Prevents indefinite hang when closing projects

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web-wireshark): return errors to client on startup failure

- Throw ControllerError when Web Wireshark startup fails
- Include detailed error messages from script stderr
- Support both ws_url and url response formats
- Client now receives proper error response instead of success

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web-wireshark): parallelize startup and remove unnecessary waits

- Parallel execution: container info query + xpra start
- Remove xpra list verification (unnecessary)
- Fire-and-forget Wireshark startup (no timeout wait)
- Startup time reduced from ~7s to ~1s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web-wireshark): add stop-container and delete-container commands

- Add stop-container command to stop container on project close
- Add delete-container command to delete container on project delete
- Enables proper container lifecycle management
- Containers are now stopped (not deleted) when project closes
- Containers are deleted when project is deleted

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(project): simplify close flow by removing redundant xpra session cleanup

Since docker stop with timeout=0 already force-kills all processes in the
container, explicitly stopping xpra sessions before stopping the container
is unnecessary. Remove the _cleanup_web_wireshark_xpra_sessions() call
to reduce subprocess overhead and simplify the close flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* perf(docker): force kill containers on stop by default

Change docker stop timeout from 10 seconds to 0 (immediate SIGKILL).
Web Wireshark containers don't need graceful shutdown since they have
no persistent state.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web-wireshark): enable WebSocket protocol for xpra connection

- Change xpra bind from --bind-tcp to --bind-ws for WebSocket support
- Enable HTML client with --html=on for xpra WebSocket server
- Pass binary subprotocol when connecting to xpra container

The xpra WebSocket server requires the 'binary' subprotocol during
handshake. Without it, the server returns 403 with message:
"client does not support 'binary' protocol".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web-wireshark): add WebSocket subprotocol negotiation support

Fix WebSocket proxy for xpra container by implementing proper subprotocol
negotiation. The xpra client requires the server to respond with the
negotiated subprotocol (binary) in the WebSocket handshake response.

Changes:
- Modified get_current_active_user_from_websocket to extract client's
  requested subprotocols from Sec-WebSocket-Protocol header
- Updated websocket.accept() call to include negotiated subprotocol
- Enhanced websocket_proxy to support subprotocol parameter
- Improved logging for WebSocket connection debugging

This fixes the issue where xpra clients would immediately disconnect
after connection due to missing subprotocol in server response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore(web-wireshark): remove verbose debug logging

Remove excessive debug logs from WebSocket proxy implementation while
keeping essential logs for troubleshooting:
- Keep: subprotocol negotiation, connection establishment, errors
- Remove: verbose step-by-step debugging information

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web-wireshark): translate Chinese comments and docs to English

- Translate all Chinese comments in project.py, link.py, and links.py to English
- Convert TEST.md and maunal-test.md documentation to English
- Remove obsolete IMPLEMENTATION_PLAN.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(docker): lock xpra version to 6.4.3 for reproducible builds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore(docker): improve Dockerfile with TZ, no-install-recommends, and labels

- Add TZ=UTC timezone setting
- Use --no-install-recommends to reduce image size
- Add LABEL metadata for maintainer and description

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(docs): rename and consolidate documentation

- Rename TEST.md to WEB_WIRESHARK.md for clearer naming
- Merge maunal-test.md content into main document under "Manual Testing" section
- Remove obsolete gns3_icon_black.svg

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(docker): add xpra-x11 package and remove --no-install-recommends

- Add xpra-x11 package required for seamless mode
- Remove --no-install-recommends to ensure all recommended packages are installed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(api): add capture file download endpoint

Add GET /{link_id}/capture/file endpoint to download PCAP capture files.
Supports downloading while capture is active (streaming).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web_wireshark): improve session cleanup and add known issues

- Add cleanup of existing processes before starting xpra session to prevent
  "another window manager seems to be running" errors
- Stop all associated processes (xpra, wireshark, Xvfb) when stopping sessions
- Document known issues in WEB_WIRESHARK.md including JWT token security,
  duplicate code, and other implementation concerns

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web_wireshark): add restart wireshark API endpoint

- Add POST /links/{link_id}/capture/wireshark/restart endpoint
- Add restart command to manage_wireshark.py CLI
- Add _restart_web_wireshark method in link.py controller
- Restart simply calls start_wireshark_session which handles cleanup

This allows users to recover after accidentally closing the Wireshark
window without having to stop and restart the entire capture.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add Web Wireshark business process documentation

Document the Web Wireshark feature including architecture diagrams,
business processes for capture start/stop, container lifecycle,
WebSocket connection flow, and session management.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web_wireshark): fix container network access and improve session cleanup

- Fix GNS3 server URL detection to use container gateway IP (172.31.0.1)
  instead of localhost/127.0.0.1/0.0.0.0 which don't work from containers
- Add import socket module for gateway IP conversion
- Move urllib.parse import to file header (code style improvement)
- Add logging for Web Wireshark startup (capture stream URL, display, etc.)
- Fix X lock file cleanup to prevent "Server is already active" errors
- Use exec pkill to reduce zombie processes from docker exec bash
- Add _cleanup_x_lock() method to remove X lock files after stopping sessions
- Update link.py to always log subprocess stderr for debugging

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): avoid zombie pkill processes by using Docker API

Replace pkill commands with Docker API-based process killing to prevent
zombie process accumulation in Web Wireshark containers.

Changes:
- Add DockerHTTPClient.list_processes() method to query container processes
- Rewrite _kill_process_tree() to use Docker API instead of pkill
- Unify all process cleanup to use _kill_process_tree() method
- Add logging for killed processes (count and PIDs)
- Include fallback to pkill if Docker API fails

This prevents the accumulation of zombie pkill processes that occurred
when using bash -c "pkill -9 -f pattern" commands.

Testing: Started and stopped multiple capture sessions, verified no new
pkill zombie processes are created during cleanup.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): use docker-init and cleanup socket files

Enable Docker init system (tini) as PID 1 and clean up xpra socket
files when stopping sessions to prevent zombie processes and leftover
sockets.

Changes:
- Add "Init": True to container host_config to use docker-init (tini)
- Extend _cleanup_x_lock() to remove xpra socket files
  * /run/user/1000/xpra/{display}/socket
  * /run/user/1000/xpra/*-{display}
  * /home/gns3/.xpra/*-{display}

Benefits:
- docker-init (tini) automatically reaps orphan processes, eliminating
  zombie process accumulation (tested: 53 zombies -> 0 zombies)
- Socket cleanup prevents xpra list from showing UNKNOWN sessions
- Cleaner container state after stopping sessions

Testing:
- Started and stopped 3 capture sessions
- Verified 0 zombie processes after stopping
- Verified xpra list shows "No xpra sessions found" (no UNKNOWN)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(web_wireshark): add comprehensive CLI script documentation

Add detailed module docstring to manage_wireshark.py explaining:
- Script purpose: CLI tool for manual management, debugging, and testing
- Important note: Use WebWiresharkManager directly for programmatic access
- Usage examples for all commands (start, stop, restart, stop-all, delete)
- Available commands list with descriptions
- Output format specification (JSON to stdout/stderr)
- Help information for getting command-specific usage

This clarifies that the script is intended as a CLI utility, not for
subprocess calls from within GNS3 server code.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web_wireshark): use direct API calls instead of subprocess

Replace subprocess calls to manage_wireshark.py with direct API calls
to WebWiresharkManager, eliminating subprocess overhead and JSON parsing.

Changes:
- Add import for WebWiresharkManager
- Refactor _start_web_wireshark() to use direct API call
- Refactor _stop_web_wireshark() to use direct API call
- Refactor _restart_web_wireshark() to use direct API call

Benefits:
- Code reduction: 78 lines (-68%)
- Better performance: No subprocess creation overhead
- Better logging: Manager logs directly to GNS3 logging system
- Simpler error handling: Direct exceptions instead of return codes
- No JSON parsing: Direct Python objects
- Resource cleanup: Added finally blocks to ensure manager.close()

Testing:
- All Web Wireshark operations work correctly
- Logs now appear in GNS3 server logs instead of stderr
- Error handling improved with proper exception propagation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): resolve circular import with delayed imports

Fix circular import error by moving WebWiresharkManager import from
module level to function level (delayed import).

Circular dependency was:
  link.py → WebWiresharkManager → Controller → link.py

Solution:
  - Remove top-level import of WebWiresharkManager
  - Add delayed imports in each method that uses it:
    * _start_web_wireshark()
    * _stop_web_wireshark()
    * _restart_web_wireshark()

This allows the controller module to fully initialize before importing
WebWiresharkManager, breaking the circular dependency.

Error before fix:
  ImportError: cannot import name 'Controller' from partially initialized
  module 'gns3server.controller' (most likely due to a circular import)

Testing:
  - Successfully imports Link module
  - GNS3 server starts without import errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: move imports to module level and remove Controller dependency

Remove circular dependency between link.py and manager.py by:

1. Remove Controller import from manager.py
   - Manager no longer imports Controller
   - URL detection now relies on Config or default only
   - link.py passes capture_stream_url to manager

2. Move WebWiresharkManager import to module level in link.py
   - No longer need delayed imports since no circular dependency
   - Clean, standard Python import pattern

3. Remove redundant Config import in ensure_network()
   - Config was already imported at module level

Changes:
- manager.py: -24 lines (removed _get_gns3_url_from_controller and redundant import)
- link.py: -30 lines net reduction after moving import to top

Testing:
- All imports work without circular dependency errors
- GNS3 server starts successfully

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(docker_client): use text response for list_processes API

Docker API /containers/{id}/top returns plain text, not JSON.
The generic _request method auto-parses JSON which caused:
  "'dict' object has no attribute 'strip'"

Fix by using session.get() directly with response.text()
instead of the generic _request method.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): use correct capture stream URL endpoint

Remove passing capture_stream_url from link.py to manager.py.
Manager.py auto-detects URL using correct endpoint:
  /v3/projects/{project_id}/links/{link_id}/capture/stream

This endpoint supports JWT authentication, unlike the compute URL
(/v3/compute/...) which requires compute credentials.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): use container-local PIDs for process killing

- Docker API returns host PIDs, not container PIDs - use pgrep inside
  container to get correct PIDs for kill
- Fix list_processes to parse Docker API JSON response correctly
- Remove unnecessary exec prefix in shell commands
- Add logging for debugging process killing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* perf(web_wireshark): optimize process killing with single pgrep call

Replace sequential _kill_process_tree calls with a new _kill_process_tree_batch
method that combines all patterns into a single regex. This reduces docker exec
calls from 8 to 1, improving performance from ~8 seconds to ~0.9 seconds.

Changes:
- Add _kill_process_tree_batch() method with combined regex pattern matching
- Update start_wireshark_session() to use batch cleanup
- Update stop_wireshark_session() to use batch cleanup
- Update stop_all_sessions() to use batch cleanup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): disable HTML5 client to improve xpra startup speed

Change --html=on to --html=off to disable the xpra HTML5 client interface.
This reduces xpra startup time from ~6.4s to ~2.9s (55% improvement) while
keeping the WebSocket server functional for browser connections.

The HTML5 client is not needed as we only require the WebSocket endpoint
for remote display forwarding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): optimize container health check using Docker built-in status

Replace manual docker exec ping with Docker's built-in health check status
to reduce container startup latency by ~1 second.

Changes:
- Use container["Health"]["Status"] instead of manual ping check
- Skip health check for containers with "healthy" or "starting" status
- Only verify containers with "unhealthy" status
- Keep manual health check for newly started containers

This reduces the container verification time from ~1s to near-zero
for healthy running containers while maintaining safety for unhealthy ones.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): get gateway IP from Docker API instead of container exec

Replace slow docker exec method with fast Docker Network API call to get
gateway IP. This reduces gateway detection from ~850ms to ~1ms (1000x faster).

Changes:
- Use docker.get_network() API to get gateway from IPAM config
- Keep container exec methods as fallback if Docker API fails
- Remove container_id requirement (not needed for Docker API method)

The Docker network gateway is shared by all containers in the network,
so querying the network is more efficient than querying each container.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web_wireshark): remove unreliable nameserver fallback for gateway detection

Remove the fallback method that reads /etc/resolv.conf nameserver as gateway.
This method is unreliable because:
- nameserver is not necessarily the gateway (could be upstream DNS)
- Many systems use 127.0.0.53 (systemd-resolved) or 127.0.0.1
- Even when not local, it could be public DNS (8.8.8.8, 1.1.1.1)

The current fallback strategy is sufficient:
1. Docker Network API (fast, reliable)
2. /proc/net/route (standard gateway detection)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): use host perspective for process killing (37x faster)

Replace docker exec with host perspective process management for killing
container processes. This reduces process cleanup from ~850ms to ~23ms.

Key optimization:
- Get container init PID using docker inspect (fast)
- Use pgrep -P <init_pid> to find child processes from host perspective
- Kill processes directly using host PID (no docker exec needed)

Performance improvements:
- Process finding: 850ms → 23ms (37x faster)
- Process killing: 850ms → <1ms (850x faster)
- File checking: 850ms → 0.003ms (280,000x faster)

Fallback to docker exec method if host perspective fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): use host perspective for file cleanup (891x faster)

Replace docker exec with direct filesystem access from host perspective
for cleaning up X lock files and xpra sockets. This reduces cleanup time
from ~890ms to ~1ms (891x faster).

Key optimization:
- Access /proc/<container_pid>/root/ directly from host
- Use os.remove() and glob.glob() instead of docker exec rm -f
- Fallback to docker exec if host perspective fails

This complements the earlier optimization for process killing, further
reducing startup time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* Revert "perf(web_wireshark): use host perspective for file cleanup (891x faster)"

* fix(web_wireshark): recursively kill all descendant processes to prevent orphans

Previous implementation only killed direct children of container init using
`pgrep -P <init_pid>`, but xpra spawns child processes (Xvfb, pulseaudio,
ibus-daemon) that become grandchildren and were not being terminated.

This fix walks the entire process tree recursively to find and kill all
descendant processes, ensuring complete cleanup without orphans.

Performance: ~20-40ms (only 10-20ms slower than previous 23ms, but ensures
thorough cleanup).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(web_wireshark): add comprehensive startup/shutdown performance metrics

Add detailed performance characteristics section documenting:
- Startup performance breakdown (before/after optimization)
- Shutdown performance breakdown (before/after optimization)
- First startup vs subsequent startup comparison
- Measured production data
- Key optimization techniques

Performance improvements: 67% faster startup, 78% faster shutdown,
zero orphan processes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): ensure container stops on project close

Remove dependency on _web_wireshark_container_created flag which gets
reset when project is reloaded, causing container to not stop on project close.

Now directly attempts to stop container on every project close. If container
doesn't exist, the script handles it gracefully. This is simpler and more
reliable than maintaining a flag.

Also removed unnecessary _cleanup_web_wireshark_xpra_sessions() call since
stopping the container automatically terminates all xpra sessions inside.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): ensure container deletion on project delete

Remove dependency on _web_wireshark_container_created flag from
_cleanup_web_wireshark_container() to ensure container is deleted
when project is deleted, even if project was reloaded and flag was reset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(web_wireshark): remove unused _web_wireshark_container_created flag

This flag was set but never read for any conditionals since we changed
the stop/delete methods to directly attempt the operation. It's purely
redundant code that adds confusion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): skip unnecessary cleanup using fast host perspective check

Add _check_residuals_exist() function that uses host perspective (~20ms)
to check if residual processes or socket files exist before cleanup.

Returns (has_process_residuals, has_socket_residuals) tuple to allow
selective cleanup - if only sockets need cleaning, skip the slower
process tree killing.

For new containers with no residuals, this saves ~3 seconds of
unnecessary docker exec calls.

Socket cleanup always uses docker exec for safety (avoiding accidental
host filesystem deletion from /proc/<pid>/root/ path errors).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(web_wireshark): increase container exec timeout from 5s to 10s

xpra start with Xvfb initialization can take longer than 5 seconds in Docker containers, causing timeout failures. Increasing timeout to 10 seconds to allow sufficient startup time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* perf(web_wireshark): optimize cleanup and document docker exec limitations

- Combine X lock and xpra socket cleanup into single docker exec call
  Reduces exec calls from 2 to 1 per stop operation, improving performance
  when stopping multiple capture sessions.

- Document Docker exec performance limitations with test data showing
  parallel exec is 42% slower than serial due to Docker daemon's
  internal queuing mechanism.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(links): prevent AssertionError in stream_pcap during rapid stop_capture

Fix race condition where stream_pcap checks link.capturing (True) but
link.capture_node becomes None before accessing link.compute.

This happens when stop_capture() is called and rapidly cleans up
_capture_node while WebSocket requests are still processing.

Now check both capturing and capture_node to ensure capture is still active.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(links): prevent AssertionError in stream_pcap during rapid stop_capture

Fix race condition where stream_pcap checks link.capturing (True) but
link.capture_node becomes None before accessing link.compute.

This happens when stop_capture() is called and rapidly cleans up
_capture_node while WebSocket requests are still processing.

Now check both capturing and capture_node to ensure capture is still active,
and log at DEBUG level since this is expected behavior during rapid stop.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web_wireshark): load container config from settings

- Load memory, cpus, and pids_limit from WebWireshark config section
- Apply config only on container creation (_start_web_wireshark)
- Skip config on restart (_restart_web_wireshark) as container exists

Users can now configure container resources in gns3_server.conf:

[WebWireshark]
memory = 4g
cpus = 2.0
pids_limit = 2000

If not configured, defaults (2g, 1.0, 1000) are used.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(web_wireshark): add container statistics to /v3/statistics endpoint

Add Web Wireshark container monitoring to the statistics API for
better visibility into packet capture sessions.

Changes:
- Create new stats.py module with collect_webwireshark_stats()
  * Collects container info (status, project, active sessions)
  * Gets resource limits (memory, CPU, PIDs) from container config
  * Gets resource usage via docker stats (memory, CPU, PIDs)
  * Properly closes aiohttp connections to avoid leaks

- Update /v3/statistics endpoint to include webwireshark data
  * total_containers: Total number of Web Wireshark containers
  * running_containers: Number of containers currently running
  * active_sessions: Total active capture sessions
  * containers: Array with per-container details

- Update statistics-api.md documentation
  * Change URL from /v1/statistics to /v3/statistics
  * Add webwireshark field descriptions and examples
  * Add dashboard integration for Web Wireshark monitoring

Example response:
{
  "webwireshark": {
    "total_containers": 1,
    "running_containers": 1,
    "active_sessions": 2,
    "containers": [{
      "project_id": "...",
      "project_name": "test",
      "container_id": "6edc9029bac0",
      "status": "running",
      "memory_limit": "4.0 GB",
      "cpu_limit": "4.0",
      "pids_limit": 4000,
      "memory": "535.7MiB / 4GiB",
      "cpu": "0.29%",
      "pids": 124
    }]
  }
}

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor(project): use WebWiresharkManager directly instead of subprocess

Replace subprocess calls to manage_wireshark.py with direct
WebWiresharkManager method calls in project.py. This eliminates
unnecessary process overhead and maintains consistent usage pattern
with link.py.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(logging): use %-formatting instead of f-strings in WebWireshark methods

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(web_wireshark): use info level log when container not found

Change log level from warning to info when container doesn't exist
during stop/delete operations, and fix f-string without placeholders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(logging): lower log level for client disconnection

Change log level from warning to debug when client possibly
disconnects, as this is normal behavior when users close
browser tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(linting): resolve ruff warnings and errors

- Remove unused variable proc (fire-and-forget subprocess)
- Remove duplicate nodes property definition
- Remove extraneous f-prefix from f-strings without placeholders
- Change bare except to except Exception
- Remove unused imports (sys, asyncio, json)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web_wireshark): improve error message when Docker image not found

When creating a container fails due to missing image, provide helpful
error message with docker pull command and local build instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(schema): add wireshark field to Link schema

Add wireshark boolean field to Link Pydantic schema so it is
included in API responses when Web Wireshark session is active.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(link): add wireshark state tracking

Track whether Web Wireshark is running on a link by adding
_wireshark boolean property, updated on start/stop operations.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(chat): add session abort functionality

Add ability to abort streaming chat sessions via REST API.

Changes:
- Add abort flag to MessagesState for tracking abort requests
- Add session_id to state for abort event correlation
- Add _abort_flags dict and check/set/clear functions in gns3_copilot.py
- Add abort_handler_node to generate aborted tool messages
- Modify should_continue to route to abort_handler_node when aborting
- Add abort_session() method in AgentService
- Add POST /sessions/{session_id}/abort API endpoint
- Clear abort flag at stream start

When abort is triggered during streaming:
- If LLM has tool_calls pending, abort_handler_node generates
  aborted tool messages to maintain checkpoint consistency
- Prevents "insufficient tool messages" error on resume

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(chat): send tool_end event when stream is aborted

When a stream is aborted during tool execution, yield proper tool_end
events for aborted tools instead of a generic abort event. This maintains
compatibility with the frontend's expected tool_start/tool_end flow.

Changes:
- Add stream_aborted tracking flag
- After stream loop, check abort flag and yield tool_end events
- Add "abort" to ChatResponse type enum (unused but available)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(web_wireshark): add gns3-wireshark-setup command for Docker image setup

Add a new entry point script that allows users to setup the Web
Wireshark Docker image with a single command:

    pip install gns3-server && gns3-wireshark-setup

The script will:
1. Try to pull gns3/web-wireshark:latest from Docker Hub
2. If pull fails, build the image locally using the included Dockerfile
3. Show raw docker pull/build output for full visibility

Files changed:
- Add setup_wireshark_image.py (new entry point script)
- Update pyproject.toml (add gns3-wireshark-setup entry point)
- Update documentation (README.md, WEB_WIRESHARK.md, web-wireshark-business-process.md)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(appliance): add tags field support for appliances and templates

- Add tags field to ApplianceV1_6 and ApplianceV8 schemas
- Add tags propagation from appliance config to template
- Simplify VPCS builtin template tags

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix test in test_link.py

* Fix link.py after failed tests

* feat(copilot): add device skills system for LLM context injection

- Add skills module with registry and DeviceSkillsTool
- Skills organized by vendor/series for easy extensibility
- Support device_type, category (device/protocol/feature), operation (config/diagnosis)
- First implementation: VPCS skill (gns3_vpcs_telnet)
- Skills tool integrated into teaching_assistant and lab_automation modes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(vpcs): change prompt detection log from warning to debug

The "VPCS prompt not clearly detected" message is not an error,
connection works fine. Change to debug level to reduce noise.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(memory): add uBridge permission issue documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(copilot): include link_id in links_summary output

Return link_id in the links_summary method so that the AI can
identify which link to analyze when using the packet capture tool.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(copilot): add packet capture analysis tool

Add PacketCaptureTool that allows AI to analyze packets from an active
GNS3 capture. The tool downloads capture files from the GNS3 server
and runs tshark analysis to help users understand network traffic.

Features:
- Download capture file from /capture/file endpoint
- Run tshark with custom arguments for flexible analysis
- Support analyzing specific packets (e.g., "explain packet #42")
- Support protocol statistics, traffic analysis, and expert info

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(copilot): use shlex.split to properly parse quoted tshark arguments

tshark_args may contain quoted filter expressions like "-Y \"frame.number == 24\"".
Using plain str.split() breaks these quoted arguments, causing tshark warnings
about conflicting display filters. Use shlex.split() to correctly parse quoted
arguments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): simplify PacketCaptureTool to accept only packet_number

Instead of exposing complex tshark arguments to the LLM, the tool now
accepts a simple packet_number parameter and internally constructs the
tshark command with verbose output. This prevents the LLM from generating
incorrect tshark parameters while still providing detailed packet analysis.

Changes:
- Remove tshark_args and max_lines parameters
- Accept only packet_number as input
- Internal command: tshark -r <file> -Y "frame.number == N" -V
- Returns complete packet structure without line limits

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add CC BY-SA 4.0 license headers to documentation files

Add SPDX license headers referencing docs/LICENSE file to all markdown
and HTML documentation files in the docs directory.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(copilot): add topology planner skill

Add new skill for automatic network lab topology planning:
- IOU as default image, 10.0.0.0/8 IP range, max 10 nodes
- Node naming convention: R/S/PC + number
- 7-step workflow for create/rename/link/start/verify/config
- IP allocation rules and troubleshooting guide

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(copilot): add node positioning rules to topology planner skill

Add grid-based positioning for GNS3 nodes:
- Minimum 250px distance between nodes
- Grid layout: 4 columns, 300x250px spacing
- Formula: x = -400 + col * 300, y = -200 + row * 250
- Update workflow params_required to include x, y coordinates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): remove unused helper functions from topology planner skill

Delete Python helper functions that cannot be serialized to JSON:
- calculate_node_positions()
- get_position_for_node()
- allocate_subnet()
- allocate_ip()
- TOPOLOGY_CREATION_STEPS (duplicate of workflow in skill dict)

LLM should use formula descriptions in skill to calculate positions/IPs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(copilot): add topology_planner workflow to lab automation prompt

Add device_skills tool to AVAILABLE TOOLS table.
Add TOPOLOGY PLANNING WORKFLOW section explaining:
- How to query topology_planner skill
- Default conventions (IOU, 10.0.0.0/8, naming rules, position formula)
- 7-step workflow for topology creation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(copilot): support name parameter in gns3_create_node tool

- Add optional 'name' field to node creation, allowing direct naming
- Update Node constructor to pass name parameter
- Remove separate rename step (step_3) from topology planner workflow
- Renumber workflow steps: 1-2-3-4-5-6 (skipping old step_3 rename)

This eliminates the need for a separate gns3_update_node_name_tool call
when creating nodes with predefined names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(copilot): update topology workflow to 6 steps

Remove rename step since name can be set directly in create_gns3_node.
Workflow changed from 7 steps to 6 steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): replace grid positioning with topology-based layout

Redesign node positioning rules to follow classic network topologies:
- Star: hub at center, spokes radiating outward
- Ring: nodes in circular arrangement
- Bus: linear chain of nodes
- Mesh: grid pattern for interconnected nodes
- Hierarchical: three-tier (Core → Distribution → Access)
- Linear P2P: point-to-point WAN links in a line

Remove old grid formula. Update prompt and workflow to reflect new approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs(copilot): add note about combining topology types

LLM can mix topology types as needed, e.g., star + linear_p2p for WAN segments.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): remove language matching rules from prompts

Remove language matching rules that cause inconsistent responses:
- "User writes in Chinese → Respond in Chinese"
- "User writes in English → Respond in English"

These created ambiguity and led to inconsistent language behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): remove Chinese from response template

Replace mixed Chinese/English headers with English only:
- "操作总结 / Operation Summary" → "Operation Summary"
- "详细信息 / Details" → "Details"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* refactor(copilot): remove Chinese mentions from prompts

Remove references to "Chinese" language in title_prompt.py:
- "Generates concise Chinese or English titles" → "Generates concise titles"
- "If the content is predominantly in Chinese, generate a Chinese title" → removed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(copilot): use short_name for link labels and support short port names

- Match ports by both name and short_name for flexibility
- Use short_name (e.g. "e0/0") instead of full name (e.g. "Ethernet0/0")
  for link labels, improving visual clarity in dense topologies

* feat(topology): replace hardcoded interface names with dynamic placeholders

- Update topology planner skill template to use {short_name} placeholder
- Allows dynamic interface name generation based on device type
- Improves template flexibility for different network device configurations

* refactor(topology): use node-pair IP format and hyphenated naming

- Use 10.0.{node_pair}.x format for P2P links (e.g., 10.0.12.x for R-1-R-2)
- Change node naming to hyphenated format: R-1, R-2, SW-1, PC-1
- Use {short_name} as placeholder for port names in output template
- Remove unused IP_SUBNET_POOL constant
- Simplify ip_planning rules to intuitive format description

* fix(web_wireshark): raise minimum Docker API version to 1.44

Docker daemon requires API version 1.44+, so the minimum
supported version should match rather than defaulting to 1.40.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(web_wireshark): call ensure_network in start_wireshark_session

Ensure Docker network exists before creating container, so that
Web Wireshark works when started via API without going through CLI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(agent): improve Docker image setup with network error detection

- Add `is_network_error()` function to detect network-related failures in Docker pull output
- Modify `pull_image()` to capture output and return success status along with output
- Enhance main logic to detect network errors and skip local build when Docker Hub is inaccessible
- Provide helpful suggestions for network issues (Docker mirror, VPN, manual image transfer)
- Improve error messages to differentiate between network failures and other errors

* feat(docs): add Ubuntu 24.04 development setup guide

Add a comprehensive development environment setup guide for Ubuntu 24.04. The guide includes steps to install dependencies via PPA, configure Docker with mirror accelerators for users in mainland China, set up user permissions, and run the server from source with a Python virtual environment. This provides a clear, step-by-step reference for new contributors and developers.

* feat(docs): add pip mirror note for China mainland users

Add a comment in the development setup documentation suggesting the use of the Aliyun PyPI mirror for users in China mainland to improve installation speed and reliability. This helps overcome network restrictions and slow downloads from the default PyPI repository.

* feat(docs): add LVM root partition expansion guide

Add optional section to development setup documentation with instructions for expanding the root partition when using LVM. This helps developers resolve low disk space issues by utilizing unallocated space in the volume group. The guide includes commands to check LVM status, extend the logical volume, and verify the changes.

* feat(docs): add tshark to development setup dependencies

Add tshark to the apt install command in the development setup documentation. Tshark is required for packet capture functionality in GNS3, ensuring the development environment has all necessary tools for network analysis and debugging.

* feat: add GNS3 documentation skill with standardized structure

Add new documentation skill file defining standards for GNS3 technical documentation. The skill establishes a structured approach focusing on architecture diagrams, flow diagrams, and text descriptions while prohibiting code examples and user scenarios. This ensures consistent, high-quality documentation across the GNS3 ecosystem.

* feat(docs): update documentation skill to focus on server technical docs

Update the GNS3 documentation skill to specifically target server technical documentation under the docs/ directory. The revised standard emphasizes high-level understanding over implementation details, using ASCII diagrams for architecture and business processes, API endpoint tables, and measured performance data. Code specifics are intentionally omitted, directing readers to the codebase for implementation details.

* feat(docs): rewrite documentation skill and statistics API doc

- Rewrite gns3-documentation skill to match actual server-side doc style:
  focus on architecture/flow diagrams, API data, skip code details
- Switch diagram standard from ASCII to Mermaid (GitHub native rendering)
- Rewrite statistics-api.md with Mermaid architecture and sequence diagrams,
  add missing webwireshark container fields (memory_limit, cpu_limit, pids_limit),
  remove speculative content

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat(docs): update VNC WebSocket console documentation with Mermaid diagrams

- Replace ASCII diagrams with Mermaid flowcharts for better visualization
- Clarify connection flow between browser, controller, compute, and VNC server
- Update authentication details and endpoint descriptions
- Add missing documentation for packet capture workflow
- Improve overall readability and maintainability

* docs: add AI disclaimer to documentation files

Add a standardized disclaimer to multiple documentation files indicating that the content has been organized by AI with reference to actual code. The disclaimer warns users that AI can make mistakes and advises verification against the source code when in doubt. This improves transparency about the documentation's origin and encourages careful usage.

* feat(docs): update chat API documentation with new features and clarifications

- Update title from "Design Document" to reflect current implementation status
- Add new features: session abort, copilot modes (teaching_assistant, lab_automation_assistant), session pinning
- Enhance architecture diagram with LangGraph StateGraph details including abort_handler_node, title_generator_node, and conditional edges
- Clarify statistics tracking: add ai_response_counted flag, filter title_generator_node from LLM counts, explain incremental token counting
- Improve documentation accuracy for real-time statistics collection and token calculation methods

* feat(docs): restructure command security documentation with visual workflows

- Replace verbose implementation details with concise architecture overview
- Add Mermaid diagrams to visualize command filtering and multi-line expansion flows
- Simplify configuration instructions and remove redundant examples
- Consolidate file structure and function reference tables for clarity
- Maintain all security principles while improving readability and maintainability

* feat(context): refactor context window management documentation for clarity

- Reorganize documentation with improved structure and visual diagrams
- Add Mermaid diagrams to illustrate architecture and trimming process
- Simplify content while maintaining technical accuracy
- Update token counting and trimming strategy explanations
- Enhance readability with better formatting and component tables

* feat(docs): update LLM model configs documentation

- Change config column type from JSONB to JSON (JSONB on PostgreSQL)
- Update provider table to mark base_url as required with planned optional status
- Add note about base_url being currently required in API schema
- Clarify GET own configs endpoint returns plain array
- Add copilot_mode field to update request schema
- Document update limitations for context_strategy and copilot_mode fields

* feat(docs): add GNS3StartNodeQuickTool and update node creation examples

- Add documentation for new `GNS3StartNodeQuickTool` (`start_gns3_node_quick`) that starts nodes without waiting for boot completion
- Update node creation example to include optional `name` field in template placement
- Clarify dynamic wait time strategy for `GNS3StartNodeTool` and contrast with quick tool
- Update tool file structure to reflect new configuration, display, and packet capture tools
- Fix truncated line in suspend tool documentation

* feat(docs): add comprehensive documentation structure with CC BY-SA 4.0 license

Add initial documentation directory with detailed README.md that outlines:
- Dual license structure (CC BY-SA 4.0 for docs, GPLv3 for code)
- Complete directory structure for features, AI Copilot, and bugs
- Feature documentation covering Controller+Compute setup, Statistics API, VNC WebSocket console, and Web Wireshark
- AI Copilot implemented features including Chat API, LLM model configs, command security, and multi-vendor device support

This provides organized technical documentation for the GNS3 server project with proper licensing and feature coverage.

* docs: update multi-vendor device support documentation

- Simplify vendor support table by removing redundant platform column
- Add VPCS as a simulator in status column
- Improve VPCS driver diagram with Mermaid syntax and detailed components
- Document VPCS-specific Netmiko parameters (fast_cli, global_delay_factor)
- Update VPCS tool usage example with connection options structure
- Remove outdated Nornir configuration approaches, reference current implementation
- Add file reference for VPCS tools location
- Clean up documentation structure for better readability

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: YueGuobin <yueguobin@gmail.com>
Co-authored-by: Jeremy Grossmann <grossmj@gns3.net>
2026-04-20 22:56:55 +08:00

102 KiB
Raw Blame History

This documentation is organized by AI with reference to actual code. AI can make mistakes — please verify against the source code when in doubt.

Template-Based System with HITL - Future Roadmap

Status: 💡 Proposed Target Version: Next Release Last Updated: 2026-03-20

Overview

This document outlines the plan for implementing template-based systems with Human-in-the-Loop (HITL) confirmations for both device configuration and node creation in GNS3 AI Copilot.

Scope & Positioning

This system focuses on baseline configuration and topology provisioning - getting from zero to a manageable state. Once devices are connected and have basic IP/routing configuration, modern network management tools can take over for production-grade configuration management.

┌─────────────────────────────────────────────────────────────┐
│ Phase 1: Environment Preparation (This System)              │
│ ─────────────────────────────────────────────────────────── │
│ • Create topology (nodes + links)                           │
│ • Baseline IP configuration                                 │
│ • Enable routing protocols (OSPF/BGP)                       │
│ • Management access (SSH/HTTPS/NETCONF)                     │
│ • Basic security (ACLs, passwords)                          │
│ ─────────────────────────────────────────────────────────── │
│ Result: Manageable network ready for production tools       │
└─────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────┐
│ Phase 2: Production Configuration (External Tools)          │
│ ─────────────────────────────────────────────────────────── │
│ • Terraform (Infrastructure as Code)                        │
│ • REST API (Modern device management)                       │
│ • NETCONF/YANG (Standardized configuration)                 │
│ • Network Controllers (SDN, APIC, etc.)                     │
│ • Monitoring & Observability                                │
└─────────────────────────────────────────────────────────────┘

Use Cases for This System:

  • Rapid lab provisioning (training, testing, CI/CD)
  • Network simulation and research
  • Proof-of-concept deployments
  • Disaster recovery drills
  • Initial topology setup before handoff to automation tools

Not In Scope (handled by other tools):

  • Fine-grained configuration management
  • Compliance and policy enforcement
  • Continuous configuration drift management
  • Production-grade change management
  • Advanced telemetry and monitoring

Motivation

Current Configuration Challenges

The current implementation requires AI to generate complete configuration commands for every device, which:

  • Consumes excessive tokens: Each device configuration is generated independently (~150 tokens/device × 10 devices = 1500 tokens)
  • Lacks user control: Configurations are executed immediately without human review
  • No reusability: Similar configurations must be regenerated from scratch
  • Higher error risk: Direct execution without preview or confirmation

Current Node Creation Challenges

Similarly, creating multiple nodes has significant inefficiencies:

  • Token waste: Each node creation requires ~50 tokens for tool calls (100 nodes = 5000 tokens)
  • Slow execution: Nodes are created serially or with limited parallelism
  • No batch operations: Cannot create groups of related nodes efficiently
  • Manual positioning: Each node must be positioned individually

Proposed Solution

Implement a unified template-based HITL workflow for both configuration and node creation:

  1. AI generates template → Human reviews and confirms
  2. AI generates parameters (optional) → Human reviews and confirms
  3. Local execution → Results displayed

Expected Benefits:

  • 98-99% token savings for large-scale operations (1000+ devices/nodes)
  • 90%+ time savings through parallel execution and batch operations
  • Full user control with preview and confirmation at every step
  • Template reusability across similar operations

Architecture Design

Workflow Diagram

User Request: "Configure OSPF on all routers"
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 1: AI Generates Jinja2 Template                         │
│                                                              │
│ Output:                                                      │
│ {                                                            │
│   "template_content": "router ospf {{ pid }}\n...",         │
│   "description": "OSPF basic configuration",                │
│   "params_schema": {                                         │
│     "process_id": "int - OSPF process ID",                  │
│     "networks": "List[Dict] - network list",                │
│     "area": "str - area ID"                                 │
│   }                                                          │
│ }                                                            │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint 1: Template Review                       │
│                                                              │
│ User sees:                                                  │
│ - Template content (Jinja2 syntax)                          │
│ - Parameter schema                                          │
│ - Example rendered output                                   │
│                                                              │
│ Options: [✓ Confirm] [✏️ Modify] [❌ Cancel]                 │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 2: AI Generates Parameters                             │
│                                                              │
│ Output:                                                      │
│ {                                                            │
│   "project_id": "uuid-xxx",                                  │
│   "device_params": [                                         │
│     {                                                        │
│       "device_name": "R1",                                   │
│       "process_id": 1,                                       │
│       "networks": [{"ip": "192.168.1.0", "mask": "0.0.0.255"}], │
│       "area": "0"                                            │
│     },                                                       │
│     ... // More devices                                      │
│   ]                                                          │
│ }                                                            │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint 2: Parameter Review                      │
│                                                              │
│ User sees:                                                  │
│ - Parameter preview per device                              │
│ - Rendered configuration commands                           │
│ - Summary of changes                                         │
│                                                              │
│ Options: [✓ Execute] [✏️ Modify] [👁️ Preview] [❌ Cancel]    │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 3: Local Rendering & Execution                         │
│                                                              │
│ Process:                                                     │
│ 1. Render template with parameters (0 tokens)               │
│ 2. Call existing ExecuteMultipleDeviceConfigCommands        │
│ 3. Return execution results                                  │
└─────────────────────────────────────────────────────────────┘

Token Consumption Comparison

Scenario: Configure OSPF on 10 Cisco Routers

Approach Token Usage Breakdown
Current Method ~1500 tokens 150 tokens/device × 10 devices
Template Method ~400 tokens Template: 150 + Parameters: 250
Savings 73% 1100 tokens saved

Scenario: Configure VLANs on 20 Switches

Approach Token Usage Breakdown
Current Method ~1600 tokens 80 tokens/switch × 20 switches
Template Method ~400 tokens Template: 100 + Parameters: 300
Savings 75% 1200 tokens saved

🔥 Scenario: Large-Scale Topology - 500+ Routers

This is where the template-based approach truly shines for rapid environment provisioning.

Approach Token Usage Execution Time Breakdown
Current Method (AI) ~75,000 tokens ~25 minutes 150 tokens/device × 500 devices, serial execution
Template + AI ~5,000 tokens ~10 minutes Template once + AI generates params, but slow
Template + Rules (Direct) ~400 tokens ~3 minutes Template once + rule engine (0 tokens) + parallel execution
Savings 99.5% 88% Game-changing for large deployments

Key Insight: For environments with hundreds or thousands of nodes, the direct execution mode (skipping AI) becomes critical for rapid topology preparation.


Core Components

System Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                         GNS3 Web UI / CLI                          │
└──────────────────────────────┬──────────────────────────────────────┘
                               │ HTTP/WebSocket
                               ↓
┌─────────────────────────────────────────────────────────────────────┐
│                       GNS3 Server (FastAPI)                         │
│                                                                      │
│  ┌─────────────┐  ┌──────────────┐  ┌──────────────────────────┐  │
│  │ Chat API    │  │ Template API │  │  SSE Progress Stream      │  │
│  │ (existing)  │  │ (new)        │  │  (new)                    │  │
│  └──────┬──────┘  └──────┬───────┘  └──────────┬───────────────┘  │
│         │                │                     │                   │
│         └────────────────┴─────────────────────┘                   │
│                               │                                     │
└───────────────────────────────┼─────────────────────────────────────┘
                                │
                                ↓
┌─────────────────────────────────────────────────────────────────────┐
│                   AI Copilot Agent (LangGraph)                      │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │              HITL Workflow Orchestrator                       │  │
│  │  ┌──────────┐    ┌──────────┐    ┌──────────┐               │  │
│  │  │ Generate │ →  │ Generate │ →  │ Execute  │               │  │
│  │  │ Template │    │ Params   │    │ Config   │               │  │
│  │  └────┬─────┘    └────┬─────┘    └────┬─────┘               │  │
│  │       │               │               │                      │  │
│  │  🔵 HITL Checkpoints (LangGraph Interrupts)                 │  │
│  └──────────────────────────────────────────────────────────────┘  │
│                                                                      │
│  ┌──────────────────────────────────────────────────────────────┐  │
│  │                    Core Modules                               │  │
│  │  ┌──────────────┐  ┌─────────────┐  ┌──────────────────┐    │  │
│  │  │   Template   │  │   Session   │  │   Rule Engine    │    │  │
│  │  │   Renderer   │  │   Manager   │  │  (Direct Mode)   │    │  │
│  │  └──────────────┘  └─────────────┘  └──────────────────┘    │  │
│  └──────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘
                                │
                                ↓
┌─────────────────────────────────────────────────────────────────────┐
│                      GNS3 Controller & Compute                      │
│  ┌────────────┐  ┌────────────┐  ┌──────────────────────────┐     │
│  │   Node     │  │   Link     │  │    Nornir + Netmiko      │     │
│  │ Management │  │ Management │  │    (Config Execution)    │     │
│  └────────────┘  └────────────┘  └──────────────────────────┘     │
└─────────────────────────────────────────────────────────────────────┘

HITL State Transition Diagram

                    ┌─────────────┐
                    │    IDLE     │
                    └──────┬──────┘
                           │ User Request
                           ↓
                    ┌─────────────┐
                    │  GENERATING │
                    │  TEMPLATE   │
                    └──────┬──────┘
                           │ AI Complete
                           ↓
                    ┌─────────────────────────────────┐
                    │      🔵 TEMPLATE_REVIEW        │
                    │      (LangGraph Interrupt)      │
                    │                                 │
                    │  User sees:                     │
                    │  - Template content             │
                    │  - Parameter schema             │
                    │  - Example output               │
                    │                                 │
                    │  Actions:                       │
                    │  [Confirm] [Modify] [Cancel]    │
                    └─────┬───────────────┬───────────┘
                          │               │
                Confirm   │               │ Cancel
                          │               ↓
                    ┌──────┴──────┐   ┌────────┐
                    │ GENERATING  │   │  END   │
                    │  PARAMS     │   └────────┘
                    └──────┬──────┘
                           │ AI Complete OR
                           │ Rule Engine
                           ↓
                    ┌─────────────────────────────────┐
                    │      🔵 PARAMS_REVIEW          │
                    │      (LangGraph Interrupt)      │
                    │                                 │
                    │  User sees:                     │
                    │  - Device list                  │
                    │  - Parameters per device        │
                    │  - Rendered configs             │
                    │                                 │
                    │  Actions:                       │
                    │  [Execute] [Modify] [Cancel]    │
                    └─────┬───────────────┬───────────┘
                          │               │
                Execute   │               │ Cancel
                          │               ↓
                    ┌──────┴──────┐   ┌────────┐
                    │  EXECUTING  │   │  END   │
                    │  (0 tokens) │   └────────┘
                    └──────┬──────┘
                           │ Complete
                           ↓
                    ┌─────────────┐
                    │  COMPLETED  │
                    └─────────────┘

Component Overview

1. LangChain Tools (3 new tools)

GenerateConfigTemplate

  • Purpose: Generate Jinja2 templates for human review
  • Input: project_id, device_type, requirement
  • Output: template_content, description, params_schema, rendered_example
  • Token Cost: ~150-200 tokens

GenerateTemplateParams

  • Purpose: Generate parameters for confirmed templates
  • Input: project_id, confirmed_template, topology_context
  • Output: device_params array with rendered previews
  • Token Cost: ~50-100 tokens/device (or 0 with rule engine)

ExecuteTemplateBasedConfig

  • Purpose: Execute configuration from templates (local rendering)
  • Input: project_id, confirmed_template, confirmed_params
  • Output: execution results per device
  • Token Cost: 0 tokens (pure local execution)

2. Template Renderer Module

Key Features:

  • Jinja2-based configuration rendering
  • Preserves network config indentation
  • Supports conditionals, loops, filters
  • Zero token consumption (local execution)

Supported Template Features:

# Variables
hostname {{ hostname }}

# Loops
{% for interface in interfaces %}
interface {{ interface.name }}
 ip address {{ interface.ip }} {{ interface.mask }}
{% endfor %}

# Conditionals
{% if ospf_enabled %}
router ospf {{ process_id }}
 network {{ networks }} area {{ area }}
{% endif %}

# Filters
{{ ip | ip_network }}  # Custom filter for IP operations

3. Session State Management

Stores:

  • Confirmed templates (awaiting params)
  • Template metadata (schema, description)
  • Session history (for audit trail)
  • User modification tracking

Lifecycle:

  1. Created when template generated
  2. Updated when user confirms/modifies
  3. Cleared after execution or cancellation
  4. TTL: 24 hours (auto-cleanup)

4. LangGraph Workflow Integration

Interrupt Mechanism:

# LangGraph interrupt points for HITL
@interrupt
def template_review_checkpoint(state):
    """Pause and wait for user confirmation."""
    return {
        "type": "template_review",
        "data": state["generated_template"]
    }

@interrupt
def params_review_checkpoint(state):
    """Pause and wait for user confirmation."""
    return {
        "type": "params_review",
        "data": state["generated_params"]
    }

State Management:

  • State persisted across interrupts
  • User can modify state before resuming
  • Full audit trail of all transitions

UI/UX Design

Template Review Interface

┌────────────────────────────────────────────────────────────────┐
│ 📋 AI-Generated Configuration Template                         │
│ ────────────────────────────────────────────────────────────── │
│                                                                 │
│ Device Type: Cisco IOS                                          │
│ Description: OSPF basic configuration                          │
│                                                                 │
│ Template Content:                                               │
│ ┌─────────────────────────────────────────────────────────┐   │
│ │ router ospf {{ process_id }}                             │   │
│ │ {% for network in networks %}                            │   │
│ │  network {{ network.ip }} {{ network.mask }} area {{ area }} │   │
│ │ {% endfor %}                                             │   │
│ └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│ Parameter Schema:                                               │
│ • process_id: int - OSPF process ID                            │
│ • networks: List[Dict] - Network configurations                │
│   - ip: str - Network address                                  │
│   - mask: str - Wildcard mask                                  │
│ • area: str - OSPF area ID                                     │
│                                                                 │
│ Example Output:                                                 │
│ ┌─────────────────────────────────────────────────────────┐   │
│ │ router ospf 1                                            │   │
│ │  network 192.168.1.0 0.0.0.255 area 0                    │   │
│ │  network 10.0.0.0 0.255.255.255 area 0                   │   │
│ └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│ [✓ Confirm & Continue]  [✏️ Request Modification]  [❌ Cancel]  │
└────────────────────────────────────────────────────────────────┘

Parameter Review Interface

┌────────────────────────────────────────────────────────────────┐
│ 📊 Configuration Parameters Preview                            │
│ ────────────────────────────────────────────────────────────── │
│                                                                 │
│ Total Devices: 3                                               │
│ Template: OSPF basic configuration                             │
│                                                                 │
│ ┌─────────────────────────────────────────────────────────┐   │
│ │ Device: R1                                               │   │
│ │ ─────────────────────────────────────────────────────── │   │
│ │ • process_id: 1                                          │   │
│ │ • area: 0                                                │   │
│ │ • networks:                                              │   │
│ │   - 192.168.1.0/24 → area 0                             │   │
│ │   - 10.0.0.0/8 → area 0                                 │   │
│ │                                                          │   │
│ │ Rendered Configuration:                                  │   │
│ │ router ospf 1                                           │   │
│ │  network 192.168.1.0 0.0.0.255 area 0                   │   │
│ │  network 10.0.0.0 0.255.255.255 area 0                  │   │
│ └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│ ┌─────────────────────────────────────────────────────────┐   │
│ │ Device: R2                                               │   │
│ │ ...                                                      │   │
│ └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│ [✓ Execute Configuration]  [✏️ Modify Parameters]               │
│ [👁️ Preview All]  [❌ Cancel]                                  │
└────────────────────────────────────────────────────────────────┘

API Design & Data Flow

REST API Endpoints

POST /api/v3/projects/{project_id}/templates/config
  ├─ Request: { "device_type": "cisco_ios", "requirement": "Configure OSPF" }
  └─ Response: { "template_id": "uuid", "template_content": "...", "params_schema": {...} }

PUT /api/v3/projects/{project_id}/templates/{template_id}/confirm
  ├─ Request: { "action": "confirm" | "modify", "modifications": {...} }
  └─ Response: { "status": "confirmed", "next_step": "generate_params" }

POST /api/v3/projects/{project_id}/templates/{template_id}/params
  ├─ Request: { "mode": "ai" | "direct" }
  └─ Response: { "device_params": [...], "preview": {...} }

POST /api/v3/projects/{project_id}/templates/{template_id}/execute
  ├─ Request: { "confirmed_params": [...] }
  └─ Response: { "execution_id": "uuid", "status": "executing" }

GET /api/v3/projects/{project_id}/templates/{template_id}/status
  └─ Response: { "status": "completed", "progress": 100, "results": [...] }

DELETE /api/v3/projects/{project_id}/templates/{template_id}
  └─ Response: { "status": "cancelled" }

SSE Progress Stream

// Server-Sent Events for real-time progress
// Endpoint: GET /api/v3/projects/{project_id}/templates/{template_id}/stream

// Event Types:
event: template_generated
data: {"template_id": "uuid", "content": "..."}

event: params_generated
data: {"total_devices": 100, "params": [...]}

event: execution_progress
data: {
  "type": "batch_complete",
  "batch": 5,
  "total_batches": 10,
  "progress": 50,
  "success": 48,
  "failed": 2,
  "current_device": "R50"
}

event: execution_complete
data: {
  "total_devices": 100,
  "success": 98,
  "failed": 2,
  "duration_sec": 180
}

Data Flow Diagram

User Request
    ↓
┌─────────────────────────────────────────────────────────────┐
│ 1. API Layer (FastAPI)                                      │
│    - Validates request                                      │
│    - Creates session state                                  │
│    - Returns template_id                                    │
└──────────────────────┬──────────────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────────────┐
│ 2. AI Agent (LangGraph)                                     │
│    - Generate template (LLM call)                           │
│    - Store in session manager                              │
│    - Trigger interrupt 🔵                                   │
└──────────────────────┬──────────────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────────────┐
│ 3. HITL Checkpoint (Frontend Display)                       │
│    - Show template to user                                  │
│    - Wait for user action                                   │
│    - [Confirm] [Modify] [Cancel]                            │
└──────────────────────┬──────────────────────────────────────┘
                       ↓ (User confirms)
┌─────────────────────────────────────────────────────────────┐
│ 4. AI Agent (LangGraph Resumes)                             │
│    Path A: Generate params (LLM) ~5000 tokens              │
│    Path B: Rule engine (0 tokens) ⚡                         │
│    - Trigger interrupt 🔵                                   │
└──────────────────────┬──────────────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────────────┐
│ 5. HITL Checkpoint (Frontend Display)                       │
│    - Show parameters to user                                │
│    - Render configuration preview                          │
│    - [Execute] [Modify] [Cancel]                            │
└──────────────────────┬──────────────────────────────────────┘
                       ↓ (User executes)
┌─────────────────────────────────────────────────────────────┐
│ 6. Execution Engine (Local, 0 tokens)                       │
│    - Render templates (Jinja2)                              │
│    - Batch execution (Nornir + Netmiko)                    │
│    - Stream progress via SSE                                │
└──────────────────────┬──────────────────────────────────────┘
                       ↓
┌─────────────────────────────────────────────────────────────┐
│ 7. Result Aggregation                                       │
│    - Collect results from all devices                      │
│    - Generate summary report                               │
│    - Clean up session state                                │
└──────────────────────┬──────────────────────────────────────┘
                       ↓
                  Return to User

Error Handling Flow

┌─────────────────────────────────────────────────────────────┐
│ Error Detection at Each Stage                               │
└─────────────────────────────────────────────────────────────┘

Template Generation Error:
    ├─ Invalid Jinja2 syntax → [AI Retry] + [Show Error Context]
    ├─ Incomplete template → [Request Clarification]
    └─ LLM timeout → [Retry] + [Fallback to template library]

Parameter Generation Error:
    ├─ Missing device data → [Fetch from topology]
    ├─ Invalid parameter values → [Validation Error] → [User Correction]
    └─ Rule engine failure → [Fallback to AI generation]

Execution Error:
    ├─ Device unreachable → [Retry 3x] → [Mark as failed] → [Continue]
    ├─ Invalid command → [Show error] → [Suggest fix] → [User decision]
    └─ Authentication failure → [Pause] → [Request credentials]

Error Recovery Strategies:
    ├─ Automatic retry (transient errors)
    ├─ Partial success handling (continue with remaining devices)
    ├─ Rollback support (undo partial changes)
    └─ User notification (SSE + UI alerts)

Template Lifecycle Management

┌─────────────────────────────────────────────────────────────┐
│                      Template Lifecycle                      │
└─────────────────────────────────────────────────────────────┘

1. DRAFT
   ├─ Created by AI
   ├─ Stored in session (temporary)
   └─ User reviews and modifies

2. CONFIRMED
   ├─ User approved template
   ├─ Stored in template library (persistent)
   └─ Ready for parameter generation

3. ACTIVE
   ├─ Parameters generated
   ├─ Ready for execution
   └─ Can be cloned for similar tasks

4. EXECUTED
   ├─ Configuration applied
   ├─ Results recorded
   └─ Move to archive

5. ARCHIVED
   ├─ Historical record
   ├─ Analytics data
   └─ Cleanup after 90 days

Version Control:
    ├─ Each save creates new version
    ├─ Semantic versioning (v1.0, v1.1, v2.0)
    ├─ Diff view between versions
    └─ Rollback to previous version

🔥 Large-Scale Topology Support (1000+ Nodes)

Overview

One of the most powerful use cases for the template-based configuration system is rapid provisioning of large-scale network topologies. This section details optimizations for environments with hundreds to thousands of nodes.

Challenge: Traditional AI Approach at Scale

Problem: Configure 1000 routers with OSPF

Traditional AI Approach:
- AI generates config for each router: 150 tokens × 1000 = 150,000 tokens
- Serial or limited parallel execution: ~30-50 minutes
- High cost, slow execution, poor scalability

Solution: Direct Execution Mode

The key innovation is allowing users to modify and directly execute templates without requiring AI re-analysis:

Template-Based Direct Execution:
1. AI generates template once: ~150 tokens
2. User reviews and modifies if needed
3. User clicks "⚡ Confirm & Execute"
4. Rule engine generates params for 1000 devices: 0 tokens
5. Parallel execution (50-100 concurrent): ~5 minutes
6. Total: 150 tokens, 5 minutes

Enhanced HITL Workflow for Scale

┌─────────────────────────────────────────────────────────────┐
│ Step 1: AI Generates Template (Once)                         │
│                                                              │
│ User: "Configure OSPF on all 1000 routers"                   │
│                                                              │
│ AI generates template: ~150 tokens                           │
│ router ospf {{ process_id }}                                 │
│ {% for network in networks %}                                │
│  network {{ network.ip }} {{ network.mask }} area {{ area }} │
│ {% endfor %}                                                 │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint 1: Template Review                        │
│                                                              │
│ User can:                                                    │
│ - Review template syntax                                     │
│ - Modify template directly                                  │
│ - See preview with sample data                               │
│                                                              │
│ Actions: [✓ Confirm & Continue]  [⚡ Confirm & Execute*]     │
│          [✏️ Modify]  [❌ Cancel]                             │
│                                                              │
│ * "Confirm & Execute" = Skip AI, go to rule engine           │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 2A: Rule Engine (0 tokens) OR Step 2B: AI (5000 tokens)│
│                                                              │
│ If user chose "⚡ Confirm & Execute":                        │
│   → Rule engine analyzes template                            │
│   → Extracts device names from topology                      │
│   → Auto-assigns IPs and parameters                          │
│   → Generates 1000 device param sets: 0 tokens               │
│                                                              │
│ If user chose "✓ Confirm & Continue":                       │
│   → AI analyzes template                                     │
│   → Generates parameters: ~5000 tokens                       │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint 2: Parameter Review                       │
│                                                              │
│ For 1000 devices, show SUMMARY:                              │
│ - Total devices: 1000                                        │
│ - Configuration patterns: 3 unique patterns                 │
│ - Sample configs (first 3 devices)                           │
│ - IP addressing scheme used                                  │
│                                                              │
│ Actions: [⚡ Execute All*]  [✓ Review & Modify]  [❌ Cancel] │
│                                                              │
│ * "Execute All" = Start parallel execution                   │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 3: Parallel Batch Execution                             │
│                                                              │
│ Configuration execution:                                     │
│ - Batch size: 50 devices (configurable)                      │
│ - Batches: 20 total (1000 / 50)                              │
│ - Parallel execution within each batch                       │
│ - Real-time progress updates via SSE                         │
│ - Estimated time: 3-5 minutes                                │
│                                                              │
│ Progress updates:                                             │
│ Batch 1/20: Configuring devices 1-50...                      │
│ Batch 2/20: Configuring devices 51-100...                    │
│ ...                                                          │
│ Complete: 998 success, 2 failed                              │
└─────────────────────────────────────────────────────────────┘

Rule Engine: Intelligent Parameter Generation

Concept: Use rule-based logic instead of AI for generating parameters in large topologies.

How It Works:

Input: Template + Topology (1000 devices)
         ↓
    Rule Engine (0 tokens)
         ↓
    Device Analysis
    ├─ Extract numbering from names (R1 → 1, R2 → 2, ...)
    ├─ Group by device type (routers, switches, firewalls)
    ├─ Apply addressing scheme (sequential, VLAN-based, hierarchical)
    └─ Generate parameters for each device
         ↓
Output: 1000 device parameter sets (< 1 second)

Addressing Schemes:

1. Sequential (Default)
   R1: 192.168.1.0/24
   R2: 192.168.2.0/24
   ...
   R1000: 192.168.1000.0/24

2. VLAN-Based
   VLAN 100: 10.0.100.0/24
   VLAN 101: 10.0.101.0/24
   ...

3. Hierarchical
   Core routers: 10.0.0.0/24
   Distribution: 10.1.0.0/16
   Access switches: 10.100.0.0/16

4. Device Type Based
   Routers: 192.168.0.0/16
   Switches: 192.169.0.0/16
   Firewalls: 192.170.0.0/16

Batch Parallel Execution

Dynamic Batching Strategy:

Device Count    Batch Size    Concurrency    Estimated Time
────────────────────────────────────────────────────────────
1-10            10            10             < 30 seconds
11-50           20            20             < 1 minute
51-100          30            30             1-2 minutes
101-500         50            50             2-5 minutes
500+            100           100            3-8 minutes

Execution Flow:

┌─────────────────────────────────────────────────────────────┐
│ Batch 1: Devices 1-100                                       │
│ ├─ Render 100 configs (Jinja2, local)                        │
│ ├─ Execute in parallel (Nornir + Netmiko)                   │
│ ├─ Collect results                                           │
│ └─ Stream progress: "Batch 1/10 complete, 35% done"         │
├─────────────────────────────────────────────────────────────┤
│ Batch 2: Devices 101-200                                     │
│ └─ ...                                                       │
├─────────────────────────────────────────────────────────────┤
│ ...                                                          │
├─────────────────────────────────────────────────────────────┤
│ Batch 10: Devices 901-1000                                   │
│ └─ Complete: 997 success, 3 failed                          │
└─────────────────────────────────────────────────────────────┘

Configuration Summary for Large Topologies

Challenge: Showing 1000 device configurations is impractical.

Solution: Intelligent summaries with pattern analysis.

┌─────────────────────────────────────────────────────────────┐
│ Configuration Summary: 1000 Devices                          │
├─────────────────────────────────────────────────────────────┤
│ Total Devices:        1,000                                  │
│ Unique Patterns:      3                                     │
│ Total Config Lines:   ~15,000                               │
│ Estimated Time:       ~5 minutes                            │
├─────────────────────────────────────────────────────────────┤
│ Pattern Analysis:                                              │
│ • Pattern A (650 devices): Standard OSPF config             │
│ • Pattern B (300 devices): OSPF + BGP                       │
│ • Pattern C (50 devices):  OSPF + BGP + MPLS                │
├─────────────────────────────────────────────────────────────┤
│ Sample Configurations (first 3):                             │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Device: R1 (Pattern A)                                  │ │
│ │ router ospf 1                                          │ │
│ │  network 192.168.1.0 0.0.0.255 area 0                  │ │
│ │  network 10.1.1.1 0.0.0.0 area 0                       │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Device: R2 (Pattern A)                                  │ │
│ │ [Similar to R1, different IPs]                          │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ...                                                          │
└─────────────────────────────────────────────────────────────┘

Performance Benchmarks

Scenario: 1000 Router OSPF Configuration

Metric Traditional AI Template + AI Template + Direct
Token Consumption 150,000 5,000 400
Execution Time 30-50 min 10-15 min 3-5 min
Cost (at $10/M tokens) $1.50 $0.05 $0.004
User Control Low Medium High
Parallel Execution Limited Yes Yes (100 concurrent)

Scenario: 5000 Switch VLAN Configuration

Metric Traditional AI Template + Direct
Token Consumption 400,000 400
Execution Time 2-3 hours 15-20 min
Cost $4.00 $0.004
Scalability Poor Excellent

Addressing Schemes for Large Topologies

The rule engine supports multiple automatic addressing schemes:

# 1. Sequential Addressing (Default)
# R1: 192.168.1.0/24, R2: 192.168.2.0/24, ..., R1000: 192.168.1000.0/24

# 2. VLAN-Based Addressing
# VLAN 100: 10.0.100.0/24, VLAN 101: 10.0.101.0/24, ...

# 3. Hierarchical Addressing
# Core routers: 10.0.0.0/24
# Distribution routers: 10.1.0.0/16
# Access switches: 10.100.0.0/16

# 4. Device Type Based
# Routers: 192.168.0.0/16
# Switches: 192.169.0.0/16
# Firewalls: 192.170.0.0/16

Error Handling for Scale

For 1000+ devices, some failures are inevitable. The system provides:

{
    "total_devices": 1000,
    "summary": {
        "success": 987,
        "failed": 13,
        "skipped": 0
    },
    "failed_devices": [
        {
            "device_name": "R456",
            "error": "Connection timeout",
            "retry_available": true
        },
        ...
    ],
    "retry_suggestions": {
        "auto_retry": True,
        "retry_batch_size": 10,
        "exponential_backoff": True
    }
}

Use Cases for Large-Scale Support

  1. Network Training Labs: Provision 1000+ device labs for student training
  2. CI/CD Testing: Automated topology setup for testing network automation scripts
  3. Disaster Recovery Drills: Rapid deployment of large backup topologies
  4. Network Simulation: Research environments with thousands of nodes
  5. Data Center Fabric: Configure spine-leaf topologies with hundreds of leaf switches

🔥🔥 Node Creation Templates (Batch Topology Provisioning)

Overview

Just as configuration templates enable rapid device configuration, node creation templates enable rapid topology provisioning. This is particularly valuable for:

  • Training labs: Provision 100+ device labs in minutes
  • Testing environments: Quickly spin up complex test topologies
  • Data center simulation: Create spine-leaf fabrics with hundreds of nodes
  • Network research: Deploy large-scale simulation topologies

Current vs. Template-Based Node Creation

Scenario: Create 100 Routers

Current Method:

AI calls create_node tool 100 times:
- Token cost: 50 tokens/node × 100 = 5000 tokens
- Execution time: 5-10 minutes (serial/limited parallel)
- No batch operations
- Manual positioning required

Template Method:

1. AI generates node creation template: ~100 tokens
2. User reviews and confirms template
3. Rule engine creates nodes in parallel batches: 0 tokens
4. Total: 100 tokens, 30-60 seconds

Savings: 98% tokens, 90% time

Node Creation Workflow

User Request: "Create a data center topology with 2 core routers,
              10 aggregation switches, and 100 access switches"
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 1: AI Generates Node Creation Template                  │
│                                                              │
│ AI Output:                                                   │
│ {                                                            │
│   "node_groups": [                                          │
│     {                                                        │
│       "node_type": "cisco_iosv",                            │
│       "count": 2,                                           │
│       "name_pattern": "Core-R{{ id }}",                     │
│       "properties": {"ram": 4096, "cpus": 2},              │
│       "position": {"y": 100, "x_spacing": 600}             │
│     },                                                       │
│     {                                                        │
│       "node_type": "cisco_iosv_l2",                         │
│       "count": 10,                                          │
│       "name_pattern": "Agg-SW{{ id }}",                    │
│       "position": {"grid": "2x5", "y": 300}                 │
│     },                                                       │
│     {                                                        │
│       "node_type": "cisco_iosv_l2",                         │
│       "count": 100,                                         │
│       "name_pattern": "Acc-SW{{ id }}",                    │
│       "position": {"grid": "10x10", "y": 600}               │
│     }                                                       │
│   ],                                                         │
│   "layout": "auto_spine_leaf",                               │
│   "resource_limits": {"max_ram_mb": 120000}                  │
│ }                                                            │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint: Node Template Review                    │
│                                                              │
│ User sees:                                                  │
│ • Total nodes: 112                                           │
│ • Group breakdown:                                           │
│   - 2x Core routers (Core-R1, Core-R2)                      │
│   - 10x Aggregation switches (Agg-SW1 - Agg-SW10)          │
│   - 100x Access switches (Acc-SW1 - Acc-SW100)             │
│ • Resource requirements:                                     │
│   - RAM: ~120 GB                                             │
│   - vCPUs: 112                                               │
│ • Layout preview (visual diagram)                            │
│                                                              │
│ Actions: [⚡ Batch Create]  [✏️ Modify]  [❌ Cancel]         │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 2: Parallel Batch Node Creation (0 tokens)             │
│                                                              │
│ Process:                                                     │
│ - Validate resources                                         │
│ - Create nodes in parallel batches (20-50 concurrent)        │
│ - Auto-position nodes using layout strategy                 │
│ - Real-time progress streaming                               │
│                                                              │
│ Progress:                                                    │
│ Batch 1/6: Creating 20 nodes...                             │
│ Batch 2/6: Creating 20 nodes...                             │
│ ...                                                          │
│ Complete: 112/112 nodes created successfully                 │
└─────────────────────────────────────────────────────────────┘

Node Template Schema

Concept: Define groups of similar nodes with positioning and auto-linking.

Schema Structure:

NodeCreationTemplate
├─ node_groups: List[NodeGroup]
│   ├─ node_type: "cisco_iosv" | "vpcs" | ...
│   ├─ count: 100
│   ├─ name_pattern: "R{{ id }}"  → R1, R2, ..., R100
│   ├─ properties: {ram, cpus, adapters}
│   └─ position: {strategy, grid, spacing}
├─ layout: "auto_grid" | "auto_spine_leaf" | "auto_star" | ...
├─ auto_link: AutoLinkConfig
│   └─ links: List[LinkPattern]
└─ resource_limits: {max_ram_mb, max_vcpus}

Example: Spine-Leaf Topology

{
  "node_groups": [
    {
      "name": "spine",
      "node_type": "cisco_iosv",
      "count": 4,
      "name_pattern": "Spine{{ id }}",
      "position": {"y": 100, "x_spacing": 400}
    },
    {
      "name": "leaf",
      "node_type": "cisco_iosv_l2",
      "count": 48,
      "name_pattern": "Leaf{{ id }}",
      "position": {"grid": "6x8", "y": 400}
    }
  ],
  "auto_link": {
    "links": [
      {
        "from": "spine",
        "to": "leaf",
        "strategy": "mesh"  # Each spine to all leafs
      }
    ]
  }
}

Result: 4 spine + 48 leaf + 192 links (4×48)
Time: ~2-3 minutes

Automatic Layout Strategies

┌─────────────────────────────────────────────────────────────┐
│ 1. Grid Layout (auto_grid)                                  │
│                                                              │
│   [1]  [2]  [3]  [4]  [5]                                   │
│   [6]  [7]  [8]  [9]  [10]                                  │
│   [11] [12] [13] [14] [15]                                  │
│                                                              │
│   Best for: Uniform node types, regular topologies         │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 2. Spine-Leaf (auto_spine_leaf)                             │
│                                                              │
│   [Spine1]--------[Spine2]                                  │
│      |  |  |  |      |  |  |  |                             │
│   [Leaf1..Leaf48]  [Leaf49..Leaf96]                         │
│                                                              │
│   Best for: Data center fabrics                             │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 3. Star (auto_star)                                         │
│                                                              │
│              [Core]                                         │
│            /  |  |  \                                       │
│        [Edge1..Edge20]                                      │
│                                                              │
│   Best for: Hub-and-spoke topologies                        │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 4. Hierarchical (manual)                                    │
│                                                              │
│   [Core1]     [Core2]                                       │
│      |            |                                         │
│   [Agg1..Agg10]                                            │
│      /    |   |    \                                        │
│  [Acc1..Acc100]                                            │
│                                                              │
│   Best for: Enterprise campus networks                      │
└─────────────────────────────────────────────────────────────┘

Auto-Linking Strategies

Link Pattern Strategies:

┌─────────────────────────────────────────────────────────────┐
│ 1. Mesh (Full Mesh)                                         │
│                                                              │
│   [A] ←→ [B]                                                │
│    ↑ ↖  ↑ ↗                                                │
│    |  \ |  |                                                │
│   [D] ←→ [C]                                                │
│                                                              │
│   Every node connects to every other node                   │
│   Links: n×(n-1)/2                                          │
│   Best for: High availability, small groups                │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 2. Paired (One-to-One)                                      │
│                                                              │
│   [Group A: A1, A2, A3...]                                  │
│         ↓  ↓  ↓                                            │
│   [Group B: B1, B2, B3...]                                  │
│                                                              │
│   A1→B1, A2→B2, A3→B3, ...                                 │
│   Links: min(count_A, count_B)                              │
│   Best for: Point-to-point connections                     │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 3. Linear (Chain)                                           │
│                                                              │
│   [A1]→[A2]→[A3]→[A4]→...→[An]                             │
│                                                              │
│   Sequential connection                                     │
│   Links: n-1                                                │
│   Best for: Ring topologies, daisy-chains                  │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│ 4. One-to-Many (Star)                                       │
│                                                              │
│         [Center]                                            │
│       /  |  |  \                                            │
│     [E1][E2][E3][E4]...                                      │
│                                                              │
│   Center connects to all edge nodes                         │
│   Links: count_edge                                         │
│   Best for: Hub-and-spoke                                   │
└─────────────────────────────────────────────────────────────┘

Performance Benchmarks

Scenario: 100 Router Lab

Metric Current Method Template Method
Token Consumption 5,000 100
Execution Time 5-10 min 30-60 sec
User Control Low High (preview before create)
Positioning Manual Automatic

Scenario: 500 Switch Data Center

Metric Current Method Template Method
Token Consumption 25,000 150
Execution Time 25-30 min 2-3 min
Links Created Manual Auto (mesh, spine-leaf)

Scenario: 1000 Node Training Lab

Metric Current Method Template Method
Token Consumption 50,000 200
Execution Time 50-60 min 4-6 min
Scalability Poor Excellent

Complete Example: Enterprise Data Center

# User Request
"""
Create an enterprise data center topology:
- 4 spine routers (high-end)
- 20 leaf switches (10G)
- 200 access switches (1G)
- 500 servers (VPCS)

Use spine-leaf architecture with full mesh connectivity.
All servers connect to access switches in pairs.
"""

# Generated Template
{
    "node_groups": [
        {
            "name": "spine",
            "node_type": "cisco_iosv",
            "count": 4,
            "name_pattern": "Spine-R{{ id }}",
            "properties": {
                "ram": 4096,
                "cpus": 2,
                "adapters": 8
            },
            "position": {
                "strategy": "hierarchical",
                "y": 100,
                "x_spacing": 600
            }
        },
        {
            "name": "leaf",
            "node_type": "cisco_iosv_l2",
            "count": 20,
            "name_pattern": "Leaf-SW{{ id }}",
            "properties": {
                "ram": 2048,
                "cpus": 1,
                "adapters": 16
            },
            "position": {
                "strategy": "grid",
                "grid_rows": 4,
                "grid_cols": 5,
                "y": 400,
                "x_spacing": 300,
                "y_spacing": 200
            }
        },
        {
            "name": "access",
            "node_type": "cisco_iosv_l2",
            "count": 200,
            "name_pattern": "Acc-SW{{ id }}",
            "properties": {
                "ram": 1024,
                "cpus": 1,
                "adapters": 4
            },
            "position": {
                "strategy": "grid",
                "grid_rows": 10,
                "grid_cols": 20,
                "y": 800,
                "x_spacing": 120,
                "y_spacing": 100
            }
        },
        {
            "name": "server",
            "node_type": "vpcs",
            "count": 500,
            "name_pattern": "Server-{{ id }}",
            "properties": {},
            "position": {
                "strategy": "grid",
                "grid_rows": 20,
                "grid_cols": 25,
                "y": 1200,
                "x_spacing": 60,
                "y_spacing": 60
            }
        }
    ],
    "auto_link": {
        "links": [
            {
                "from_group": "spine",
                "to_group": "leaf",
                "strategy": "mesh"
            },
            {
                "from_group": "leaf",
                "to_group": "access",
                "strategy": "paired",
                "count": 10
            },
            {
                "from_group": "access",
                "to_group": "server",
                "strategy": "paired",
                "count": 2
            }
        ]
    },
    "layout": "auto_spine_leaf",
    "resource_limits": {
        "max_ram_mb": 750000,
        "max_vcpus": 724
    }
}

# Execution Result
{
    "total_nodes": 724,
    "created": 724,
    "failed": 0,
    "duration_sec": 285,  # ~4.75 minutes
    "links_created": 4280,  # Auto-created
    "groups": [
        {"name": "spine", "created": 4, "failed": 0},
        {"name": "leaf", "created": 20, "failed": 0},
        {"name": "access", "created": 200, "failed": 0},
        {"name": "server", "created": 500, "failed": 0}
    ]
}

Combined Workflow: Node Creation + Configuration

The real power comes from combining both template systems:

1. Create topology with node templates
   - 724 nodes created in ~5 minutes
   - 4280 links auto-created

2. Configure devices with config templates
   - Generate OSPF/BGP templates
   - Configure 724 devices in ~5 minutes

Total: 724-node data center
  - Created and configured in ~10 minutes
  - Token cost: ~400 (vs ~100,000 with AI-only approach)
  - 99.6% token savings

Overview

Just as node and configuration templates enable rapid provisioning, link creation templates enable rapid connectivity setup. This completes the template trilogy for complete topology automation.

Scenario: Create Full-Mesh Network (100 Routers)

Current Method:

AI calls create_link tool 4950 times (100×99/2):
- Token cost: 30 tokens/link × 4950 = ~150,000 tokens
- Execution time: 30-40 minutes (serial/limited parallel)
- Manual port management
- Error-prone

Template Method:

1. AI generates link template: ~200 tokens
2. User reviews link patterns and topology preview
3. Rule engine creates links in parallel batches: 0 tokens
4. Total: 200 tokens, 2-3 minutes

Savings: 99.9% tokens, 95% time

User Request: "Create full-mesh connectivity between all routers"
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 1: AI Generates Link Creation Template                 │
│                                                              │
│ AI Output:                                                   │
│ {                                                            │
│   "link_patterns": [                                        │
│     {                                                        │
│       "from_nodes": {"tag": "router"},                      │
│       "to_nodes": {"tag": "router"},                        │
│       "strategy": "full_mesh",                              │
│       "port_allocation": "round_robin"                       │
│     }                                                       │
│   ],                                                         │
│   "total_links": 4950                                       │
│ }                                                            │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ 🔵 HITL Checkpoint: Link Template Review                    │
│                                                              │
│ User sees:                                                  │
│ • Total links: 4,950                                         │
│ • Topology type: Full Mesh                                  │
│ • Port allocation strategy: Round-robin                     │
│ • Topology preview (visual graph)                            │
│ • Port utilization estimates                                 │
│                                                              │
│ Sample links (first 10):                                     │
│ • R1:Gi0/0 → R2:Gi0/0                                       │
│ • R1:Gi0/1 → R3:Gi0/0                                       │
│ • ...                                                        │
│                                                              │
│ Actions: [⚡ Batch Create]  [👁️ Detailed Preview]  [✏️ Modify] │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 2: Detailed Preview (Optional)                          │
│                                                              │
│ • Port assignment per node                                   │
│ • Bandwidth calculations                                     │
│ • Redundancy analysis                                        │
│ • Link naming scheme                                         │
│                                                              │
│ [⚡ Confirm Create All]  [🔧 Adjust Ports]  [⬅️ Back]        │
└─────────────────────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────────────────────┐
│ Step 3: Parallel Batch Link Creation (0 tokens)             │
│                                                              │
│ Process:                                                     │
│ - Validate port availability                                  │
│ - Allocate ports using strategy                             │
│ - Create links in parallel batches (50-100 concurrent)       │
│ - Handle conflicts automatically                              │
│ - Real-time progress streaming                               │
│                                                              │
│ Progress:                                                    │
│ Batch 1/50: Creating 99 links...                            │
│ Batch 2/50: Creating 99 links...                            │
│ ...                                                          │
│ Complete: 4,950/4,950 links created successfully              │
└─────────────────────────────────────────────────────────────┘
class LinkCreationTemplate(BaseModel):
    """Template for batch link creation."""

    # Link patterns
    link_patterns: List[LinkPattern]

    # Port allocation strategy
    port_allocation: PortAllocationStrategy


class LinkPattern(BaseModel):
    """Pattern for creating links between node groups."""

    from_nodes: NodeSelector  # Source nodes
    to_nodes: NodeSelector    # Destination nodes

    strategy: Literal[
        "one_to_one",        # 1:1 pairing
        "one_to_many",       # Star topology
        "many_to_many",      # Full mesh
        "sequential",        # Linear chain
        "ring"              # Ring topology
    ]

    port_allocation: PortAllocationStrategy


class NodeSelector(BaseModel):
    """Select nodes for linking."""

    selector_type: Literal["group", "name_pattern", "tag", "all"]
    group_name: Optional[str]
    name_pattern: Optional[str]  # "R*", "Core-*"
    tag: Optional[str]


class PortAllocationStrategy(BaseModel):
    """How to allocate ports for links."""

    strategy: Literal[
        "round_robin",       # Distribute evenly
        "sequential",        # Use in order
        "optimized",         # Smart allocation
        "auto"               # Automatic selection
    ]

    on_conflict: Literal[
        "skip",              # Skip if port unavailable
        "use_next",          # Use next available port
        "fail"               # Fail on conflict
    ] = "use_next"

Common Topology Patterns

The system includes pre-built topology patterns:

1. Spine-Leaf (Data Center)

Pattern: Full mesh between spine and leaf layers

Example: 4 Spine × 48 Leaf
- Links: 4 × 48 = 192 links
- Each spine: 48 downlinks
- Each leaf: 4 uplinks

2. Three-Tier Hierarchical

Core ↔ Aggregation ↔ Access

Example: 2 Core × 10 Agg × 100 Access
- Core-Agg: Full mesh (2×10 = 20 links)
- Agg-Access: Paired (10×10 = 100 links)
- Total: 120 links

3. Ring Topology

Sequential connection with wrap-around

Example: 10 routers in ring
- Links: 10 (each node connects to 2 neighbors)
- Pattern: R1→R2→R3→...→R10→R1

4. Full Mesh

All nodes connected to all nodes

Example: 10 routers
- Links: 45 (10×9/2)
- Every node connects to every other node

5. Star Topology

Center node connects to all edge nodes

Example: 1 Core + 20 Edge
- Links: 20
- Center degree: 20
- Edge degree: 1

Performance Benchmarks

Scenario: Spine-Leaf Data Center (8 Spine × 100 Leaf)

Metric Current Method Template Method
Token Consumption 30,000 200
Execution Time 15-20 min 2-3 min
Links Created Manual Auto (800 links)
Port Management Manual Auto (round-robin)

Scenario: Full Mesh (100 Routers)

Metric Current Method Template Method
Token Consumption 150,000 200
Execution Time 30-40 min 2-3 min
Links Created 4,950 4,950
Error Rate High (manual) Low (validated)

Scenario: Large-Scale Data Center

Topology:

  • 8 Spine routers
  • 100 Leaf switches (48-port each)
  • 2000 Servers
  • Redundant connections

Link Creation:

  • Spine-Leaf: 8 × 100 = 800 links
  • Leaf-Server: 2000 × 2 = 4000 links
  • Total: 4,800 links
Metric Current Method Template Method
Token Consumption ~150,000 300
Execution Time 45-60 min 5-8 min
Savings - 99.8% tokens, 90% time

Intelligent Port Allocation

The system includes smart port allocation algorithms:

# Example: Optimized allocation for multi-adapter switches

Strategy: "optimized"

Considerations:
- Port speed matching (10G ports for spine-leaf, 1G for servers)
- Physical adapter separation (redundancy across modules)
- Load balancing (distribute connections evenly)
- Future expansion planning (reserve ports)

Result:
- Spine-Leaf: Use 10G ports on adapter 0-3
- Leaf-Server: Use 1G ports on adapter 4-7
- Redundant paths: Use different physical adapters

Combined Workflow: Complete Topology Provisioning

Step 1: Node Creation Template
  - 2108 nodes created in ~4 minutes
  - Token cost: ~200

Step 2: Link Creation Template
  - 20,780 links created in ~6 minutes
  - Token cost: ~300

Step 3: Configuration Template
  - 2108 devices configured in ~5 minutes
  - Token cost: ~200

TOTAL: Large Data Center
  - 2,108 nodes + 20,780 links
  - Created, linked, and configured in ~15 minutes
  - Token cost: ~700 (vs ~250,000 with AI-only)
  - 99.7% token savings

Use Cases

  1. Data Center Fabric: Spine-Leaf with thousands of links
  2. ISP Backbone: Full-mesh core routers
  3. Campus Network: Three-tier hierarchical
  4. Ring Topology: Metropolitan area networks
  5. Research Networks: Custom experimental topologies

Implementation Phases

Phase 1: Core MVP (Minimum Viable Product)

Status: 📋 Planned Estimated Effort: 3-5 days

Tasks:

  1. Create ConfigTemplateRenderer class
  2. Create TemplateSessionManager class
  3. Implement GenerateConfigTemplate tool
  4. Implement GenerateTemplateParams tool
  5. Implement ExecuteTemplateBasedConfig tool
  6. Create config_templates/ package structure
  7. Update system prompts with template workflow
  8. Basic error handling and validation

Deliverables:

  • Working three-step HITL workflow
  • Template rendering for Cisco IOS devices
  • Basic CLI/API responses
  • Unit tests for core components

Phase 2: Enhanced User Experience & Direct Execution

Status: 💡 Proposed Estimated Effort: 2-3 days

Tasks:

  1. Enhanced UI for template/parameter review
  2. Configuration preview functionality
  3. Template modification and retry logic
  4. 🔥 Direct execution mode (skip AI, use rule engine)
  5. Progress indicators for multi-device configs
  6. Improved error messages and recovery

Deliverables:

  • User-friendly review interfaces
  • Preview-before-execute capability
  • Rule-based parameter generation (0 token cost)
  • User documentation

Phase 2.5: Node Creation Templates

Status: 💡 Proposed Estimated Effort: 2-3 days

Tasks:

  1. 🔥🔥 Implement GenerateNodeTemplate tool
  2. 🔥🔥 Implement ExecuteBatchNodeCreation tool
  3. 🔥🔥 Create NodeCreationTemplate schema
  4. 🔥🔥 Implement automatic positioning algorithms
  5. 🔥🔥 Implement auto-linking functionality
  6. Resource validation before creation

Deliverables:

  • Batch node creation with 0 token cost
  • Auto-positioning (grid, spine-leaf, star, mesh)
  • Auto-linking (mesh, paired, linear)
  • Progress streaming for large batches

Status: 💡 Proposed Estimated Effort: 2-3 days

Tasks:

  1. 🔥🔥🔥 Implement GenerateLinkTemplate tool
  2. 🔥🔥🔥 Implement ExecuteBatchLinkCreation tool
  3. 🔥🔥🔥 Create LinkCreationTemplate schema
  4. 🔥🔥🔥 Implement topology pattern library (Spine-Leaf, Ring, Mesh, Star, etc.)
  5. 🔥🔥🔥 Implement intelligent port allocation algorithms
  6. Port availability validation and conflict handling

Deliverables:

  • Batch link creation with 0 token cost
  • 5+ pre-built topology patterns
  • Smart port allocation (round-robin, optimized)
  • Port conflict detection and auto-resolution
  • Progress streaming for thousands of links

Phase 3: Template Library & Large-Scale Support

Status: 💡 Proposed Estimated Effort: 2-3 days

Tasks:

  1. Template persistence and storage
  2. Pre-built template library (OSPF, BGP, VLAN, NAT, etc.)
  3. 🔥 Batch parallel execution (dynamic batching for 100+ devices)
  4. 🔥 Rule engine enhancements (intelligent parameter generation)
  5. 🔥 Real-time progress streaming via SSE
  6. Template versioning and history

Deliverables:

  • 20+ pre-built templates
  • Support for 1000+ device configurations
  • Parallel execution with 50-100 concurrent connections
  • Template management API

Phase 4: Advanced Features & Optimization

Status: 💡 Proposed Estimated Effort: 3-4 days

Tasks:

  1. Multi-vendor template support (Huawei, H3C, Juniper)
  2. 🔥 Intelligent addressing schemes (sequential, VLAN-based, hierarchical)
  3. 🔥 Configuration summary generation (pattern analysis for large topologies)
  4. Configuration diff and comparison
  5. Template analytics and usage statistics
  6. 🔥 Performance optimization (caching, connection pooling)

Deliverables:

  • Multi-vendor template ecosystem
  • Optimized for 10,000+ node topologies
  • Advanced configuration management
  • Analytics dashboard

Technical Considerations

Jinja2 Configuration

Key Settings for Network Configs:

Environment Configuration:
├─ trim_l_blocks=True       # Remove block left whitespace
├─ trim_r_blocks=True       # Remove block right whitespace
├─ lstrip_blocks=True       # Strip leading whitespace
├─ autoescape=False         # Don't escape config commands
└─ Custom Filters
   ├─ to_cidr: Convert IP+mask to CIDR
   ├─ ip_network: Parse IP network
   └─ Wildcard to CIDR conversion

Supported Template Features:

  • Variables: {{ hostname }}
  • Loops: {% for interface in interfaces %}...{% endfor %}
  • Conditionals: {% if ospf_enabled %}...{% endif %}
  • Filters: {{ ip | to_cidr }}
  • Comments: {# This is a comment #}

Security Considerations

Template Validation:

┌─────────────────────────────────────────────────────────────┐
│ Template Security Checks                                    │
├─────────────────────────────────────────────────────────────┤
│ 1. Syntax Validation                                        │
│    ├─ Parse Jinja2 syntax                                   │
│    ├─ Check for undefined variables                         │
│    └─ Validate template structure                           │
│                                                              │
│ 2. Sandbox Enforcement                                      │
│    ├─ Disable dangerous built-ins (eval, exec, import)      │
│    ├─ Limit template complexity (max loops, recursion)      │
│    └─ Restrict available filters                            │
│                                                              │
│ 3. Content Security                                         │
│    ├─ Scan for command injection attempts                   │
│    ├─ Validate against forbidden commands list              │
│    └─ Audit logging for all templates                       │
└─────────────────────────────────────────────────────────────┘

Parameter Validation:

Validation Layers:
├─ Type Checking
│  └─ int, str, List[Dict], etc.
├─ Range Validation
│  ├─ IP addresses (valid format)
│  ├─ VLAN IDs (1-4094)
│  └─ Port numbers (1-65535)
├─ Device-Specific Validation
│  └─ Check device capabilities
└─ Business Logic Validation
   └─ Network-specific rules

Error Handling Strategy

Error Categories:

┌─────────────────────────────────────────────────────────────┐
│ Error Types & Recovery Strategies                           │
├─────────────────────────────────────────────────────────────┤
│ 1. TemplateSyntaxError                                      │
│    ├─ Cause: Invalid Jinja2 syntax                          │
│    ├─ Detection: Pre-rendering validation                   │
│    └─ Recovery: [Show error] → [User fixes] → [Retry]      │
│                                                              │
│ 2. ParameterValidationError                                 │
│    ├─ Cause: Wrong type/value/range                         │
│    ├─ Detection: Pre-execution validation                   │
│    └─ Recovery: [Highlight errors] → [User corrects]        │
│                                                              │
│ 3. RenderingError                                           │
│    ├─ Cause: Runtime rendering failure                      │
│    ├─ Detection: During template render                     │
│    └─ Recovery: [Show context] → [User modifies params]     │
│                                                              │
│ 4. ExecutionError                                           │
│    ├─ Cause: Device connection/command failure              │
│    ├─ Detection: During config execution                    │
│    └─ Recovery: [Retry] → [Skip] → [Continue others]        │
└─────────────────────────────────────────────────────────────┘

Error Response Format:

{
  "error": "ParameterValidationError",
  "message": "Invalid IP address format for device R1",
  "details": {
    "device": "R1",
    "parameter": "interface.ip",
    "value": "999.999.999.999",
    "expected": "Valid IPv4 address (e.g., 192.168.1.1)"
  },
  "suggestions": [
    "Verify IP address format",
    "Check for typos in address",
    "Ensure address is in correct range"
  ]
}

Testing Strategy

Unit Tests

Template Rendering Tests:

Test Cases:
├─ Simple Variables
│  └─ Input: "hostname {{ name }}" + {name: "R1"}
│     Output: ["hostname R1"]
│
├─ Loops
│  └─ Input: "{% for n in nets %}network {{ n }}\n{% endfor %}"
│          + {nets: ["192.168.1.0", "192.168.2.0"]}
│     Output: ["network 192.168.1.0", "network 192.168.2.0"]
│
├─ Conditionals
│  └─ Input: "{% if ospf %}router ospf 1\n{% endif %}"
│          + {ospf: true}
│     Output: ["router ospf 1"]
│
└─ Nested Structures
   └─ Input: Complex multi-level config
      Output: Properly indented commands

Rule Engine Tests:

Test Cases:
├─ Device Number Extraction
│  ├─ "R1" → 1
│  ├─ "Router-100" → 100
│  └─ "DeviceX" → fallback to index
│
├─ IP Address Generation
│  ├─ Sequential: 192.168.1.0, 192.168.2.0, ...
│  ├─ VLAN-based: 10.0.100.0, 10.0.101.0, ...
│  └─ Hierarchical: Correct prefix assignment
│
└─ Parameter Validation
   ├─ Type checking
   ├─ Range validation
   └─ Device-specific constraints

Integration Tests

Full HITL Workflow:

Test Scenario:
┌─────────────────────────────────────────────────────────────┐
│ 1. Template Generation                                      │
│    ├─ Input: "Configure OSPF on 10 routers"                │
│    ├─ Expected: Valid Jinja2 template with schema          │
│    └─ Verify: Template syntax, parameter completeness      │
│                                                              │
│ 2. Parameter Generation (AI mode)                          │
│    ├─ Input: Template + topology context                   │
│    ├─ Expected: 10 device parameter sets                   │
│    └─ Verify: Correct IP assignment, device mapping        │
│                                                              │
│ 3. Parameter Generation (Direct mode)                      │
│    ├─ Input: Template + topology (100 devices)             │
│    ├─ Expected: 100 parameter sets (0 tokens)              │
│    └─ Verify: Rule engine logic, addressing schemes        │
│                                                              │
│ 4. Execution                                                │
│    ├─ Input: Template + parameters                         │
│    ├─ Expected: Successful configuration on all devices    │
│    └─ Verify: Config applied, execution results            │
└─────────────────────────────────────────────────────────────┘

End-to-End Tests

Large-Scale Topology Test:

Scenario: 1000 Router OSPF Configuration

Setup:
├─ Create GNS3 project with 1000 routers
├─ Deploy in test environment
└─ Verify connectivity

Execution:
├─ Generate template (~150 tokens)
├─ Generate params (rule engine, 0 tokens)
├─ Execute in batches of 100
└─ Monitor progress via SSE

Validation:
├─ Verify all 1000 devices configured
├─ Check OSPF process running on each
├─ Verify IP addressing correctness
├─ Measure execution time (< 8 minutes)
└─ Verify token consumption (~400 total)

Cleanup:
└─ Remove test project

Performance Tests:

Benchmarks:
├─ 10 devices: < 30 seconds
├─ 50 devices: < 1 minute
├─ 100 devices: 1-2 minutes
├─ 500 devices: 2-5 minutes
└─ 1000 devices: 3-8 minutes

Metrics:
├─ Token usage (target: 99%+ reduction)
├─ Execution time (vs. baseline)
├─ Memory usage
└─ Concurrent connection handling

Success Metrics

Token Savings

  • Target: 70%+ reduction in token usage for multi-device configurations
  • Measurement: Compare token usage before/after for same tasks

User Adoption

  • Target: 60%+ of configuration tasks use template workflow
  • Measurement: Track tool usage statistics

Error Reduction

  • Target: 50%+ reduction in configuration errors
  • Measurement: Compare error rates before/after HITL

User Satisfaction

  • Target: 4.5+ star rating (5-star scale)
  • Measurement: Post-task user surveys

Risks and Mitigations

Risk Impact Mitigation
AI generates invalid Jinja2 syntax High Add template validation, provide syntax feedback
Users find HITL workflow too slow Medium Add "quick confirm" option, template reuse
Template reuse causes stale configs Medium Template versioning, checksum validation
Multi-vendor complexity High Phase 1: Cisco only, Phase 4: expand
Session state management bugs Medium Comprehensive testing, state cleanup

Open Questions

  1. Template Storage: Should templates be stored per-user or shared globally?
  2. Template Validation: How strict should template validation be?
  3. Backward Compatibility: Should existing direct-config tools remain available?
  4. Template Sharing: Should users be able to share templates in a marketplace?
  5. Performance: How to handle template rendering for 100+ devices?

Dependencies

Required Python Packages

jinja2>=3.1.0
langchain>=0.1.0
langgraph>=0.0.20

Integration Points

  • gns3server/agent/gns3_copilot/tools_v2/config_tools_nornir.py (existing)
  • gns3server/agent/gns3_copilot/prompts/lab_automation_assistant_prompt.py (update)
  • gns3server/agent/gns3_copilot/gns3_client/gns3_topology_reader.py (existing)
  • gns3server/agent/gns3_copilot/utils/command_filter.py (existing)

Timeline

Sprint 1: Foundation (Week 1-2)

  • Core rendering engine
  • Three LangChain tools
  • Basic session management
  • System prompt updates

Sprint 2: User Experience (Week 3)

  • Review interfaces
  • Preview functionality
  • Error handling
  • Documentation

Sprint 3: Enhancement (Week 4-5)

  • Template library
  • Caching mechanisms
  • Multi-vendor support
  • Testing and QA

Sprint 4: Polish (Week 6)

  • Performance optimization
  • Bug fixes
  • User feedback integration
  • Release preparation

References


Changelog

Date Version Changes
2026-03-20 0.6 Clarified system scope and positioning - focuses on baseline configuration (0→1), with handoff to production tools (Terraform/REST API/NETCONF) for advanced configuration (1→N)
2026-03-20 0.5 Major documentation refactor - Reduced code content by ~60%, added comprehensive diagrams: System architecture, HITL state transitions, API design, data flow, error handling, template lifecycle; Enhanced section on testing strategy; Improved visual documentation
2026-03-20 0.4 Added link creation templates section with topology patterns (Spine-Leaf, Ring, Mesh, Star), intelligent port allocation, performance benchmarks for large-scale connectivity
2026-03-20 0.3 Added node creation templates section with batch topology provisioning, auto-linking, automatic positioning; Combined node creation + configuration workflows for rapid 1000+ node data center deployment
2026-03-20 0.2 Added large-scale topology support section (1000+ nodes), direct execution mode, batch parallel execution, rule engine optimizations
2026-03-20 0.1 Initial roadmap document created

Document Status: 💡 Proposed - Awaiting Implementation Next Review: After Phase 1 completion


For questions or feedback about this roadmap, please open an issue or contact the AI Copilot team.