Commit Graph

17 Commits

Author SHA1 Message Date
Evan Mattson e6536fb459 Python: Align AG-UI run continuity (#7662)
* Python: Align AG-UI run continuity

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

* Python: Refine AG-UI continuation ownership

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

* Python: Persist AG-UI checkpoint ownership

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

---------

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92
2026-08-18 22:53:09 +00:00
MohammadHaroonAbuomar 58da0cc253 Python: add MiddlewareFailure, a first-class fatal signal for function middleware (#7562)
* feat(core): first-class fatal signal (MiddlewareFailure) for function middleware

The function-invocation loop converts every exception raised by
function middleware into a tool-error result and keeps looping, so
middleware that needs fail-closed semantics (enforcement layers,
guardrails) had no loud escape: the agent-hooks feature simulated one
by mutating shared run state, raising MiddlewareTermination, and
re-raising the real failure two hops away at the run boundary.

Introduce MiddlewareFailure (a MiddlewareException sibling of
MiddlewareTermination) as the loop's explicit fail-closed escape:

- _auto_invoke_function re-raises it (both the direct and the
  pipeline path) instead of absorbing it into a tool-error result;
  ordinary exceptions keep the absorb-and-continue contract.
- A failing call fails the whole parallel batch: in-flight sibling
  tool tasks are cancelled and awaited before the failure propagates.
- Every existing MiddlewareTermination absorb site (agent/chat
  pipelines, _execute_single_function_call, harness loop, purview)
  passes it through untouched by construction, and agent/chat
  middleware exceptions already propagate, so one exception type
  gives uniform fail-loud semantics across all three categories.

Migrate the agent-hooks feature to the new signal: delete the
_RunState.halted back-channel and its three run-boundary re-raise
checks, drop the halted arm of the termination special case in the
function middleware (the approval-request pass-through moves to the
single approval check on the normal path), and fail partial installs
loudly. Tool-seam host_error blocks keep surfacing as
InterceptionBlocked at the run boundary via the exception cause chain
(one deny surface at every seam, pinned by tests).

Spec 004 gains the middleware-failure invariants and matrix rows.

Closes #7522

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): harden tool-seam unwrap and pin review findings

Review round follow-ups for the MiddlewareFailure feature:

- Only agent-hooks' own tagged tool-seam halts (_ToolSeamBlockFailure)
  authorize re-raising the chained InterceptionBlocked at the run
  boundary; a third-party MiddlewareFailure with a crafted
  InterceptionBlocked cause now propagates as raised instead of
  laundering an attacker-shaped interception record into the feature's
  deny surface (regression test added, verified by mutation).
- Document that middleware must not catch MiddlewareFailure (docstring
  and spec 004): swallowing it converts a fail-closed abort back into
  a running, possibly unguarded loop.
- Pin the trailing termination re-raise in the agent-hooks function
  middleware: an inner short-circuit is bracketed and still propagates,
  skipping outer middleware post-code (test fails with the re-raise
  removed).

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): acyclic tool-seam unwrap chain; document cooperative batch cancellation

Address two automated-review findings on the MiddlewareFailure PR,
both confirmed empirically:

- _reraise_tool_seam_block created a two-object exception-chain cycle
  (block.__cause__ -> wrapper -> block) by re-raising the chained
  InterceptionBlocked `from` its transport wrapper. Detach the
  wrapper's back-links and re-raise bare, recording the wrapper as
  the block's __context__ — acyclic, both exceptions still visible in
  tracebacks. Regression test walks the chain and pins finiteness
  (verified to fail against the cyclic re-raise).

- Batch cancellation is cooperative: a synchronous tool body already
  running in a worker thread (asyncio.to_thread) cannot be interrupted
  by task cancellation and may complete its side effects after the
  failure reached the caller; its result is discarded either way and
  propagation is not delayed behind it. Narrow the stated contract
  (MiddlewareFailure docstring, loop comment, spec 004) and pin it
  with a blocking-sync-sibling regression test.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): settle dangling calls on service-managed conversations on abort

Address maintainer review on the MiddlewareFailure PR:

- A MiddlewareFailure escaping a tool batch on a service-managed
  conversation left the hosted thread ending in unresolved
  function_call items: _update_continuation_state persists
  session.service_session_id when the model turn completes (before
  tool execution), and probe-verified the next run sends only the new
  user message against that conversation — OpenAI-style continuations
  reject such a request, so a routine policy abort left the session
  permanently stuck. Both loops now settle the thread before
  propagating: one error function_result per dangling call, submitted
  with tool_choice="none" in a single extra request whose response is
  discarded; a settlement failure never masks the abort, and runs
  without a service-managed conversation make no extra request.
  Pinned by three regression tests (non-streaming, streaming, and the
  no-conversation no-cost case); spec 004 and the MiddlewareFailure
  docstring updated.

