Add parameter schema and defaults to ToolResource model and schemas. Implement runtime tool resolution in assistants and tools routers, ensuring proper handling of tool parameters. Update tests to validate new functionality and ensure correct integration of parameter handling in the API.
This commit is contained in:
@@ -13,7 +13,7 @@ import uuid
|
||||
from datetime import datetime
|
||||
|
||||
from ..db import get_db
|
||||
from ..models import Assistant, AssistantOpenerAudio, LLMModel, ASRModel, Voice
|
||||
from ..models import Assistant, AssistantOpenerAudio, LLMModel, ASRModel, Voice, ToolResource
|
||||
from ..schemas import (
|
||||
AssistantCreate,
|
||||
AssistantUpdate,
|
||||
@@ -22,6 +22,7 @@ from ..schemas import (
|
||||
AssistantOpenerAudioGenerateRequest,
|
||||
AssistantOpenerAudioOut,
|
||||
)
|
||||
from .tools import TOOL_REGISTRY, TOOL_CATEGORY_MAP, TOOL_PARAMETER_DEFAULTS, _ensure_tool_resource_schema
|
||||
|
||||
router = APIRouter(prefix="/assistants", tags=["Assistants"])
|
||||
|
||||
@@ -78,7 +79,75 @@ def _config_version_id(assistant: Assistant) -> str:
|
||||
return f"asst_{assistant.id}_{updated.strftime('%Y%m%d%H%M%S')}"
|
||||
|
||||
|
||||
def _normalize_runtime_tool_schema(tool_id: str, raw_schema: Any) -> Dict[str, Any]:
|
||||
schema = dict(raw_schema) if isinstance(raw_schema, dict) else {}
|
||||
if not schema:
|
||||
fallback = TOOL_REGISTRY.get(tool_id, {}).get("parameters")
|
||||
if isinstance(fallback, dict):
|
||||
schema = dict(fallback)
|
||||
schema.setdefault("type", "object")
|
||||
if not isinstance(schema.get("properties"), dict):
|
||||
schema["properties"] = {}
|
||||
required = schema.get("required")
|
||||
if required is None or not isinstance(required, list):
|
||||
schema["required"] = []
|
||||
return schema
|
||||
|
||||
|
||||
def _resolve_runtime_tools(db: Session, selected_tool_ids: List[str], warnings: List[str]) -> List[Dict[str, Any]]:
|
||||
_ensure_tool_resource_schema(db)
|
||||
ids = [str(tool_id).strip() for tool_id in selected_tool_ids if str(tool_id).strip()]
|
||||
if not ids:
|
||||
return []
|
||||
|
||||
resources = (
|
||||
db.query(ToolResource)
|
||||
.filter(ToolResource.id.in_(ids))
|
||||
.all()
|
||||
)
|
||||
by_id = {str(item.id): item for item in resources}
|
||||
|
||||
runtime_tools: List[Dict[str, Any]] = []
|
||||
for tool_id in ids:
|
||||
resource = by_id.get(tool_id)
|
||||
if resource and resource.enabled is False:
|
||||
warnings.append(f"Tool is disabled and skipped in runtime config: {tool_id}")
|
||||
continue
|
||||
|
||||
category = str(resource.category if resource else TOOL_CATEGORY_MAP.get(tool_id, "query"))
|
||||
description = (
|
||||
str(resource.description or resource.name or "").strip()
|
||||
if resource
|
||||
else str(TOOL_REGISTRY.get(tool_id, {}).get("description") or "").strip()
|
||||
)
|
||||
schema = _normalize_runtime_tool_schema(
|
||||
tool_id,
|
||||
resource.parameter_schema if resource else TOOL_REGISTRY.get(tool_id, {}).get("parameters"),
|
||||
)
|
||||
defaults_raw = resource.parameter_defaults if resource else TOOL_PARAMETER_DEFAULTS.get(tool_id)
|
||||
defaults = dict(defaults_raw) if isinstance(defaults_raw, dict) else {}
|
||||
|
||||
if not resource and tool_id not in TOOL_REGISTRY:
|
||||
warnings.append(f"Tool resource not found: {tool_id}")
|
||||
|
||||
runtime_tool: Dict[str, Any] = {
|
||||
"type": "function",
|
||||
"executor": "client" if category == "system" else "server",
|
||||
"function": {
|
||||
"name": tool_id,
|
||||
"description": description or tool_id,
|
||||
"parameters": schema,
|
||||
},
|
||||
}
|
||||
if defaults:
|
||||
runtime_tool["defaultArgs"] = defaults
|
||||
runtime_tools.append(runtime_tool)
|
||||
|
||||
return runtime_tools
|
||||
|
||||
|
||||
def _resolve_runtime_metadata(db: Session, assistant: Assistant) -> tuple[Dict[str, Any], List[str]]:
|
||||
warnings: List[str] = []
|
||||
metadata: Dict[str, Any] = {
|
||||
"systemPrompt": assistant.prompt or "",
|
||||
"firstTurnMode": assistant.first_turn_mode or "bot_first",
|
||||
@@ -90,14 +159,13 @@ def _resolve_runtime_metadata(db: Session, assistant: Assistant) -> tuple[Dict[s
|
||||
"minDurationMs": int(assistant.interruption_sensitivity or 500),
|
||||
},
|
||||
"services": {},
|
||||
"tools": assistant.tools or [],
|
||||
"tools": _resolve_runtime_tools(db, assistant.tools or [], warnings),
|
||||
"history": {
|
||||
"assistantId": assistant.id,
|
||||
"userId": int(assistant.user_id or 1),
|
||||
"source": "debug",
|
||||
},
|
||||
}
|
||||
warnings: List[str] = []
|
||||
|
||||
config_mode = str(assistant.config_mode or "platform").strip().lower()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user