Skip to content

Commit e9c4251

Browse files
waleedlatif1icecrasher321Sg312
authored
v0.5.68: router block reasoning, executor improvements, variable resolution consolidation, helm updates (#2946)
* improvement(workflow-item): stabilize avatar layout and fix name truncation (#2939) * improvement(workflow-item): stabilize avatar layout and fix name truncation * fix(avatars): revert overflow bg to hardcoded color for contrast * fix(executor): stop parallel execution when block errors (#2940) * improvement(helm): add per-deployment extraVolumes support (#2942) * fix(gmail): expose messageId field in read email block (#2943) * fix(resolver): consolidate reference resolution (#2941) * fix(resolver): consolidate code to resolve references * fix edge cases * use already formatted error * fix multi index * fix backwards compat reachability * handle backwards compatibility accurately * use shared constant correctly * feat(router): expose reasoning output in router v2 block (#2945) * fix(copilot): always allow, credential masking (#2947) * Fix always allow, credential validation * Credential masking * Autoload * fix(executor): handle condition dead-end branches in loops (#2944) --------- Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com> Co-authored-by: Siddharth Ganesan <33737564+Sg312@users.noreply.github.com>
2 parents cc2be33 + 748793e commit e9c4251

File tree

41 files changed

+3227
-469
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+3227
-469
lines changed

apps/sim/app/api/function/execute/route.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ describe('Function Execute API Route', () => {
313313
'block-2': 'world',
314314
},
315315
blockNameMapping: {
316-
validVar: 'block-1',
316+
validvar: 'block-1',
317317
another_valid: 'block-2',
318318
},
319319
})
@@ -539,7 +539,7 @@ describe('Function Execute API Route', () => {
539539
'block-complex': complexData,
540540
},
541541
blockNameMapping: {
542-
complexData: 'block-complex',
542+
complexdata: 'block-complex',
543543
},
544544
})
545545

apps/sim/app/api/function/execute/route.ts

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ import { executeInE2B } from '@/lib/execution/e2b'
66
import { executeInIsolatedVM } from '@/lib/execution/isolated-vm'
77
import { CodeLanguage, DEFAULT_CODE_LANGUAGE, isValidCodeLanguage } from '@/lib/execution/languages'
88
import { escapeRegExp, normalizeName, REFERENCE } from '@/executor/constants'
9+
import { type OutputSchema, resolveBlockReference } from '@/executor/utils/block-reference'
910
import {
1011
createEnvVarPattern,
1112
createWorkflowVariablePattern,
1213
} from '@/executor/utils/reference-validation'
13-
import { navigatePath } from '@/executor/variables/resolvers/reference'
1414
export const dynamic = 'force-dynamic'
1515
export const runtime = 'nodejs'
1616

