Fix stack 10: typed model/reasoning_effort fields + FinishReason enum#34
Merged
ebarti merged 3 commits intoJul 2, 2026
Merged
Conversation
2c1512b to
76ee95f
Compare
61c32c4 to
b3da251
Compare
660535d to
3cd343d
Compare
b3da251 to
23c6d0c
Compare
…ocabulary - Promote model and reasoning_effort to typed AgentTask fields instead of the stringly-typed metadata['model'] / metadata['reasoning_effort'] magic keys. Adapters prefer the fields and fall back to the metadata aliases, so existing callers keep working while the typed surface becomes the documented path. - Add a FinishReason(str, Enum) canonical vocabulary (done/failed/max_turns/ max_tokens/interrupted) that callers can match against instead of bare string literals. finish_reason stays typed str for forward-compat; because FinishReason is a str subclass, both == FinishReason.X and == 'x' hold. Refs REVIEW.md §5.3, §5.4.
…3.11+
(str, Enum) format/str changed in 3.11: f"{FinishReason.FAILED}" produced
"FinishReason.FAILED", leaking the enum name into event summaries for
callers who pass members. Adopt the StrEnum __str__/__format__ assignments
so rendering matches the wire value on every supported Python.
… keyword-only The first-class model/reasoning_effort fields shipped only half-wired: Codex consumed both, Claude and Antigravity consumed model only, so a requested reasoning_effort silently no-oped on two of three adapters. - Claude maps reasoning_effort -> effort= (claude-agent-sdk >= 0.2.87); on an older SDK the drop is recorded in dropped_options, not fatal, since effort is a quality preference rather than a security posture. - Antigravity raises UnsupportedTaskInputError: google-antigravity 0.1.x exposes no reasoning-effort control, and an explicit typed request must not silently no-op. The legacy metadata alias stays ignored as before for this adapter. - AgentTask.model / .reasoning_effort become kw_only so inserting them mid-dataclass does not shift the positional layout that predates them (the fourth positional argument is still working_directory).
23c6d0c to
f6537d5
Compare
3cd343d to
336bc6c
Compare
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.
Stacked review-fix PR 10/N (base:
review-fixes/09-open-kind-lifecycle).REVIEW.md §5.3, §5.4 — typed public surface:
model/reasoning_effortare now first-classAgentTaskfields, not stringly-typedmetadatamagic keys. Adapters prefer the fields and fall back to themetadataaliases, so existing callers keep working.FinishReason(str, Enum)gives callers a canonical vocabulary (done/failed/max_turns/max_tokens/interrupted) to match against instead of bare literals.finish_reasonstays typedstrfor forward-compat; sinceFinishReasonsubclassesstr, both== FinishReason.Xand== "x"hold, so nothing breaks.Tests: typed model/effort preference + metadata-alias override, FinishReason string equivalence. Full suite 176 passed / 12 skipped; ruff + mypy strict clean.
Re-review amendment.
FinishReasonadopts theStrEnum__str__/__format__assignments: on Python 3.11+ a plain(str, Enum)rendersf"{FinishReason.FAILED}"as"FinishReason.FAILED", leaking the enum name into event summaries for callers who pass members. Rendering now matches the wire value on every supported Python, with tests.Round 2 (re-review follow-up)
reasoning_effortis now wired end-to-end instead of half-wired: Claude maps it toeffort=(claude-agent-sdk >= 0.2.87; older SDKs record the drop indropped_options— a quality preference, not a security kwarg), and Antigravity rejects it with a typed error since google-antigravity 0.1.x has no reasoning-effort control (the legacy metadata alias stays ignored there, as before).AgentTask.model/AgentTask.reasoning_effortare nowkw_only, so inserting them mid-dataclass no longer shifts the positional layout that predates them (the fourth positional argument is stillworking_directory).