From 97533029fc906dd6a04e6e7b4c65feb782ea4307 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:11:39 +0000 Subject: [PATCH 1/8] Initial plan From fa33826e6b85f410a6e8ee18ae1e6205a914c526 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:21:37 +0000 Subject: [PATCH 2/8] fix: add regex support to condition node Co-authored-by: shazee257 <50085698+shazee257@users.noreply.github.com> --- .../agentflow/Condition/Condition.test.ts | 58 +++++++++++++++++++ .../nodes/agentflow/Condition/Condition.ts | 7 +++ 2 files changed, 65 insertions(+) create mode 100644 packages/components/nodes/agentflow/Condition/Condition.test.ts diff --git a/packages/components/nodes/agentflow/Condition/Condition.test.ts b/packages/components/nodes/agentflow/Condition/Condition.test.ts new file mode 100644 index 00000000000..12d3a605396 --- /dev/null +++ b/packages/components/nodes/agentflow/Condition/Condition.test.ts @@ -0,0 +1,58 @@ +const { nodeClass: Condition_Agentflow } = require('./Condition') +import { INodeData } from '../../../src/Interface' + +function createNodeData(inputs: any): INodeData { + return { + id: 'condition-node', + label: 'Condition', + name: 'conditionAgentflow', + type: 'Condition', + icon: 'condition.svg', + version: 1.0, + category: 'Agent Flows', + baseClasses: ['Condition'], + inputs + } +} + +describe('Condition Agentflow', () => { + let nodeClass: any + + beforeEach(() => { + nodeClass = new Condition_Agentflow() + }) + + it('should match regex operation for string conditions', async () => { + const nodeData = createNodeData({ + conditions: [ + { + type: 'string', + value1: 'Hello123', + operation: 'regex', + value2: '^Hello\\d+$' + } + ] + }) + + const result = await nodeClass.run(nodeData, '', { agentflowRuntime: { state: {} } }) + expect(result.output.conditions[0].isFulfilled).toBe(true) + expect(result.output.conditions[1].isFulfilled).toBe(false) + }) + + it('should return false for invalid regex patterns', async () => { + const nodeData = createNodeData({ + conditions: [ + { + type: 'string', + value1: 'Hello123', + operation: 'regex', + value2: '[invalid' + } + ] + }) + + const result = await nodeClass.run(nodeData, '', { agentflowRuntime: { state: {} } }) + expect(result.output.conditions[0].isFulfilled).toBe(false) + expect(result.output.conditions[1].isFulfilled).toBe(true) + }) +}) diff --git a/packages/components/nodes/agentflow/Condition/Condition.ts b/packages/components/nodes/agentflow/Condition/Condition.ts index 7ae1be06291..9a964d1cb05 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.ts @@ -270,6 +270,13 @@ class Condition_Agentflow implements INode { endsWith: (value1: CommonType, value2: CommonType) => (value1 as string).endsWith(value2 as string), equal: (value1: CommonType, value2: CommonType) => value1 === value2, notEqual: (value1: CommonType, value2: CommonType) => value1 !== value2, + regex: (value1: CommonType, value2: CommonType) => { + try { + return new RegExp((value2 ?? '').toString()).test((value1 ?? '').toString()) + } catch { + return false + } + }, larger: (value1: CommonType, value2: CommonType) => (Number(value1) || 0) > (Number(value2) || 0), largerEqual: (value1: CommonType, value2: CommonType) => (Number(value1) || 0) >= (Number(value2) || 0), smaller: (value1: CommonType, value2: CommonType) => (Number(value1) || 0) < (Number(value2) || 0), From 538b8c9ef552a986d03c8ddb37b495eb91aa8dd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:22:43 +0000 Subject: [PATCH 3/8] test: clarify condition regex assertions Co-authored-by: shazee257 <50085698+shazee257@users.noreply.github.com> --- .../agentflow/Condition/Condition.test.ts | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.test.ts b/packages/components/nodes/agentflow/Condition/Condition.test.ts index 12d3a605396..a96f12751a3 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.test.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.test.ts @@ -35,8 +35,14 @@ describe('Condition Agentflow', () => { }) const result = await nodeClass.run(nodeData, '', { agentflowRuntime: { state: {} } }) - expect(result.output.conditions[0].isFulfilled).toBe(true) - expect(result.output.conditions[1].isFulfilled).toBe(false) + const matchedCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'regex' && condition.value1 === 'Hello123' && condition.value2 === '^Hello\\d+$' + ) + const elseCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'equal' && condition.value1 === '' && condition.value2 === '' + ) + expect(matchedCondition?.isFulfilled).toBe(true) + expect(elseCondition?.isFulfilled).toBe(false) }) it('should return false for invalid regex patterns', async () => { @@ -52,7 +58,13 @@ describe('Condition Agentflow', () => { }) const result = await nodeClass.run(nodeData, '', { agentflowRuntime: { state: {} } }) - expect(result.output.conditions[0].isFulfilled).toBe(false) - expect(result.output.conditions[1].isFulfilled).toBe(true) + const matchedCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'regex' && condition.value1 === 'Hello123' && condition.value2 === '[invalid' + ) + const elseCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'equal' && condition.value1 === '' && condition.value2 === '' + ) + expect(matchedCondition?.isFulfilled).toBe(false) + expect(elseCondition?.isFulfilled).toBe(true) }) }) From b7dab95030f85bb0e9fcbe51fcf42af114f0b1ff Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 20 Jan 2026 16:27:30 +0000 Subject: [PATCH 4/8] fix: guard condition regex evaluation Co-authored-by: shazee257 <50085698+shazee257@users.noreply.github.com> --- .../agentflow/Condition/Condition.test.ts | 25 ++++++++++++++++++- .../nodes/agentflow/Condition/Condition.ts | 7 +++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.test.ts b/packages/components/nodes/agentflow/Condition/Condition.test.ts index a96f12751a3..17fc67ce4fe 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.test.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.test.ts @@ -1,4 +1,4 @@ -const { nodeClass: Condition_Agentflow } = require('./Condition') +import { nodeClass as Condition_Agentflow } from './Condition' import { INodeData } from '../../../src/Interface' function createNodeData(inputs: any): INodeData { @@ -67,4 +67,27 @@ describe('Condition Agentflow', () => { expect(matchedCondition?.isFulfilled).toBe(false) expect(elseCondition?.isFulfilled).toBe(true) }) + + it('should return false when regex exceeds safety limits', async () => { + const nodeData = createNodeData({ + conditions: [ + { + type: 'string', + value1: 'Hello123', + operation: 'regex', + value2: 'a'.repeat(300) + } + ] + }) + + const result = await nodeClass.run(nodeData, '', { agentflowRuntime: { state: {} } }) + const matchedCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'regex' && condition.value2 === 'a'.repeat(300) + ) + const elseCondition = result.output.conditions.find( + (condition: any) => condition.operation === 'equal' && condition.value1 === '' && condition.value2 === '' + ) + expect(matchedCondition?.isFulfilled).toBe(false) + expect(elseCondition?.isFulfilled).toBe(true) + }) }) diff --git a/packages/components/nodes/agentflow/Condition/Condition.ts b/packages/components/nodes/agentflow/Condition/Condition.ts index 9a964d1cb05..bd103b0b42d 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.ts @@ -271,8 +271,13 @@ class Condition_Agentflow implements INode { equal: (value1: CommonType, value2: CommonType) => value1 === value2, notEqual: (value1: CommonType, value2: CommonType) => value1 !== value2, regex: (value1: CommonType, value2: CommonType) => { + const pattern = (value2 ?? '').toString() + const input = (value1 ?? '').toString() + if (pattern.length > 256 || input.length > 10000) { + return false + } try { - return new RegExp((value2 ?? '').toString()).test((value1 ?? '').toString()) + return new RegExp(pattern).test(input) } catch { return false } From a18a7030f336341db6bf12b63001351aee719e9a Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 20 Jan 2026 22:18:15 +0500 Subject: [PATCH 5/8] Update packages/components/nodes/agentflow/Condition/Condition.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/components/nodes/agentflow/Condition/Condition.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.ts b/packages/components/nodes/agentflow/Condition/Condition.ts index bd103b0b42d..2b0a17a3a61 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.ts @@ -271,9 +271,11 @@ class Condition_Agentflow implements INode { equal: (value1: CommonType, value2: CommonType) => value1 === value2, notEqual: (value1: CommonType, value2: CommonType) => value1 !== value2, regex: (value1: CommonType, value2: CommonType) => { + const MAX_PATTERN_LENGTH = 256 + const MAX_INPUT_LENGTH = 10000 const pattern = (value2 ?? '').toString() const input = (value1 ?? '').toString() - if (pattern.length > 256 || input.length > 10000) { + if (pattern.length > MAX_PATTERN_LENGTH || input.length > MAX_INPUT_LENGTH) { return false } try { From 44e9425ca1ff5ed133174280f1e219f60de53149 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 20 Jan 2026 22:18:53 +0500 Subject: [PATCH 6/8] Update packages/components/nodes/agentflow/Condition/Condition.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../nodes/agentflow/Condition/Condition.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.ts b/packages/components/nodes/agentflow/Condition/Condition.ts index 2b0a17a3a61..4a39acfa509 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.ts @@ -276,11 +276,24 @@ class Condition_Agentflow implements INode { const pattern = (value2 ?? '').toString() const input = (value1 ?? '').toString() if (pattern.length > MAX_PATTERN_LENGTH || input.length > MAX_INPUT_LENGTH) { + console.warn( + '[Condition_Agentflow] Regex condition skipped due to safety limits:', + { + patternLength: pattern.length, + inputLength: input.length, + maxPatternLength: 256, + maxInputLength: 10000 + } + ) return false } try { return new RegExp(pattern).test(input) - } catch { + } catch (e) { + console.warn('[Condition_Agentflow] Invalid regex pattern in condition.', { + error: (e as Error)?.message, + pattern + }) return false } }, From 6419c196f37e2c23613dc6971a76908775253167 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 20 Jan 2026 22:19:07 +0500 Subject: [PATCH 7/8] Update packages/components/nodes/agentflow/Condition/Condition.test.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- packages/components/nodes/agentflow/Condition/Condition.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.test.ts b/packages/components/nodes/agentflow/Condition/Condition.test.ts index 17fc67ce4fe..41b651ee85f 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.test.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.test.ts @@ -87,7 +87,7 @@ describe('Condition Agentflow', () => { const elseCondition = result.output.conditions.find( (condition: any) => condition.operation === 'equal' && condition.value1 === '' && condition.value2 === '' ) - expect(matchedCondition?.isFulfilled).toBe(false) + expect(matchedCondition?.isFulfilled).toBeFalsy() expect(elseCondition?.isFulfilled).toBe(true) }) }) From f040c4a895c779ee4ec3f4231ffde0e5f854f742 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 20 Jan 2026 22:19:39 +0500 Subject: [PATCH 8/8] Update packages/components/nodes/agentflow/Condition/Condition.test.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- packages/components/nodes/agentflow/Condition/Condition.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/nodes/agentflow/Condition/Condition.test.ts b/packages/components/nodes/agentflow/Condition/Condition.test.ts index 41b651ee85f..b3a44f84e9f 100644 --- a/packages/components/nodes/agentflow/Condition/Condition.test.ts +++ b/packages/components/nodes/agentflow/Condition/Condition.test.ts @@ -1,5 +1,5 @@ import { nodeClass as Condition_Agentflow } from './Condition' -import { INodeData } from '../../../src/Interface' +import { INodeData, INode, ICondition } from '../../../src/Interface' function createNodeData(inputs: any): INodeData { return {