Add dynamic variable support to Assistant model and related components
- Introduce dynamic variable definitions in AssistantConfig and Assistant models, allowing for flexible prompt customization. - Implement validation for dynamic variable names and types in the schema. - Update backend services and routes to handle dynamic variables in assistant configurations and runtime processing. - Enhance frontend components to support dynamic variable definitions, including a new editor for managing variables. - Add tests to ensure proper functionality and validation of dynamic variables in various scenarios.
This commit is contained in:
@@ -154,6 +154,7 @@ async def _to_out(session: AsyncSession, assistant: Assistant) -> AssistantOut:
|
||||
knowledge_retrieval_config=assistant.knowledge_retrieval_config or {},
|
||||
tool_ids=await _tool_ids(session, assistant.id),
|
||||
prompt=assistant.prompt,
|
||||
dynamic_variable_definitions=assistant.dynamic_variable_definitions or {},
|
||||
api_url=assistant.api_url,
|
||||
api_key=mask(assistant.api_key),
|
||||
app_id=assistant.app_id,
|
||||
@@ -220,6 +221,7 @@ async def duplicate_assistant(
|
||||
knowledge_base_id=source.knowledge_base_id,
|
||||
knowledge_retrieval_config=dict(source.knowledge_retrieval_config or {}),
|
||||
prompt=source.prompt,
|
||||
dynamic_variable_definitions=dict(source.dynamic_variable_definitions or {}),
|
||||
api_url=source.api_url,
|
||||
api_key=source.api_key,
|
||||
app_id=source.app_id,
|
||||
|
||||
@@ -16,6 +16,7 @@ from loguru import logger
|
||||
from models import AssistantConfig, SignalingOffer
|
||||
from services.auth import require_admin, require_admin_websocket
|
||||
from services.config_resolver import resolve_runtime_config
|
||||
from services.runtime_variables import DynamicVariableError, prepare_dynamic_config
|
||||
from starlette.websockets import WebSocketDisconnect, WebSocketState
|
||||
|
||||
from services.webrtc_ice import aiortc_ice_servers, client_ice_servers
|
||||
@@ -52,7 +53,11 @@ async def voice_signaling(websocket: WebSocket):
|
||||
{
|
||||
"type": "error",
|
||||
"payload": {
|
||||
"message": f"语音会话启动失败: {type(e).__name__}"
|
||||
"message": (
|
||||
str(e)
|
||||
if isinstance(e, DynamicVariableError)
|
||||
else f"语音会话启动失败: {type(e).__name__}"
|
||||
)
|
||||
},
|
||||
}
|
||||
)
|
||||
@@ -71,9 +76,18 @@ async def _resolve_config(offer: SignalingOffer) -> AssistantConfig:
|
||||
"""优先用 assistant_id 从 DB 解析(含真 key);否则用调试内联配置。"""
|
||||
if offer.assistant_id:
|
||||
async with SessionLocal() as session:
|
||||
return await resolve_runtime_config(session, offer.assistant_id)
|
||||
cfg = await resolve_runtime_config(session, offer.assistant_id)
|
||||
return prepare_dynamic_config(
|
||||
cfg,
|
||||
offer.dynamic_variables,
|
||||
assistant_id=offer.assistant_id,
|
||||
)
|
||||
if offer.inline_config:
|
||||
return offer.inline_config
|
||||
return prepare_dynamic_config(
|
||||
offer.inline_config,
|
||||
offer.dynamic_variables,
|
||||
assistant_id=None,
|
||||
)
|
||||
raise ValueError("offer 缺少 assistant_id 或 inline_config")
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ from loguru import logger
|
||||
from models import AssistantConfig
|
||||
from services.auth import require_admin_websocket
|
||||
from services.config_resolver import resolve_runtime_config
|
||||
from services.runtime_variables import prepare_dynamic_config
|
||||
from starlette.websockets import WebSocketDisconnect
|
||||
|
||||
# pipecat 重依赖,惰性导入(见 voice_webrtc.py 说明)
|
||||
@@ -28,12 +29,24 @@ async def _resolve_start_config(raw: str) -> tuple[AssistantConfig, str | None]:
|
||||
data = json.loads(raw)
|
||||
if data.get("assistant_id"):
|
||||
async with SessionLocal() as session:
|
||||
cfg = await resolve_runtime_config(session, data["assistant_id"])
|
||||
return (
|
||||
await resolve_runtime_config(session, data["assistant_id"]),
|
||||
prepare_dynamic_config(
|
||||
cfg,
|
||||
data.get("dynamic_variables"),
|
||||
assistant_id=data["assistant_id"],
|
||||
),
|
||||
data["assistant_id"],
|
||||
)
|
||||
if data.get("inline_config"):
|
||||
return AssistantConfig(**data["inline_config"]), None
|
||||
return (
|
||||
prepare_dynamic_config(
|
||||
AssistantConfig(**data["inline_config"]),
|
||||
data.get("dynamic_variables"),
|
||||
assistant_id=None,
|
||||
),
|
||||
None,
|
||||
)
|
||||
raise ValueError("启动参数缺少 assistant_id 或 inline_config")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user