* Python: Move session persistence into core Move SessionStore and durable msgspec-backed storage into core, restore sessions in Foundry Responses hosting with per-user isolation, and document the serialization design. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Address session persistence review feedback Harden scoped file paths and corruption recovery, preserve session serialization compatibility, clarify dependency placement, and add reproducible benchmark evidence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Preserve session snapshot compatibility Deep-copy in-memory session writes and retain existing Telegram session keys so stored conversations continue resolving. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Simplify Foundry session isolation Add experimental FoundrySessionStore backed by Agent Server request context, remove resolver plumbing, and centralize v2 user isolation for sessions, checkpoints, and approvals. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Reduce Foundry session helper layering Inline the single-use request user accessor while keeping separate context validation, fingerprint, and directory helpers for their distinct callers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Clarify Foundry request context validation Separate fail-fast request validation from context retrieval so Responses no longer appears to discard a returned context. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Python: Share Foundry request context helpers Move protocol validation and user-scope derivation into a dedicated request-context module, leaving the session-store module focused on storage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Restore Foundry checkpoint storage paths Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Simplify Foundry session storage paths Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Persist Foundry sessions under hosted home Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Make hosted path test platform independent Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Address session persistence review feedback Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Isolate Foundry session path handling Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Clarify Foundry session path terminology Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Align Foundry sessions with Responses continuity Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Finalize Foundry Responses session persistence Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Add session store feature usage telemetry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c * Fix hosted per-call history persistence Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c --------- Copilot-Session: 3e5c81ad-75e8-4e92-a883-8bbd676c6c8c
local_responses — Responses helpers with native FastAPI routes
The smallest end-to-end Responses hosting shape: one Foundry agent with a
@tool, one native FastAPI route, core's experimental SessionStore, and the
Responses helper functions:
responses_to_run(...)responses_session_id(...)create_response_id(...)responses_from_run(...)
The sample demonstrates the lighter hosting direction. Agent Framework provides the run conversion and session-state pieces; FastAPI owns route registration, request bodies, response objects, and server startup.
What the route demonstrates:
- Uses an explicit request-option allowlist. This sample only allows
max_tokensand then overridesreasoning; all other caller-supplied options, includingmodel,temperature,store,tools, andtool_choice, are denied by default. Your app decides the exact allowed, altered, and denied options. - Forces a
reasoningpreset (effort=medium,summary=auto) on every turn. - Produces the AF messages, options, and session id that the route passes to
agent.run(...). - Stores each newly minted response id for response-keyed continuation,
via
state.set_session(response_id, session)afteragent.run(...)has updated the session. OpenAI'sprevious_response_idrotates every turn by design — it lets a caller continue from any earlier response, not just the latest one — so every response id needs to stay independently resolvable, not just the most recent. - Treats an unknown
conversation_idas a request to create a new local session. Your app can choose a stricter policy, such as requiring a separate API to create new conversations before callers can continue them. - Explicitly advances a supplied
conversation_idafter each completed run. A conversation id is a mutable head, so only one caller should advance it at a time. The sample andAgentStatedo not provide that locking; production apps must serialize writers or use optimistic concurrency. These requests store the updated session only under the stable conversation id. - Treats each
previous_response_idas an immutable snapshot. Multiple callers can branch from the same response concurrently because each receives a session copy and stores its result under a newly minted response id. - Uses core's msgspec-backed
FileSessionStoreunderstorage/sessions/snapshots.
app:app is a module-level FastAPI ASGI app; recommended local launch is
Hypercorn.
Production readiness
This is not a full-fledged production deployment. Before exposing this pattern to callers, add authentication and authorization at the infrastructure layer, the FastAPI app layer, or inside the route body.
Session continuation deserves particular care: treat previous_response_id and
conversation_id as untrusted request values, authorize the caller before
loading or storing a session for those ids, and partition any durable session
store by tenant/user as appropriate for your application. Also coordinate
writers for each stable conversation_id; this sample does not do so out of
the box.
Run
export FOUNDRY_PROJECT_ENDPOINT=https://<your-project>.services.ai.azure.com
export FOUNDRY_MODEL=gpt-5-nano
az login
uv sync
uv run hypercorn app:app --bind 0.0.0.0:8000
Single-process for quick iteration:
uv run python app.py
Call locally
uv sync --group dev
# Plain OpenAI SDK call:
uv run python call_server.py
# The client intentionally omits `model`; the app chooses the backing deployment
# from FOUNDRY_MODEL.
# The script then sends two more turns, each continuing from the previous
# turn's `response.id` as `previous_response_id`. The third turn asks about
# the first turn's city, so it only succeeds if the server still remembers
# that far back in the chain.
# Same three-turn interaction through an Agent Framework Agent backed by
# OpenAIChatClient:
uv run python call_server_af.py
This sample is local-only — no Dockerfile, no Foundry packaging.