Merge branch 'master' into dev

This commit is contained in:
Reinier van der Leer
2025-08-18 16:42:59 +02:00
4 changed files with 34 additions and 14 deletions

View File

@@ -548,7 +548,7 @@ async def validate_graph_with_credentials(
return node_input_errors
async def _construct_node_execution_input(
async def _construct_starting_node_execution_input(
graph: GraphModel,
user_id: str,
graph_inputs: BlockInput,
@@ -622,7 +622,7 @@ async def validate_and_construct_node_execution_input(
graph_version: Optional[int] = None,
graph_credentials_inputs: Optional[dict[str, CredentialsMetaInput]] = None,
nodes_input_masks: Optional[dict[str, dict[str, JsonValue]]] = None,
) -> tuple[GraphModel, list[tuple[str, BlockInput]]]:
) -> tuple[GraphModel, list[tuple[str, BlockInput]], dict[str, dict[str, JsonValue]]]:
"""
Public wrapper that handles graph fetching, credential mapping, and validation+construction.
This centralizes the logic used by both scheduler validation and actual execution.
@@ -666,14 +666,14 @@ async def validate_and_construct_node_execution_input(
nodes_input_masks or {},
)
starting_nodes_input = await _construct_node_execution_input(
starting_nodes_input = await _construct_starting_node_execution_input(
graph=graph,
user_id=user_id,
graph_inputs=graph_inputs,
nodes_input_masks=nodes_input_masks,
)
return graph, starting_nodes_input
return graph, starting_nodes_input, nodes_input_masks
def _merge_nodes_input_masks(
@@ -856,13 +856,15 @@ async def add_graph_execution(
else:
edb = get_database_manager_async_client()
graph, starting_nodes_input = await validate_and_construct_node_execution_input(
graph_id=graph_id,
user_id=user_id,
graph_inputs=inputs or {},
graph_version=graph_version,
graph_credentials_inputs=graph_credentials_inputs,
nodes_input_masks=nodes_input_masks,
graph, starting_nodes_input, nodes_input_masks = (
await validate_and_construct_node_execution_input(
graph_id=graph_id,
user_id=user_id,
graph_inputs=inputs or {},
graph_version=graph_version,
graph_credentials_inputs=graph_credentials_inputs,
nodes_input_masks=nodes_input_masks,
)
)
graph_exec = None

View File

@@ -676,7 +676,15 @@ async def update_graph(
# Handle deactivation of the previously active version
await on_graph_deactivate(current_active_version, user_id=user_id)
return new_graph_version
# Fetch new graph version *with sub-graphs* (needed for credentials input schema)
new_graph_version_with_subgraphs = await graph_db.get_graph(
graph_id,
new_graph_version.version,
user_id=user_id,
include_subgraphs=True,
)
assert new_graph_version_with_subgraphs # make type checker happy
return new_graph_version_with_subgraphs
@v1_router.put(

View File

@@ -241,7 +241,11 @@ async def get_library_agent_by_graph_id(
)
if not agent:
return None
return library_model.LibraryAgent.from_db(agent)
assert agent.AgentGraph # make type checker happy
# Include sub-graphs so we can make a full credentials input schema
sub_graphs = await graph_db.get_sub_graphs(agent.AgentGraph)
return library_model.LibraryAgent.from_db(agent, sub_graphs=sub_graphs)
except prisma.errors.PrismaError as e:
logger.error(f"Database error fetching library agent by graph ID: {e}")
raise store_exceptions.DatabaseError("Failed to fetch library agent") from e

View File

@@ -71,4 +71,10 @@ class GraphValidationError(ValueError):
self.node_errors = node_errors or {}
def __str__(self):
return self.message
return self.message + "".join(
[
f"\n {node_id}:"
+ "".join([f"\n {k}: {e}" for k, e in errors.items()])
for node_id, errors in self.node_errors.items()
]
)