Skip to content

Commit b45fc62

Browse files
committed
fix(codegen): function prologue resolution edge cases
1 parent 80f0047 commit b45fc62

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,12 @@ function resolveWorkflowVariables(
387387
if (type === 'number') {
388388
variableValue = Number(variableValue)
389389
} else if (type === 'boolean') {
390-
variableValue = variableValue === 'true' || variableValue === true
390+
if (typeof variableValue === 'boolean') {
391+
// Already a boolean, keep as-is
392+
} else {
393+
const normalized = String(variableValue).toLowerCase().trim()
394+
variableValue = normalized === 'true' || normalized === '1'
395+
}
391396
} else if (type === 'json' && typeof variableValue === 'string') {
392397
try {
393398
variableValue = JSON.parse(variableValue)
@@ -689,6 +694,10 @@ export async function POST(req: NextRequest) {
689694
for (const [k, v] of Object.entries(contextVariables)) {
690695
if (v === undefined) {
691696
prologue += `const ${k} = undefined;\n`
697+
} else if (v === null) {
698+
prologue += `const ${k} = null;\n`
699+
} else if (typeof v === 'boolean' || typeof v === 'number') {
700+
prologue += `const ${k} = ${v};\n`
692701
} else {
693702
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
694703
}
@@ -764,6 +773,12 @@ export async function POST(req: NextRequest) {
764773
for (const [k, v] of Object.entries(contextVariables)) {
765774
if (v === undefined) {
766775
prologue += `${k} = None\n`
776+
} else if (v === null) {
777+
prologue += `${k} = None\n`
778+
} else if (typeof v === 'boolean') {
779+
prologue += `${k} = ${v ? 'True' : 'False'}\n`
780+
} else if (typeof v === 'number') {
781+
prologue += `${k} = ${v}\n`
767782
} else {
768783
prologue += `${k} = json.loads(${JSON.stringify(JSON.stringify(v))})\n`
769784
}

apps/sim/executor/variables/resolver.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,14 @@ export class VariableResolver {
157157

158158
let replacementError: Error | null = null
159159

160-
// Use generic utility for smart variable reference replacement
160+
const blockType = block?.metadata?.id
161+
const language =
162+
blockType === BlockType.FUNCTION
163+
? ((block?.config?.params as Record<string, unknown> | undefined)?.language as
164+
| string
165+
| undefined)
166+
: undefined
167+
161168
let result = replaceValidReferences(template, (match) => {
162169
if (replacementError) return match
163170

@@ -167,14 +174,18 @@ export class VariableResolver {
167174
return match
168175
}
169176

170-
const blockType = block?.metadata?.id
171177
const isInTemplateLiteral =
172178
blockType === BlockType.FUNCTION &&
173179
template.includes('${') &&
174180
template.includes('}') &&
175181
template.includes('`')
176182

177-
return this.blockResolver.formatValueForBlock(resolved, blockType, isInTemplateLiteral)
183+
return this.blockResolver.formatValueForBlock(
184+
resolved,
185+
blockType,
186+
isInTemplateLiteral,
187+
language
188+
)
178189
} catch (error) {
179190
replacementError = error instanceof Error ? error : new Error(String(error))
180191
return match

apps/sim/executor/variables/resolvers/block.ts

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,15 @@ export class BlockResolver implements Resolver {
162162
public formatValueForBlock(
163163
value: any,
164164
blockType: string | undefined,
165-
isInTemplateLiteral = false
165+
isInTemplateLiteral = false,
166+
language?: string
166167
): string {
167168
if (blockType === 'condition') {
168169
return this.stringifyForCondition(value)
169170
}
170171

171172
if (blockType === 'function') {
172-
return this.formatValueForCodeContext(value, isInTemplateLiteral)
173+
return this.formatValueForCodeContext(value, isInTemplateLiteral, language)
173174
}
174175

175176
if (blockType === 'response') {
@@ -210,14 +211,29 @@ export class BlockResolver implements Resolver {
210211
return String(value)
211212
}
212213

213-
private formatValueForCodeContext(value: any, isInTemplateLiteral: boolean): string {
214+
private formatValueForCodeContext(
215+
value: any,
216+
isInTemplateLiteral: boolean,
217+
language?: string
218+
): string {
219+
const isPython = language === 'python'
220+
214221
if (isInTemplateLiteral) {
215222
if (typeof value === 'string') {
216223
return value
217224
}
218225
if (typeof value === 'object' && value !== null) {
219226
return JSON.stringify(value)
220227
}
228+
if (typeof value === 'boolean') {
229+
return isPython ? (value ? 'True' : 'False') : String(value)
230+
}
231+
if (value === undefined) {
232+
return isPython ? 'None' : 'undefined'
233+
}
234+
if (value === null) {
235+
return isPython ? 'None' : 'null'
236+
}
221237
return String(value)
222238
}
223239

@@ -228,10 +244,13 @@ export class BlockResolver implements Resolver {
228244
return JSON.stringify(value)
229245
}
230246
if (value === undefined) {
231-
return 'undefined'
247+
return isPython ? 'None' : 'undefined'
232248
}
233249
if (value === null) {
234-
return 'null'
250+
return isPython ? 'None' : 'null'
251+
}
252+
if (typeof value === 'boolean') {
253+
return isPython ? (value ? 'True' : 'False') : String(value)
235254
}
236255
return String(value)
237256
}

apps/sim/lib/execution/isolated-vm-worker.cjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ async function executeCode(request) {
132132
for (const [key, value] of Object.entries(contextVariables)) {
133133
if (value === undefined) {
134134
await jail.set(key, undefined)
135+
} else if (value === null) {
136+
await jail.set(key, null)
135137
} else {
136138
await jail.set(key, new ivm.ExternalCopy(value).copyInto())
137139
}

0 commit comments

Comments
 (0)