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
```
#### 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).
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
These commands will install the server as well as all Python dependencies:
These commands will install the server with core Python dependencies:
```shell
git clone https://github.com/GNS3/gns3-server
@ -89,6 +128,18 @@ python3 -m pip install .
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.
### 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
# 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 appliances
from . import computes
from . import drawings
from . import gns3vm
from . import links
from . import llm_model_configs
from . import nodes
from . import projects
from . import snapshots
@ -149,13 +169,13 @@ router.include_router(
)
router.include_router(
llm_model_configs.router,
_llm_router,
prefix="/access",
tags=["LLM Model Configurations"]
)
router.include_router(
chat.router,
_chat_router,
prefix="/projects/{project_id}/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.projects import ProjectCreate, ProjectUpdate, ProjectDuplicate, Project, ProjectFile, ProjectCompression
from .controller.users import UserCreate, UserUpdate, LoggedInUserUpdate, User, Credentials, UserGroupCreate, UserGroupUpdate, UserGroup
from .controller.llm_model_configs import (
LLMModelConfigData,
LLMModelConfigCreate,
LLMModelConfigUpdate,
LLMModelConfigResponse,
LLMModelConfigWithSource,
LLMModelConfigInheritedResponse,
LLMModelConfigListResponse
)
from .controller.chat import (
OpenAIToolCall,
ChatRequest,
ChatResponse,
OpenAIMessage,
ConversationHistory,
ChatSession,
RenameSession
)
# Conditionally import AI-related schemas
try:
from .controller.llm_model_configs import (
LLMModelConfigData,
LLMModelConfigCreate,
LLMModelConfigUpdate,
LLMModelConfigResponse,
LLMModelConfigWithSource,
LLMModelConfigInheritedResponse,
LLMModelConfigListResponse
)
from .controller.chat import (
OpenAIToolCall,
ChatRequest,
ChatResponse,
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.pools import Resource, ResourceCreate, ResourcePoolCreate, ResourcePoolUpdate, ResourcePool
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"}
[tool.setuptools.dynamic.optional-dependencies]
# Development dependencies
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]
"Homepage" = "http://gns3.com"
"Repository" = "http://github.com/GNS3/gns3-server"
@ -48,3 +53,4 @@ dev = {file = ['dev-requirements.txt']}
[project.scripts]
gns3server = "gns3server.main: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
truststore>=0.10.4; python_version >= '3.10'
# ==============================================================================
# GNS3 Copilot AI Agent Dependencies
# ==============================================================================
# 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
# Shared dependencies (also used by AI Copilot)
typing-extensions>=4.15.0
requests>=2.32.5
urllib3>=2.6.2
httpx>=0.27.0
# Authentication
PyJWT>=2.10.1
psycopg-pool>=3.1.0
# Type Extensions
typing-extensions>=4.15.0
# Image Processing
Pillow>=12.1.1
# ==============================================================================
# AI Copilot Optional Dependencies
# ==============================================================================
# AI Copilot features are now optional. Install with:
# pip install gns3-server[ai-copilot]
# Or:
# pip install -r ai-requirements.txt
#
# This reduces installation size and supports restricted environments where
# AI dependencies may not be allowed.
# ==============================================================================