269 Commits

Author SHA1 Message Date
YueGuobin
8e340f0ce8
Add descriptive detail to 403 errors in compute file endpoints
Both is_safe_path rejection and PermissionError were returning 403
without a detail message, making them indistinguishable in logs.
Add specific detail strings to each:
- is_safe_path: 'Path is outside the project directory'
- PermissionError (write): 'Permission denied writing to ...'
- PermissionError (delete): 'Permission denied deleting ...'
2026-06-09 23:33:35 +08:00
YueGuobin
16a9064eb8
Fix silent file write failure in write_compute_project_file
The inner try-except caught OSError/UnicodeEncodeError with 'pass',
silently swallowing all write failures and returning HTTP 204 as if
the file was written successfully.

Remove the nested try-except and let errors propagate properly:
- OSError → 500 with error detail
- PermissionError → 403 (already handled)
- FileNotFoundError → 404 (already handled)
2026-06-09 23:27:45 +08:00
YueGuobin
cbb21e8e40
feat: Node file streaming, recursive listing, file type detection, and file delete
- Stream file GET/POST through controller without buffering in memory
- Add recursive and subdirectory filtering to node file listing
- Replace file extension with magic-based file type detection
- Add DELETE endpoint for node and project files
- Include directories in listing response
- Add params and stream support to http_query
- Fix lambda closures, streamer exception scope, and delete error codes
2026-06-09 22:52:50 +08:00
YueGuobin
f91d7b18e9
Update README tool descriptions: .txt → .md
Only description strings changed to tell AI the content is Markdown
format (.md). The actual handler still reads/writes README.txt for
Web UI compatibility.
2026-06-07 23:32:26 +08:00
YueGuobin
4ca1a80adb
Update README tool descriptions to mention Markdown format
Web UI supports rendering Markdown in README.txt, so note this in the
tool descriptions and content parameter.
2026-06-07 23:23:38 +08:00
YueGuobin
4921b98948
Add MCP project tools: update, duplicate, and README operations
- Add update_project and duplicate_project MCP tools
- Add get_project_readme and update_project_readme tools
- Add Gns3Connector methods: update_project, duplicate_project,
  get_project_file, write_project_file
2026-06-07 23:14:07 +08:00
Guobin Yue
fbe6b280d5
Merge branch '3.1' into fix/mcp-template-update-kwargs-handling 2026-06-07 00:37:02 +08:00
YueGuobin
1f985a2823
fix: update MCP link tools descriptions with detailed filter info
Updated the actual MCP tool definitions in __init__.py with detailed
filter parameter descriptions. The previous update to links.py was incorrect
because MCP tools are defined via @mcp.tool() decorators in __init__.py.

Changes:
- Updated update_link tool docstring with comprehensive filter information
- Updated create_link tool filters parameter description
- Added all 5 filter types with proper array format requirements
- Added parameter ranges and usage examples

Filters now properly documented:
- frequency_drop: [N] (N: -1 to 32767)
- packet_loss: [rate] (rate: 0 to 100)
- delay: [ms, jitter] (milliseconds)
- corrupt: [rate] (rate: 0 to 100)
- bpf: [expression] (BPF syntax)

This will prevent TypeError: 'int' object is not iterable errors and
help users understand the correct filter format.
2026-06-07 00:20:29 +08:00
YueGuobin
eac6c9f17d
docs: improve MCP link tools filter parameter descriptions
Updated the filters parameter description in create_link and update_link
MCP tools to specify the required array format and provide examples.

Changes:
- Updated create_link filters description with array format requirements
- Updated update_link filters description with array format and example
- Added specific filter types: frequency_drop, packet_loss, delay, corrupt, bpf

This helps users understand the correct format:
- frequency_drop: [N] (drop every Nth packet)
- packet_loss: [rate] (packet loss percentage)
- delay: [ms, jitter] (latency and jitter in milliseconds)
- corrupt: [rate] (packet corruption percentage)
- bpf: [expression] (Berkeley Packet Filter)

