feat: make AI Copilot an optional dependency

This change makes AI Copilot features optional to reduce installation
size and support restricted environments.

Changes:
- Split AI dependencies into ai-requirements.txt
- Add ai-copilot optional dependency in pyproject.toml
- Add import protection in gns3server/agent/__init__.py
- Return 501 for AI endpoints when dependencies not installed
- Add gns3server-uninstall-ai-copilot command for cleanup
- Update README with installation and uninstallation instructions

Installation:
- Basic: pip install gns3-server
- With AI: pip install gns3-server[ai-copilot]
- Development: pip install gns3-server[ai-copilot,dev]

Uninstallation:
- gns3server-uninstall-ai-copilot
This commit is contained in:
YueGuobin 2026-03-18 15:21:23 +08:00
parent 0b741dd834
commit cd1d28729a
8 changed files with 337 additions and 76 deletions

View File

@ -54,6 +54,45 @@ python3 -m pip install gns3-gui
python3 -m pip install gns3-server python3 -m pip install gns3-server
``` ```
#### Optional Features
GNS3 server supports optional features that can be installed as needed:
**AI Copilot** (Optional):
```shell
python3 -m pip install gns3-server[ai-copilot]
```
AI-powered assistant for network topology design and automation.
**Development** (For contributors):
```shell
python3 -m pip install gns3-server[dev]
```
**Combination Installation**:
You can install multiple optional features together:
```shell
python3 -m pip install gns3-server[ai-copilot,dev]
```
**Why optional?**
- Reduces installation size for users who don't need specific features
- Supports restricted environments (government, education, corporate) where certain libraries may not be allowed
- Faster installation for basic GNS3 usage
- Allows users to choose only the features they need
**Note:** If you install without optional extras, the server will work normally but optional features will be disabled. You can add features later by running the appropriate install command.
**Uninstalling AI Copilot:**
To remove AI Copilot dependencies:
```shell
gns3server-uninstall-ai-copilot
```
This will remove all AI Copilot dependencies while keeping the core functionality intact. The server will continue to work, but AI features will return a 501 (Not Implemented) status code.
The downside of this method is you will have to manually install all dependencies (see below). The downside of this method is you will have to manually install all dependencies (see below).
Please see our [documentation](https://docs.gns3.com/docs/getting-started/installation/linux) for more details. Please see our [documentation](https://docs.gns3.com/docs/getting-started/installation/linux) for more details.
@ -77,7 +116,7 @@ Note that Docker needs the script program (`bsdutils` or `util-linux` package),
### Setting up ### Setting up
These commands will install the server as well as all Python dependencies: These commands will install the server with core Python dependencies:
```shell ```shell
git clone https://github.com/GNS3/gns3-server git clone https://github.com/GNS3/gns3-server
@ -89,6 +128,18 @@ python3 -m pip install .
python3 -m gns3server python3 -m gns3server
``` ```
**For AI Copilot development**, install with additional dependencies:
```shell
python3 -m pip install .[ai-copilot,dev]
```
**For development (tests and linting)**:
```shell
python3 -m pip install .[dev]
```
You will have to manually install other software dependencies (see above), for Dynamips, VPCS and uBridge the easiest is to install from our PPA. You will have to manually install other software dependencies (see above), for Dynamips, VPCS and uBridge the easiest is to install from our PPA.
### Docker container ### Docker container

49
ai-requirements.txt Normal file
View File

@ -0,0 +1,49 @@
# ==============================================================================
# GNS3 Copilot AI Agent Dependencies
# ==============================================================================
# Install with: pip install gns3-server[ai-copilot]
# Or directly: pip install -r ai-requirements.txt
# ==============================================================================
# Core AI and Automation Framework
# Note: aiosqlite is in core requirements.txt
langchain>=1.2.10
langchain-core>=1.2.16
langgraph>=1.0.9
langgraph-checkpoint>=4.0.0
langgraph-checkpoint-sqlite>=3.0.3
langgraph-checkpoint-postgres>=3.0.4
# Model Providers
langchain-openai>=1.1.10
langchain-anthropic>=1.3.4
langchain-google-genai>=4.2.1
langchain-aws>=1.3.1
langchain-ollama>=1.0.1
langchain-deepseek>=1.0.1
langchain-xai>=1.2.2
# Token Counting
tiktoken>=0.8.0
# LangSmith SDK
langsmith>=0.7.7
# Network Automation
netmiko>=4.6.0
nornir>=3.5.0
nornir-netmiko>=1.0.1
nornir-utils>=0.2.0
nornir-salt>=0.23.0
# Telnet Client
telnetlib3>=2.0.8
# Environment & Configuration
python-dotenv>=1.2.1
# Authentication
PyJWT>=2.10.1
psycopg-pool>=3.1.0
# Note: httpx is only for testing (in dev-requirements.txt)

View File

@ -0,0 +1,75 @@
#
# Copyright (C) 2025 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Agent module with optional AI Copilot support.
This module provides the AI Copilot functionality as an optional feature.
If the AI dependencies are not installed, the module will be disabled but
will not prevent the server from starting.
Installation:
pip install gns3-server[ai-copilot]
"""
import logging
# Feature flag: AI Copilot is available
AI_COPILOT_AVAILABLE = False
# Try to import AI Copilot components
try:
from .gns3_copilot.project_agent_manager import get_project_agent_manager
from .gns3_copilot.project_agent_manager import ProjectAgentManager
AI_COPILOT_AVAILABLE = True
except ImportError as e:
# AI dependencies not installed, disable AI Copilot feature
logging.warning(
f"AI Copilot dependencies not installed: {e}. "
"AI features will be disabled. Install with: pip install gns3-server[ai-copilot]"
)
AI_COPILOT_AVAILABLE = False
# Provide stub functions that raise helpful errors
async def get_project_agent_manager():
"""
Get the global ProjectAgentManager singleton instance.
Raises:
RuntimeError: If AI Copilot dependencies are not installed
"""
raise RuntimeError(
"AI Copilot is not available. "
"Install AI dependencies with: pip install gns3-server[ai-copilot]"
)
class ProjectAgentManager:
"""
Stub class for ProjectAgentManager when AI dependencies are not installed.
"""
def __init__(self):
raise RuntimeError(
"AI Copilot is not available. "
"Install AI dependencies with: pip install gns3-server[ai-copilot]"
)
__all__ = [
"AI_COPILOT_AVAILABLE",
"get_project_agent_manager",
"ProjectAgentManager",
]

View File

@ -14,16 +14,36 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends, HTTPException
# Check AI Copilot availability
from gns3server.agent import AI_COPILOT_AVAILABLE
# Conditionally import AI-dependent routes
if AI_COPILOT_AVAILABLE:
from . import chat
from . import llm_model_configs
_chat_router = chat.router
_llm_router = llm_model_configs.router
else:
# Create stub routers that return 501 for all AI endpoints
_chat_router = APIRouter()
_llm_router = APIRouter()
@_chat_router.api_route("/{path:path}", methods=["GET", "POST", "DELETE", "PATCH", "PUT"])
@_llm_router.api_route("/{path:path}", methods=["GET", "POST", "DELETE", "PATCH", "PUT"])
async def ai_not_available(path: str = ""):
raise HTTPException(
status_code=501,
detail="AI Copilot is not available. Install AI dependencies with: pip install gns3-server[ai-copilot]"
)
from . import chat
from . import controller from . import controller
from . import appliances from . import appliances
from . import computes from . import computes
from . import drawings from . import drawings
from . import gns3vm from . import gns3vm
from . import links from . import links
from . import llm_model_configs
from . import nodes from . import nodes
from . import projects from . import projects
from . import snapshots from . import snapshots
@ -149,13 +169,13 @@ router.include_router(
) )
router.include_router( router.include_router(
llm_model_configs.router, _llm_router,
prefix="/access", prefix="/access",
tags=["LLM Model Configurations"] tags=["LLM Model Configurations"]
) )
router.include_router( router.include_router(
chat.router, _chat_router,
prefix="/projects/{project_id}/chat", prefix="/projects/{project_id}/chat",
tags=["Chat"] tags=["Chat"]
) )

View File

@ -30,24 +30,31 @@ from .controller.gns3vm import GNS3VM
from .controller.nodes import NodeCreate, NodeUpdate, NodeDuplicate, NodeCapture, Node from .controller.nodes import NodeCreate, NodeUpdate, NodeDuplicate, NodeCapture, Node
from .controller.projects import ProjectCreate, ProjectUpdate, ProjectDuplicate, Project, ProjectFile, ProjectCompression from .controller.projects import ProjectCreate, ProjectUpdate, ProjectDuplicate, Project, ProjectFile, ProjectCompression
from .controller.users import UserCreate, UserUpdate, LoggedInUserUpdate, User, Credentials, UserGroupCreate, UserGroupUpdate, UserGroup from .controller.users import UserCreate, UserUpdate, LoggedInUserUpdate, User, Credentials, UserGroupCreate, UserGroupUpdate, UserGroup
from .controller.llm_model_configs import (
LLMModelConfigData, # Conditionally import AI-related schemas
LLMModelConfigCreate, try:
LLMModelConfigUpdate, from .controller.llm_model_configs import (
LLMModelConfigResponse, LLMModelConfigData,
LLMModelConfigWithSource, LLMModelConfigCreate,
LLMModelConfigInheritedResponse, LLMModelConfigUpdate,
LLMModelConfigListResponse LLMModelConfigResponse,
) LLMModelConfigWithSource,
from .controller.chat import ( LLMModelConfigInheritedResponse,
OpenAIToolCall, LLMModelConfigListResponse
ChatRequest, )
ChatResponse, from .controller.chat import (
OpenAIMessage, OpenAIToolCall,
ConversationHistory, ChatRequest,
ChatSession, ChatResponse,
RenameSession OpenAIMessage,
) ConversationHistory,
ChatSession,
RenameSession
)
except ImportError:
# AI schemas are not available (should not happen as they don't depend on external libs)
pass
from .controller.rbac import RoleCreate, RoleUpdate, Role, Privilege, ACECreate, ACEUpdate, ACE from .controller.rbac import RoleCreate, RoleUpdate, Role, Privilege, ACECreate, ACEUpdate, ACE
from .controller.pools import Resource, ResourceCreate, ResourcePoolCreate, ResourcePoolUpdate, ResourcePool from .controller.pools import Resource, ResourceCreate, ResourcePoolCreate, ResourcePoolUpdate, ResourcePool
from .controller.tokens import Token from .controller.tokens import Token

View File

@ -0,0 +1,92 @@
#!/usr/bin/env python3
"""
Uninstall AI Copilot dependencies.
Usage:
gns3server-uninstall-ai-copilot
gns3server-uninstall-ai-copilot -y
"""
import os
import sys
import subprocess
import argparse
def get_ai_packages():
"""Read packages from ai-requirements.txt."""
# Find the requirements file
if hasattr(sys, '_MEIPASS'):
# PyInstaller bundle
base_dir = os.path.dirname(sys.executable)
else:
# __file__ = gns3server/utils/uninstall_ai_copilot.py
# Need to go up 2 levels to reach project root
base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
requirements_file = os.path.join(base_dir, "ai-requirements.txt")
packages = []
with open(requirements_file, "r") as f:
for line in f:
line = line.strip()
if not line or line.startswith("#"):
continue
# Remove version specifiers
package = line.split(">=")[0].split("==")[0].split("~=")[0]
packages.append(package)
return packages
def uninstall(packages, yes=False):
"""Uninstall packages."""
if not packages:
print("No packages found to uninstall.")
return
print(f"Found {len(packages)} AI Copilot dependencies:")
for pkg in packages:
print(f" - {pkg}")
print()
if not yes:
response = input("Do you want to uninstall these packages? [y/N]: ")
if response.lower() != "y":
print("Cancelled.")
return
print("Uninstalling...")
for package in packages:
try:
result = subprocess.run(
[sys.executable, "-m", "pip", "uninstall", "-y", package],
capture_output=True,
text=True
)
if result.returncode == 0:
print(f" Removed: {package}")
else:
print(f" Failed to remove {package} (may not be installed)")
except Exception as e:
print(f" Error removing {package}: {e}")
print("\nAI Copilot dependencies have been uninstalled.")
print("You can reinstall them with: pip install gns3-server[ai-copilot]")
def main():
parser = argparse.ArgumentParser(
description="Uninstall AI Copilot dependencies"
)
parser.add_argument(
"-y", "--yes", action="store_true",
help="Automatically confirm uninstallation"
)
args = parser.parse_args()
packages = get_ai_packages()
uninstall(packages, yes=args.yes)
if __name__ == "__main__":
main()

View File

@ -38,8 +38,13 @@ version = {attr = "gns3server.version.__version__"}
dependencies = {file = "requirements.txt"} dependencies = {file = "requirements.txt"}
[tool.setuptools.dynamic.optional-dependencies] [tool.setuptools.dynamic.optional-dependencies]
# Development dependencies
dev = {file = ['dev-requirements.txt']} dev = {file = ['dev-requirements.txt']}
# Optional components (can be installed individually or combined)
ai-copilot = {file = ['ai-requirements.txt']}
# terraform = {file = ['terraform-requirements.txt']} # Future component
[project.urls] [project.urls]
"Homepage" = "http://gns3.com" "Homepage" = "http://gns3.com"
"Repository" = "http://github.com/GNS3/gns3-server" "Repository" = "http://github.com/GNS3/gns3-server"
@ -48,3 +53,4 @@ dev = {file = ['dev-requirements.txt']}
[project.scripts] [project.scripts]
gns3server = "gns3server.main:main" gns3server = "gns3server.main:main"
gns3vmnet = "gns3server.utils.vmnet:main" gns3vmnet = "gns3server.utils.vmnet:main"
gns3server-uninstall-ai-copilot = "gns3server.utils.uninstall_ai_copilot:main"

View File

@ -24,58 +24,19 @@ zstandard==0.25.0
platformdirs>=2.4.0,<3 # platformdirs >=3 conflicts when building Debian packages platformdirs>=2.4.0,<3 # platformdirs >=3 conflicts when building Debian packages
truststore>=0.10.4; python_version >= '3.10' truststore>=0.10.4; python_version >= '3.10'
# ============================================================================== # Shared dependencies (also used by AI Copilot)
# GNS3 Copilot AI Agent Dependencies typing-extensions>=4.15.0
# ==============================================================================
# Core AI and Automation Framework
aiosqlite>=0.19.0
langchain>=1.2.10
langchain-core>=1.2.16
langgraph>=1.0.9
langgraph-checkpoint>=4.0.0
langgraph-checkpoint-sqlite>=3.0.3
langgraph-checkpoint-postgres>=3.0.4
# Model Providers
langchain-openai>=1.1.10
langchain-anthropic>=1.3.4
langchain-google-genai>=4.2.1
langchain-aws>=1.3.1
langchain-ollama>=1.0.1
langchain-deepseek>=1.0.1
langchain-xai>=1.2.2
# Token Counting
tiktoken>=0.8.0
# LangSmith SDK
langsmith>=0.7.7
# Network Automation
netmiko>=4.6.0
nornir>=3.5.0
nornir-netmiko>=1.0.1
nornir-utils>=0.2.0
nornir-salt>=0.23.0
# Telnet Client
telnetlib3>=2.0.8
# Environment & Configuration
python-dotenv>=1.2.1
# HTTP Requests
requests>=2.32.5 requests>=2.32.5
urllib3>=2.6.2 urllib3>=2.6.2
httpx>=0.27.0
# Authentication # ==============================================================================
PyJWT>=2.10.1 # AI Copilot Optional Dependencies
psycopg-pool>=3.1.0 # ==============================================================================
# AI Copilot features are now optional. Install with:
# Type Extensions # pip install gns3-server[ai-copilot]
typing-extensions>=4.15.0 # Or:
# pip install -r ai-requirements.txt
# Image Processing #
Pillow>=12.1.1 # This reduces installation size and supports restricted environments where
# AI dependencies may not be allowed.
# ==============================================================================