fix: isolate startup tools and preview dialogs
This commit is contained in:
@@ -90,20 +90,54 @@ def _secret(resource: ModelResource | None, key: str, default: str = "") -> str:
|
||||
return str((resource.secrets or {}).get(key) or default)
|
||||
|
||||
|
||||
async def _tools_for(session: AsyncSession, assistant: Assistant) -> list[RuntimeTool]:
|
||||
if assistant.type not in {"prompt", "workflow"}:
|
||||
return []
|
||||
tools = (
|
||||
async def _bound_tool_ids(session: AsyncSession, assistant_id: str) -> list[str]:
|
||||
rows = (
|
||||
await session.execute(
|
||||
select(Tool)
|
||||
.join(AssistantToolBinding, AssistantToolBinding.tool_id == Tool.id)
|
||||
.where(
|
||||
AssistantToolBinding.assistant_id == assistant.id,
|
||||
Tool.status == "active",
|
||||
)
|
||||
.order_by(AssistantToolBinding.created_at, Tool.id)
|
||||
select(AssistantToolBinding.tool_id)
|
||||
.where(AssistantToolBinding.assistant_id == assistant_id)
|
||||
.order_by(AssistantToolBinding.created_at, AssistantToolBinding.tool_id)
|
||||
)
|
||||
).scalars().all()
|
||||
return [str(tool_id) for tool_id in rows]
|
||||
|
||||
|
||||
def _startup_tool_ids(startup: dict | None) -> list[str]:
|
||||
"""Return lifecycle-only tool references in configured execution order."""
|
||||
|
||||
result: list[str] = []
|
||||
for action in (startup or {}).get("actions") or []:
|
||||
if not isinstance(action, dict):
|
||||
continue
|
||||
tool_id = str(action.get("tool_id") or action.get("toolId") or "").strip()
|
||||
if tool_id and tool_id not in result:
|
||||
result.append(tool_id)
|
||||
return result
|
||||
|
||||
|
||||
def _runtime_tool_ids(llm_tool_ids: list[str], startup: dict | None) -> list[str]:
|
||||
"""Merge both tool scopes without changing either scope's meaning."""
|
||||
|
||||
return list(dict.fromkeys([*llm_tool_ids, *_startup_tool_ids(startup)]))
|
||||
|
||||
|
||||
async def _tools_for(
|
||||
session: AsyncSession,
|
||||
assistant: Assistant,
|
||||
tool_ids: list[str],
|
||||
) -> list[RuntimeTool]:
|
||||
if assistant.type not in {"prompt", "workflow"} or not tool_ids:
|
||||
return []
|
||||
rows = (
|
||||
await session.execute(
|
||||
select(Tool)
|
||||
.where(
|
||||
Tool.id.in_(tool_ids),
|
||||
Tool.status == "active",
|
||||
)
|
||||
)
|
||||
).scalars().all()
|
||||
tool_by_id = {tool.id: tool for tool in rows}
|
||||
tools = [tool_by_id[tool_id] for tool_id in tool_ids if tool_id in tool_by_id]
|
||||
server_ids = {
|
||||
str(tool.mcp_server_id)
|
||||
for tool in tools
|
||||
@@ -217,6 +251,10 @@ async def resolve_runtime_config(
|
||||
if kb.status == "active"
|
||||
}
|
||||
|
||||
llm_tool_ids = await _bound_tool_ids(session, assistant.id)
|
||||
runtime_tool_ids = _runtime_tool_ids(llm_tool_ids, assistant.startup or {})
|
||||
runtime_tools = await _tools_for(session, assistant, runtime_tool_ids)
|
||||
|
||||
return AssistantConfig(
|
||||
name=assistant.name,
|
||||
type=assistant.type,
|
||||
@@ -228,7 +266,8 @@ async def resolve_runtime_config(
|
||||
enableInterrupt=assistant.enable_interrupt,
|
||||
turnConfig=assistant.turn_config or {},
|
||||
startup=assistant.startup or {},
|
||||
tools=await _tools_for(session, assistant),
|
||||
tools=runtime_tools,
|
||||
llm_tool_ids=llm_tool_ids,
|
||||
knowledge_base_id=assistant.knowledge_base_id,
|
||||
knowledge_base_name=knowledge_base.name if knowledge_base else "",
|
||||
knowledge_base_description=knowledge_base.description if knowledge_base else "",
|
||||
|
||||
Reference in New Issue
Block a user