Skip to content

Commit ae49a8e

Browse files
authored
Merge pull request #2 from OmniJax/chore/vibe-safety
chore(vibe): non-core safety and maintainability improvements
2 parents 946d7b0 + 6b18f55 commit ae49a8e

File tree

4 files changed

+62
-70
lines changed

4 files changed

+62
-70
lines changed

masfactory/components/vibe/vibe_graph.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ def build(self):
107107
"system_advice": "",
108108
}
109109
)
110+
if not isinstance(output, dict):
111+
raise TypeError(
112+
f"Vibe build workflow must return dict output, got {type(output).__name__}"
113+
)
110114
raw_graph_design = output.get("graph_design", {})
111115
graph_design = normalize_graph_design(raw_graph_design)
112116
else:

masfactory/components/vibe/vibe_workflow/planner/planner_diagnose_loop.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1-
from masfactory import NodeTemplate,Loop
1+
from masfactory import NodeTemplate, Loop
22
from .planner_agent import PlannerAgent
33
from .diagnose_node import DiagnoseNode
4+
5+
6+
def _as_bool(value: object) -> bool:
7+
"""Best-effort bool coercion used by loop termination checks."""
8+
if isinstance(value, bool):
9+
return value
10+
if isinstance(value, str):
11+
lowered = value.strip().lower()
12+
if lowered in {"true", "1", "yes", "y", "on"}:
13+
return True
14+
if lowered in {"false", "0", "no", "n", "off", ""}:
15+
return False
16+
return bool(value)
17+
18+
419
def terminate_check(messages: dict, _attributes: dict | None = None) -> bool:
5-
return not bool(messages.get("diagnose_has_issues", False))
20+
return not _as_bool(messages.get("diagnose_has_issues", False))
621

722

823
PlannerDiagnoseLoop = NodeTemplate(
Lines changed: 33 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,63 @@
1-
from masfactory import Loop,NodeTemplate,HumanFileEditVisual
1+
from masfactory import Loop, NodeTemplate, HumanFileEditVisual
22
from .planner_diagnose_loop import PlannerDiagnoseLoop
3-
def terminate_check(messages:dict):
4-
user_advice:str = messages.get("user_advice","")
5-
if len(user_advice.strip()) == 0 or "agree" in user_advice.lower():
6-
return True
7-
else:
8-
return False
3+
4+
5+
def terminate_check(messages: dict) -> bool:
6+
"""Stop when user gives no feedback or explicitly agrees."""
7+
user_advice = messages.get("user_advice", "")
8+
if not isinstance(user_advice, str):
9+
user_advice = str(user_advice)
10+
return (not user_advice.strip()) or ("agree" in user_advice.lower())
911

1012
PlannerHuman = NodeTemplate(
11-
HumanFileEditVisual,
12-
pull_keys={},
13-
push_keys={},
13+
HumanFileEditVisual,
14+
pull_keys={},
15+
push_keys={},
1416
)
1517

16-
# PlannerGraph = NodeTemplate(
17-
# Loop,
18-
# pull_keys={},
19-
# push_keys={},
20-
# terminate_condition_function=terminate_check,
21-
# nodes=[
22-
# ("planner",Planner),
23-
# ("planner-human",PlannerHuman)
24-
# ],
25-
# edges=[
26-
# ("CONTROLLER","planner",
27-
# {
28-
# "user_demand":"",
29-
# "role_list":"",
30-
# "user_advice":"No advice yet."
31-
# }
32-
# ),
33-
# ("planner","planner-human",
34-
# {
35-
# "graph_design":"The generated graph design accroding to the user's demand and the roles."
36-
# }
37-
# ),
38-
# ("planner","CONTROLLER",
39-
# {
40-
# "graph_design":"The generated graph design accroding to the user's demand and the roles."
41-
# }
42-
# ),
43-
# ("planner-human","CONTROLLER",
44-
# {
45-
# "user_advice":"Do you agree the plan? If you agree, enter AGREE. If you have any comments, please enter your comments."
46-
# }
47-
# )
48-
# ]
49-
# )
50-
5118
PlannerGraph = NodeTemplate(
5219
Loop,
5320
terminate_condition_function=terminate_check,
54-
pull_keys={"cache_file_path":""},
21+
pull_keys={"cache_file_path": ""},
5522
push_keys={},
56-
nodes=[
57-
("planner-diagnose-loop",PlannerDiagnoseLoop),
58-
("planner-human",PlannerHuman)
59-
],
23+
nodes=[
24+
("planner-diagnose-loop", PlannerDiagnoseLoop),
25+
("planner-human", PlannerHuman),
26+
],
6027
edges=[
6128
(
62-
"CONTROLLER","planner-diagnose-loop",
29+
"CONTROLLER",
30+
"planner-diagnose-loop",
6331
{
6432
"user_demand": "User demand",
6533
"role_list": "Role list",
66-
"user_advice":"User's feedback"
34+
"user_advice": "User's feedback",
6735
},
6836
),
6937
(
70-
"planner-diagnose-loop","planner-human",
38+
"planner-diagnose-loop",
39+
"planner-human",
7140
{
72-
"graph_design":"The generated graph design accroding to the user's demand and the roles."
41+
"graph_design": "The generated graph design accroding to the user's demand and the roles."
7342
},
7443
),
7544
(
76-
"planner-human","CONTROLLER",
45+
"planner-human",
46+
"CONTROLLER",
7747
{
78-
"user_advice":"Do you agree the plan? If you agree, enter AGREE. If you have any comments, please enter your comments."
48+
"user_advice": "Do you agree the plan? If you agree, enter AGREE. If you have any comments, please enter your comments."
7949
}
8050
),
8151
(
82-
"planner-diagnose-loop","CONTROLLER",
52+
"planner-diagnose-loop",
53+
"CONTROLLER",
8354
{
84-
"graph_design":"The generated graph design accroding to the user's demand and the roles."
55+
"graph_design": "The generated graph design accroding to the user's demand and the roles."
8556
}
86-
)
57+
),
8758
],
8859
)
8960

90-
__ALL__=[
91-
'PlannerGraph'
92-
]
61+
__ALL__ = [
62+
"PlannerGraph",
63+
]

masfactory/components/vibe/vibe_workflow/role_assigner.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@
4848
pull_keys={},
4949
push_keys={},
5050
)
51-
def terminate_check(messages:dict):
52-
user_advice:str = messages.get("user_advice","")
53-
if len(user_advice.strip()) == 0 or "agree" in user_advice.lower():
54-
return True
55-
else:
56-
return False
51+
52+
53+
def terminate_check(messages: dict) -> bool:
54+
"""Stop when user gives no feedback or explicitly agrees."""
55+
user_advice = messages.get("user_advice", "")
56+
if not isinstance(user_advice, str):
57+
user_advice = str(user_advice)
58+
return (not user_advice.strip()) or ("agree" in user_advice.lower())
5759

5860
RoleAssignerGraph = NodeTemplate(
5961
Loop,

0 commit comments

Comments
 (0)