mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-14 17:47:57 -05:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47a996e75d | ||
|
|
2ff033aeb2 | ||
|
|
95b1beecaf | ||
|
|
cb5452f7ae | ||
|
|
02a60966d4 | ||
|
|
f28112f5e2 | ||
|
|
20f018b2e5 | ||
|
|
6f144ef77a | ||
|
|
bd1fa8f6c2 |
@@ -254,7 +254,7 @@ class GraphModel(Graph):
|
|||||||
for link in self.links:
|
for link in self.links:
|
||||||
input_links[link.sink_id].append(link)
|
input_links[link.sink_id].append(link)
|
||||||
|
|
||||||
# Nodes: required fields are filled or connected
|
# Nodes: required fields are filled or connected and dependencies are satisfied
|
||||||
for node in self.nodes:
|
for node in self.nodes:
|
||||||
block = get_block(node.block_id)
|
block = get_block(node.block_id)
|
||||||
if block is None:
|
if block is None:
|
||||||
@@ -275,6 +275,38 @@ class GraphModel(Graph):
|
|||||||
f"Node {block.name} #{node.id} required input missing: `{name}`"
|
f"Node {block.name} #{node.id} required input missing: `{name}`"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Get input schema properties and check dependencies
|
||||||
|
input_schema = block.input_schema.model_fields
|
||||||
|
required_fields = block.input_schema.get_required_fields()
|
||||||
|
|
||||||
|
def has_value(name):
|
||||||
|
return (
|
||||||
|
node is not None
|
||||||
|
and name in node.input_default
|
||||||
|
and node.input_default[name] is not None
|
||||||
|
and str(node.input_default[name]).strip() != ""
|
||||||
|
) or (name in input_schema and input_schema[name].default is not None)
|
||||||
|
|
||||||
|
# Validate dependencies between fields
|
||||||
|
for field_name, field_info in input_schema.items():
|
||||||
|
|
||||||
|
# Apply input dependency validation only on run & field with depends_on
|
||||||
|
json_schema_extra = field_info.json_schema_extra or {}
|
||||||
|
dependencies = json_schema_extra.get("depends_on", [])
|
||||||
|
if not for_run or not dependencies:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# Check if dependent field has value in input_default
|
||||||
|
field_has_value = has_value(field_name)
|
||||||
|
field_is_required = field_name in required_fields
|
||||||
|
|
||||||
|
# Check for missing dependencies when dependent field is present
|
||||||
|
missing_deps = [dep for dep in dependencies if not has_value(dep)]
|
||||||
|
if missing_deps and (field_has_value or field_is_required):
|
||||||
|
raise ValueError(
|
||||||
|
f"Node {block.name} #{node.id}: Field `{field_name}` requires [{', '.join(missing_deps)}] to be set"
|
||||||
|
)
|
||||||
|
|
||||||
node_map = {v.id: v for v in self.nodes}
|
node_map = {v.id: v for v in self.nodes}
|
||||||
|
|
||||||
def is_static_output_block(nid: str) -> bool:
|
def is_static_output_block(nid: str) -> bool:
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ def SchemaField(
|
|||||||
secret: bool = False,
|
secret: bool = False,
|
||||||
exclude: bool = False,
|
exclude: bool = False,
|
||||||
hidden: Optional[bool] = None,
|
hidden: Optional[bool] = None,
|
||||||
|
depends_on: list[str] | None = None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
) -> T:
|
) -> T:
|
||||||
json_extra = {
|
json_extra = {
|
||||||
@@ -133,6 +134,7 @@ def SchemaField(
|
|||||||
"secret": secret,
|
"secret": secret,
|
||||||
"advanced": advanced,
|
"advanced": advanced,
|
||||||
"hidden": hidden,
|
"hidden": hidden,
|
||||||
|
"depends_on": depends_on,
|
||||||
}.items()
|
}.items()
|
||||||
if v is not None
|
if v is not None
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -406,6 +406,54 @@ export default function useAgentGraph(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Object.entries(node.data.inputSchema.properties || {}).forEach(
|
||||||
|
([key, schema]) => {
|
||||||
|
if (schema.depends_on) {
|
||||||
|
const dependencies = schema.depends_on;
|
||||||
|
|
||||||
|
// Check if dependent field has value
|
||||||
|
const hasValue =
|
||||||
|
inputData[key] != null ||
|
||||||
|
("default" in schema && schema.default != null);
|
||||||
|
|
||||||
|
const mustHaveValue = node.data.inputSchema.required?.includes(key);
|
||||||
|
|
||||||
|
// Check for missing dependencies when dependent field is present
|
||||||
|
const missingDependencies = dependencies.filter(
|
||||||
|
(dep) =>
|
||||||
|
!inputData[dep as keyof typeof inputData] ||
|
||||||
|
String(inputData[dep as keyof typeof inputData]).trim() === "",
|
||||||
|
);
|
||||||
|
|
||||||
|
if ((hasValue || mustHaveValue) && missingDependencies.length > 0) {
|
||||||
|
setNestedProperty(
|
||||||
|
errors,
|
||||||
|
key,
|
||||||
|
`Requires ${missingDependencies.join(", ")} to be set`,
|
||||||
|
);
|
||||||
|
errorMessage = `Field ${key} requires ${missingDependencies.join(", ")} to be set`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if field is required when dependencies are present
|
||||||
|
const hasAllDependencies = dependencies.every(
|
||||||
|
(dep) =>
|
||||||
|
inputData[dep as keyof typeof inputData] &&
|
||||||
|
String(inputData[dep as keyof typeof inputData]).trim() !== "",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hasAllDependencies && !hasValue) {
|
||||||
|
setNestedProperty(
|
||||||
|
errors,
|
||||||
|
key,
|
||||||
|
`${key} is required when ${dependencies.join(", ")} are set`,
|
||||||
|
);
|
||||||
|
errorMessage = `${key} is required when ${dependencies.join(", ")} are set`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Set errors
|
// Set errors
|
||||||
setNodes((nodes) => {
|
setNodes((nodes) => {
|
||||||
return nodes.map((n) => {
|
return nodes.map((n) => {
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ export type BlockIOSubSchemaMeta = {
|
|||||||
description?: string;
|
description?: string;
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
advanced?: boolean;
|
advanced?: boolean;
|
||||||
|
depends_on?: string[];
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user