- Make the three tool-bracket escape tuples in the agent-hooks
  function middleware identical (MiddlewareTermination,
  MiddlewareFailure, CancelledError): a MiddlewareFailure raised
  inside the post/error-bracket emit bodies is unreachable today, but
  the uniform tuples remove the need to reason about why they would
  differ, and preserve the exact exception (including the private
  tool-seam tag) if the emitter ever surfaces one.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): advance settled continuation; settle approved-replay aborts

Address maintainer review on the MiddlewareFailure settlement path,
both probe-verified (branch rebased onto current main first):

- Advance the persisted continuation to the settlement response. For
  response-ID continuations (OpenAI Responses store=True, where the
  response id is the continuation handle) the settlement response is
  the first endpoint whose chain includes the synthetic tool outputs;
  leaving session.service_session_id on the pre-settlement response
  made the settlement ineffective — the next run would continue from
  the still-unresolved turn. The settlement response now runs through
  _update_function_invocation_continuation_state (a no-op for stable
  conversation-object ids). Pinned by a regression test that fails
  with the advance removed.

- Cover the approval-resolution phase: a MiddlewareFailure raised
  while an approved tool is replayed escapes loudly (probe-verified,
  already the case) but executed before the loops' settlement seams,
  leaving the original — already service-persisted — call unresolved.
  _resolve_approval_responses now takes a settle_dangling_calls
  callback invoked with the approved batch on abort; the settlement
  helper became a layer method taking explicit calls
  (approval-response wrappers unwrap to their underlying calls,
  hosted-tool approvals are left to their provider protocol) and
  carries its own best-effort containment. Pinned by deny-during-
  replay regression tests in both response modes, mutation-verified.

Spec 004 invariants and matrix rows updated accordingly.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

