Repository navigation
Commit a94a8aa
[agentserver-core] Update task client to Routines=V2Preview opt-in header (#48617)
* [agentserver] Gate resilient TaskManager on the explicit enablement flag
Make the durable-response/task subsystem strictly opt-in via
`set_resilient_tasks_enabled` (auto-set by `resilient_background` /
`steerable_conversations`). Previously every responses host wrapped all
`store=true` responses in internal resilient tasks and therefore forced the
boot-time recovery scan, even for a plain host that opted into nothing.
Core (_base.py):
- Construct the TaskManager (and run startup recovery) ONLY when the switch is
enabled. When off, no manager is installed; `get_task_manager()` raises
`TaskManagerNotInitialized` and callers degrade to non-durable in-process
execution. A plain host pays nothing: no manager, no task-store call.
Responses:
- ResilientResponseOrchestrator auto-enables the switch when
`resilient_background` or `steerable_conversations` is set, so resilient
deployments keep full Row 1/2/3 recovery.
- _start_resilient_background swallows `TaskManagerNotInitialized` at the
single outer catch and runs the handler in-process (non-durable). Removed the
hosted fail-loud branch and the now-unused `_is_hosted_environment` helper.
Tests/samples:
- Updated the opt-in gate tests for gated construction.
- Rewrote the resilient-start-failure contract test: no-manager now swallows and
runs in-process (real task-store start failures with a manager present still
fail loud as platform errors).
- Conformance `_test_handler` enables the switch so Row 2
(resilient_background=False) still validates mark-failed-on-crash.
- Invocations resilient samples (research, multiturn, langgraph) enable the
switch explicitly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Log a startup notice when responses resilience is disabled
Emit a one-time WARNING at responses host startup when the durable-response
subsystem is off (store=true responses are non-durable across an ungraceful
crash), and an INFO when it is enabled, so operators are not surprised by the
plain non-durable default. Reflects the final resolved state (after the
resilient orchestrator's resilient_background/steerable auto-enable).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Auto-enable resilient tasks only for resilient_background
Narrow the responses auto-enable of the resilient-tasks switch to
`resilient_background` only; `steerable_conversations` no longer implicitly
enables the durable subsystem. Recovery is tied to resilient_background alone; a
steerable host that wants durability sets resilient_background=True (or the
switch explicitly). The two-switch UX is a known rough edge to smooth over
post-Public-Preview.
Steering conformance handler now enables the switch explicitly, since steering
(multi-turn input queuing) needs the TaskManager regardless of
resilient_background.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Address PR feedback: docs, docstring, test, revert invocations samples
- Rewrite set_resilient_tasks_enabled/_enablement docs to describe the switch as
the opt-in gate for TaskManager construction (not just the recovery scan), and
that a declared @task no longer implicitly enables it.
- Update core README + tasks-guide to show the required opt-in, and core/responses
CHANGELOGs with the breaking-change note.
- Fix _start_resilient_background docstring: TaskManagerNotInitialized is now
swallowed (in-process fallback) regardless of hosting; only real task-start
failures raise/tag platform errors.
- Rewrite the swallow contract test to enter the ASGI lifespan with the switch
off, assert no TaskManager is installed, and poll GET to completion.
- Revert the 3 invocations resilient sample edits (unrelated api.md whitespace
consistency drift); sample opt-in to be handled as a follow-up.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Fix contract test isolation + actionable TaskManagerNotInitialized message
- The switch-off contract tests asserted get_task_manager() raises, but the
process-global TaskManager singleton can leak from a prior test in a shared
pytest process (CI), causing DID-NOT-RAISE. The _switch_off fixture now also
snapshots/resets/restores the manager singleton (set_task_manager(None)), so
the no-manager path is exercised deterministically.
- Make the TaskManagerNotInitialized message actionable: it now names
set_resilient_tasks_enabled(True) and the responses resilient_background=True
option instead of a generic 'ensure resilient tasks are enabled'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Make no-manager contract tests deterministic (fix CI flake)
The switch-off contract tests asserted get_task_manager() raises after entering
the lifespan, but that depended on process-global manager/flag state (mutated by
1400+ other tests) and on which core build performs manager construction — making
it fail deterministically in CI while passing locally. Force the no-manager
condition explicitly via set_task_manager(None) inside the running lifespan so
the responses SWALLOW path is exercised robustly. Core's gating of manager
construction is covered separately by the core opt-in tests.
Verified in a Linux (WSL) full-suite run: both tests pass among 1436 others.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Fix pylint R0915: extract responses startup logging to a helper
The added durability-mode startup log pushed ResponsesAgentServerHost.__init__
over the 50-statement pylint limit (53/50, R0915). Move the startup config +
resilience-mode logging into a module-level _log_startup_configuration() helper,
called once from __init__. Also correct the resilience note to reflect that only
resilient_background auto-enables the subsystem (not steerable_conversations).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Address review: fix ref leak, boot fail-fast, test isolation
Copilot review fixes:
- _RUNTIME_REFS leak: start_resilient() cached per-request refs keyed by
response_id but only the resilient task body's finally evicts them. When
primitive .start() raises (e.g. TaskManagerNotInitialized on the opt-out
fallback), the body never runs, permanently retaining record/context/parsed/
cancel. Pop the entry on any start failure before propagating.
- Ambiguous TaskManagerNotInitialized: instead of a per-request switch check
(which broke non-lifespan test clients that auto-enable via
resilient_background), AgentServerHost now FAILS THE LIFESPAN when resilient
tasks are enabled but manager construction/startup fails - fail-fast at boot.
A missing manager at request time therefore means opt-out, so the responses
swallow stays unconditional (in-process non-durable fallback).
- ASCII-only TaskManagerNotInitialized message (the em-dash broke latin-1 HTTP
header encoding on the platform-error path).
Test isolation:
- Add an autouse fixture in the responses tests that snapshots/restores the
process-global resilient-tasks switch + TaskManager singleton per test, so a
resilient_background=True host in one test no longer leaks enabled state into
later tests (was causing integration failures when run after resilient e2e).
- Add a core test asserting the lifespan fails fast on boot startup failure.
Verified on Linux (WSL): core optin 12, responses contract 6, and the full
responses suite (minus the POSIX-only crash-harness dir) 1436 passed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* [agentserver] Clear TaskManager singleton when boot startup fails
When resilient tasks are enabled and TaskManager.startup() raises, the manager
was already installed globally via set_task_manager() but the lifespan aborts
before the shutdown block, leaving a failed/partially-started manager visible
through get_task_manager(). Wrap startup with best-effort shutdown + clear the
singleton before re-raising. The startup-failure test now asserts the singleton
is cleared (and shutdown was invoked).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Update task client to Routines=V2Preview opt-in header
Aligns the hosted task provider's Foundry-Features opt-in header with the
Routines V1Preview -> V2Preview rename in the agentserver-persistence
TypeSpec contract (azure-rest-api-specs #45520).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Assert exact Routines=V2Preview opt-in header in transport test
Addresses PR review feedback: the transport conformance test sent requests
but did not verify the Foundry-Features opt-in value, so it would pass with
the old or a misspelled key. Extend test_request_carries_user_agent_and_request_id
to assert the emitted header is exactly 'Routines=V2Preview'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Naman Tyagi <namantyagi@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>1 parent c24957f commit a94a8aa
2 files changed
Lines changed: 8 additions & 2 deletions
File tree
- sdk/agentserver/azure-ai-agentserver-core
- azure/ai/agentserver/core/tasks
- tests/tasks
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
402 | 402 | | |
403 | 403 | | |
404 | 404 | | |
405 | | - | |
| 405 | + | |
406 | 406 | | |
407 | 407 | | |
408 | 408 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
| 209 | + | |
210 | 210 | | |
211 | 211 | | |
212 | 212 | | |
| |||
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
237 | 243 | | |
238 | 244 | | |
239 | 245 | | |
| |||
0 commit comments