@@ -470,14 +470,17 @@ function resolveEnvironmentVariables(
470470

471471
function resolveTagVariables(
472472
code: string,
473-
blockData: Record<string, any>,
473+
blockData: Record<string, unknown>,
474474
blockNameMapping: Record<string, string>,
475-
contextVariables: Record<string, any>
475+
blockOutputSchemas: Record<string, OutputSchema>,
476+
contextVariables: Record<string, unknown>,
477+
language = 'javascript'
476478
): string {
477479
let resolvedCode = code
480+
const undefinedLiteral = language === 'python' ? 'None' : 'undefined'
478481

479482
const tagPattern = new RegExp(
480-
`${REFERENCE.START}([a-zA-Z_][a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*[a-zA-Z0-9_])${REFERENCE.END}`,
483+
`${REFERENCE.START}([a-zA-Z_](?:[a-zA-Z0-9_${REFERENCE.PATH_DELIMITER}]*[a-zA-Z0-9_])?)${REFERENCE.END}`,
481484
'g'
482485
)
483486
const tagMatches = resolvedCode.match(tagPattern) || []
@@ -486,41 +489,37 @@ function resolveTagVariables(
486489
const tagName = match.slice(REFERENCE.START.length, -REFERENCE.END.length).trim()
487490
const pathParts = tagName.split(REFERENCE.PATH_DELIMITER)
488491
const blockName = pathParts[0]
492+
const fieldPath = pathParts.slice(1)
489493

490-
const blockId = blockNameMapping[blockName]
491-
if (!blockId) {
492-
continue
493-
}
494+
const result = resolveBlockReference(blockName, fieldPath, {
495+
blockNameMapping,
496+
blockData,
497+
blockOutputSchemas,
498+
})
494499

495-
const blockOutput = blockData[blockId]
496-
if (blockOutput === undefined) {
500+
if (!result) {
497501
continue
498502
}
499503

500-
let tagValue: any
501-
if (pathParts.length === 1) {
502-
tagValue = blockOutput
503-
} else {
504-
tagValue = navigatePath(blockOutput, pathParts.slice(1))
505-
}
504+
let tagValue = result.value
506505

507506
if (tagValue === undefined) {
507+
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), undefinedLiteral)
508508
continue
509509
}
510510

511-
if (
512-
typeof tagValue === 'string' &&
513-
tagValue.length > 100 &&
514-
(tagValue.startsWith('{') || tagValue.startsWith('['))
515-
) {
516-
try {
517-
tagValue = JSON.parse(tagValue)
518-
} catch {
519-
// Keep as-is
511+
if (typeof tagValue === 'string') {
512+
const trimmed = tagValue.trimStart()
513+
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
514+
try {
515+
tagValue = JSON.parse(tagValue)
516+
} catch {
517+
// Keep as string if not valid JSON
518+
}
520519
}
521520
}
522521

523-
const safeVarName = `__tag_${tagName.replace(/[^a-zA-Z0-9_]/g, '_')}`
522+
const safeVarName = `__tag_${tagName.replace(/_/g, '_1').replace(/\./g, '_0')}`
524523
contextVariables[safeVarName] = tagValue
525524
resolvedCode = resolvedCode.replace(new RegExp(escapeRegExp(match), 'g'), safeVarName)
526525
}
@@ -537,18 +536,27 @@ function resolveTagVariables(
537536
*/
538537
function resolveCodeVariables(
539538
code: string,
540-
params: Record<string, any>,
539+
params: Record<string, unknown>,
541540
envVars: Record<string, string> = {},
542-
blockData: Record<string, any> = {},
541+
blockData: Record<string, unknown> = {},
543542
blockNameMapping: Record<string, string> = {},
544-
workflowVariables: Record<string, any> = {}
545-
): { resolvedCode: string; contextVariables: Record<string, any> } {
543+
blockOutputSchemas: Record<string, OutputSchema> = {},
544+
workflowVariables: Record<string, unknown> = {},
545+
language = 'javascript'
546+
): { resolvedCode: string; contextVariables: Record<string, unknown> } {
546547
let resolvedCode = code
547-
const contextVariables: Record<string, any> = {}
548+
const contextVariables: Record<string, unknown> = {}
548549

549550
resolvedCode = resolveWorkflowVariables(resolvedCode, workflowVariables, contextVariables)
550551
resolvedCode = resolveEnvironmentVariables(resolvedCode, params, envVars, contextVariables)
551-
resolvedCode = resolveTagVariables(resolvedCode, blockData, blockNameMapping, contextVariables)
552+
resolvedCode = resolveTagVariables(
553+
resolvedCode,
554+
blockData,
555+
blockNameMapping,
556+
blockOutputSchemas,
557+
contextVariables,
558+
language
559+
)
552560

553561
return { resolvedCode, contextVariables }
554562
}
@@ -585,6 +593,7 @@ export async function POST(req: NextRequest) {
585593
envVars = {},
586594
blockData = {},
587595
blockNameMapping = {},
596+
blockOutputSchemas = {},
588597
workflowVariables = {},
589598
workflowId,
590599
isCustomTool = false,
@@ -601,20 +610,21 @@ export async function POST(req: NextRequest) {
601610
isCustomTool,
602611
})
603612

604-
// Resolve variables in the code with workflow environment variables
613+
const lang = isValidCodeLanguage(language) ? language : DEFAULT_CODE_LANGUAGE
614+
605615
const codeResolution = resolveCodeVariables(
606616
code,
607617
executionParams,
608618
envVars,
609619
blockData,
610620
blockNameMapping,
611-
workflowVariables
621+
blockOutputSchemas,
622+
workflowVariables,
623+
lang
612624
)
613625
resolvedCode = codeResolution.resolvedCode
614626
const contextVariables = codeResolution.contextVariables
615627

616-
const lang = isValidCodeLanguage(language) ? language : DEFAULT_CODE_LANGUAGE
617-
618628
let jsImports = ''
619629
let jsRemainingCode = resolvedCode
620630
let hasImports = false
@@ -670,7 +680,11 @@ export async function POST(req: NextRequest) {
670680
prologue += `const environmentVariables = JSON.parse(${JSON.stringify(JSON.stringify(envVars))});\n`
671681
prologueLineCount++
672682
for (const [k, v] of Object.entries(contextVariables)) {
673-
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
683+
if (v === undefined) {
684+
prologue += `const ${k} = undefined;\n`
685+
} else {
686+
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
687+
}
674688
prologueLineCount++
675689
}
676690

@@ -741,7 +755,11 @@ export async function POST(req: NextRequest) {
741755
prologue += `environmentVariables = json.loads(${JSON.stringify(JSON.stringify(envVars))})\n`
742756
prologueLineCount++
743757
for (const [k, v] of Object.entries(contextVariables)) {
744-
prologue += `${k} = json.loads(${JSON.stringify(JSON.stringify(v))})\n`
758+
if (v === undefined) {
759+
prologue += `${k} = None\n`
760+
} else {
761+
prologue += `${k} = json.loads(${JSON.stringify(JSON.stringify(v))})\n`
762+
}
745763
prologueLineCount++
746764
}
747765
const wrapped = [

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,29 @@ export const ActionBar = memo(
151151
</Tooltip.Root>
152152
)}
153153

154+
{isSubflowBlock && (
155+
<Tooltip.Root>
156+
<Tooltip.Trigger asChild>
157+
<Button
158+
variant='ghost'
159+
onClick={(e) => {
160+
e.stopPropagation()
161+
if (!disabled) {
162+
collaborativeBatchToggleBlockEnabled([blockId])
163+
}
164+
}}
165+
className={ACTION_BUTTON_STYLES}
166+
disabled={disabled}
167+
>
168+
{isEnabled ? <Circle className={ICON_SIZE} /> : <CircleOff className={ICON_SIZE} />}
169+
</Button>
170+
</Tooltip.Trigger>
171+
<Tooltip.Content side='top'>
172+
{getTooltipMessage(isEnabled ? 'Disable Block' : 'Enable Block')}
173+
</Tooltip.Content>
174+
</Tooltip.Root>
175+
)}
176+
154177
{!isStartBlock && !isResponseBlock && (
155178
<Tooltip.Root>
156179
<Tooltip.Trigger asChild>
@@ -222,29 +245,6 @@ export const ActionBar = memo(
222245
</Tooltip.Root>
223246
)}
224247

225-
{isSubflowBlock && (
226-
<Tooltip.Root>
227-
<Tooltip.Trigger asChild>
228-
<Button
229-
variant='ghost'
230-
onClick={(e) => {
231-
e.stopPropagation()
232-
if (!disabled) {
233-
collaborativeBatchToggleBlockEnabled([blockId])
234-
}
235-
}}
236-
className={ACTION_BUTTON_STYLES}
237-
disabled={disabled}
238-
>
239-
{isEnabled ? <Circle className={ICON_SIZE} /> : <CircleOff className={ICON_SIZE} />}
240-
</Button>
241-
</Tooltip.Trigger>
242-
<Tooltip.Content side='top'>
243-
{getTooltipMessage(isEnabled ? 'Disable Block' : 'Enable Block')}
244-
</Tooltip.Content>
245-
</Tooltip.Root>
246-
)}
247-
248248
<Tooltip.Root>
249249
<Tooltip.Trigger asChild>
250250
<Button

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/copilot-message/copilot-message.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const CopilotMessage: FC<CopilotMessageProps> = memo(
7878
mode,
7979
setMode,
8080
isAborting,
81+
maskCredentialValue,
8182
} = useCopilotStore()
8283

8384
const messageCheckpoints = isUser ? allMessageCheckpoints[message.id] || [] : []
@@ -210,7 +211,10 @@ const CopilotMessage: FC<CopilotMessageProps> = memo(
210211
const isLastTextBlock =
211212
index === message.contentBlocks!.length - 1 && block.type === 'text'
212213
const parsed = parseSpecialTags(block.content)
213-
const cleanBlockContent = parsed.cleanContent.replace(/\n{3,}/g, '\n\n')
214+
// Mask credential IDs in the displayed content
215+
const cleanBlockContent = maskCredentialValue(
216+
parsed.cleanContent.replace(/\n{3,}/g, '\n\n')
217+
)
214218

215219
if (!cleanBlockContent.trim()) return null
216220

@@ -238,7 +242,7 @@ const CopilotMessage: FC<CopilotMessageProps> = memo(
238242
return (
239243
<div key={blockKey} className='w-full'>
240244
<ThinkingBlock
241-
content={block.content}
245+
content={maskCredentialValue(block.content)}
242246
isStreaming={isActivelyStreaming}
243247
hasFollowingContent={hasFollowingContent}
244248
hasSpecialTags={hasSpecialTags}
@@ -261,7 +265,7 @@ const CopilotMessage: FC<CopilotMessageProps> = memo(
261265
}
262266
return null
263267
})
264-
}, [message.contentBlocks, isActivelyStreaming, parsedTags, isLastMessage])
268+
}, [message.contentBlocks, isActivelyStreaming, parsedTags, isLastMessage, maskCredentialValue])
265269

266270
if (isUser) {
267271
return (

0 commit comments

Comments
 (0)