Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
bb9e92b
fix: isolate MCP sessions by workflow session
baywet Sep 22, 2026
5232c71
.NET/Python: Address MCP session review feedback
baywet Sep 22, 2026
777056f
Address MCP review feedback
baywet Sep 23, 2026
2182915
chore: linting
baywet Sep 23, 2026
c5a98d7
Merge origin/main into fix/mcp-workflow-session-isolation
baywet Sep 23, 2026
f1dde52
Address MCP review lifecycle comments
Copilot Sep 23, 2026
3293b65
Address MCP session review feedback
Copilot Sep 23, 2026
2ce112b
Fix MCP creation cancellation and run isolation
Copilot Sep 23, 2026
4024d20
Merge branch 'main' into fix/mcp-workflow-session-isolation
baywet Sep 28, 2026
bda47d1
fix: retry MCP waiter after creator cancellation
baywet Sep 28, 2026
f5c133f
chore: Use generated session ID for workflow session context
baywet Sep 28, 2026
5f21a68
chore: Use generated workflow session ID for context
baywet Sep 28, 2026
3c97cc2
Merge origin/main into fix/mcp-workflow-session-isolation
baywet Sep 28, 2026
97c636d
fix: make MCP shutdown cancellation-safe
baywet Sep 28, 2026
bfcd02e
chore: Potential fix for pull request finding 'Statement has no effect'
baywet Sep 29, 2026
d8d8c61
fix: support MCP cancellation on Python 3.10
baywet Sep 29, 2026
46abaee
test: avoid assigning None from MCP shutdown
baywet Sep 29, 2026
b470205
fix: observe failed MCP client creation tasks
baywet Sep 29, 2026
f47001b
chore: Potential fix for pull request finding 'Statement has no effect'
baywet Sep 29, 2026
80988a0
test: await MCP shutdown through gather
baywet Sep 29, 2026
9548e5b
Fix MCP shutdown cancellation draining
baywet Sep 29, 2026
af94e4f
Fix net472 MCP lifetime test build
baywet Sep 29, 2026
dd617dc
Wait for MCP client creators during disposal
baywet Sep 29, 2026
f33b4c6
chore: Potential fix for pull request finding 'Generic catch clause'
baywet Sep 29, 2026
18720f0
Harden nested MCP session lifetimes
baywet Sep 29, 2026
bdee27b
Clarify cancelled MCP task coordination
baywet Sep 29, 2026
1283c99
Harden MCP restore and cancellation handling
baywet Sep 29, 2026
447f8b6
Fix async workflow test naming
baywet Sep 29, 2026
a5adae5
Surface MCP cleanup failures during shutdown
baywet Oct 5, 2026
2ac83cf
Fix cancellation assertions in MCP shutdown test
baywet Oct 5, 2026
d1eab3f
Make MCP approval checkpoint test deterministic
baywet Oct 5, 2026
abcd9c7
Exclude expected MCP disposal rejection
baywet Oct 5, 2026
e4058ba
Fix declarative MCP session continuity
baywet Oct 5, 2026
c5ccc2d
Fix MCP session concurrency review findings
baywet Oct 6, 2026
c82c4ac
Merge origin/main into fix/mcp-workflow-session-isolation
baywet Oct 6, 2026
9acfbe4
Stabilize MCP cancellation assertions
baywet Oct 6, 2026
29d114d
Fix cross-framework cancellation assertion
baywet Oct 6, 2026
e227494
Fix workflow agent session identity on rejected concurrent runs
baywet Oct 7, 2026
0b293d3
Fix fresh workflow session isolation and MCP cleanup cancellation
baywet Oct 7, 2026
c8ef63f
Preserve originating MCP scope through approval continuations
baywet Oct 7, 2026
b10b5c4
Distinguish agent turns from direct workflow MCP sessions
baywet Oct 7, 2026
2cfd09d
Reject mixed MCP approval batches and preserve cleanup outcomes
baywet Oct 7, 2026
8204ea0
Annotate MCP workflow regression inputs for Zuban
baywet Oct 7, 2026
c3cb5b8
Isolate sessionless workflow agent MCP scopes
baywet Oct 7, 2026
ab67a01
chore: Update _close_claimed_entry to manage cleanup outcome
baywet Oct 8, 2026
b6ea27c
Merge branch 'main' into fix/mcp-workflow-session-isolation
baywet Oct 8, 2026
c8df515
Fix background-agent stale-waiter test thread-pool starvation
baywet Oct 8, 2026
49865cf
Merge main into fix/mcp-workflow-session-isolation
baywet Oct 15, 2026
839e4f0
fix: finish MCP cache cleanup and preserve entry checkpoint identity
baywet Oct 15, 2026
b4d4d1a
fix: bound MCP client lifetimes and align workflow dependencies
baywet Oct 15, 2026
31acf5b
fix: select built workspace wheels in meta install checks
baywet Oct 15, 2026
ec94868
fix: preserve cancellation during MCP lifecycle cleanup
baywet Oct 15, 2026
d6c9526
fix: retain workflow identity on response continuations
baywet Oct 15, 2026
0e2f255
Merge origin/main into fix/mcp-workflow-session-isolation
baywet Oct 15, 2026
30ff41a
fix: retain originating workflow scope for external input
baywet Oct 15, 2026
3b2f7b3
fix(python): preserve pending request scopes and recover legacy conti…
baywet Oct 15, 2026
97ed49b
fix(python): use generator unpacking in continuation regression
baywet Oct 15, 2026
16dc9b2
fix(workflows): validate queued response origins before replay
baywet Oct 15, 2026
39f9174
fix(workflows): preflight nested checkpoints before restoring state
baywet Oct 15, 2026
87c2e35
Merge branch 'main' into fix/mcp-workflow-session-isolation
baywet Oct 16, 2026
27ec8f9
fix(workflows): validate delegated responses before consuming state
baywet Oct 16, 2026
3e29746
fix(workflows): preflight delegated response migrations together
baywet Oct 16, 2026
f35ed14
fix(tests): initialize nested workflow wrapper before iteration
baywet Oct 16, 2026
9e4d86f
fix(workflows): preflight queued wrapped child replies
baywet Oct 16, 2026
fde8d77
chore: remove packaging changes from workflow fix
baywet Oct 16, 2026
e5886f4
Merge branch 'main' into fix/mcp-workflow-session-isolation
baywet Oct 19, 2026
2c52eed
chore: resets dotnet changes
baywet Oct 19, 2026
1b858e5
Merge branch 'main' into fix/mcp-workflow-session-isolation
baywet Oct 27, 2026
626b3fb
Python: avoid caching unscoped MCP invocations
baywet Oct 27, 2026
cdedd69
Python: preserve legacy runner context response handling
baywet Oct 27, 2026
c7bfe99
fix(tests): narrow runner context before queue inspection
baywet Oct 27, 2026
be2ef00
fix(workflows): preserve agent context on rejected checkpoint restore
baywet Oct 27, 2026
a9fe090
fix(workflows): forward agent context to nested fresh runs
baywet Oct 27, 2026
0d767ce
fix(workflows): normalize postponed workflow annotation
baywet Oct 27, 2026
7b957d1
fix(workflows): preserve child scopes on parent entry replay
baywet Oct 27, 2026
8639a74
fix(workflows): restore parent scopes for child continuations
baywet Oct 27, 2026
e1b150d
fix(workflows): preserve core request origins during continuations
baywet Oct 27, 2026
16b1655
fix(workflows): preflight wrapped replies and queued cancellations
baywet Oct 27, 2026
7e45ede
fix: honor Core scopes in manually composed workflows
baywet Oct 27, 2026
f0f1906
fix(workflows): isolate relay origins and incrementally update reques…
baywet Oct 29, 2026
5009d68
fix(workflows): validate selected wrapped reply routes
baywet Oct 29, 2026
517ebf1
fix(workflows): make routing regression types explicit
baywet Oct 29, 2026
0577d31
fix(workflows): add state-dependent reply routing regression coverage
baywet Oct 29, 2026
1e4d973
fix(workflows): validate wrapped replies at delivery time
baywet Oct 29, 2026
4d515ae
fix(workflows): retain reply scope across continuation steps
baywet Oct 29, 2026
3aad44e
fix(workflows): avoid cross-edge wrapped reply deadlocks
baywet Oct 30, 2026
7f1f8f4
Merge remote-tracking branch 'origin/main' into fix/mcp-workflow-sess…
Copilot Nov 4, 2026
feb59e3
fix(workflows): keep ordinary reply consumers outside child validation
baywet Nov 4, 2026
513cdea
Python: consolidate workflow session scope ownership
eavanvalkenburg Nov 5, 2026
d700d96
Defer optional MCP helper import in declarative tests
Copilot Nov 5, 2026
5ca6004
Python: scope declarative MCP sessions to invocations
eavanvalkenburg Nov 5, 2026
98a9843
fix: Change headers to static_headers in MCP handler
baywet Nov 5, 2026
c6b4574
docs: re-sequences ADRs
baywet Nov 5, 2026
8ac8568
tests: Rename 'headers' to 'static_headers'
baywet Nov 5, 2026
05f954c
Python: reject reserved MCP discovery arguments with ValueError
baywet Nov 5, 2026
c4f44ff
Python: propagate declarative MCP infrastructure failures
baywet Nov 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Explore new MAF capabilities and real implementation patterns on the [official b
- **Declarative Agents**: Define agents using YAML for faster setup and versioning
- [Declarative agent samples](./declarative-agents/)
- **Agent Skills**: Build domain-specific knowledge bases from multiple sources—files, inline code, class libraries—for agents to discover and use
- [Skills design](./docs/decisions/0037-agent-skills-design.md)
- [Skills design](./docs/decisions/0030-agent-skills-design.md)
- **AF Labs**: Experimental packages for cutting-edge features including benchmarking, reinforcement learning, and research initiatives
- [Labs directory](./python/packages/lab/)
- **DevUI**: Interactive developer UI for agent development, testing, and debugging workflows
Expand Down
4 changes: 2 additions & 2 deletions docs/decisions/0026-hosted-session-identity-context.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: superseded by [ADR-0030](0030-hosted-platform-context-agentserver-2.0.md)
status: superseded by [ADR-0034](0034-hosted-platform-context-agentserver-2.0.md)
contact: rogerbarreto
date: 2026-06-29
deciders: rogerbarreto
Expand All @@ -9,7 +9,7 @@ informed: []

# Hosted session identity context for Foundry Hosting

> **Superseded by [ADR-0030](0030-hosted-platform-context-agentserver-2.0.md).** `Azure.AI.AgentServer.*` 2.0.0 (responses protocol `2.0.0`) replaced `ResponseContext.Isolation` (`UserIsolationKey` / `ChatIsolationKey`, headers `x-agent-user-isolation-key` / `x-agent-chat-isolation-key`) with `ResponseContext.PlatformContext` (`UserIdKey` / `CallId`, headers `x-agent-user-id` / `x-agent-foundry-call-id`). The chat isolation key was removed and `HostedSessionContext` is now user-only. This ADR is retained as the historical record of the original design.
> **Superseded by [ADR-0034](0034-hosted-platform-context-agentserver-2.0.md).** `Azure.AI.AgentServer.*` 2.0.0 (responses protocol `2.0.0`) replaced `ResponseContext.Isolation` (`UserIsolationKey` / `ChatIsolationKey`, headers `x-agent-user-isolation-key` / `x-agent-chat-isolation-key`) with `ResponseContext.PlatformContext` (`UserIdKey` / `CallId`, headers `x-agent-user-id` / `x-agent-foundry-call-id`). The chat isolation key was removed and `HostedSessionContext` is now user-only. This ADR is retained as the historical record of the original design.

## Context and Problem Statement

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ informed: []

# Per-agent and per-user session-storage isolation for Foundry Hosting

Builds on [ADR-0030](0030-hosted-platform-context-agentserver-2.0.md).
Builds on [ADR-0034](0034-hosted-platform-context-agentserver-2.0.md).

## Context and Problem Statement

A Foundry hosted container can serve many end users (and, in .NET, many agents) over its lifetime. The
`AgentSessionStore` persists each turn's `AgentSession` (which for a workflow agent carries the workflow
checkpoint, and which also carries the tool-approval mapping via `ToolApprovalIdMap` in the session state
bag). [ADR-0030](0030-hosted-platform-context-agentserver-2.0.md) protected cross-user access only through
bag). [ADR-0034](0034-hosted-platform-context-agentserver-2.0.md) protected cross-user access only through
the strict-resume identity check (a 403 when the persisted `HostedSessionContext.UserId` does not match the
live request). The persisted artifacts themselves were keyed by `conversationId` (+ agent name), not
physically partitioned per user, so a forged `conversation_id` would still resolve to another user's file
Expand All @@ -34,7 +34,7 @@ hosting model.
must isolate per agent as well as per user (Python hosts a single agent and needs no agent layer).
- Path-traversal safety (CWE-22) for the untrusted, platform-injected user id.
- Back-compat for local development (no `x-agent-user-id` header) and for direct/non-hosted store use.
- Keep the change contained and avoid the async-iterator `AsyncLocal` revert hazard from ADR-0030.
- Keep the change contained and avoid the async-iterator `AsyncLocal` revert hazard from ADR-0034.

