Skip to content

fix: support conditions on function steps#162

Open
Ruari-Phipps wants to merge 4 commits into
mainfrom
ruari/fix/add_function_step_conditions
Open

fix: support conditions on function steps#162
Ruari-Phipps wants to merge 4 commits into
mainfrom
ruari/fix/add_function_step_conditions

Conversation

@Ruari-Phipps
Copy link
Copy Markdown
Collaborator

Summary

Adds full sync support for flow conditions on function steps, including pull, push, YAML serialization, and the correct Agent Studio protobuf APIs (CreateStepCondition / UpdateStepCondition / DeleteStepCondition instead of the no-code condition endpoints).

Motivation

Function steps can define branching via goto_step() in their Python code, but the ADK only handled conditions for no-code steps. Conditions on function steps were dropped on pull and could not be pushed reliably. The backend also auto-creates conditions from goto_step() calls, which caused duplicate labels when pushing explicit conditions alongside real function code.

Changes

  • Add conditions field to FunctionStep with YAML read/write and goto_step() extraction (mirroring FlowStep)
  • Route function-step conditions through step_condition protos; no-code step conditions unchanged
  • Track parent_is_no_code_step on Condition to select the correct create/update/delete API
  • Two-phase push for new function steps with conditions: create with stub pass code first, then update with real code to avoid backend duplicate conditions
  • Include Condition in sync ordering so conditions are created before dependent updates
  • Pull function-step conditions from the platform API in sync_client
  • Add unit tests for pull, push, and YAML round-trip of function-step conditions

Test strategy

  • Added/updated unit tests
  • Manual CLI testing (poly <command>)
  • Tested against a live Agent Studio project
  • N/A (docs, config, or trivial change)

Checklist

  • ruff check . and ruff format --check . pass
  • pytest passes
  • No breaking changes to the poly CLI interface (or migration path documented)
  • Commit messages follow conventional commits

Screenshots / Logs

N/A

Made with Cursor

@Ruari-Phipps Ruari-Phipps requested a review from a team May 27, 2026 09:15
@github-actions

This comment has been minimized.

@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report

Base (main) PR Change
70.1% 70.2% +0.1% ✅

Changed file coverage

File Coverage Change
poly/handlers/sync_client.py 25.4% -0.1% ⚠️
poly/project.py 67.8% +0.2% ✅
poly/resources/function.py 81.6% +0.4% ✅
poly/resources/flows.py 83.6% -2.4% ⚠️
poly/resources/resource_utils.py 84.5% +0.2% ✅

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds end-to-end sync support for conditions on function steps in ADK flows, ensuring conditions are correctly pulled from the platform, represented locally, and pushed back using the proper step-condition protobuf APIs (rather than the no-code condition endpoints).

Changes:

  • Extend FunctionStep to carry conditions, including extraction from goto_step() / exit_flow() patterns and condition subresource diffing.
  • Update platform projection parsing and sync command ordering so function-step conditions round-trip reliably and use the correct create/update/delete APIs.
  • Add/extend unit tests and update the bundled test project fixtures to cover YAML/JSON round-trips and push behavior (including the stub-code two-phase push).

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/poly/utils.py Import ordering adjustment.
src/poly/tests/test_projects/test_project/test_project.json Updates test projection fixture to include function-step conditions and updated code.
src/poly/tests/test_projects/test_project/flows/test_flow/function_steps/process_payment.py Updates fixture function-step code to include goto_step() call.
src/poly/tests/resources_test.py Adds tests for goto_step/goto_flow extraction and function-step condition extraction behavior.
src/poly/tests/project_test.py Adds tests validating stub-code behavior for new function steps with conditions.
src/poly/resources/resource_utils.py Adds reusable regex extractors for goto_step() and goto_flow() calls.
src/poly/resources/function.py Switches validation to use the new extract_go_to_steps/flows helpers.
src/poly/resources/flows.py Core implementation: condition API routing via parent_is_no_code_step, adds FunctionStep.conditions, extracts conditions from function-step code, and emits condition subresource commands.
src/poly/project.py Implements two-phase push (stub code first) for new function steps with conditions to avoid backend duplicate conditions.
src/poly/handlers/sync_client.py Pulls conditions for both flow steps and function steps; includes Condition in sync priority ordering.
src/poly/handlers/platform_api.py Import ordering adjustment.
Comments suppressed due to low confidence (1)

src/poly/resources/flows.py:1274

  • build_delete_proto / build_create_proto can return DeleteStepCondition / CreateStepCondition when parent_is_no_code_step is false, but the return type annotations are still DeleteNoCodeCondition / CreateNoCodeCondition. Update these annotations (and any related docstrings) to reflect the actual union return types so type checking and IDE tooling stay accurate.
    def build_delete_proto(self) -> DeleteNoCodeCondition:
        """Create a proto for deleting the condition."""
        if self.parent_is_no_code_step:
            return DeleteNoCodeCondition(
                flow_id=self.flow_id,
                step_id=self.step_id,
                condition_id=self.resource_id,
            )
        return DeleteStepCondition(
            flow_id=self.flow_id,
            step_id=self.step_id,
            condition_id=self.resource_id,
        )

    def build_create_proto(self) -> CreateNoCodeCondition:
        """Create a proto for creating the condition."""
        if self.parent_is_no_code_step:
            return CreateNoCodeCondition(
                flow_id=self.flow_id,
                step_id=self.step_id,
                condition_id=self.resource_id,
                **self._get_condition_type_proto(),
            )
        return CreateStepCondition(
            flow_id=self.flow_id,
            step_id=self.step_id,
            condition_id=self.resource_id,
            **self._get_condition_type_proto(),
        )

condition_name_map = {
cond.name: cond
for cond in known_conditions
if cond.command_type != ConditionType.EXIT_FLOW
Comment on lines +1544 to +1548
child_step=child_step_id,
position=known_condition.position if known_condition else None,
ingress=known_condition.ingress if known_condition else None,
exit_flow_position=None,
parent_is_no_code_step=False,
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants