feat: preserve inline object type in template resolution (fixes #31)#32
Conversation
Fixes the double-serialization bug where templates in nested structures
like {"key": "${dict_var}"} would produce {"key": "{\"nested\": \"value\"}"}
instead of the correct {"key": {"nested": "value"}}.
Changes:
- Add is_simple_template() and extract_simple_template_var() helpers
- Rename resolve_string() to resolve_template() with type preservation
- Simple templates (${var}) now preserve original type (dict, list, int, etc.)
- Complex templates ("Hello ${name}") still return interpolated strings
- Update node_wrapper to use shared helper for DRY
- Update workflow_executor to use resolve_template
Fixes #31
Task-ID: 103
PR review fixes:
- Extract shared _VAR_NAME_PATTERN for consistency between TEMPLATE_PATTERN
and SIMPLE_TEMPLATE_PATTERN
- Stricter validation rejects invalid variable names (${123}, ${ var })
- Add test for invalid variable name patterns
Documentation:
- Update template-variables.md with type preservation behavior
- Update runtime CLAUDE.md with new method names
- Add comprehensive task-103 review document
Code Review: Template Type Preservation (PR #32)SummaryThis PR fixes a double-serialization bug where simple templates in nested structures (e.g., ✅ Critical — No blocking issues foundThe implementation is production-ready with no critical issues.
|
Add task specification for markdown-based workflow authoring format that compiles to IR. Optimizes for LLM authoring with literate programming, lintable code blocks, and token efficiency. Also: - Mark Task 103 as complete (merged in PR #32) - Reorganize roadmap: v0.7.0 for LLM authoring, v0.8.0 for expressiveness
Summary
Fixes the double-serialization bug where templates in nested structures like
{"key": "${dict_var}"}would produce{"key": "{\"nested\": \"value\"}"}instead of the correct{"key": {"nested": "value"}}.This enables the intuitive pattern of passing multiple data sources to shell commands:
{ "stdin": {"config": "${config}", "data": "${data}"}, "command": "jq '.config + .data'" }Changes
New helper methods in
TemplateResolver:is_simple_template()- detects if string is exactly${var}extract_simple_template_var()- extracts variable name from simple templateRenamed
resolve_string()→resolve_template()with type preservation:${var}) preserve original type (dict, list, int, bool, None)"Hello ${name}") return interpolated stringsUpdated callers:
workflow_executor.py- nested workflow param mappingnode_wrapper.py- refactored to use shared helper (DRY)Test Coverage
test_template_type_preservation.py- Core type preservation behavior (12 tests)test_shell_stdin_type_preservation.py- Integration tests with shell node (4 tests)resolve_template()(36 occurrences across 5 files)Created Docs
.taskmaster/tasks/task_103/implementation/implementation-plan.md.taskmaster/tasks/task_103/implementation/progress-log.mdFile Stats
Testing
Task-ID: 103