Bind restored handoffs to target agent identity#3566
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38fd7a842f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| handoff_data["target_agent"] = _serialize_agent_reference( | ||
| target_agent, | ||
| agent_identity_keys_by_id=agent_identity_keys_by_id, | ||
| ) |
There was a problem hiding this comment.
Bump schema for target-bound handoff snapshots
Adding target_agent changes the serialized RunState shape for pending handoff actions, but snapshots still advertise $schemaVersion 1.10, whose summary is unrelated to this field. Per the repo AGENTS.md RunState schema rule, shape changes need a CURRENT_SCHEMA_VERSION/SCHEMA_VERSION_SUMMARIES update; otherwise an older SDK that already accepts 1.10 can load these new snapshots, ignore target_agent, and resume duplicate-name handoffs with the old ambiguous tool-name behavior instead of failing fast.
Useful? React with 👍 / 👎.
| if _get_handoff_target_agent(handoff) is target_agent: | ||
| return handoff | ||
|
|
||
| return handoffs_map.get(tool_name) |
There was a problem hiding this comment.
Keep target-bound handoffs from falling back by name
When a serialized handoff includes target_agent but the restored current_agent.handoffs has no handoff with that exact target, this falls back to the bare tool-name map. In deployments where the graph changed or duplicate/overridden handoff tool names remain, a target-bound snapshot can still resume against a different agent, which defeats the new binding; reserve the tool-name fallback for legacy entries that do not have target_agent, and skip or raise on unmatched target-bound data.
Useful? React with 👍 / 👎.
38fd7a8 to
2e0d18d
Compare
Summary
Why
RunStatehandoff serialization currently records the generated handoff tool name for pending handoff actions. When a current agent has multiple same-name handoff targets, those targets can share the same generated handoff tool name. Restoring from a snapshot can then select a different target handoff than the one that produced the original pending action.Binding the serialized action to the target agent identity keeps restored handoff actions attached to the same target while retaining compatibility with legacy snapshots.
Tests
uv run ruff check src/agents/run_state.py tests/test_run_state.pyuv run pytest -q tests/test_run_state.py::TestDeserializeHelpers::test_last_processed_handoff_restores_duplicate_target_by_identity tests/test_run_state.py::TestDeserializeHelpers::test_serialization_uses_duplicate_identities_for_handoff_and_output_guardrails tests/test_run_state.py::TestDeserializeHelpers::test_model_response_serialization_roundtrip tests/test_run_state.py::TestRunState::test_from_json_restores_duplicate_name_current_agent_by_identity tests/test_run_state.py::TestRunStateSerializationEdgeCases::test_deserialize_processed_response_handoff_with_tool_nameuv run pytest -q tests/test_run_state.pygit diff --check