mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-04-28 11:40:25 +00:00
Co-authored-by: bytecraftii <bytecraftii@users.noreply.github.com> Co-authored-by: Wendong-Fan <w3ndong.fan@gmail.com>
139 lines
5.4 KiB
Python
139 lines
5.4 KiB
Python
# ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
# ========= Copyright 2025-2026 @ Eigent.ai All Rights Reserved. =========
|
|
|
|
from fastapi import APIRouter, HTTPException
|
|
from pydantic import BaseModel, Field, field_validator
|
|
from app.component.model_validation import create_agent
|
|
from app.model.chat import PLATFORM_MAPPING
|
|
from camel.types import ModelType
|
|
from app.component.error_format import normalize_error_to_openai_format
|
|
import logging
|
|
|
|
logger = logging.getLogger("model_controller")
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
class ValidateModelRequest(BaseModel):
|
|
model_platform: str = Field("OPENAI", description="Model platform")
|
|
model_type: str = Field("GPT_4O_MINI", description="Model type")
|
|
api_key: str | None = Field(None, description="API key")
|
|
url: str | None = Field(None, description="Model URL")
|
|
model_config_dict: dict | None = Field(None, description="Model config dict")
|
|
extra_params: dict | None = Field(None, description="Extra model parameters")
|
|
|
|
@field_validator("model_platform")
|
|
@classmethod
|
|
def map_model_platform(cls, v: str) -> str:
|
|
return PLATFORM_MAPPING.get(v, v)
|
|
|
|
|
|
class ValidateModelResponse(BaseModel):
|
|
is_valid: bool = Field(..., description="Is valid")
|
|
is_tool_calls: bool = Field(..., description="Is tool call used")
|
|
error_code: str | None = Field(None, description="Error code")
|
|
error: dict | None = Field(None, description="OpenAI-style error object")
|
|
message: str = Field(..., description="Message")
|
|
|
|
|
|
@router.post("/model/validate")
|
|
async def validate_model(request: ValidateModelRequest):
|
|
"""Validate model configuration and tool call support."""
|
|
platform = request.model_platform
|
|
model_type = request.model_type
|
|
has_custom_url = request.url is not None
|
|
has_config = request.model_config_dict is not None
|
|
|
|
logger.info("Model validation started", extra={"platform": platform, "model_type": model_type, "has_url": has_custom_url, "has_config": has_config})
|
|
|
|
# API key validation
|
|
if request.api_key is not None and str(request.api_key).strip() == "":
|
|
logger.warning("Model validation failed: empty API key", extra={"platform": platform, "model_type": model_type})
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail={
|
|
"message": "Invalid key. Validation failed.",
|
|
"error_code": "invalid_api_key",
|
|
"error": {
|
|
"type": "invalid_request_error",
|
|
"param": None,
|
|
"code": "invalid_api_key",
|
|
},
|
|
}
|
|
)
|
|
|
|
try:
|
|
extra = request.extra_params or {}
|
|
|
|
logger.debug("Creating agent for validation", extra={"platform": platform, "model_type": model_type})
|
|
agent = create_agent(
|
|
platform,
|
|
model_type,
|
|
api_key=request.api_key,
|
|
url=request.url,
|
|
model_config_dict=request.model_config_dict,
|
|
**extra,
|
|
)
|
|
|
|
logger.debug("Agent created, executing test step", extra={"platform": platform, "model_type": model_type})
|
|
response = agent.step(
|
|
input_message="""
|
|
Get the content of https://www.camel-ai.org,
|
|
you must use the get_website_content tool to get the content ,
|
|
i just want to verify the get_website_content tool is working,
|
|
you must call the get_website_content tool only once.
|
|
"""
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
# Normalize error to OpenAI-style error structure
|
|
logger.error("Model validation failed", extra={"platform": platform, "model_type": model_type, "error": str(e)}, exc_info=True)
|
|
message, error_code, error_obj = normalize_error_to_openai_format(e)
|
|
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail={
|
|
"message": message,
|
|
"error_code": error_code,
|
|
"error": error_obj,
|
|
}
|
|
)
|
|
|
|
# Check validation results
|
|
is_valid = bool(response)
|
|
is_tool_calls = False
|
|
|
|
if response and hasattr(response, "info") and response.info:
|
|
tool_calls = response.info.get("tool_calls", [])
|
|
if tool_calls and len(tool_calls) > 0:
|
|
is_tool_calls = (
|
|
tool_calls[0].result
|
|
== "Tool execution completed successfully for https://www.camel-ai.org, Website Content: Welcome to CAMEL AI!"
|
|
)
|
|
|
|
result = ValidateModelResponse(
|
|
is_valid=is_valid,
|
|
is_tool_calls=is_tool_calls,
|
|
message="Validation Success"
|
|
if is_tool_calls
|
|
else "This model doesn't support tool calls. please try with another model.",
|
|
error_code=None,
|
|
error=None,
|
|
)
|
|
|
|
logger.info("Model validation completed", extra={"platform": platform, "model_type": model_type, "is_valid": is_valid, "is_tool_calls": is_tool_calls})
|
|
|
|
return result
|