Prevents TypeError: 'int' object is not iterable errors.
2026-06-06 23:46:22 +08:00
YueGuobin
3ba11c8bff
fix: correct MCP nodes and links tool parameter handling for nested kwargs
Extended the kwargs parameter handling fix to nodes and links MCP tools,
which had the same nested kwargs structure issue as templates.

Changes:
- Modified update_node_handler to extract params from nested kwargs
- Modified update_link_handler to extract params from nested kwargs

This ensures that node and link updates through MCP tools work correctly,
allowing proper modification of node and link properties.
2026-06-06 23:31:32 +08:00
YueGuobin
0d22d275fb
fix: correct MCP template tool parameter handling for nested kwargs
Fixed an issue where MCP template tools (update_template, create_template)
were not correctly handling nested kwargs parameter structure from MCP clients.

The problem occurred when MCP clients passed parameters in the format:
  {'template_id': 'xxx', 'kwargs': {'adapters': 3}}

The original code was passing the entire kwargs dictionary as a parameter,
instead of extracting the actual update parameters from within it.

Changes:
- Modified update_template_handler to extract params from nested kwargs
- Modified create_template_handler to handle the same issue

This fix ensures that template updates through MCP tools now work correctly,
allowing proper modification of template properties like adapters count.
2026-06-06 23:26:21 +08:00
YueGuobin
3958279b8a
feat: add client information logging to MCP connection rejection
Add reusable utility for extracting client information from ASGI scope:
- Create gns3server/utils/request_utils.py with extract_client_info()
- Extract client IP, port, path, method, and authenticated username
- Format comprehensive log messages with client context

Benefits:
- Better observability for connection rejection events
- Reusable utility for other modules
- Consistent client logging format across codebase
- Helps diagnose timing issues during server startup

Usage:
  from gns3server.utils.request_utils import extract_client_info
  client_info = extract_client_info(scope, auth_service)
  log.warning(f"Connection rejected - Client: {client_info['host']}:{client_info['port']} ({client_info['user_info']})")
2026-06-06 22:35:43 +08:00
YueGuobin
9e5b575d1c
refactor: replace MCP ready state polling with asyncio.Event
Replace the global variable + lock + polling mechanism with asyncio.Event
pattern for MCP server ready state tracking.

Benefits:
- Eliminates race conditions (Event.set() is thread-safe)
- Event-driven notification instead of polling (no 50x sleep overhead)
- Fixes test contamination from global state
- Reduces code from 54 lines to 30 lines
- Uses standard asyncio primitive for this pattern
2026-06-06 22:24:10 +08:00
YueGuobin
67a960fbce
fix: return 503 error on MCP server ready timeout
Instead of allowing connections to proceed when server initialization
times out, return HTTP 503 Service Unavailable to prevent MCP
protocol initialization errors.

This prevents the original "Received request before initialization
was complete" errors when GNS3 server startup takes longer than
the 5-second timeout.
2026-06-06 15:23:52 +08:00
YueGuobin
b1514edf88
fix: add MCP server ready check to prevent initialization errors
Add server ready state tracking for MCP service to prevent
"Received request before initialization was complete" errors
when clients connect before GNS3 server completes startup.

Changes:
- Add MCP server ready state management with wait/notify mechanism
- Modify auth wrapper to wait for server initialization before accepting connections
- Set MCP server ready flag after GNS3 startup completes

This ensures MCP protocol initialization handshake only occurs
after GNS3 server is fully initialized, preventing race
conditions during server startup.
2026-06-06 15:21:17 +08:00
YueGuobin
db9772ca7a
fix: resolve MCP server URL host via default route IP when bound to 0.0.0.0
When GNS3 server is configured to listen on 0.0.0.0 (all interfaces),
_server_url() was hardcoding 127.0.0.1, making the WebSocket console
URL unreachable from remote MCP clients.