---------

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
2026-08-18 22:33:52 +00:00
westey e289320027 Python: Add approval storage and improve truth checks (#7631)
* Add approval storage and improve truth checks

* Address PR comments

* Update spec

* Revert changes to agui since it is already handled in another pr

* Add missed change
2026-08-14 09:52:47 +00:00
Evan Mattson 8c4da3c3b9 Python: Harden AG-UI approval lifecycle and resume semantics (#7594)
* Route local approvals through lifecycle owner

Key decisions:
- Add an internal typed approval lifecycle with pending, claimed, executing, and settled states.
- Keep authorization separate from execution; only LocalPendingToolTransitionOwner invokes approved local calls.
- Register server-owned occurrences before canonical ResumeDecision claims and retain one replayable result under the original call identity.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_approval_state.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_approval_result_event.py
- packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py

Verification:
- 952 AG-UI tests passed.
- Focused lifecycle/public tracer passed with warnings treated as errors.
- Ruff format/check and AG-UI Pyright passed.
- git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping is inaccessible under the organization content-exclusion policy and could not be updated.
- The workspace Poe package fan-out is blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks were run.

* Make approval batches occurrence-safe

Key decisions:
- Give each local approval a scoped logical occurrence identity and share one occurrence across trusted thread aliases.
- Validate complete Resume Decision batches before applying claims, then account for accepted, rejected, and cancelled occurrences independently.
- Preserve sibling authority and original result identity across failures, mixed decisions, and reused raw call IDs.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_approval_state.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py

Verification:
- 959 AG-UI tests passed with 90% lifecycle branch coverage.
- 30 focused lifecycle/public tracer tests passed with warnings treated as errors.
- Ruff format/check and AG-UI Pyright passed.
- git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace typing fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; package-local Pyright passed, while package-local MyPy retains three unrelated baseline errors.

* Make approval resume retries idempotent

Key decisions:
- Retain terminal decisions and outcomes by scoped occurrence so identical accepted and rejected retries reproject results without granting execution authority again.
- Reject conflicting names, arguments, decisions, wrong-scope lookups, and expired authority before an execution intent can reach the local transition owner.
- Keep protocol normalization in the runner while using server-owned lifecycle context to canonicalize retries and preserve existing AG-UI wire aliases.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py
- packages/ag-ui/tests/ag_ui/test_endpoint.py

Verification:
- 965 AG-UI tests passed with 90% approval lifecycle coverage.
- 18 focused lifecycle, hostile-resume, wrong-thread, and endpoint retry tests passed with runtime and deprecation warnings treated as errors.
- Ruff format/check and AG-UI package-local Pyright passed.
- git diff --check passed.

Notes for next iteration:
- Terminal retention is process-local and unbounded until the later bounded-retention issue adds its explicit policy.
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.

* Separate approval execution ownership

Key decisions:
- Carry explicit local, hosted, deferred in-run, or unavailable ownership on every approval occurrence and authorized intent.
- Keep lifecycle authorization separate from execution; local calls execute only through the local adapter while hosted and setup-injected decisions forward through owner-specific adapters.
- Leave declaration-only calls pending when no transition owner can act, and settle forwarded outcomes against the original occurrence without local fallback.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_approval_state.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_endpoint.py

Verification:
- 967 AG-UI tests passed with 92% package coverage and 89% approval lifecycle coverage.
- 94 focused lifecycle, hosted, deferred-owner, hostile-resume, and approval tests passed.
- Ruff format/check and package-local Pyright passed.
- git diff --check passed.

Notes for next iteration:
- Executing-without-outcome recovery remains for the indeterminate execution-window issue.
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace Poe fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks passed.

* Represent approval execution uncertainty

Key decisions:
- Distinguish reserved claims from execution windows that may have started an external side effect.
- Recover non-idempotent execution failures as indeterminate and reject identical retries without another invocation.
- Permit claim release only under an explicit safe policy and execution retry only with a predeclared idempotency key shared by local and forwarded owners.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_endpoint.py

Verification:
- 972 AG-UI tests passed with 92% line coverage and 89% package branch coverage.
- 23 focused lifecycle, duplicate-resume, hosted-owner, and public settlement-window tests passed.
- Package-local Ruff and Pyright passed; git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace Poe fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks passed.

* Reconcile approval snapshots with lifecycle state

Key decisions:
- Keep Approval State authoritative and emit typed snapshot reconciliation keyed by logical occurrence identity.
- Retire settled, rejected, cancelled, expired, indeterminate, and missing controls while preserving nonterminal authority.
- Reconcile stale snapshots before hydration or resume, and retain lifecycle deduplication when snapshot saves fail.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/agent_framework_ag_ui/_snapshot_session.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_endpoint.py

Verification:
- 975 AG-UI tests passed with 92% package coverage and 89% approval lifecycle coverage.
- Package-local Ruff and Pyright passed; git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace Poe fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks passed.

* Bound process-local approval lifecycle state

Key decisions:
- Protect pending, claimed, executing, and indeterminate occurrences from eviction while retaining terminal outcomes for a configurable 15-minute process-local deduplication window.
- Serialize complete approval batches by logical occurrence locks so aliases share atomic decisions and independent batches can progress concurrently.
- Fail capacity, claim, and settlement conflicts explicitly, and emit redacted structured lifecycle telemetry without tool names, arguments, or approval payloads.
- Remove legacy LRU eviction paths so active Approval State and middleware state are never silently discarded.

Files changed:
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_approval_state.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_approval_state.py

Verification:
- 982 AG-UI tests passed with 92% package coverage and 91% approval lifecycle coverage.
- 34 focused lifecycle and storage tests passed with RuntimeWarning and DeprecationWarning treated as errors.
- Package-local Ruff and Pyright passed; git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace Poe fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks passed.

* Complete approval lifecycle cutover

Key decisions:
- Make ApprovalLifecycle the sole owner of trusted aliases, occurrence metadata, authority transitions, and retained outcomes.
- Remove the parallel mutable pending-approval registry and route local, hosted, deferred, cancellation, replay, and snapshot reconciliation through lifecycle occurrences.
- Encapsulate middleware Approval State behind copy-isolated store methods while keeping AG-UI protocol normalization and event projection in the runner.

Files changed:
- packages/ag-ui/AGENTS.md
- packages/ag-ui/agent_framework_ag_ui/_agent.py
- packages/ag-ui/agent_framework_ag_ui/_agent_run.py
- packages/ag-ui/agent_framework_ag_ui/_approval_lifecycle.py
- packages/ag-ui/agent_framework_ag_ui/_approval_state.py
- packages/ag-ui/tests/ag_ui/test_agent_wrapper_comprehensive.py
- packages/ag-ui/tests/ag_ui/test_approval_lifecycle.py
- packages/ag-ui/tests/ag_ui/test_approval_result_event.py
- packages/ag-ui/tests/ag_ui/test_approval_state.py
- packages/ag-ui/tests/ag_ui/test_endpoint.py
- packages/ag-ui/tests/ag_ui/test_run.py

Verification:
- 964 package-local AG-UI tests passed with 92% coverage and 90% approval lifecycle coverage.
- 85 warning-strict focused approval tests passed.
- Package-local Ruff and Pyright passed; git diff --check passed.

Notes for next iteration:
- The function-calling-loop scenario mapping remains inaccessible under the organization content-exclusion policy.
- Workspace Poe fan-out remains blocked by the pre-existing missing packages/durabletask/pyproject.toml; equivalent package-local checks passed.

* Align AG-UI approval resumes with protocol

* Align workflow approvals with AG-UI resumes

* Address AG-UI approval review findings

* fix AG-UI test typing checks

* fix AG-UI approval retention and cancellation retries
2026-08-14 00:28:14 +00:00
westey e926ad2859 Python: fix streaming transcript duplication with message injection and per-service-call persistence (#7605)
* Fix ordering issue when streaming with content injection and per-service-call persistence

* Update spec

* Address PR comment

* revert uv.lock changes
2026-08-13 15:04:58 +00:00
Tao Chen e85b3c8ba8 Python: Fix FHA session ID translation (#7608)
* Fix FHA session ID traslation

* Fix tests

* Address comments and fix tests

* Fix typing

* Show how to use user created sessions

* Update README
2026-08-11 17:30:56 +00:00
Evan Mattson 48e547506b Python: Make encrypted reasoning opt-in for Foundry chat (#7536)
* Python: Make Foundry encrypted reasoning opt-in

* Python: Opt hosted replay test into encrypted reasoning
2026-08-10 02:36:48 +00:00
Evan Mattson 5f3ca8f93c Python: Fix AG-UI approval resume at the protocol boundary (#7480)
* Python: Fix Ollama approval resume message handling

* Python: Reject empty Ollama approval resume payload

* Python: Keep AG-UI approval controls out of provider input

* Python: Do not trust pending AG-UI tool results
2026-08-04 15:12:33 +00:00
Eduard van Valkenburg 07511b80c9 Python: Prevent orphaned local approval responses (#7462)
* Python: Prevent orphaned local approval responses

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0efaca91-a0a7-46f4-9b81-022385607fe4

* Python: Clarify approval serialization boundaries

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0efaca91-a0a7-46f4-9b81-022385607fe4

---------

Copilot-Session: 0efaca91-a0a7-46f4-9b81-022385607fe4
2026-08-04 01:05:08 +00:00
Eduard van Valkenburg 28389df805 Python: Move SessionStore to core and persist Foundry Responses sessions (#7306)
* 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
2026-07-30 13:04:08 +00:00
Eduard van Valkenburg 99dcf3c133 Python: Preserve declaration-only streaming metadata (#7409)
* Python: Preserve declaration-only streaming metadata

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Chore: retrigger PR checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Reconcile remaining function-loop spec gaps

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 09:11:51 +00:00
Eduard van Valkenburg 95ec5b7d36 Python: Preserve approval decisions under OpenAI continuation (#7407)
* Python: Preserve approval decisions under OpenAI continuation

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Chore: retrigger PR checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 08:29:05 +00:00
Eduard van Valkenburg 0937233d86 Python: Remove tool content returned after invocation limits (#7408)
* Python: Remove tool content returned after invocation limits

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Chore: retrigger PR checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Preserve provider-owned content after limits

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Isolate post-limit spec update

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 08:27:57 +00:00
Eduard van Valkenburg 572a9621bd Python: Keep call and result occurrences atomic in compaction (#7406)
* Python: Keep call and result occurrences atomic in compaction

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Clarify ambiguous compaction reannotation

Document why incremental reannotation retains all prior duplicate candidates and strengthen the regression that keeps ambiguous results unpaired without changing existing groups.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Handle assistant-embedded compaction results

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 07:58:07 +00:00
Eduard van Valkenburg e344f456ae Python: Correlate AG-UI confirm_changes snapshots by call id (#7411)
* Python: Correlate AG-UI confirm_changes snapshots by call id

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Chore: retrigger PR checks

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Require real results for accepted confirmations

Keep accepted confirm_changes snapshot payloads inert unless approval resolution produced a matching function result, while retaining explicit rejection cleanup.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 07:08:03 +00:00
Eduard van Valkenburg e18a64569c Python: Defer provider-injected approvals to in-run execution (#7410)
* Python: Defer provider-injected approvals to in-run execution

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Remove vacuous AG-UI approval test

Drop the forged-approval test that was stripped by pending-approval validation; the real pause-approve-resume regression remains the authoritative provider-injected coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-30 06:48:36 +00:00
Eduard van Valkenburg 5987a6791b Python: Improve function approval resume and replay (#7345)
* Python: Harden function approval resume and replay

Make approval resume immutable and occurrence-aware, return grouped approved and rejected results consistently, preserve pending approval history without model-orphaned calls, and align streaming, non-streaming, and AG-UI result boundaries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1

* Python: Clarify function invocation orchestration

Simplify approval-resolution setup and add phase-level comments around the key function invocation orchestration paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
EOF && git push origin python-approval-resume-contract

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 1ee1d250-d1e2-4c6f-8c36-aae0d94fe7a1
2026-07-29 20:01:42 +00:00