Add strip_fences option and fix exec() scoping for nested functions

- Add strip_fences field to PromptStep for removing markdown code fences
- Fix exec() to use same dict for globals and locals, allowing nested
  functions to access module-level imports
- Add GUI checkbox for strip_fences option
- Update CLAUDE.md with improved documentation

Co-Authored-By: Claude Opus 4.5 <[email protected]>
This commit is contained in:
rob
2026-02-17 16:14:45 -04:00
co-authored by Claude Opus 4.5
parent 33b807d545
commit f980fe05f1
5 changed files with 121 additions and 18 deletions
+13 -3
View File
@@ -221,7 +221,13 @@ def execute_prompt_step(
print(f"Error in prompt step: {result.error}", file=sys.stderr)
return "", False
return result.text, True
text = result.text
if step.strip_fences:
import re
text = re.sub(r'^```\w*\n', '', text.strip())
text = re.sub(r'\n```\s*$', '', text)
return text, True
def execute_code_step(
@@ -245,11 +251,15 @@ def execute_code_step(
code = substitute_variables(step.code, variables, warn_non_scalar=verbose)
# Create execution environment with variables
local_vars = dict(variables)
# IMPORTANT: Use the same dict for both globals and locals.
# When exec() gets separate dicts, nested functions can't access
# module-level imports (they look in globals, not the exec's locals).
local_vars = {"__builtins__": __builtins__}
local_vars.update(variables)
try:
# Execute the code with substituted variables
exec(code, {"__builtins__": __builtins__}, local_vars)
exec(code, local_vars, local_vars)
# Support comma-separated output vars (e.g., "a, b, c")
output_vars = [v.strip() for v in step.output_var.split(',')]