fix(todo): accept the TodoItem shape todo_write declares - #29
Open
eastagiletracker wants to merge 1 commit into
Open
Conversation
todo_write is annotated `todos: list[TodoItem]`, but its validation and rendering index every item as a mapping. Passing the declared model returns "Error: Todo item 0 missing 'content' field", because BaseModel.__iter__ yields (name, value) tuples rather than field names, and passing an attribute-style item raises TypeError. Normalize each item to a dict before validation, accepting mappings, pydantic models and attribute objects — mirroring the handling already used in thought_logger._display_todo_list. Dict callers, including the decoded tool-call path, are unaffected.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR proposes a fix for
ToDoResource.todo_write(), which rejects theTodoItemtype its own signature declares. We include this PR work along with a full history of your repo at https://eastagiletracker.com/projects/252. You can sign in with your GitHub ID to claim ownership of the project.The defect
todo_write()is annotatedtodos: list[TodoItem], but its validation and rendering index every item as a mapping (if "content" not in todo,todo["status"],todo['activeForm']). Passing the very model the signature declares does not raise — it silently returns a false validation error, becauseBaseModel.__iter__yields(name, value)tuples, so"content" not in todois always true. Passing an attribute-style item, such as theTodoItemdataclass indana.core.runtime.protocols, raisesTypeErrorinstead.Reproduced on
developatacb72ec:To be precise about the blast radius: the tool-call path decodes JSON to dicts, so agents driving
todo_writethrough an LLM are unaffected today. What breaks is calling the method directly on its published signature —ToDoResourceis exported fromdana.core.resourceand attached byDanaCodingAgentand the explore agent — and any caller holding the runtimeTodoItemdataclass, which crashes outright.The change
_as_mapping()normalizes each item to a dict before validation, accepting mappings, pydantic models and attribute objects. This mirrors the handling already inthought_logger._display_todo_list, which comments "Handle both TodoItem objects and dicts" — the same two shapes, reconciled in one more place. Dict callers, including the decoded tool-call path, are byte-for-byte unaffected, andget_todos()now genuinely returns thelist[dict]it is annotated to return whatever shape went in. An item that is genuinely missing a field, like the two-field runtime dataclass, now gets the intendedmissing 'activeForm' fieldmessage rather than aTypeError.Verification, with
tests/unit/test_todo_resource.pyadded — this resource had no direct tests before:uv run pytest tests/ -m "not live and not deep"goes from 1898 passed / 38 skipped on a cleandevelopto 1910 passed / 38 skipped here — the 12 new tests, no new failures and no change in what is skipped.uv run ruff check dana/passes, as it does on the baseline.Covered: each accepted shape, all three rendering identically for the same todo, mixed shapes in one call, stored state, missing fields, invalid status, the error index in a mixed list, and the empty list.
How this was managed
We tracked this work on a board imported from this repository's own issues and pull requests (28 stories), so the fix has a story you can read start to finish: todo_write rejects the TodoItem type its own signature declares, on the Dana Runtime board.
If you'd rather not receive contributions like this, reply
no-more-prson this pull request and we won't open any further ones on your repositories.Lawrence W. Sinclair
CEO / East Agile
linkedin.com/in/lwsinclair/
eastagile.com