Invocation modes and session lifetime
The three ways to call a hosted agent, the session idle timeout that kills long runs, and how to size the run timeout.
The endpoint
The endpoint is agent-scoped and isn't in the agent record. deploy.py prints it:
<your-foundry-project-endpoint>/agents/<agent-name>/endpoint/protocols/openai/responses?api-version=v1The project-level openai/v1/responses path returns 400. Callers authenticate with an Entra token for https://ai.azure.com.
Three calls
| Call | Served by | Limit | Use for |
|---|---|---|---|
POST {"input": …} (no stream, no background) | _run_once | About 100 s, platform-capped. A real run never finishes. | {"mode":"preflight"} and local tests |
POST {"input": …, "stream": true} | _run_stream | Session idle timeout and RUN_TIMEOUT_SECONDS | A watching consumer: AMC, its scheduler, a person. Steps arrive live; the run ends completed or failed. |
POST {"input": …, "background": true}, then GET …/responses/{id} | _run_once | Same | A raw scheduler that can't hold a stream. Read the envelope's status. |
What each mode means
- A cut stream cancels the turn. So a streaming client's own timeout must exceed
RUN_TIMEOUT_SECONDS, and a probe that closes early has still spent the minutes it watched. - Background runs don't depend on the client, but the stored response holds only the final items: no
Starting …step and no phase steps. Its status readscompletedeven when the envelope saysfailed. See Run steps, token markers and cost. - Stale background responses can't be cancelled through the endpoint once the container is gone; they stay
in_progress. The shell logsResponses resilience: DISABLEDat start, which is the platform saying so. - One turn per session. A second request during a turn is refused before spend.
The session idle timeout
This is the one setting that silently kills every long run until you set it. session_configuration.idle_timeout_seconds on the agent version tells the platform to suspend the sandbox after that many seconds without an inbound request. The default is 900 s; the range is 120 to 3600.
A running turn, an open stream with keepalives, a background response in progress, and completed output items do not count as activity. Without the setting, a run dies at about 15 minutes: the stream is cut, a background response sticks at in_progress, there's no envelope, and the spend is lost. It's easy to misread as gateway flakiness or the model.
deploy.pysets it fromSESSION_IDLE_TIMEOUT_SECONDS, default 3600. Set the maximum for any run over about 10 minutes.- A run that can exceed 60 minutes also needs its caller to
GET /responses/{id}within the window. A GET is an inbound request. Polling every 60 s is good hygiene either way. - Between HITL turns the same timer applies: an unanswered question past the timeout lands the resumed turn in a fresh sandbox with an empty
/work.
RUN_TIMEOUT_SECONDS
A different limit: the wall clock for one turn. When it expires the runner terminates the CLI and the envelope reports timed_out. The spend up to that point is real.
- It must be at least 300 s below the session idle timeout.
deploy.pyrefuses otherwise. The idle timer starts at the inbound request and the runner still needs time to end the turn and write the envelope. - With the 3600 s maximum, the default is 3300.
- Size it at 2× or more of a measured run's wall clock.
- If the skill calls MCP servers, the per-turn token lives about 60 to 90 minutes. Keep the timeout inside that.
What a scheduler sends
{"input": "{}", "background": true}Every request field is optional with a server-side default, so {} is a full run. A raw scheduler then polls by id and alerts on a failed envelope status or a missing run. AMC streams instead and treats response.failed as a failed run. See how AMC calls this agent.
Sizing
Illustrative only: a research-and-write skill on Sonnet took on the order of 60 to 90 turns and 25 to 35 minutes. On Opus the same skill took more turns and roughly twice the cost. Measure your own skill with one dry run, then set ceilings at about 1.5× and RUN_TIMEOUT_SECONDS at 2× or more of the wall clock.
Related
Last updated 2026-10-21