mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
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:
parent
d7e5fe065e
commit
13a032ea2c
50
docs/gns3-copilot/DESIGN_DOCS_LICENSE.md
Normal file
50
docs/gns3-copilot/DESIGN_DOCS_LICENSE.md
Normal 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
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
781
docs/gns3-copilot/todo/runtime-llm-config-override.md
Normal file
781
docs/gns3-copilot/todo/runtime-llm-config-override.md
Normal 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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
1009
docs/gns3-copilot/todo/vision-topology-creation.md
Normal file
1009
docs/gns3-copilot/todo/vision-topology-creation.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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/).
|
||||
|
||||

|
||||
|
||||
### 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)
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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.
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
@ -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.
|
||||
#
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
#
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user