feat: spill Pydantic BaseModel tool results - #11
Open
thomwebb wants to merge 1 commit into
Open
Conversation
Contributor
|
[Wes's CodePuppy Agent Review] Adds mutable Pydantic Qodo Merge TriageQodo: not configured for OSS/public GitHub. Really Should Fix TheseNone. NitsNone. Scope observations — not changes requested on this PR
|
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.
What
The spill plugin now also bounds Pydantic
BaseModeltool results, not just dicts.This closes the plugin's biggest practical gap: most big-output built-in tools return models, not dicts —
agent_run_shell_command→ShellCommandOutput,list_files→ListFileOutput,invoke_agent→AgentInvokeOutput— and until now those all passed through spill untouched. (The dict-returning tools, e.g.create_file's{"path", "message"}, were the small ones.)How (small on purpose)
_field_map()— adict(result)view for models; the existing planner/notice/store machinery is reused verbatim, operating on field names instead of dict keys._commit_replacements()— item assignment for dicts,setattrfor models; on a rejected assignment (frozen model,validate_assignmentvalidator) it restores already-applied fields and re-raises, and the outer hook's existing fail-open path keeps the result byte-identical inline.BaseModelwith oversized plain-string top-level fields is eligible; exotic cases (frozen, rejecting validators) simply stay inline.Verified end-to-end against current app
main: aShellCommandOutputwith 4 KBstdoutat a 500-byte cap becomes head/tail preview + retrieval notice, file written verbatim.Tests (
tests/test_spill_models.py, local models — no app-tool imports)validate_assignmentvalidator rejects a previewFull spill suite on app
main:21 passed, 4 skipped(the 4 skips are the per-agent tests gated on the runtime execution-context seam, from #9). Ruff clean.