Skip to content

Commit 418c139

Browse files
feat: Add workflow session persistence and loop step support (#542)
* wip: Refactor workflow operations - add loop step and array indexing Temporary commit of workflow automation refactoring: - Add loop step implementation with nested loop support - Enhance WorkflowContext with array indexing (e.g., tasks[0].items) - Replace AI split/mapreduce operations with decompose operation - Add operation schemas for better type safety - Update tests to reflect new loop step functionality - Remove deprecated workflow examples 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: Add session persistence to workflow engine and enhance error logging - Add SessionManager integration to WorkflowEngine for state persistence - Support session creation, resumption, and listing for workflows - Save workflow state, step results, and outputs to sessions automatically - Add load_from_session and resume_from_session methods for workflow recovery - Update AI research demo to use session persistence and display session info - Switch demo from copilot to claude CLI with haiku model - Enhance CLI executor error logging with stdout/stderr details This enables workflows to persist their state for debugging, resumption, and long-running operations that may need to be interrupted and resumed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> --------- Co-authored-by: Claude <[email protected]>
1 parent 18f8fea commit 418c139

23 files changed

+1810
-2019
lines changed

plugins/automation/runtime_data/state.py

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,23 @@ def __init__(
8383

8484
def get(self, path: str, default: Any = None) -> Any:
8585
"""
86-
Get value from context using dot notation path.
86+
Get value from context using dot notation path with array indexing.
8787
8888
Supports:
8989
- inputs.key
9090
- steps.step_id.result
91+
- steps.step_id.result.tasks[0].items
9192
- steps.step_id.status
9293
- outputs.key
9394
9495
Args:
95-
path: Dot-notation path (e.g., "steps.step1.result")
96+
path: Dot-notation path with array indexing (e.g., "steps.step1.result.tasks[0].items")
9697
default: Default value if path not found
9798
9899
Returns:
99100
Value at path or default
100101
"""
102+
101103
parts = path.split(".")
102104
if not parts:
103105
return default
@@ -106,6 +108,10 @@ def get(self, path: str, default: Any = None) -> Any:
106108
if parts[0] == "inputs":
107109
obj = self.inputs
108110
parts = parts[1:]
111+
elif parts[0] in self.inputs:
112+
# Direct access to input variable with nested path (e.g., "chunk.items")
113+
obj = self.inputs[parts[0]]
114+
parts = parts[1:]
109115
elif parts[0] == "steps":
110116
if len(parts) < 2:
111117
return default
@@ -130,14 +136,41 @@ def get(self, path: str, default: Any = None) -> Any:
130136
else:
131137
return default
132138

133-
# Navigate remaining path
139+
# Navigate remaining path with array indexing support
134140
for part in parts:
135-
if isinstance(obj, dict):
136-
obj = obj.get(part)
137-
if obj is None:
141+
# Check for array indexing like "tasks[0]"
142+
if "[" in part and part.endswith("]"):
143+
# Split into key and index
144+
key, index_str = part[:-1].split("[", 1)
145+
try:
146+
index = int(index_str)
147+
except ValueError:
148+
return default
149+
150+
# Get the array/list
151+
if isinstance(obj, dict):
152+
obj = obj.get(key)
153+
if obj is None:
154+
return default
155+
else:
156+
return default
157+
158+
# Index into the array
159+
if isinstance(obj, list):
160+
if 0 <= index < len(obj):
161+
obj = obj[index]
162+
else:
163+
return default
164+
else:
138165
return default
139166
else:
140-
return default
167+
# Regular dictionary access
168+
if isinstance(obj, dict):
169+
obj = obj.get(part)
170+
if obj is None:
171+
return default
172+
else:
173+
return default
141174

142175
return obj if obj is not None else default
143176

0 commit comments

Comments
 (0)