Centria: Pass boolean and integer template values in HTTP Block (#4435)

This commit is contained in:
Marc Kelechava
2026-01-12 09:50:51 -08:00
committed by GitHub
parent 4b61b7c041
commit b1c41492f9
2 changed files with 44 additions and 3 deletions

View File

@@ -107,6 +107,28 @@ else:
jinja_sandbox_env = SandboxedEnvironment()
# Sentinel marker for native JSON type injection via | json filter.
_JSON_TYPE_MARKER = "__SKYVERN_RAW_JSON__"
def _json_type_filter(value: Any) -> str:
"""Jinja filter that marks a value for native JSON type injection.
Usage in templates: {{ some_bool | json }}
The filter serializes the value to JSON and wraps it with sentinel markers.
When _render_templates_in_json() detects these markers, it unwraps and
parses the JSON to get the native typed value (bool, int, list, etc.).
Args:
value: Any JSON-serializable value (bool, int, float, str, list, dict, None).
"""
return f"{_JSON_TYPE_MARKER}{json.dumps(value)}{_JSON_TYPE_MARKER}"
jinja_sandbox_env.filters["json"] = _json_type_filter
# Mapping from TaskV2Status to the corresponding BlockStatus. Declared once at
# import time so it is not recreated on each block execution.
TASKV2_TO_BLOCK_STATUS: dict[TaskV2Status, BlockStatus] = {
@@ -4032,11 +4054,30 @@ class HttpRequestBlock(Block):
This is required because HTTP request bodies are often deeply nested
dict/list structures, and templates may appear at any depth.
Supports {{ expr | json }} filter for type-preserving JSON injection.
"""
if isinstance(value, str):
return self.format_block_parameter_template_from_workflow_run_context(
rendered = self.format_block_parameter_template_from_workflow_run_context(
value, workflow_run_context, **template_kwargs
)
if rendered.startswith(_JSON_TYPE_MARKER) and rendered.endswith(_JSON_TYPE_MARKER):
json_str = rendered[len(_JSON_TYPE_MARKER) : -len(_JSON_TYPE_MARKER)]
try:
return json.loads(json_str)
except json.JSONDecodeError:
raise FailedToFormatJinjaStyleParameter(
value, f"Raw JSON filter produced invalid JSON: {json_str}"
)
elif _JSON_TYPE_MARKER in rendered:
raise FailedToFormatJinjaStyleParameter(
value,
"The '| json' filter can only be used for complete value replacement. "
"It cannot be combined with other text (e.g., 'prefix-{{ val | json }}'). "
"Remove the surrounding text or remove the '| json' filter.",
)
return rendered
if isinstance(value, list):
return [_render_templates_in_json(item) for item in value]
if isinstance(value, dict):