mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
fix(condition): stop shipping all block outputs in every evaluation (#6468)
ConditionBlockHandler forwarded collectBlockData's full blockData — every
block output accumulated so far in the run — to function_execute on each
condition evaluation. The resolver already inlines every <block.field>
reference into the expression before the handler runs, so that payload was
never read; it only inflated the request body.
Inside a wide subflow one flat blockStates map holds every branch's outputs,
so a 91-branch parallel pushed the body past the 10MB cap and failed the
gate with "Request body size limit exceeded" even though the expression was
just a boolean compare. Per-value large-value offload does not catch this:
its threshold is 8MB for a single value, while this is an aggregate of many
medium ones.
Mirrors FunctionBlockHandler, which moved to blockData: {} in #4560 and left
the condition handler on the old path.
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
220495c196
commit
19c3171560
@@ -179,7 +179,7 @@ describe('ConditionBlockHandler', () => {
|
||||
timeout: 5000,
|
||||
envVars: mockContext.environmentVariables,
|
||||
workflowVariables: mockContext.workflowVariables,
|
||||
blockData: { 'source-block-1': { value: 10, text: 'hello' } },
|
||||
blockData: {},
|
||||
blockNameMapping: { sourceblock: 'source-block-1' },
|
||||
_context: {
|
||||
workflowId: 'test-workflow-id',
|
||||
@@ -190,6 +190,24 @@ describe('ConditionBlockHandler', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('should never forward collected block outputs in the request body', async () => {
|
||||
mockCollectBlockData.mockReturnValueOnce({
|
||||
blockData: { 'huge-block': { payload: 'x'.repeat(1024) } },
|
||||
blockNameMapping: { hugeblock: 'huge-block' },
|
||||
})
|
||||
mockExecuteTool.mockResolvedValueOnce({ success: true, output: { result: true } })
|
||||
|
||||
const conditions = [
|
||||
{ id: 'cond1', title: 'if', value: 'true' },
|
||||
{ id: 'else1', title: 'else', value: '' },
|
||||
]
|
||||
|
||||
await handler.execute(mockContext, mockBlock, { conditions: JSON.stringify(conditions) })
|
||||
|
||||
const [, toolParams] = mockExecuteTool.mock.calls[0]
|
||||
expect(toolParams.blockData).toEqual({})
|
||||
})
|
||||
|
||||
it('should select the else path if other conditions fail', async () => {
|
||||
mockExecuteTool.mockResolvedValueOnce({ success: true, output: { result: false } })
|
||||
|
||||
|
||||
@@ -22,6 +22,12 @@ const CONDITION_TIMEOUT_MS = 5000
|
||||
* Evaluates a single condition expression.
|
||||
* The resolver preserves legacy Condition expression substitution before this function executes the
|
||||
* resulting JavaScript through the shared function execution boundary.
|
||||
*
|
||||
* `blockData` is deliberately empty: the resolver already inlines every `<block.field>` reference
|
||||
* into the expression before this runs, so shipping the run's accumulated block outputs would only
|
||||
* inflate the request body. Sending them blew the 10MB body cap on wide subflows, where a single
|
||||
* flat `blockStates` map holds every branch's outputs.
|
||||
*
|
||||
* Returns true if condition is met, false otherwise.
|
||||
*/
|
||||
async function evaluateConditionExpression(
|
||||
@@ -36,7 +42,7 @@ async function evaluateConditionExpression(
|
||||
const contextSetup = `const context = ${JSON.stringify(evalContext)};`
|
||||
const code = `${contextSetup}\nreturn Boolean(${conditionExpression})`
|
||||
|
||||
const { blockData, blockNameMapping, blockOutputSchemas } = collectBlockData(ctx, currentNodeId)
|
||||
const { blockNameMapping, blockOutputSchemas } = collectBlockData(ctx, currentNodeId)
|
||||
|
||||
const result = await executeTool(
|
||||
'function_execute',
|
||||
@@ -45,7 +51,7 @@ async function evaluateConditionExpression(
|
||||
timeout: CONDITION_TIMEOUT_MS,
|
||||
envVars: normalizeStringRecord(ctx.environmentVariables),
|
||||
workflowVariables: normalizeWorkflowVariables(ctx.workflowVariables),
|
||||
blockData,
|
||||
blockData: {},
|
||||
blockNameMapping,
|
||||
blockOutputSchemas,
|
||||
_context: {
|
||||
|
||||
Reference in New Issue
Block a user