chore: update author name and copyright headers

Updated the author name and copyright statements across the
gns3_copilot module. The name has been standardized from
"Guobin Yue" to "Yue Guobin (岳国宾)" to reflect the correct
author attribution including Chinese characters.
This commit is contained in:
YueGuobin 2026-03-09 11:46:28 +08:00
parent d7e5fe065e
commit 13a032ea2c
55 changed files with 2358 additions and 83 deletions

View File

@ -0,0 +1,50 @@
# GNS3 Copilot Design Documents License
**Copyright © 2025 Yue Guobin (岳国宾)** ([GitHub](https://github.com/yueguobin))
All design documents in this directory and its subdirectories are licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0).
## License Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: https://creativecommons.org/licenses/by-sa/4.0/
## What This Means
This is a **strong copyleft** license, similar to the GPL license used for
the GNS3 server code. It ensures that:
- Anyone can use and modify these documents
- Commercial use is permitted (training, books, etc.)
- All derivative works must remain under CC BY-SA 4.0
- The original author must be credited
## Icons
License icons are available from:
- https://creativecommons.org/downloads/
- https://chooser-beta.creativecommons.org/
## Contributing
By contributing to these design documents, you agree that your contributions
will be licensed under the same CC BY-SA 4.0 license, with copyright attributed
to you respectively for your contributions.
## Contact
For questions about licensing, please contact:
- GitHub: https://github.com/yueguobin

View File

@ -967,3 +967,32 @@ if request.max_tokens is not None:
- [LangGraph Checkpoint Documentation](https://langchain-ai.github.io/langgraph/how-tos/checkpointers/)
- [Server-Sent Events (MDN)](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events)
- [OpenAI Chat Format](https://platform.openai.com/docs/api-reference/chat)
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -431,3 +431,32 @@ If you:
- Have suggestions for improving the filtering system
Please submit an issue: https://github.com/yueguobin/gns3-copilot/issues
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -324,3 +324,32 @@ except Exception as e:
- `gns3server/agent/gns3_copilot/agent/context_manager.py` - Context management core logic
- `gns3server/agent/gns3_copilot/agent/gns3_copilot.py` - LLM call node (StateGraph)
- `gns3server/agent/gns3_copilot/agent/model_factory.py` - Model creation and tool binding
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -884,3 +884,32 @@ HTTP 400 Bad Request
"detail": "context_limit is required (unit: K tokens, e.g., 128 = 128K = 128,000 tokens). Please check your model provider's documentation for the current context window size and specify it in the configuration."
}
```
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -1204,3 +1204,32 @@ const exampleACEs = [
**Document Version**: 1.0
**Last Updated**: 2026-03-06
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -821,3 +821,32 @@ pools = {p.resource_pool_id: p for p in pools_result.scalars().all()}
**Document Version**: 1.0
**Last Updated**: 2026-03-06
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -1400,3 +1400,32 @@ If rollback is needed:
**Document Version**: v1.0
**Created Date**: 2026-03-04
**Author**: GNS3 Development Team
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -576,3 +576,32 @@ async def test_concurrent_config_operations():
| Date | Change |
|------|--------|
| 2025-03-06 | Initial document creation |
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -449,3 +449,32 @@ log.info("After fix: tool_calls=%d",
- [LangGraph Checkpointer Documentation](https://langchain-ai.github.io/langgraph/concepts/low_level/#checkpointer)
- [LangGraph State Management](https://langchain-ai.github.io/langgraph/concepts/low_level/#state)
- [GNS3-Copilot AI Chat API Design](../ai-chat-api-design.md)
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -490,3 +490,32 @@ class AdvancedAgentControls(BaseModel):
**Last Updated**: 2025-03-06
**Target Version**: TBD
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -0,0 +1,781 @@
# Runtime LLM Config Override
**Document Status**: Design Phase
**Priority**: Medium
**Created**: 2026-03-09
**Related Docs**:
- [AI Chat API Design](../ai-chat-api-design.md)
- [LLM Model Configs API](../llm-model-configs-api.md)
- [User-Selectable Group Default Config](./user-selectable-group-default-config.md)
---
## Table of Contents
- [Problem Description](#problem-description)
- [Requirements Analysis](#requirements-analysis)
- [Solution Design](#solution-design)
- [Implementation Steps](#implementation-steps)
- [Code Changes Checklist](#code-changes-checklist)
- [Testing Plan](#testing-plan)
- [Risk Assessment](#risk-assessment)
---
## Problem Description
### Current Behavior
Currently, the Chat API always uses the user's default LLM configuration from the database. Users cannot:
1. Select a different saved configuration for a specific request
2. Temporarily override certain parameters (e.g., use a different model, adjust temperature) for a single request
### User Scenarios
**Scenario 1: Quick Model Testing**
```
User has multiple configs:
- "GPT-4o" (default)
- "Claude 3.5 Sonnet"
- "Gemini Pro"
User wants to test the same prompt on Claude 3.5 without changing default
```
**Scenario 2: Temporary Parameter Adjustment**
```
User's default config:
- model: "gpt-4o"
- temperature: 0.7
User wants to try a more creative response (temperature=1.2) for this request only
```
**Scenario 3: Cost Optimization**
```
User's default config:
- model: "gpt-4o" (expensive)
User wants to use "gpt-4o-mini" for this simple request
```
### Current Limitation
**File**: `gns3server/api/routes/controller/chat.py:122`
```python
# Always gets user's default config
llm_config = await get_user_llm_config_full(str(user_id), app)
```
No way to specify alternative config or override parameters at request time.
---
## Requirements Analysis
### Functional Requirements
1. **Select Saved Configuration**
- User can specify `llm_config_id` to use a different saved config
- Must be a config owned by the user or inherited from their group
- Validation: If config_id is invalid or inaccessible, return error
2. **Override LLM Parameters**
- Support temporary override of common LLM parameters:
- `model`: Model name (e.g., "gpt-4o", "claude-3-5-sonnet-20241022")
- `temperature`: Sampling temperature (0.0-2.0)
- `max_tokens`: Maximum tokens to generate
- `top_p`: Nucleus sampling parameter
- (Additional provider-specific parameters as needed)
- Overrides apply only to the current request
- Original config in database is NOT modified
3. **Parameter Precedence**
```
Request Overrides > Database Config > Provider Defaults
```
4. **Backward Compatibility**
- All new parameters are optional
- Existing requests without new parameters work unchanged
### Non-Functional Requirements
1. **Security**
- API key from selected config remains secure
- Users can only select their accessible configs
- Overrides are logged for audit
2. **Performance**
- Minimal overhead for config retrieval and validation
- No database write for temporary overrides
3. **Maintainability**
- Clear code structure for override logic
- Easy to add new overridable parameters in the future
---
## Solution Design
### API Schema Changes
**File**: `gns3server/schemas/controller/chat.py`
```python
class LLMConfigOverride(BaseModel):
"""Temporary LLM configuration overrides for a single request."""
model: Optional[str] = Field(
None,
description="Override the model name (e.g., 'gpt-4o', 'claude-3-5-sonnet-20241022'). "
"Provider and API key still come from the selected or default config."
)
temperature: Optional[float] = Field(
None,
ge=0.0,
le=2.0,
description="Override sampling temperature (0.0-2.0). "
"Lower values make output more deterministic, higher values more random."
)
max_tokens: Optional[int] = Field(
None,
ge=1,
description="Override maximum tokens to generate in the response."
)
top_p: Optional[float] = Field(
None,
ge=0.0,
le=1.0,
description="Override nucleus sampling parameter (0.0-1.0)."
)
class ChatRequest(BaseModel):
"""Chat request model."""
message: str = Field(..., description="User message content")
session_id: Optional[str] = Field(None, description="Session ID (auto-generated if not provided)")
stream: bool = Field(default=True, description="Enable streaming response")
# NEW: LLM Configuration Selection
llm_config_id: Optional[str] = Field(
None,
description="LLM configuration ID to use for this request. "
"Must be a config owned by the user or inherited from their group. "
"If not provided, uses the user's default LLM config."
)
# NEW: Runtime Parameter Overrides
llm_config_override: Optional[LLMConfigOverride] = Field(
None,
description="Temporary overrides for LLM parameters. "
"These overrides apply only to this request and do not modify the stored config. "
"Overrides take precedence over the selected/default config values."
)
mode: Literal["text"] = Field(default="text", description="Interaction mode")
```
### Configuration Resolution Flow
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 1. API Layer (chat.py) │
│ POST /v3/projects/{project_id}/chat/stream │
│ ChatRequest { │
│ message, │
│ llm_config_id?, # Select config │
│ llm_config_override?: { # Override params │
│ model?, temperature?, max_tokens?, top_p? │
│ } │
│ } │
└────────────────────────────┬────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ 2. Config Resolution (get_llm_config_for_request) │
│ │
│ if llm_config_id provided: │
│ → Get specific config by ID │
│ → Validate: user must have access (own or inherited group) │
│ → If invalid: return 403 Forbidden │
│ else: │
│ → Get user's default config (current behavior) │
│ │
│ Decrypt API key from resolved config │
│ Apply llm_config_override (if provided) │
│ → Override fields: model, temperature, max_tokens, top_p │
│ │
│ Result: { │
│ provider, api_key, model*, temperature*, max_tokens*, top_p*, ... │
│ } │
│ (* = overridden if provided) │
└────────────────────────────┬────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ 3. Agent Execution (agent_service.py) │
│ Set ContextVars with resolved and overridden config │
│ Proceed with normal Agent flow │
└─────────────────────────────────────────────────────────────────────────┘
```
### Implementation Details
#### File: `gns3server/db/tasks.py`
Add new function `get_llm_config_for_request`:
```python
async def get_llm_config_for_request(
user_id: str,
app: FastAPI,
config_id: Optional[str] = None,
overrides: Optional[dict] = None
) -> Optional[dict]:
"""
Get LLM configuration for a specific request with optional overrides.
Args:
user_id: User UUID
app: FastAPI application instance
config_id: Optional specific config ID to use
overrides: Optional dict of parameter overrides (model, temperature, etc.)
Returns:
Dictionary with LLM configuration (with overrides applied) or None if not found.
Raises:
ValueError: If config_id is specified but not accessible to user
"""
from uuid import UUID
from gns3server.db.repositories.llm_model_configs import LLMModelConfigsRepository
from gns3server.utils.encryption import decrypt, is_encrypted
try:
user_uuid = UUID(user_id) if isinstance(user_id, str) else user_id
async with AsyncSession(app.state._db_engine, expire_on_commit=False) as session:
repo = LLMModelConfigsRepository(session)
# Step 1: Resolve base config
if config_id:
# User specified a config - validate access
config_uuid = UUID(config_id) if isinstance(config_id, str) else config_id
# Get all accessible configs for user
effective = await repo.get_user_effective_configs(
user_uuid,
current_user_id=user_uuid,
current_user_is_superadmin=False
)
accessible_config_ids = {c["config_id"] for c in effective["configs"]}
if config_uuid not in accessible_config_ids:
log.warning(
f"User {user_id} attempted to use inaccessible config {config_id}"
)
raise ValueError(f"Config {config_id} is not accessible to user")
# Get the config (bypass API key hiding since this is system-level)
config_record = await repo.get_user_config(config_uuid)
if not config_record:
log.error(f"Config {config_id} not found in database")
return None
source = "user_selected"
else:
# Use user's default config
result = await repo.get_user_effective_configs(
user_uuid,
current_user_id=user_uuid,
current_user_is_superadmin=False
)
if not result or not result.get("default_config"):
log.warning(f"No default LLM configuration found for user {user_id}")
return None
default_config = result["default_config"]
config_id_str = default_config["config_id"]
config_record = await repo.get_user_config(UUID(config_id_str))
if not config_record:
log.error(f"Default config {config_id_str} not found in database")
return None
source = "default"
# Step 2: Decrypt API key
config_data = config_record.config.copy()
inherited_from_config_id = config_record.inherited_from_config_id
# Handle shadow configs - get API key from parent
if inherited_from_config_id:
parent_config = await repo.get_group_config(inherited_from_config_id)
if parent_config and "api_key" in parent_config.config:
try:
encrypted_key = parent_config.config["api_key"]
if encrypted_key and is_encrypted(encrypted_key):
config_data["api_key"] = decrypt(encrypted_key)
else:
config_data["api_key"] = encrypted_key
except Exception as e:
log.error(f"Failed to decrypt inherited API key: {e}")
return None
else:
# Regular config - decrypt directly
if "api_key" in config_data and config_data["api_key"]:
try:
if is_encrypted(config_data["api_key"]):
config_data["api_key"] = decrypt(config_data["api_key"])
except Exception as e:
log.error(f"Failed to decrypt API key: {e}")
return None
# Step 3: Apply overrides
if overrides:
if overrides.get("model"):
config_data["model"] = overrides["model"]
log.info(f"Model override applied: {overrides['model']}")
if overrides.get("temperature") is not None:
config_data["temperature"] = overrides["temperature"]
log.info(f"Temperature override applied: {overrides['temperature']}")
if overrides.get("max_tokens") is not None:
config_data["max_tokens"] = overrides["max_tokens"]
log.info(f"Max tokens override applied: {overrides['max_tokens']}")
if overrides.get("top_p") is not None:
config_data["top_p"] = overrides["top_p"]
log.info(f"Top-p override applied: {overrides['top_p']}")
# Step 4: Build final config dict
llm_config = {
"config_id": str(config_record.config_id),
"name": config_record.name,
"model_type": str(config_record.model_type),
"source": source,
"user_id": str(config_record.user_id) if config_record.user_id else None,
"group_id": str(config_record.group_id) if config_record.group_id else None,
"inherited_from": str(inherited_from_config_id) if inherited_from_config_id else None,
**config_data
}
# Validate required fields
if not llm_config.get("provider"):
log.error(f"LLM config missing 'provider' field: {config_record.config_id}")
return None
if not llm_config.get("model"):
log.error(f"LLM config missing 'model' field: {config_record.config_id}")
return None
if not llm_config.get("api_key"):
log.error(f"LLM config missing 'api_key' field: {config_record.config_id}")
return None
log.info(
f"Retrieved LLM config for user {user_id}: "
f"provider={llm_config.get('provider')}, model={llm_config.get('model')}, "
f"source={source}, overrides_applied={bool(overrides)}"
)
return llm_config
except ValueError:
raise # Re-raise validation errors
except Exception as e:
log.error(f"Failed to retrieve LLM config for user {user_id}: {e}", exc_info=True)
return None
```
#### File: `gns3server/api/routes/controller/chat.py`
Modify the stream endpoint to use new function:
```python
@router.post("/stream", response_model=SkipValidation[ChatResponse])
async def stream_chat(
project_id: str,
request: ChatRequest,
current_user: schemas.User = Depends(get_current_active_user),
):
"""Stream chat responses from the GNS3 Copilot Agent."""
# ... existing project validation code ...
# NEW: Resolve LLM config with overrides
overrides = None
if request.llm_config_override:
overrides = request.llm_config_override.model_dump(exclude_none=True)
try:
llm_config = await get_llm_config_for_request(
user_id=str(current_user.user_id),
app=app,
config_id=request.llm_config_id,
overrides=overrides
)
except ValueError as e:
raise HTTPException(
status_code=403,
detail=str(e)
)
if not llm_config:
raise HTTPException(
status_code=400,
detail="LLM configuration not found or not accessible. Please configure an LLM model first."
)
# ... rest of existing code with llm_config ...
# Set ContextVars
set_current_jwt_token(jwt_token)
set_current_llm_config(llm_config)
# ... continue with Agent flow ...
```
---
## Implementation Steps
| Step | Task | File(s) | Difficulty | Priority |
|------|------|---------|------------|----------|
| 1 | Add `LLMConfigOverride` schema | `schemas/controller/chat.py` | ⭐ Low | P0 |
| 2 | Add `llm_config_id` and `llm_config_override` to `ChatRequest` | `schemas/controller/chat.py` | ⭐ Low | P0 |
| 3 | Implement `get_llm_config_for_request` function | `db/tasks.py` | ⭐⭐ Medium | P0 |
| 4 | Modify `stream_chat` endpoint to use new function | `api/routes/controller/chat.py` | ⭐ Low | P0 |
| 5 | Update API documentation | `docs/gns3-copilot/ai-chat-api-design.md` | ⭐ Low | P1 |
| 6 | Add unit tests for config resolution logic | `tests/` | ⭐⭐ Medium | P1 |
| 7 | Add integration tests for override scenarios | `tests/` | ⭐⭐ Medium | P2 |
---
## Usage Examples
### Example 1: Select Different Config
```bash
# Use a specific saved config instead of default
curl -X POST http://localhost:3080/v3/projects/{project_id}/chat/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Explain OSPF configuration",
"llm_config_id": "123e4567-e89b-12d3-a456-426614174000"
}'
```
### Example 2: Override Model Only
```bash
# Use default config but with a different model
curl -X POST http://localhost:3080/v3/projects/{project_id}/chat/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Configure OSPF on all routers",
"llm_config_override": {
"model": "gpt-4o-mini"
}
}'
```
### Example 3: Override Temperature
```bash
# Use default config but with higher temperature for creativity
curl -X POST http://localhost:3080/v3/projects/{project_id}/chat/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Write a creative network scenario",
"llm_config_override": {
"temperature": 1.2,
"top_p": 0.95
}
}'
```
### Example 4: Select Config + Override Parameters
```bash
# Use specific config and override multiple parameters
curl -X POST http://localhost:3080/v3/projects/{project_id}/chat/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Analyze network topology",
"llm_config_id": "123e4567-e89b-12d3-a456-426614174000",
"llm_config_override": {
"model": "claude-3-5-sonnet-20241022",
"temperature": 0.3,
"max_tokens": 4096
}
}'
```
### Example 5: Error Case - Inaccessible Config
```bash
# Attempting to use another user's config returns 403
curl -X POST http://localhost:3080/v3/projects/{project_id}/chat/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Test",
"llm_config_id": "00000000-0000-0000-0000-000000000000"
}'
# Response:
# {
# "detail": "Config 00000000-0000-0000-0000-000000000000 is not accessible to user"
# }
```
---
## Code Changes Checklist
### Files to Modify
| File Path | Change Type | Description |
|-----------|-------------|-------------|
| `gns3server/schemas/controller/chat.py` | Modify | Add `LLMConfigOverride` model and new fields to `ChatRequest` |
| `gns3server/db/tasks.py` | Add | Add `get_llm_config_for_request` function |
| `gns3server/api/routes/controller/chat.py` | Modify | Use `get_llm_config_for_request` with error handling |
| `docs/gns3-copilot/ai-chat-api-design.md` | Modify | Update API documentation with new parameters |
### New Files
| File Path | Description |
|-----------|-------------|
| N/A | No new files (all changes are modifications) |
---
## Testing Plan
### Unit Tests
#### 1. Test `get_llm_config_for_request`
- **Test 1.1**: Use default config (no config_id)
- Input: `config_id=None, overrides=None`
- Expected: Returns user's default config
- **Test 1.2**: Use specific user config
- Input: Valid `config_id` owned by user
- Expected: Returns specified config
- **Test 1.3**: Use inherited group config
- Input: Valid `config_id` from user's group
- Expected: Returns specified config with API key from parent
- **Test 1.4**: Use inaccessible config
- Input: `config_id` from another user
- Expected: Raises `ValueError`
- **Test 1.5**: Apply model override
- Input: `overrides={"model": "gpt-4o-mini"}`
- Expected: Returns config with `model="gpt-4o-mini"`
- **Test 1.6**: Apply temperature override
- Input: `overrides={"temperature": 1.5}`
- Expected: Returns config with `temperature=1.5`
- **Test 1.7**: Apply multiple overrides
- Input: `overrides={"model": "x", "temperature": 0.5, "max_tokens": 1000}`
- Expected: Returns config with all overrides applied
- **Test 1.8**: Invalid config_id
- Input: Non-existent `config_id`
- Expected: Returns `None`
### Integration Tests
#### 1. API Endpoint Tests
- **Test 1.1**: Request without new parameters (backward compatibility)
- Expected: Works exactly as before
- **Test 1.2**: Request with `llm_config_id` only
- Expected: Uses specified config
- **Test 1.3**: Request with `llm_config_override` only
- Expected: Uses default config with overrides
- **Test 1.4**: Request with both `llm_config_id` and `llm_config_override`
- Expected: Uses specified config with overrides
- **Test 1.5**: Request with inaccessible `llm_config_id`
- Expected: Returns 403 Forbidden
- **Test 1.6**: Override validation (temperature out of range)
- Input: `temperature=3.0` (exceeds max 2.0)
- Expected: Returns 422 Validation Error
#### 2. Agent Integration Tests
- **Test 2.1**: Agent uses overridden config correctly
- Verify LLM is called with overridden parameters
- **Test 2.2**: Multiple concurrent requests with different configs
- Verify no cross-contamination between requests
---
## Risk Assessment
### Technical Risks
| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| Config retrieval performance degradation | Medium | Low | Cache frequently used configs, optimize queries |
| Override validation bypass | High | Low | Pydantic validation for all override fields |
| API key leakage in logs | High | Low | Ensure API key is never logged, use [REDACTED] |
| Incorrect config precedence | Medium | Low | Clear documentation and thorough testing |
### Security Risks
| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| User accessing another user's config | High | Low | Validate config accessibility before use |
| Privilege escalation via config_id | High | Low | Strict access control validation |
| API key exposure via override | Low | Low | API key cannot be overridden (not in schema) |
### Compatibility Risks
| Risk | Impact | Probability | Mitigation |
|------|--------|-------------|------------|
| Existing clients break | High | Low | All new fields are optional, default behavior unchanged |
| UI doesn't support new fields | Low | Medium | UI can ignore new fields, phased rollout |
---
## Security Considerations
### Access Control
1. **Config Access Validation**
- User can only specify configs they own or inherited from their group
- Validation happens before API key decryption
- 403 Forbidden error for inaccessible configs
2. **Immutable Fields**
- `api_key` cannot be overridden (not in `LLMConfigOverride`)
- `provider` cannot be overridden (requires different API key handling)
- Only safe parameters can be overridden
3. **Audit Logging**
- Log all override operations with user_id, config_id, and override values
- Do not log API keys (use [REDACTED] placeholder)
### Parameter Validation
| Parameter | Validation | Rationale |
|-----------|------------|-----------|
| `llm_config_id` | Must be valid UUID, accessible to user | Prevent injection attacks |
| `model` | String, max length 255 | Prevent oversized strings |
| `temperature` | 0.0 ≤ value ≤ 2.0 | LLM API limits |
| `max_tokens` | ≥ 1 | Prevent negative/zero values |
| `top_p` | 0.0 ≤ value ≤ 1.0 | LLM API limits |
---
## Future Enhancements
### Phase 2 Features
1. **Additional Override Parameters**
- `frequency_penalty`: Token frequency penalty
- `presence_penalty`: Token presence penalty
- `stop`: Stop sequences
- Provider-specific parameters (e.g., OpenAI functions)
2. **Config Templates**
- Predefined override templates (e.g., "creative", "precise", "fast")
- Users can save and reuse override combinations
3. **Usage Statistics**
- Track which configs are most commonly used
- Track which overrides are most commonly applied
- Provide insights for default config optimization
4. **Config Recommendations**
- Suggest optimal config based on request content
- Auto-select cost-effective config for simple queries
---
## Related Features
- [User-Selectable Group Default Config](./user-selectable-group-default-config.md) - Setting default config
- [Runtime Agent Parameters](./runtime-agent-params.md) - Controlling Agent execution behavior
- [LLM Model Configs API](../llm-model-configs-api.md) - Managing saved configurations
---
## References
- [AI Chat API Design](../ai-chat-api-design.md)
- [Pydantic Field Validation](https://docs.pydantic.dev/latest/concepts/fields/)
- FastAPI Request Handling: https://fastapi.tiangolo.com/tutorial/body/
---
## Discussion Points
### Open Questions
1. **Should we allow `provider` override?**
- Pro: More flexibility (e.g., switch from OpenAI to Anthropic)
- Con: Requires different API key handling, more complex
- **Recommendation**: No - keep it simple for now
2. **Should overrides be visible in response metadata?**
- Pro: User knows which config/overrides were used
- Con: Increases response size
- **Recommendation**: Add to session metadata, not SSE messages
3. **Should we support parameter shortcuts?**
- Example: `"mode": "fast"` instead of specifying all parameters
- **Recommendation**: Future enhancement via templates
---
**Document Version**: 1.0
**Last Updated**: 2026-03-09
**Target Version**: TBD
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -238,3 +238,32 @@ async def stream_chat(request_id: str, ...):
2. [ ] Add client disconnect detection in yield loop
3. [ ] Document frontend handling for incomplete messages
4. [ ] Test reconnection scenario with tool_call interruption
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -213,3 +213,32 @@ When the format changes, update the `metadata.version` field, and the frontend a
- Implementation: `gns3server/agent/gns3_copilot/utils/parse_tool_content.py`
- Message conversion: `gns3server/agent/gns3_copilot/utils/message_converters.py`
- Tool examples: `gns3server/agent/gns3_copilot/tools_v2/`
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -928,3 +928,32 @@ Add `inherited_from` field description in response schema section:
**Document Version**: 1.0
**Last Updated**: 2026-03-06
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

File diff suppressed because it is too large Load Diff

View File

@ -149,3 +149,32 @@ class Base:
- Backend: `gns3server/api/server.py`
- Backend: `gns3server/db/models/base.py`
- Schemas: `gns3server/schemas/controller/base.py`
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -148,3 +148,32 @@ gns3server
- [ ] Add process health check mechanism
- [ ] Implement more robust port and ID reuse logic
- [ ] Add residual process detection and warnings
---
## License
**Copyright © 2025 Yue Guobin (岳国宾)**
This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0
International License (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/).
![CC BY-SA 4.0](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)
### Summary
You are free to:
- **Share** — Copy and redistribute the material in any medium or format
- **Adapt** — Remix, transform, and build upon the material for any purpose
Under the following terms:
- **Attribution** — You must give appropriate credit to **Yue Guobin (岳国宾)**, provide
a link to the license, and indicate if changes were made.
- **ShareAlike** — If you remix, transform, or build upon the material, you must
distribute your contributions under the **same license** (CC BY-SA 4.0).
Full license text: [DESIGN_DOCS_LICENSE](../DESIGN_DOCS_LICENSE.md)

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -39,6 +39,6 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -41,7 +41,7 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -2,8 +2,8 @@
#
# GNS3-Copilot - AI-powered Network Lab Assistant for GNS3
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# This file is part of GNS3-Copilot project.
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -73,7 +73,7 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -48,7 +48,7 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -45,7 +45,7 @@ Main modules:
Note: GNS3TopologyTool is now available from gns3_client package
Author: Guobin Yue
Author: Yue Guobin (岳国宾)
"""
# Import main tool classes
@ -67,7 +67,7 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -33,7 +33,7 @@ Main modules:
- get_gns3_device_port: Device port information retrieval from GNS3 topology
- parse_tool_content: Tool execution result parsing and formatting utilities
Author: Guobin Yue
Author: Yue Guobin (岳国宾)
"""
# Import main utility functions
@ -50,7 +50,7 @@ try:
except Exception:
__version__ = "unknown"
__author__ = "Guobin Yue"
__author__ = "Yue Guobin (岳国宾)"
__description__ = "AI-powered network automation assistant for GNS3"
__url__ = "https://github.com/yueguobin/gns3-copilot"

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#

View File

@ -2,8 +2,8 @@
#
# GNS3-Copilot - AI-powered Network Lab Assistant for GNS3
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# This file is part of GNS3-Copilot project.
#

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#
@ -60,7 +60,7 @@ Standard Tool Response Format:
"error": str # Error message (if failed)
}
Author: Guobin Yue
Author: Yue Guobin (岳国宾)
"""
import ast

View File

@ -17,8 +17,8 @@
# You should have received a copy of the GNU General Public License
# along with GNS3-Copilot. If not, see <https://www.gnu.org/licenses/>.
#
# Copyright (C) 2025 Guobin Yue
# Author: Guobin Yue
# Copyright (C) 2025 Yue Guobin (岳国宾)
# Author: Yue Guobin (岳国宾)
#
# Project Home: https://github.com/yueguobin/gns3-copilot
#