## Considered Options

Expand All @@ -45,7 +45,7 @@ hosting model.
user id on the read path and yields a flat key rather than nested per-tenant directories.
- An `AsyncLocal<string?>` user-context set by the handler. Rejected: the session is saved in the handler's
`finally` after the streaming `yield`s, where an `AsyncLocal` set up front is reverted (the same hazard
that forced explicit call-id re-application in ADR-0030). Explicit threading is safer and clearer.
that forced explicit call-id re-application in ADR-0034). Explicit threading is safer and clearer.
- A separate per-user approval store (as in Python). Rejected as unnecessary: see below.

## Decision Outcome
Expand Down Expand Up @@ -74,7 +74,7 @@ Other elements:
- Path-traversal guard: the user id is rejected (not sanitized) when it is not a single safe path segment
(path separators, NUL, drive letters, rooted paths, all-dot segments). After building the path, the
fully-resolved path is asserted to remain under the storage root.
- The strict-resume 403 identity check from ADR-0030 is **kept** as the second defense layer (it still
- The strict-resume 403 identity check from ADR-0034 is **kept** as the second defense layer (it still
catches a session that reaches the wrong partition, e.g. via a non-partitioning custom store or in-process
tampering).
- **No separate approval store.** The tool-approval mapping lives in `ToolApprovalIdMap` ->
Expand All @@ -94,7 +94,7 @@ Negative:

- Breaking change to the experimental Foundry `AgentSessionStore` API (added `userId`).
- The on-disk layout and leaf filename change (`<conv>.json` -> `c-<conv>.json`), orphaning sessions written
by the ADR-0030 release. Acceptable for an experimental package; a fresh session is created on next use.
by the ADR-0034 release. Acceptable for an experimental package; a fresh session is created on next use.

## Out of scope

Expand All @@ -103,7 +103,7 @@ Negative:

## Update (2026-09-01): contract promoted to Abstractions

[ADR-0039](0039-shared-agent-session-store.md) promotes this `AgentSessionStore` contract to
[ADR-0045](0045-shared-agent-session-store.md) promotes this `AgentSessionStore` contract to
`Microsoft.Agents.AI.Abstractions` and makes it the common contract for Foundry Hosting and conventional
Hosting. It supersedes the required `userId` parameter with `AgentSessionStoreKey.Partitions`. Foundry
Hosting adds the resolved user identity as a named partition before loading or saving a session.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ informed: []

Realizes the helper-first direction of [ADR-0027](0027-hosting-channels.md) for .NET.

> **Update (2026-09-01):** [ADR-0039](0039-shared-agent-session-store.md) supersedes the
> **Update (2026-09-01):** [ADR-0045](0045-shared-agent-session-store.md) supersedes the
> `AgentSessionStore` portion of this decision. The protocol helper and workflow decisions remain accepted.

## Context and Problem Statement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ implementations.
owns or re-exports `SessionStore` (this will be a breaking change in the `hosting` package).

Actual `SessionStore` and `FileSessionStore` operations mark Python feature-usage index 17,
`core.session_store`, following ADR-0033's use-not-presence policy. Construction and import alone do not mark the bit.
`core.session_store`, following ADR-0037's use-not-presence policy. Construction and import alone do not mark the bit.

`SessionStore` accepts opaque non-empty keys so custom backends can use their native key contracts. `FileSessionStore`
accepts opaque keys up to 128 characters and encodes values that are not portable filename stems; this supports
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ Negative:

## More Information

- [ADR-0031](0031-hosted-per-user-session-storage-isolation.md) records the earlier Foundry-specific user partition.
- [ADR-0032](0032-dotnet-hosting-protocol-helpers.md) records the previous conventional Hosting contract.
- [ADR-0035](0035-hosted-per-user-session-storage-isolation.md) records the earlier Foundry-specific user partition.
- [ADR-0036](0036-dotnet-hosting-protocol-helpers.md) records the previous conventional Hosting contract.
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ while every adapter decides placement independently.

[Spec 004](../specs/004-python-function-calling-loop.md) already defines function-call identity:
`function_call.Content.id` identifies one locally actionable Agent Framework occurrence, while `call_id` is the
provider's call/result correlation. [ADR 0039](0039-python-refusal-content.md) defines the flat
provider's call/result correlation. [ADR 0042](0042-python-refusal-content.md) defines the flat
`model_output_kind="refusal"` marker. This decision keeps spec 004's identity semantics and the meaning of ADR
0039's marker unchanged, but moves that marker into the `core` namespace described below. It also changes which
0042's marker unchanged, but moves that marker into the `core` namespace described below. It also changes which
field marks the hosted server boundary in spec 004's approval scenarios; the implementing change updates spec 004's
hosted-server-boundary scenario row and its authoritative test mapping.

Expand Down Expand Up @@ -202,7 +202,7 @@ content.additional_properties == {
data under `foundry`. Each owner documents its keys in its package README and may publish a `TypedDict` for its
namespace and small accessor functions.
3. **Provider-neutral data lives in `core`.** `additional_properties["core"]` holds semantics documented by
core that any package may read or write: `model_output_kind` from ADR 0039 and the caller-facing
core that any package may read or write: `model_output_kind` from ADR 0042 and the caller-facing
`prompt_cache_breakpoint`. Only core adds keys to `core`. File names use the first-class `Content.name` field.
4. **Namespaces are exactly one level deep.** A namespace maps flat key names to plain JSON values (mappings, lists,
strings, numbers, booleans, and `None`), never dataclass or Pydantic instances, because `Content.from_dict()` does
Expand Down Expand Up @@ -260,7 +260,7 @@ reserved names.
content that a newer provider package produced.
- `model_output_kind` and `prompt_cache_breakpoint` move into `core`; their meaning is unchanged. Readers accept the
flat keys indefinitely, writers write both until their next major version, and applications that set the flat keys
keep working. ADR 0039 remains the record of the refusal decision.
keep working. ADR 0042 remains the record of the refusal decision.
- A package that writes namespaces requires, as its minimum core version, the core release that merges them. On an
older core, streamed fragments would lose namespace fields during aggregation.
- Keys used only for display, diagnostics, or a single request switch directly.
Expand All @@ -286,7 +286,7 @@ nevertheless use the same namespaces; response aggregation uses the namespace-aw
- Bad, because writers must replace namespaces rather than mutate them; a writer that mutates in place corrupts
metadata shared with copies. The core helpers make the safe path easy but cannot enforce it.
- Bad, because core gains public helper functions, and writer packages must raise their minimum core version.
- Bad, because ADR 0039's marker and the caller-facing `prompt_cache_breakpoint` move, so samples and documentation
- Bad, because ADR 0042's marker and the caller-facing `prompt_cache_breakpoint` move, so samples and documentation
change, although the flat keys remain readable.
- Bad, because `core` and every namespace name become reserved top-level keys. No collisions exist in this
repository, but applications outside it could already use those names.
Expand Down Expand Up @@ -373,7 +373,7 @@ forms are removed during implementation rather than documented as compatibility

- [Spec 004: Python function-calling loop](../specs/004-python-function-calling-loop.md)
- [Spec 005: Python content identity and protocol metadata](../specs/005-python-content-identity-and-protocol-metadata.md)
- [ADR 0039: Preserve model refusals with marked Python text content](0039-python-refusal-content.md)
- [ADR 0043: Preserve host runtime context through MCP invocation and approval](0043-python-mcp-runtime-context.md)
- [ADR 0042: Preserve model refusals with marked Python text content](0042-python-refusal-content.md)
- [ADR 0047: Preserve host runtime context through MCP invocation and approval](0047-python-mcp-runtime-context.md)
- [Issue 8910: Explicit append/replace semantics for streamed content merging](https://github.com/microsoft/agent-framework/issues/8910)
- [Issue 8903: Streamed code-interpreter code can be corrupted by prefix inference](https://github.com/microsoft/agent-framework/issues/8903)
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,6 @@ Committed contract tests cover:
- [MCP MRTR specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr)
- [MCP subscriptions specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/subscriptions)
- [MCP caching specification](https://modelcontextprotocol.io/specification/2026-07-28/server/utilities/caching)
- [ADR 0043: MCP runtime context](0043-python-mcp-runtime-context.md)
- [ADR 0047: MCP runtime context](0047-python-mcp-runtime-context.md)

This ADR was accepted through the repository ADR review process.
46 changes: 46 additions & 0 deletions docs/decisions/0053-python-invocation-owned-mcp-sessions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
---
status: proposed
---

# Own declarative MCP sessions per invocation

## Context and Problem Statement

A shared `DefaultMCPToolHandler` caches initialized MCP clients by connection
configuration. Independently constructed workflows with identical endpoint and
headers can therefore share server-side protocol state. Workflow-owned session
identity would partition that cache, but also require Core changes for run
admission, approval routing, nested workflows, and checkpoint recovery.

## Considered Options

- Retain the cache and propagate workflow identity through Core and declarative requests.
- Create and close a protocol session for each invocation.
- Require every host to implement a custom handler.

## Decision Outcome

Choose invocation ownership, matching the lifetime principle in [.NET PR #9722](https://github.com/microsoft/agent-framework/pull/9722).
Every invocation, including `tools/list`, connects and closes its own
`MCPStreamableHTTPTool`. Cleanup completes before the call returns, including
on failure or cancellation. Cleanup failures are logged without replacing the
invocation result or error; cancellation still propagates.

Keep the existing optional Python `client_provider` callback. Its clients are
borrowed and remain host-owned; returning `None` creates an internally owned
client. This separates HTTP connection pooling from MCP protocol-session
ownership without introducing a factory abstraction or new transport options.
Core already supports both ownership modes, so no Core changes are necessary.

Remove the initialized-client cache, `cache_max_size`, `aclose()`, and the handler
async context manager. Hosts own admission, deadlines, cancellation, and shutdown
coordination. They must cancel and await active invocations before disposing
borrowed HTTP clients.

This is an intentional API and behavioral break. Replace handler context
managers with ordinary construction and remove handler shutdown calls. Each call
pays connection and discovery overhead. Implicit server-session continuity no
longer survives subsequent calls, approval waits, or checkpoint resumes.
Applications needing continuity must use explicit remote state handles or an
explicitly scoped custom handler. Existing checkpoint and approval contracts
remain unchanged; no workflow identity field or checkpoint migration is added.
4 changes: 2 additions & 2 deletions docs/features/code_act/dotnet-implementation.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CodeAct .NET implementation

This document describes the .NET realization of the CodeAct design in
[`docs/decisions/0038-codeact-integration.md`](../../decisions/0038-codeact-integration.md).
[`docs/decisions/0031-codeact-integration.md`](../../decisions/0031-codeact-integration.md).

This document is intentionally focused on the .NET design and public API surface.
The initial public .NET type described here is `HyperlightCodeActProvider`. Future .NET backends, such as Monty, should follow the same conceptual model with their own concrete provider types rather than through a public abstract base class or a public executor parameter.
Expand All @@ -23,7 +23,7 @@ Implementation-free outcome:

## What is the problem being solved?

The cross-SDK problem statement and decision rationale live in the [ADR](../../decisions/0038-codeact-integration.md). The items below narrow that statement to .NET-specific design concerns:
The cross-SDK problem statement and decision rationale live in the [ADR](../../decisions/0031-codeact-integration.md). The items below narrow that statement to .NET-specific design concerns:

- Today, the easiest way to prototype CodeAct in .NET is to manually configure an `AIFunction` and wire instructions — this is fragile and requires understanding internal sandbox lifecycle details.
- There is no first-class .NET design that simultaneously covers Hyperlight-backed CodeAct now, future backend-specific providers, and both tool-enabled and interpreter modes.
Expand Down
4 changes: 2 additions & 2 deletions docs/features/code_act/python-implementation.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CodeAct Python implementation

This document describes the Python realization of the CodeAct design in
[`docs/decisions/0038-codeact-integration.md`](../../decisions/0038-codeact-integration.md).
[`docs/decisions/0031-codeact-integration.md`](../../decisions/0031-codeact-integration.md).

This document is intentionally focused on the Python design and public API surface.
The initial public Python type described here is `HyperlightCodeActProvider`. Future Python backends, such as Monty, should follow the same conceptual model with their own concrete provider types rather than through a public abstract base class or a public executor parameter.
Expand All @@ -23,7 +23,7 @@ Implementation-free outcome:

## What is the problem being solved?

The cross-SDK problem statement and decision rationale live in the [ADR](../../decisions/0038-codeact-integration.md). The items below narrow that statement to Python-specific design concerns:
The cross-SDK problem statement and decision rationale live in the [ADR](../../decisions/0031-codeact-integration.md). The items below narrow that statement to Python-specific design concerns:

- Today, the easiest way to prototype CodeAct is to infer or reshape the agent's direct tool surface, which is fragile and hard to reason about.
- In Python, inferring a CodeAct tool surface from generic agent tool configuration is fragile and hard to reason about.
Expand Down
2 changes: 1 addition & 1 deletion docs/specs/003-dotnet-hosting-protocol-helpers.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ informed: []

# .NET hosting: OpenAI Responses protocol helpers and optional execution state

Implements [ADR-0032](../decisions/0032-dotnet-hosting-protocol-helpers.md), which realizes the
Implements [ADR-0036](../decisions/0036-dotnet-hosting-protocol-helpers.md), which realizes the
helper-first direction of [ADR-0027](../decisions/0027-hosting-channels.md) for .NET.

## What is the goal of this feature?
Expand Down
Loading
Loading