feat(agent): refactor LLM configuration to support new llm_model_configs system

- Remove direct logging of LLM config from gns3_copilot.py
- Update model_factory to accept configuration from llm_model_configs dictionary
- Add fallback to environment variables for backward compatibility
- Centralize configuration loading in _load_llm_config function
This commit is contained in:
YueGuobin committed 2026-03-03 23:26:20 +08:00
1 parent 3c54a7d90a
commit 4857cff59c
10 files changed
+77 -305

No files matched your search

@@ -63,23 +63,12 @@ from gns3_copilot.tools_v2 import (
LinuxTelnetBatchTool,
VPCSMultiCommands,
)
from gns3_copilot.utils import get_config
# Set up logger for FlowNet-Lab
logger = logging.getLogger(__name__)
# Log loaded LLM model information
model_name = get_config("MODEL_NAME")
model_provider = get_config("MODE_PROVIDER")
base_url = get_config("BASE_URL", "")
temperature = get_config("TEMPERATURE", "0")
logger.info(
"LLM model configuration: name=%s, provider=%s, base_url=%s, temperature=%s",
model_name,
model_provider,
base_url,
temperature,
)
# Note: LLM model configuration is now managed by the new llm_model_configs system.
# The model_factory module handles model creation with configuration from the database.
# Define the available tools for the agent
tools = [
@@ -1,35 +1,50 @@
"""
Model Factory for FlowNet-Lab Agent
This module provides factory functions to create fresh LLM model instances
on-demand from SQLite configuration. This allows configuration changes
to take effect without restarting the application.
This module provides factory functions to create fresh LLM model instances.
Configuration can be loaded from:
1. Passed llm_config dictionary (from new llm_model_configs system)
2. Environment variables (fallback for backward compatibility)
"""
import logging
from typing import Any
import os
from typing import Any, Optional
from langchain.chat_models import init_chat_model
from gns3_copilot.utils import get_config
logger = logging.getLogger(__name__)
def _load_env_variables() -> dict[str, str]:
def _load_llm_config(llm_config: Optional[dict[str, Any]] = None) -> dict[str, str]:
"""
Load model configuration from SQLite database.
Load model configuration from llm_config dict or environment variables.
Args:
llm_config: Optional configuration dictionary from llm_model_configs system.
If not provided, will load from environment variables.
Returns:
Dictionary containing model configuration.
"""
return {
"model_name": get_config("MODEL_NAME", ""),
"model_provider": get_config("MODE_PROVIDER", ""),
"api_key": get_config("MODEL_API_KEY", ""),
"base_url": get_config("BASE_URL", ""),
"temperature": get_config("TEMPERATURE", "0"),
}
if llm_config:
# Use provided configuration (from llm_model_configs system)
return {
"model_name": llm_config.get("model", ""),
"model_provider": llm_config.get("provider", ""),
"api_key": llm_config.get("api_key", ""),
"base_url": llm_config.get("base_url", ""),
"temperature": str(llm_config.get("temperature", "0")),
}
else:
# Fallback to environment variables
return {
"model_name": os.getenv("MODEL_NAME", ""),
"model_provider": os.getenv("MODE_PROVIDER", ""),
"api_key": os.getenv("MODEL_API_KEY", ""),
"base_url": os.getenv("BASE_URL", ""),
"temperature": os.getenv("TEMPERATURE", "0"),
}
def create_base_model() -> Any:
@@ -46,7 +61,7 @@ def create_base_model() -> Any:
Raises:
ValueError: If required environment variables are missing or invalid.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
# Log the loaded configuration (mask sensitive data)
logger.info(
@@ -98,7 +113,7 @@ def create_title_model() -> Any:
Raises:
ValueError: If required environment variables are missing or invalid.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating title model: name=%s, provider=%s, base_url=%s, temperature=1.0",
@@ -174,7 +189,7 @@ def create_note_organizer_model() -> Any:
Raises:
ValueError: If required environment variables are missing or invalid.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating note organizer model: name=%s, provider=%s, base_url=%s, temperature=0.3",
@@ -245,7 +260,7 @@ def create_window_agent_base_model() -> Any:
ValueError: If required environment variables are missing.
RuntimeError: If model creation fails.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating Window Agent base model: name=%s, provider=%s, base_url=%s, temperature=0",
@@ -298,7 +313,7 @@ def create_window_agent_model_with_tools(tools: list[Any]) -> Any:
ValueError: If required environment variables are missing.
RuntimeError: If model creation or tool binding fails.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating Window Agent model: name=%s, provider=%s, base_url=%s, temperature=0",
@@ -351,7 +366,7 @@ def create_experiment_planner_model() -> Any:
Raises:
ValueError: If required environment variables are missing or invalid.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating experiment planner model: name=%s, provider=%s, base_url=%s, temperature=0.7",
@@ -428,7 +443,7 @@ def create_presentation_eval_model() -> Any:
ValueError: If required environment variables are missing.
RuntimeError: If model creation fails.
"""
env_vars = _load_env_variables()
env_vars = _load_llm_config()
logger.info(
"Creating presentation evaluator model: name=%s, provider=%s, base_url=%s, temperature=0.5",
@@ -7,6 +7,7 @@ through DashScope SDK to identify network topology diagrams from images.
import base64
import json
import os
from typing import Any, Dict, Optional
from pathlib import Path
@@ -17,8 +18,6 @@ except ImportError:
import logging
from gns3_copilot.utils import get_config
logger = logging.getLogger(__name__)
@@ -161,13 +160,13 @@ class QwenVisionModel:
"Please install it: pip install dashscope"
)
# Load API key from config if not provided
# Load API key from environment variable if not provided
if api_key is None:
api_key = get_config("QWEN_API_KEY", "")
api_key = os.getenv("QWEN_API_KEY", "")
if not api_key:
raise ValueError(
"Qwen API key is required. Please set QWEN_API_KEY in configuration "
"Qwen API key is required. Please set QWEN_API_KEY environment variable "
"or pass it to the constructor."
)
@@ -389,19 +388,19 @@ def create_qwen_vision_model(
"""
Factory function to create a Qwen-VL vision model instance.
This function loads configuration from the database and creates
This function loads configuration from environment variables and creates
a QwenVisionModel instance with appropriate settings.
Args:
api_key: DashScope API key (if None, will load from config)
model_name: Model name to use (if None, will load from config, default: qwen3-vl-plus)
api_key: DashScope API key (if None, will load from QWEN_API_KEY env var)
model_name: Model name to use (if None, will load from QWEN_MODEL_NAME env var, default: qwen3-vl-plus)
Returns:
QwenVisionModel instance
Raises:
ImportError: If dashscope is not installed
ValueError: If API key is not provided or found in config
ValueError: If API key is not provided or found in environment
Example:
>>> model = create_qwen_vision_model()
@@ -409,8 +408,8 @@ def create_qwen_vision_model(
>>> print(topology["topology_name"])
>>> print(f"Found {len(topology['devices'])} devices")
"""
# Load model name from config if not provided
# Load model name from environment variable if not provided
if model_name is None:
model_name = get_config("QWEN_MODEL_NAME", "qwen3-vl-plus")
model_name = os.getenv("QWEN_MODEL_NAME", "qwen3-vl-plus")
return QwenVisionModel(api_key=api_key, model_name=model_name)