Skip to content

fix(agentflow): prevent ConditionAgent silent failure when no scenario matches#5760

Open
aviu16 wants to merge 3 commits intoFlowiseAI:mainfrom
aviu16:fix/condition-agent-loop
Open

fix(agentflow): prevent ConditionAgent silent failure when no scenario matches#5760
aviu16 wants to merge 3 commits intoFlowiseAI:mainfrom
aviu16:fix/condition-agent-loop

Conversation

@aviu16
Copy link

@aviu16 aviu16 commented Feb 16, 2026

fixes #5620

the ConditionAgent was doing a strict exact string match between the LLM response and the full scenario description text. LLMs (especially gpt-4o-mini) often return abbreviated or slightly different versions, so the match would fail and ALL branches would be marked unfulfilled. this caused the flow to silently terminate with no response, or loop until hitting the max iteration limit.

whats changed:

  • added fallback matching in ConditionAgent.ts: tries exact match first, then startsWith, then includes/substring match
  • if nothing matches at all, uses the last scenario as a default "else" branch (same pattern the regular Condition node already uses)
  • added a safety net in buildAgentflow.ts so that when all conditions are unfulfilled, the last branch is treated as a fallback instead of killing the entire flow

before: sending "Hello" to a Router with GREETING/SQL/GENERAL scenarios would silently fail because the LLM returned something like "GREETING" instead of the full scenario description
after: the partial match catches it correctly, or worst case the else branch handles it

… scenario matches

the ConditionAgent was doing strict exact string matching against
scenario descriptions, but LLMs often return abbreviated or slightly
different versions of the scenario text. when nothing matched, all
branches got marked as unfulfilled and the flow silently terminated
with no response.

added fallback matching (startsWith, includes) so partial matches
still route correctly, plus a last-resort else branch so the flow
never just dies silently. also added a safety net in the execution
engine to catch the case where all conditions are unfulfilled.

fixes FlowiseAI#5620
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @aviu16, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical issue where the ConditionAgent could silently fail or loop indefinitely when an LLM's response didn't exactly match a scenario description. The changes introduce more flexible matching logic within the ConditionAgent to better interpret LLM outputs, along with a robust fallback mechanism that ensures a default path is always taken if no conditions are explicitly met, thereby improving the reliability and resilience of agent flows.

Highlights

  • Enhanced Scenario Matching: The ConditionAgent now employs a multi-stage matching process for LLM responses against scenario descriptions, starting with an exact match, then startsWith, and finally includes (substring match) to prevent failures due to abbreviated or slightly different LLM outputs.
  • Default "Else" Branch: If no scenario matches after all attempts, the ConditionAgent will now automatically select the last defined scenario as a default "else" branch, ensuring the flow does not silently terminate.
  • Flow Safety Net: A new safety mechanism in buildAgentflow.ts ensures that even if all conditions in a decision node are initially unfulfilled, the last condition is marked as fulfilled to act as a fallback, preventing the entire flow from being killed.
Changelog
  • packages/components/nodes/agentflow/ConditionAgent/ConditionAgent.ts
    • Implemented tiered matching logic for LLM responses against scenario descriptions (exact, startsWith, includes).
    • Added a fallback mechanism to select the last scenario as a default "else" branch if no match is found.
  • packages/server/src/utils/buildAgentflow.ts
    • Introduced a safety net to ensure that if no conditions are fulfilled in a decision node, the last condition is treated as a fallback.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request addresses a silent failure in the ConditionAgent by implementing more robust matching logic for LLM outputs. It introduces several fallback mechanisms, from exact string matching to substring checks, and finally defaults to an 'else' branch if no match is found. This significantly improves the reliability of conditional flows. A general safety net has also been added to buildAgentflow.ts to prevent flows from dying when no conditions are met in any decision node. The changes are well-reasoned and directly address the issue. My review includes suggestions to improve code quality and consistency.

Comment on lines 410 to 428
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

To improve readability and ensure consistency, it's better to normalize the calledOutputName once before performing the matches. This also fixes a potential issue where the initial exact match doesn't trim() the output, which could lead to match failures if the LLM returns trailing whitespace.

            const normalizedOutput = calledOutputName.toLowerCase().trim()

            // try exact match first
            let matchedScenarioIndex = _conditionAgentScenarios.findIndex(
                (scenario) => scenario.scenario.toLowerCase() === normalizedOutput
            )

            // fallback: check if LLM returned a partial/abbreviated scenario name
            if (matchedScenarioIndex === -1) {
                matchedScenarioIndex = _conditionAgentScenarios.findIndex((scenario) =>
                    scenario.scenario.toLowerCase().startsWith(normalizedOutput)
                )
            }

            // further fallback: substring match in either direction
            if (matchedScenarioIndex === -1) {
                matchedScenarioIndex = _conditionAgentScenarios.findIndex(
                    (scenario) =>
                        scenario.scenario.toLowerCase().includes(normalizedOutput) ||
                        normalizedOutput.includes(scenario.scenario.toLowerCase())
                )
            }

Copy link
Author

Choose a reason for hiding this comment

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

good point, normalized it once at the top now. also trims on that first pass so whitespace wont mess up the exact match either

Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The type of c can be inferred from outputConditions which is ICondition[]. Explicitly typing it as any is unnecessary and reduces type-safety.

        const anyFulfilled = outputConditions.some((c) => c.isFulfilled === true)

Copy link
Author

Choose a reason for hiding this comment

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

yeah removed those, inference handles it fine since outputConditions is already typed as ICondition[]

- normalize calledOutputName once before all matching steps instead of
  calling toLowerCase().trim() repeatedly
- remove explicit any types where inference handles it
@aviu16
Copy link
Author

aviu16 commented Feb 17, 2026

friendly follow-up: let me know if you want changes on this and I can patch quickly.

@aviu16
Copy link
Author

aviu16 commented Feb 17, 2026

added targeted unit coverage for the scenario-match fallback logic and extracted that logic into a small pure helper to make behavior explicit/testable.\n\nnew tests cover:\n- exact case-insensitive match\n- whitespace-trimmed match\n- startsWith fallback\n- substring fallback\n- final else-branch fallback\n\ntest run:\npnpm --filter flowise-components test -- nodes/agentflow/ConditionAgent/matchScenario.test.ts\npassed (6 tests).

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.

[Bug] Router/Condition Agent enters loop for GREETING intents in Multi-Agent Flow

1 participant

Comments