Add workflow support and enhance runtime configuration in models and services
- Introduce RuntimeModelResource and RuntimeKnowledgeBase classes to manage workflow resources. - Update AssistantConfig to include workflow_model_resources and workflow_knowledge_bases for better integration. - Refactor validation and processing logic in routes and services to accommodate workflow types. - Implement dynamic variable support for workflow assistants and enhance graph normalization. - Add ToolExecutor for reusable tool execution across different assistant types. - Update various services to ensure compatibility with new workflow features and improve error handling.
This commit is contained in:
@@ -12,7 +12,13 @@ from db.models import (
|
||||
ModelResource,
|
||||
Tool,
|
||||
)
|
||||
from models import AssistantConfig, RuntimeTool
|
||||
from models import (
|
||||
AssistantConfig,
|
||||
RuntimeKnowledgeBase,
|
||||
RuntimeModelResource,
|
||||
RuntimeTool,
|
||||
)
|
||||
from services.node_specs import graph_references, normalize_graph
|
||||
from sqlalchemy import select
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -83,7 +89,7 @@ def _secret(resource: ModelResource | None, key: str, default: str = "") -> str:
|
||||
|
||||
|
||||
async def _tools_for(session: AsyncSession, assistant: Assistant) -> list[RuntimeTool]:
|
||||
if assistant.type != "prompt":
|
||||
if assistant.type not in {"prompt", "workflow"}:
|
||||
return []
|
||||
tools = (
|
||||
await session.execute(
|
||||
@@ -134,6 +140,43 @@ async def resolve_runtime_config(
|
||||
else None
|
||||
)
|
||||
|
||||
graph = normalize_graph(assistant.graph or {}) if assistant.type == "workflow" else {}
|
||||
refs = graph_references(graph) if graph else {
|
||||
"model_resources": set(),
|
||||
"knowledge_bases": set(),
|
||||
}
|
||||
workflow_resources: dict[str, RuntimeModelResource] = {}
|
||||
if refs["model_resources"]:
|
||||
resources = (
|
||||
await session.execute(
|
||||
select(ModelResource).where(ModelResource.id.in_(refs["model_resources"]))
|
||||
)
|
||||
).scalars().all()
|
||||
workflow_resources = {
|
||||
resource.id: RuntimeModelResource(
|
||||
id=resource.id,
|
||||
name=resource.name,
|
||||
capability=resource.capability,
|
||||
interface_type=resource.interface_type,
|
||||
values=resource.values or {},
|
||||
secrets=resource.secrets or {},
|
||||
)
|
||||
for resource in resources
|
||||
if resource.enabled
|
||||
}
|
||||
workflow_knowledge: dict[str, RuntimeKnowledgeBase] = {}
|
||||
if refs["knowledge_bases"]:
|
||||
knowledge_rows = (
|
||||
await session.execute(
|
||||
select(KnowledgeBase).where(KnowledgeBase.id.in_(refs["knowledge_bases"]))
|
||||
)
|
||||
).scalars().all()
|
||||
workflow_knowledge = {
|
||||
kb.id: RuntimeKnowledgeBase(id=kb.id, name=kb.name, description=kb.description)
|
||||
for kb in knowledge_rows
|
||||
if kb.status == "active"
|
||||
}
|
||||
|
||||
return AssistantConfig(
|
||||
name=assistant.name,
|
||||
type=assistant.type,
|
||||
@@ -150,7 +193,9 @@ async def resolve_runtime_config(
|
||||
knowledge_base_description=knowledge_base.description if knowledge_base else "",
|
||||
knowledge_retrieval_config=assistant.knowledge_retrieval_config or {},
|
||||
# workflow 图:仅 workflow 类型非空,引擎据此启用图驱动对话
|
||||
graph=(assistant.graph or {}) if assistant.type == "workflow" else {},
|
||||
graph=graph,
|
||||
workflow_model_resources=workflow_resources,
|
||||
workflow_knowledge_bases=workflow_knowledge,
|
||||
# 外部托管类型连接信息(DB 存真 key,直接注入)
|
||||
dify_api_url=str(_value(agent_resource, "apiUrl", assistant.api_url)),
|
||||
dify_api_key=_secret(agent_resource, "apiKey", assistant.api_key),
|
||||
|
||||
Reference in New Issue
Block a user