fix: isolate startup tools and preview dialogs

This commit is contained in:
Xin Wang
2026-08-02 00:07:35 +08:00
parent 0331f8cd07
commit 479a516546
10 changed files with 202 additions and 49 deletions

View File

@@ -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 "",