Use the UDP connect trick (connect to 8.8.8.8:80 without sending data)
to discover the default route interface IP, which is the address remote
clients can actually reach.
2026-06-06 00:48:22 +08:00
YueGuobin
0e6db9a7b6
fix: correct MCP transport security config to actually allow all hosts by default
The MCP library's TransportSecurityMiddleware only supports exact host
matches or "host:*" port wildcards. It does NOT support a standalone "*"
wildcard to mean "allow all hosts" — setting allowed_hosts=["*"] would
reject every connection because no Host header equals "*".

Worse, when transport_security=None was passed to FastMCP while its default
host is "127.0.0.1", FastMCP would auto-enable protection with strict
localhost-only rules, overriding GNS3's intent to allow all hosts.

Root cause analysis:
- FastMCP auto-enables DNS rebinding protection when host is localhost
  and no explicit TransportSecuritySettings is provided
- GNS3 was passing transport_security=None (indirectly via FastMCP's default)
  when protection was disabled, triggering the auto-enable
- The TransportSecuritySettings "allowed_hosts" list does NOT support "*"
  as a catch-all wildcard

This fix:
1. Always pass an explicit TransportSecuritySettings to FastMCP
   - Disabled: TransportSecuritySettings(enable_dns_rebinding_protection=False)
   - Enabled: TransportSecuritySettings(enable_dns_rebinding_protection=True, ...)
2. Restore mcp_allowed_hosts and mcp_allowed_origins config fields
3. Set mcp_enable_dns_rebinding_protection default to False (allow all hosts)

Behaviour:
- Default (no config change): all hosts can connect to MCP server
- With mcp_enable_dns_rebinding_protection=true: only configured hosts
- Aligns with GNS3 server's 0.0.0.0 binding policy
2026-06-05 23:20:57 +08:00
YueGuobin
bb39238f02
feat: add configurable MCP transport security settings via gns3_server.conf
Add MCP transport security configuration to gns3_server.conf with permissive
defaults that align with GNS3's design philosophy and VM distribution requirements.

## Changes

### 1. Configuration Schema (gns3server/schemas/config.py)
- Added MCP transport security fields to ServerSettings class:
  - mcp_enable_dns_rebinding_protection (bool, default: True)
  - mcp_allowed_hosts (list[str], default: ["*"])
  - mcp_allowed_origins (list[str], default: ["*"])
- Added field validators to handle comma-separated string input

### 2. MCP Server Initialization (gns3server/api/routes/mcp/__init__.py)
- Import TransportSecuritySettings from mcp.server.transport_security
- Added _create_mcp_server() function to read configuration
- Updated FastMCP instantiation to use configured security settings

### 3. Configuration Sample (gns3server/config_samples/gns3_server.conf)
- Added MCP transport security settings section
- Documented default behavior and security options
- Provided examples for different use cases

## Design Philosophy

**Default: Allow All Hosts** (matches GNS3's 0.0.0.0 binding):
- VM distribution works out-of-the-box
- Users can access from any network location
- Security-conscious users can restrict when needed

**Security: Optional Restriction**:
Users can configure specific hosts for enhanced security:
``ini
mcp_allowed_hosts = 127.0.0.1:*,localhost:*,192.168.1.3:*
mcp_allowed_origins = http://127.0.0.1:*,http://localhost:*,http://192.168.1.3:*
```

## Benefits

- Flexible: Users can configure based on security requirements
- User-friendly: Default matches GNS3's 0.0.0.0 binding philosophy
- Maintainable: No code changes needed for different deployment scenarios
- Secure: DNS rebinding protection remains enabled with configurable hosts

## Related

- Issue #2771
- FastMCP DNS rebinding protection design
- Existing skills configuration in ServerSettings
2026-06-05 23:06:06 +08:00
YueGuobin
24953c1712
refactor: convert all MCP tool parameter descriptions to Annotated+Field
- Replace Args: docstring blocks with Annotated[str, Field(description=...)]
  so parameter descriptions appear in inputSchema.properties.*.description
- mcp.server.fastmcp does not parse Args: blocks from docstrings;
  only Annotated with pydantic Field injects descriptions into the
  structured JSON Schema visible to AI clients via tools/list
- Remove redundant Args: blocks from docstrings (info moved to Field)
- Restore full 4-step websocat workflow in get_node_console_info docstring
  with connection, command sending, response receiving, and timeout
2026-06-05 14:02:58 +08:00
YueGuobin
4c44a32db7
docs: update get_node_console_info description with websocat connection workflow 2026-06-05 13:17:23 +08:00
YueGuobin
a056fa3450
refactor: move all imports to top of __init__.py 2026-06-05 01:16:17 +08:00
YueGuobin
f34de4c075
fix: remove console_host/port from get_node_console_info
Return only ws_url + websocat command to avoid LLM misinterpreting
direct telnet connection.
2026-06-04 23:53:03 +08:00
YueGuobin
8775583b83
feat: add get_node_console_info tool
Returns console type, host, port and a suggested command (e.g. telnet,
vncviewer) for connecting to a node's console. Total: 30 tools.
2026-06-04 23:45:34 +08:00
YueGuobin
e416ef8d5e
feat: add 3 Compute MCP tools
- Add list_computes, get_compute, get_compute_images
- Total MCP tools: 29
2026-06-04 23:22:14 +08:00
YueGuobin
6889f51737
feat: add 5 Template MCP tools
Add list_templates, get_template, create_template, update_template,
delete_template. Total MCP tools: 26.
2026-06-04 23:21:01 +08:00
YueGuobin
cad216705a
feat: add Node and Link MCP tools, update copyright
- Add 9 node tools and 5 link tools
- Update copyright year to 2026, add author
2026-06-04 23:19:00 +08:00
YueGuobin
1e9b3d5879
feat: complete MCP SSE transport with JWT auth
- SSE endpoint at /v3/mcp/transport/sse with token auth
- Supports Authorization: Bearer header and ?token= query param
- JWT validated via GNS3 auth_service, stored in contextvars
- Tool handlers use GNS3 REST API via Gns3Connector with JWT token
- 7 project tools: list_projects, get_project, create_project,
  delete_project, open_project, close_project, get_project_stats
- Claude Code: claude mcp add --transport sse ... -H 'Authorization: Bearer <jwt>'
- Claude Desktop: SSE URL with ?token=<jwt>
2026-06-04 23:06:20 +08:00
YueGuobin
19e7533cd7
feat: support Authorization header and query param for MCP token
- SSE endpoint supports both Authorization: Bearer header and ?token= query param
- Claude Code can use headers (no URL exposure)
- Claude Desktop (EventSource) can use ?token= URL param
2026-06-04 22:38:49 +08:00
YueGuobin
55b3a7d622
feat: implement standard MCP protocol with SSE transport
- Use FastMCP (Anthropic MCP SDK) for tool registration and SSE transport
- Mount SSE app under /v3/mcp/transport with JWT token authentication
- Token passed via ?token=<jwt> query parameter on SSE connection
- Token validated against GNS3 auth_service and stored in contextvars
- Tool handlers create Gns3Connector with JWT token to call GNS3 REST API
- 7 project tools: list_projects, get_project, create_project, delete_project,
  open_project, close_project, get_project_stats
- Unauthenticated SSE connections return 401
2026-06-04 22:19:43 +08:00
YueGuobin
7086db4226
feat: add MCP (Model Context Protocol) service with project tools
- Add MCPTool/MCPToolRegistry system for centralized tool registration
- Add 7 project-related MCP tools: list_projects, get_project, create_project,
  delete_project, open_project, close_project, get_project_stats
- Tools use Gns3Connector (custom_gns3fy) to call GNS3 REST API via HTTP loopback,
  keeping the MCP layer decoupled from controller internals
- Handlers run in thread pool via asyncio.to_thread() to avoid blocking
  the event loop on synchronous requests calls
- Unified POST /v3/mcp/execute endpoint with JWT authentication
2026-06-04 13:53:05 +08:00
YueGuobin
8c1dbdf079
Fix ghost Docker nodes causing 60-second VNC timeout on variable updates
When a Docker node is deleted, the compute node's DELETE endpoint only calls
node.delete() which removes the working directory but does not remove the node
object from the project's self._nodes collection. This causes ghost nodes to
remain in memory.

When project variables are updated, the code iterates through ALL nodes in
memory and calls update() on them. For ghost nodes with VNC configuration, this
triggers VNC startup attempts, resulting in 60-second timeouts waiting for X11
socket files that don't exist.

The fix adds await node.project.remove_node(node) to ensure the node object is
removed from the project's node collection when deleted, matching the behavior
of other node types that use manager.delete_node() which already calls
project.remove_node().

This resolves the issue where updating project variables after deleting a VNC
Docker container would timeout with: 'x11 socket file "/tmp/.X11-unix/X100"
does not exist'

Fixes issue #2755
2026-05-30 22:15:40 +08:00
YueGuobin
2efcc619b1
perf: batch RBAC permission checking for GET /projects
Replace per-project check_user_has_privilege calls with a single
batch method that performs 3 fixed DB queries regardless of project
count. Reduces GET /projects response time for 10000 projects from
~12s to ~290ms (40x improvement).
2026-05-27 13:27:35 +08:00
YueGuobin
1eca8c5c94
fix: prevent duplicate projects when user projects are in resource pools
Fixed a bug where projects created by a user that are also in a resource pool
the user has access to would appear twice in the GET /projects response.

Changes:
- Add seen_project_ids set to track already added projects
- Check for duplicates before adding projects in Step 2 (user projects)
- Check for duplicates before adding projects in Step 3 (resource pool projects)

This ensures each project appears only once regardless of whether it's user-created
or shared via resource pool.
2026-05-27 10:47:36 +08:00
YueGuobin
9fca2181a8
feat: add independent LLMConfig permissions for AI profile management
Add new privilege definitions:
- LLMConfig.Audit - View LLM model configurations
- LLMConfig.Modify - Update LLM model configurations
- LLMConfig.Allocate - Create/delete LLM model configurations

Add LLMConfig.Audit and LLMConfig.Modify to default User role so that
regular users can manage their own AI profiles without needing the
User.Manager role.

User-scoped LLM config endpoints now use LLMConfig.* permissions.
Group-scoped LLM config endpoints retain Group.* permissions.
2026-05-26 14:24:41 +08:00
YueGuobin
f7a69bd546
feat: remove resource pools from 'all endpoints' list
Remove resource pools from the ACE endpoints list to prevent accidental
access through the 'all endpoints' option. Resource pools must be
explicitly configured for team sharing to maintain clear security
boundaries and prevent unintended exposure of shared projects.

This change aligns the UI behavior with the actual permission checking
logic where 'path: /' does not grant resource pool access.
2026-05-26 13:31:04 +08:00
YueGuobin
5e4d9e057e
refactor: add efficient get_aces_for_path method for resource pool checks
Add a new repository method get_aces_for_path() that:
- Queries ACEs for a specific path at database level (more efficient)
- Preloads related user, group, and role objects to prevent 500 errors
- Keeps original get_aces() method unchanged to avoid performance impact

This improves both performance and code clarity for resource pool
deletion safety checks.
2026-05-26 12:59:37 +08:00
YueGuobin
6fcbb8e57b
feat: prevent deletion of resource pools used by ACE configurations
Add safety check to prevent deletion of resource pools that are being
used by ACE configurations. If an attempt is made to delete a resource
pool that has ACE rules referencing it, the API returns a 400 error
with detailed information showing which users/groups are using the
pool and their roles.

The error message only shows the resource pool name for a clean,
user-friendly experience without exposing internal path details.
2026-05-26 12:54:48 +08:00
YueGuobin
ee36a9aec2
feat: fix permission check logic to properly handle ACE and user isolation
Implement the correct three-step permission check logic:
- Step 1: ACE check - basic access permission (get projects user has ACE for)
- Step 2: Filter ace_projects by created_by - user's own projects (project sharing only through resource pools)
- Step 3: Resource pool projects (projects shared through resource pools)

This fixes the design flaw where:
- ACE check could bypass user isolation with broad ACE configurations
- seen_project_ids mechanism prevented proper layered checking
- Project sharing was confused with direct ACE configuration

The new logic ensures:
- User isolation works even with broad ACE (path='/', propagate=True)
- Project sharing is only available through resource pools (clear design)
- Proper layered checking without seen blocking mechanism
2026-05-26 12:33:08 +08:00
YueGuobin
265d0ff860
feat: implement layered permission checks for proper user isolation and sharing
Implement a three-layer permission system:
- Layer 1: ACE strategy check (explicitly authorized/shared projects)
- Layer 2: Ownership check (user's own projects based on created_by)
- Layer 3: Resource pools (team shared projects)

This approach:
- Resolves the conflict between ACE and user isolation
- Enables project sharing via ACE (other users can grant access)
- Maintains default user isolation via ownership
- Prevents duplicate projects in results
- Preserves resource pool functionality
2026-05-26 00:31:19 +08:00
YueGuobin
7c0b465b74
feat: implement simple user isolation based on project ownership
Users can only see projects they created (created_by field).
Super admins see all projects.
Resource pool projects continue to work as before.
2026-05-26 00:16:45 +08:00
YueGuobin
aa6845b32b
feat: add show_filters_icon property to Link for controlling Web UI filter icon display
This commit adds a new `show_filters_icon` property to the Link class, allowing users to control whether filter icons are displayed in the Web UI at the individual link level.

**Changes:**
- Added `_show_filters_icon` attribute to Link class (default: True)
- Added `show_filters_icon` property getter
- Added `update_show_filters_icon()` method for updating the property
- Updated `asdict()` to include the new field in both topology and regular dumps
- Added `show_filters_icon` field to LinkBase schema
- Updated API routes to handle the new field in create and update operations

**API Impact:**
- POST /v3/projects/{project_id}/links - accepts `show_filters_icon` in request body
- PUT /v3/projects/{project_id}/links/{link_id} - can update `show_filters_icon`
- GET /v3/projects/{project_id}/links/{link_id} - returns `show_filters_icon` field

**Future Applications:**
This feature provides granular control for future AI fault injection modules to manage link-level protocol failures while maintaining clean UI presentation.
2026-05-23 14:57:58 +08:00
YueGuobin
868e317d24
fix: close DockerHTTPClient session to prevent UnixConnector leak in Web Wireshark
The Web Wireshark WebSocket endpoint created a WebWiresharkManager but
never called close(), leaving the DockerHTTPClient's ClientSession with
UnixConnector unclosed when users closed the browser tab.

Also switch asyncio.wait in WebSocket proxy from ALL_COMPLETED to
FIRST_COMPLETED to avoid blocking cleanup when one direction disconnects.
2026-05-18 23:59:56 +08:00
YueGuobin
a408148073
feat: require superadmin for /reload/skills endpoint
Only administrators can reload skills from the external repository.
Non-admin users receive 403 Forbidden.
2026-05-11 22:59:28 +08:00
YueGuobin
e68cc17ed5
feat: add fault injection system and external skills repository
## Summary

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

## Key Changes

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

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

### Architecture
- API unified under /copilot/ prefix
- SkillsManager moved from Controller to agent module
- Lazy initialization with startup background preload
- Per-command Git timeout, smart update checks
- Forbidden commands hot-reloadable from external repo
- 32 INFO logs downgraded to DEBUG
2026-05-11 01:24:55 +08:00
YueGuobin
51a4c73e21
feat: Add detailed metadata to node files listing
Enhance the node files API to include comprehensive file metadata:
- File size in bytes
- File creation time (ISO 8601 format)
- File modification time (ISO 8601 format)
- File extension

Create new NodeFile schema to support these additional fields
while keeping the existing ProjectFile schema for backward compatibility.

This provides users with better information to manage and identify
files in the Web UI.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:57:19 +08:00
YueGuobin
5b75d633aa
feat: Add API endpoint to list node files
Implement issue #2719 - Add API endpoint to list project files

- Add GET /v3/projects/{project_id}/nodes/{node_id}/files endpoint
- Add list_node_files() method to Project class
- Add security checks to prevent path traversal
- Filter out .ghost temporary files
- Return file paths with MD5 checksums
- Require Node.Audit privilege

This allows users to discover dynamically created files
such as QEMU disk images created via the disk image API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 22:52:17 +08:00
YueGuobin
952ef66a6b
fix: handle directory access for static web-ui routes
When accessing /static/web-ui without trailing slash, the request would
fail with "RuntimeError: File at path ... is not a file" because:

1. The route /static/web-ui/{file_path:path} doesn't match paths without
   trailing slash (Starlette's path regex requires the /)
2. The request falls through to StaticFiles mount, which tries to serve
   the directory as a file

This fix:
- Sets html=True on StaticFiles mount to automatically redirect directory
  URLs to trailing slash versions
- Adds os.path.isdir() check to handle empty file_path gracefully

Fixes #2680

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-03 17:21:03 +08:00
YueGuobin
517764a7ac
fix: include error details in LLM model config failure response
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-25 01:48:45 +08:00
YueGuobin
6c96e7493f
feat(web-wireshark): add method to retrieve container IP and refactor websocket endpoint
- Add `get_container_ip` method to WebWiresharkManager for retrieving container IP addresses in wireshark network
- Method uses Docker API as primary approach with container command execution as fallback
- Refactor web_wireshark_websocket endpoint to use new method instead of direct Docker queries
- Improve error handling and logging for container IP retrieval failures
2026-04-22 22:35:50 +08:00
Guobin Yue
df28036a68
fix(deps): resolve 3 security vulnerabilities (CVE-2025-71176, CVE-2026-40347, CVE-2018-25031) (#2671)
* fix(deps): upgrade pytest to 9.0.3 to fix CVE-2025-71176

CVE-2025-71176: pytest 9.0.2 and earlier versions have a local
security vulnerability due to predictable temporary directory naming.

- pytest: 8.4.2 → 9.0.3
- Python 3.10+ is now required

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

* fix(deps): upgrade python-multipart to 0.0.26 to fix CVE-2026-40347

CVE-2026-40347: python-multipart < 0.0.26 has a denial of
service vulnerability when parsing multipart data.

- python-multipart: 0.0.22 → 0.0.26

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

* fix(deps): upgrade swagger-ui to 4.1.3 to fix CVE-2018-25031

CVE-2018-25031: swagger-ui < 4.1.3 has a spoofing vulnerability
where remote attackers can display remote OpenAPI definitions
via crafted URLs.

- swagger-ui: 3.30.0 → 4.1.3
- Updated swagger-ui-bundle.js and swagger-ui.css

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

* fix(api): change FastAPI version from "v3" to "3.0.0" for Swagger UI 4.1.3 compatibility

Swagger UI 4.x enforces stricter version format validation.
The version "v3" is not accepted by the new validator.

Changed from:
- version="v3"

To:
- version="3.0.0"

This affects both controller and compute API definitions.

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

* fix(deps): upgrade swagger-ui to 5.32.4

Fixes "Unable to render this definition" error when loading OpenAPI 3.0
docs. Swagger UI 3.x had incomplete OpenAPI 3.0 support.

- swagger-ui: 3.19.1 → 5.32.4 (latest)

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 00:35:15 +08:00