Fix ForLoop blocks not executing with cached scripts (#SKY-7751) (#4630)
This commit is contained in:
32
skyvern/core/script_generations/CLAUDE.md
Normal file
32
skyvern/core/script_generations/CLAUDE.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Script Generation Context
|
||||
|
||||
## Key Constants
|
||||
|
||||
- `SCRIPT_TASK_BLOCKS` - Block types that have task_id and actions (task, navigation, extraction, etc.)
|
||||
- `BLOCK_TYPES_THAT_SHOULD_BE_CACHED` in `workflow/service.py` - Block types eligible for caching (includes for_loop)
|
||||
|
||||
## Script Block Requirements for `run_with: code`
|
||||
|
||||
For a workflow to execute with cached scripts (`run_with: code`), ALL top-level blocks must have:
|
||||
1. A `script_block` database entry
|
||||
2. A non-null `run_signature` field
|
||||
|
||||
Without these, the system falls back to `run_with: agent`.
|
||||
|
||||
## Adding New Cacheable Block Types
|
||||
|
||||
When adding a new block type that should support cached execution:
|
||||
1. Add to `BLOCK_TYPES_THAT_SHOULD_BE_CACHED` in `workflow/service.py`
|
||||
2. Add handling in `generate_workflow_script_python_code()` with BOTH:
|
||||
- `create_or_update_script_block()` - stores metadata in database
|
||||
- `append_block_code(block_code)` - adds code to generated script output
|
||||
3. Ensure `run_signature` is set (the code statement to execute the block)
|
||||
|
||||
**CRITICAL**: Every block type needs BOTH database entry AND script output. Missing `append_block_code()` causes runtime failures even if database entries exist.
|
||||
|
||||
## Block Processing Order in generate_script.py
|
||||
|
||||
1. `task_v1_blocks` - Blocks in `SCRIPT_TASK_BLOCKS`
|
||||
2. `task_v2_blocks` - task_v2 blocks with child blocks
|
||||
3. `for_loop_blocks` - ForLoop container blocks
|
||||
4. `__start_block__` - Workflow entry point
|
||||
@@ -2305,6 +2305,50 @@ async def generate_workflow_script_python_code(
|
||||
|
||||
append_block_code(block_code)
|
||||
|
||||
# Handle for_loop blocks
|
||||
# ForLoop blocks need script_block entries with run_signature so they can be executed via cached scripts
|
||||
for_loop_blocks = [block for block in blocks if block["block_type"] == "for_loop"]
|
||||
for for_loop_block in for_loop_blocks:
|
||||
for_loop_label = for_loop_block.get("label") or f"for_loop_{for_loop_block.get('workflow_run_block_id')}"
|
||||
|
||||
cached_source = cached_blocks.get(for_loop_label)
|
||||
use_cached = cached_source is not None and for_loop_label not in updated_block_labels
|
||||
|
||||
block_workflow_run_id = for_loop_block.get("workflow_run_id") or run_id
|
||||
block_workflow_run_block_id = for_loop_block.get("workflow_run_block_id")
|
||||
|
||||
if use_cached:
|
||||
assert cached_source is not None
|
||||
block_code = cached_source.code
|
||||
run_signature = cached_source.run_signature
|
||||
block_workflow_run_id = cached_source.workflow_run_id
|
||||
block_workflow_run_block_id = cached_source.workflow_run_block_id
|
||||
else:
|
||||
# Build the for loop statement
|
||||
for_loop_stmt = _build_for_loop_statement(for_loop_label, for_loop_block)
|
||||
temp_module = cst.Module(body=[for_loop_stmt])
|
||||
block_code = temp_module.code
|
||||
run_signature = block_code.strip()
|
||||
|
||||
if script_id and script_revision_id and organization_id:
|
||||
try:
|
||||
await create_or_update_script_block(
|
||||
block_code=block_code,
|
||||
script_revision_id=script_revision_id,
|
||||
script_id=script_id,
|
||||
organization_id=organization_id,
|
||||
block_label=for_loop_label,
|
||||
update=pending,
|
||||
run_signature=run_signature,
|
||||
workflow_run_id=block_workflow_run_id,
|
||||
workflow_run_block_id=block_workflow_run_block_id,
|
||||
input_fields=None,
|
||||
)
|
||||
except Exception as e:
|
||||
LOG.error("Failed to create for_loop script block", error=str(e), exc_info=True)
|
||||
|
||||
append_block_code(block_code)
|
||||
|
||||
# --- runner ---------------------------------------------------------
|
||||
run_fn = _build_run_fn(blocks, workflow_run_request)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user