Skip to content

Commit

Permalink
Merge pull request #427 from NVIDIA/feature/colang-single-flow-activa…
Browse files Browse the repository at this point in the history
…tion

Feature/colang single flow activation
  • Loading branch information
drazvan authored Mar 25, 2024
2 parents fa63bfd + 5a7c22d commit 1cf10a2
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 10 deletions.
58 changes: 49 additions & 9 deletions nemoguardrails/colang/v2_x/runtime/statemachine.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,15 +473,55 @@ def _process_internal_events_without_default_matchers(
# Start new flow state instance if flow exists
flow_id = event.arguments["flow_id"]
if flow_id in state.flow_configs and flow_id != "main":
add_new_flow_instance(
state,
create_flow_instance(
state.flow_configs[flow_id],
event.arguments["flow_instance_uid"],
event.arguments["flow_hierarchy_position"],
event.arguments,
),
)

started_instance = None
if (
event.arguments.get("activated", None)
and flow_id in state.flow_id_states
):
# Check if there already exists an instance of the same activated flow
for activated_flow in state.flow_id_states[flow_id]:
if activated_flow.status != FlowStatus.STARTED:
continue
has_same_arguments = False
for idx, arg in enumerate(state.flow_configs[flow_id].parameters):
val = activated_flow.arguments[arg.name]
if (
arg.name in event.arguments
and val == event.arguments[arg.name]
):
has_same_arguments = True
elif (
f"${idx}" in event.arguments
and val == event.arguments[f"${idx}"]
):
has_same_arguments = True
else:
has_same_arguments = False
break
if has_same_arguments:
started_instance = activated_flow
break

if not started_instance:
add_new_flow_instance(
state,
create_flow_instance(
state.flow_configs[flow_id],
event.arguments["flow_instance_uid"],
event.arguments["flow_hierarchy_position"],
event.arguments,
),
)
else:
started_event = started_instance.started_event(
event.matching_scores,
{"flow_instance_uid": event.arguments["flow_instance_uid"]},
)
_push_internal_event(
state,
started_event,
)
elif event.name == InternalEvents.FINISH_FLOW:
if "flow_instance_uid" in event.arguments:
flow_instance_uid = event.arguments["flow_instance_uid"]
Expand Down
64 changes: 63 additions & 1 deletion tests/v2_x/test_flow_mechanics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ def test_flow_parameter_await_mechanism():
{
"type": "StartUtteranceBotAction",
"script": "Success",
}
},
],
)

Expand Down Expand Up @@ -1616,5 +1616,67 @@ def test_flow_context_sharing():
)


def test_single_flow_activation():
"""Test how a parent flow can share its context with a child flow."""

content = """
flow a
start UtteranceBotAction(script="a")
activate z 1
match WaitEvent()
flow b
start UtteranceBotAction(script="b")
activate z 1
match WaitEvent()
flow c
start UtteranceBotAction(script="c")
activate z 2
match WaitEvent()
flow z $param
await UtteranceBotAction(script="test {$param}")
flow main
activate a
activate b
activate c
await UtteranceBotAction(script="done")
"""

state = run_to_completion(_init_state(content), start_main_flow_event)
assert is_data_in_events(
state.outgoing_events,
[
{
"type": "StartUtteranceBotAction",
"script": "a",
},
{
"type": "StartUtteranceBotAction",
"script": "test 1",
},
{
"type": "StartUtteranceBotAction",
"script": "b",
},
{
"type": "StartUtteranceBotAction",
"script": "c",
},
{
"type": "StartUtteranceBotAction",
"script": "test 2",
},
{
"type": "StartUtteranceBotAction",
"script": "done",
},
],
)


if __name__ == "__main__":
test_meta_decorators()

0 comments on commit 1cf10a2

Please sign in to comment.