Repository navigation
Restore durable Responses request context - #48605
Shiva S (Shivakishore14) merged 3 commits into
Conversation
Rebind reconstructed user, call, and session identity while durable response handlers execute, including recovered tasks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdc32ee9-9e8f-4a1c-ba27-bdfa318afa1e
|
Azure Pipelines: Successfully started running 1 pipeline(s). 9 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
|
Azure Pipelines: Successfully started running 1 pipeline(s). 9 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Restores ambient request identity during durable Responses handler execution.
Changes:
- Rebinds user, call, and session identity for durable handlers.
- Covers synchronous, streaming, and recovered execution.
- Documents the fix in the changelog.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
CHANGELOG.md |
Records the request-context fix. |
_orchestrator.py |
Adds and applies durable context rebinding. |
test_streaming_request_context.py |
Tests stored synchronous and streaming handlers. |
test_recovery_reconstruction.py |
Tests reconstructed identity and ambient context. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (1)
sdk/agentserver/azure-ai-agentserver-responses/azure/ai/agentserver/responses/hosting/_orchestrator.py:110
_iter_with_winddownresumes this iterator throughasyncio.wait_for(aiter.__anext__(), ...)after cancellation (_orchestrator.py:206), which executes__anext__in a copied task context. If the handler then completes or times out, thisfinallytries to reset a token created in the parent context and raisesValueError; the cancellation path can be recorded as a handler failure and the parent task retains the bound identity. Bind and reset around each individual__anext__call so every token is consumed in the same task/context that created it.
finally:
if token is not None:
reset_request_context(token)
[Pilot] PR Pipeline Failure AnalysisA CI pipeline failed on this pull request. Here is an automated analysis of what went wrong and how to get the build green. What failedTwo jobs failed in build 6712729:
Recommended next steps
Raw pipeline analysis (azsdk ci analyze)
|
Bind ambient context independently for each handler iterator advancement and preserve empty platform identity values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdc32ee9-9e8f-4a1c-ba27-bdfa318afa1e
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.
Suppressed comments (2)
sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_streaming_request_context.py:132
- Constructing
TestClientwithout entering it skips lifespan startup, and the orchestrator deliberately degrades such test clients to its non-durable fallback. This streaming test therefore does not verify ambient context inside a durable streaming task. Enter the client context before issuing the request so the resilient task manager is initialized.
client = _build_capturing_client(captured, resilient=True, storage_dir=tmp_path / "stream")
with client.stream(
"POST",
"/responses",
sdk/agentserver/azure-ai-agentserver-responses/tests/contract/test_streaming_request_context.py:124
- This test never enters
TestClientas a context manager, so Starlette's lifespan does not run._start_resilient_backgroundexplicitly handles this case by catchingTaskManagerNotInitializedand using the non-durable in-process fallback (_orchestrator.py:3971-3979, 4054-4070). Consequently, this does not cover the durable foreground execution named by the PR and can pass via inherited request context. Start the client lifespan so the request actually runs through the resilient task subsystem.
This issue also appears on line 128 of the same file.
def test_stored_sync_handler_sees_call_id_and_user_id(self, tmp_path: Path) -> None:
captured: dict[str, Any] = {}
client = _build_capturing_client(captured, resilient=True, storage_dir=tmp_path / "sync")
Summary
get_request_context()while durable Responses handlers executeResponseContext.platform_contextand the ambient AgentServer request contextThis fixes the root cause observed in microsoft-foundry/foundry-samples-pr#910, where the hosted request contained identity and durable storage received it, but developer handlers saw
Nonethroughget_request_context().Validation
py -3.12 -m pytest tests\unit tests\contract tests\e2e\test_recovery_reconstruction.py -q(1156 passed, 3 skipped)azpysdk pyright .git diff --check