fix(codegen): function prologue resolution edge cases

This commit is contained in:
Vikhyath Mondreti
2026-01-26 00:03:15 -08:00
parent 80f00479a3
commit b45fc62e7b
4 changed files with 56 additions and 9 deletions

View File

@@ -387,7 +387,12 @@ function resolveWorkflowVariables(
if (type === 'number') {
variableValue = Number(variableValue)
} else if (type === 'boolean') {
variableValue = variableValue === 'true' || variableValue === true
if (typeof variableValue === 'boolean') {
// Already a boolean, keep as-is
} else {
const normalized = String(variableValue).toLowerCase().trim()
variableValue = normalized === 'true' || normalized === '1'
}
} else if (type === 'json' && typeof variableValue === 'string') {
try {
variableValue = JSON.parse(variableValue)
@@ -689,6 +694,10 @@ export async function POST(req: NextRequest) {
for (const [k, v] of Object.entries(contextVariables)) {
if (v === undefined) {
prologue += `const ${k} = undefined;\n`
} else if (v === null) {
prologue += `const ${k} = null;\n`
} else if (typeof v === 'boolean' || typeof v === 'number') {
prologue += `const ${k} = ${v};\n`
} else {
prologue += `const ${k} = JSON.parse(${JSON.stringify(JSON.stringify(v))});\n`
}
@@ -764,6 +773,12 @@ export async function POST(req: NextRequest) {
for (const [k, v] of Object.entries(contextVariables)) {
if (v === undefined) {
prologue += `${k} = None\n`
} else if (v === null) {
prologue += `${k} = None\n`
} else if (typeof v === 'boolean') {
prologue += `${k} = ${v ? 'True' : 'False'}\n`
} else if (typeof v === 'number') {
prologue += `${k} = ${v}\n`
} else {
prologue += `${k} = json.loads(${JSON.stringify(JSON.stringify(v))})\n`
}

View File

@@ -157,7 +157,14 @@ export class VariableResolver {
let replacementError: Error | null = null
// Use generic utility for smart variable reference replacement
const blockType = block?.metadata?.id
const language =
blockType === BlockType.FUNCTION
? ((block?.config?.params as Record<string, unknown> | undefined)?.language as
| string
| undefined)
: undefined
let result = replaceValidReferences(template, (match) => {
if (replacementError) return match
@@ -167,14 +174,18 @@ export class VariableResolver {
return match
}
const blockType = block?.metadata?.id
const isInTemplateLiteral =
blockType === BlockType.FUNCTION &&
template.includes('${') &&
template.includes('}') &&
template.includes('`')
return this.blockResolver.formatValueForBlock(resolved, blockType, isInTemplateLiteral)
return this.blockResolver.formatValueForBlock(
resolved,
blockType,
isInTemplateLiteral,
language
)
} catch (error) {
replacementError = error instanceof Error ? error : new Error(String(error))
return match

View File

@@ -162,14 +162,15 @@ export class BlockResolver implements Resolver {
public formatValueForBlock(
value: any,
blockType: string | undefined,
isInTemplateLiteral = false
isInTemplateLiteral = false,
language?: string
): string {
if (blockType === 'condition') {
return this.stringifyForCondition(value)
}
if (blockType === 'function') {
return this.formatValueForCodeContext(value, isInTemplateLiteral)
return this.formatValueForCodeContext(value, isInTemplateLiteral, language)
}
if (blockType === 'response') {
@@ -210,7 +211,13 @@ export class BlockResolver implements Resolver {
return String(value)
}
private formatValueForCodeContext(value: any, isInTemplateLiteral: boolean): string {
private formatValueForCodeContext(
value: any,
isInTemplateLiteral: boolean,
language?: string
): string {
const isPython = language === 'python'
if (isInTemplateLiteral) {
if (typeof value === 'string') {
return value
@@ -218,6 +225,15 @@ export class BlockResolver implements Resolver {
if (typeof value === 'object' && value !== null) {
return JSON.stringify(value)
}
if (typeof value === 'boolean') {
return isPython ? (value ? 'True' : 'False') : String(value)
}
if (value === undefined) {
return isPython ? 'None' : 'undefined'
}
if (value === null) {
return isPython ? 'None' : 'null'
}
return String(value)
}
@@ -228,10 +244,13 @@ export class BlockResolver implements Resolver {
return JSON.stringify(value)
}
if (value === undefined) {
return 'undefined'
return isPython ? 'None' : 'undefined'
}
if (value === null) {
return 'null'
return isPython ? 'None' : 'null'
}
if (typeof value === 'boolean') {
return isPython ? (value ? 'True' : 'False') : String(value)
}
return String(value)
}

View File

@@ -132,6 +132,8 @@ async function executeCode(request) {
for (const [key, value] of Object.entries(contextVariables)) {
if (value === undefined) {
await jail.set(key, undefined)
} else if (value === null) {
await jail.set(key, null)
} else {
await jail.set(key, new ivm.ExternalCopy(value).copyInto())
}