tenseleyflow/loader / 78c5d51

Browse files

Tolerate lean TodoWrite payloads

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
78c5d51dbc02597c5dfd9d9146afedf8d0868088
Parents
4e907a5
Tree
b07571f

2 changed files

StatusFile+-
M src/loader/tools/workflow_tools.py 9 3
M tests/test_workflow_tools.py 26 0
src/loader/tools/workflow_tools.pymodified
@@ -28,14 +28,17 @@ class TodoItem:
2828
 
2929
     @classmethod
3030
     def from_dict(cls, data: dict[str, Any]) -> TodoItem:
31
+        content = str(data.get("content", "")).strip()
3132
         active_form = str(
3233
             data.get("active_form")
3334
             or data.get("activeForm")
3435
             or data.get("active")
3536
             or ""
3637
         ).strip()
38
+        if not active_form:
39
+            active_form = content
3740
         return cls(
38
-            content=str(data.get("content", "")).strip(),
41
+            content=content,
3942
             active_form=active_form,
4043
             status=str(data.get("status", "")).strip().lower(),
4144
         )
@@ -89,7 +92,10 @@ class TodoWriteTool(Tool):
8992
                             },
9093
                             "active_form": {
9194
                                 "type": "string",
92
-                                "description": "Progressive-tense form, e.g. 'Running tests'.",
95
+                                "description": (
96
+                                    "Optional progressive-tense form, e.g. "
97
+                                    "'Running tests'. Defaults to content when omitted."
98
+                                ),
9399
                             },
94100
                             "status": {
95101
                                 "type": "string",
@@ -97,7 +103,7 @@ class TodoWriteTool(Tool):
97103
                                 "description": "Current todo status.",
98104
                             },
99105
                         },
100
-                        "required": ["content", "active_form", "status"],
106
+                        "required": ["content", "status"],
101107
                     },
102108
                 }
103109
             },
tests/test_workflow_tools.pymodified
@@ -145,6 +145,32 @@ async def test_todo_write_rejects_invalid_payloads_and_sets_verification_nudge(
145145
     assert json.loads(nudged.output)["verification_nudge_needed"] is True
146146
 
147147
 
148
+@pytest.mark.asyncio
149
+async def test_todo_write_defaults_missing_active_form_to_content(
150
+    tmp_path: Path,
151
+) -> None:
152
+    tool = TodoWriteTool(tmp_path)
153
+
154
+    result = await tool.execute(
155
+        todos=[
156
+            {
157
+                "content": "Create the nginx chapters content",
158
+                "status": "completed",
159
+            }
160
+        ]
161
+    )
162
+
163
+    payload = json.loads(result.output)
164
+    assert result.is_error is False
165
+    assert payload["new_todos"] == [
166
+        {
167
+            "content": "Create the nginx chapters content",
168
+            "active_form": "Create the nginx chapters content",
169
+            "status": "completed",
170
+        }
171
+    ]
172
+
173
+
148174
 @pytest.mark.asyncio
149175
 async def test_ask_user_question_uses_callback_and_resolves_numbered_options() -> None:
150176
     tool = AskUserQuestionTool()