8000 Python: Add Foundry Memory Context Provider by Copilot · Pull Request #3943 · microsoft/agent-framework · GitHub
[go: up one dir, main page]

Skip to content

Python: Add Foundry Memory Context Provider#3943

Merged
eavanvalkenburg merged 13 commits intomainfrom
copilot/add-foundry-memory-provider
Feb 24, 2026
Merged

Python: Add Foundry Memory Context Provider#3943
eavanvalkenburg merged 13 commits intomainfrom
copilot/add-foundry-memory-provider

Conversation

Copy link
Contributor
Copilot AI commented Feb 15, 2026

Motivation and Context

Agents need persistent semantic memory capabilities using Azure AI Foundry Memory Store. Existing context providers (Mem0, Redis) don't integrate with Foundry's memory APIs.

Description

Implements FoundryMemoryProvider as a BaseContextProvider that wraps Azure AI Projects SDK memory operations.

Architecture:

  • before_run: Retrieves static memories (user profiles) once per session, then searches contextual memories per turn using search_memories API
  • after_run: Fires begin_update_memories with configurable delay (default 300s), chains operations via previous_update_id
  • Error handling: Non-critical failures logged, agent continues without memory
  • State management: All stateful data stored in session.state[source_id] for proper persistence and multi-provider support
  • Client lifecycle: Provider does not close externally-provided project_client (follows Mem0ContextProvider pattern with _should_close_client flag)

Key implementation details:

  • Uses ItemParam for message formatting, compatible with Foundry memory extraction pipeline
  • Session state namespaced under source_id prevents collisions when multiple providers are used
  • Memory updates debounced server-side by update_delay parameter
  • Async context manager respects client ownership - does not close externally-provided clients
  • DEFAULT_SOURCE_ID = "foundry" provides sensible default while allowing customization
  • Uses standard logging.getLogger(__name__) for logging

Usage:

from agent_framework.azure import FoundryMemoryProvider
from azure.ai.projects.aio import AIProjectClient

# Uses default source_id="foundry"
memory_provider = FoundryMemoryProvider(
    project_client=project_client,
    memory_store_name="my_store",
    scope="user_123",
    update_delay=60
)

agent = Agent(
    client=chat_client,
    context_providers=[memory_provider]
)

Files:

  • Core: _foundry_memory_provider.py (237 lines)
  • Tests: 21 test methods covering init, hooks, edge cases, state management, client lifecycle
  • Sample: azure_ai_foundry_memory.py demonstrating memory store creation/cleanup with correct environment variable names

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? No
Original prompt

This section details on the original issue you should resolve

<issue_title>Python: Add Foundry Memory Context Provider</issue_title>
<issue_description>We should add a Context Provider based on Foundry Memory. This can be done using the foundry project client sdk: https://learn.microsoft.com/en-us/python/api/overview/azure/ai-projects-readme?view=azure-python-preview (.memory_store operations), a snippet that can be used to get started (incomplete, not validated and uses verbs from the SK version of context providers):

class FoundryMemoryProvider(ContextProvider):
  client: AzureChatClient
  memory_store_id: str
  scope: str
  _previous_update_id: str
  _previous_search_id: str

  def __init__(
    self, client: AzureChatClient, 
    memory_store_id: str, 
    scope: str
  ) -> None:
    super().__init__(client, memory_store_id, scope)

  async def thread_created(self, thread_id: str | None = None) -> None:
    # Retrieve/update user profile memories
    self._static_memories = self.client.memory_stores.search_memories(
      self.memory_store_id,
      self.scope
    )

  async def messages_adding(
    self, thread_id: str | None, new_messages: ChatMessage | Sequence[ChatMessage]
  ) -> None:
    messages_list = ( [new_messages] if isinstance(new_messages, ChatMessage) else list(new_messages) )
    messages: list[dict[str, str]] = [
      {"role": message.role.value, "content": message.text}
      for message in messages_list
      if message.role.value in {"user", "assistant", "system"} and message.text and message.text.strip()
    ]
    self._new_search_messages.extend(messages)
    self._new_update_messages.extend(messages)

    # Update memories with delay (fire and forget)
    update_poller = client.memory_stores.update_memories(
      self.memory_store_id, self.scope, new_update_messages, self.previous_update_id, update_delay="5m")
    self.previous_update_id = update_poller.update_id
    self._new_update_messages = []


  async def model_invoking(
      self, messages: ChatMessage | MutableSequence[ChatMessage]
  ) -> Context:
    # Awkward that thread_id is part of messages_adding, but not model_invoking
    search_response = self.client.memory_stores.search_memories(
      self.memory_store_id, self.scope, self._new_search_messages, self._previous_search_id)
    self._previous_search_id = search_response.search_id
    self._new_search_messages = []

    context_memories = self._static_memories.concat(search_response.memories)
    line_separated_memories = "\n".join(memory.content for memory in context_memories)
    context_prompt = "## Memories\nConsider the following memories when answering user questions:"
    content = TextContent(f"{context_prompt}\n{line_separated_memories}")
    return Context(contents=[content])
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add Foundry Memory Context Provider Python: Add Foundry Memory Context Provider Feb 15, 2026
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python labels Feb 16, 2026
Copy link
Member
@eavanvalkenburg eavanvalkenburg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot couple of comments, please address

@markwallace-microsoft
Copy link
Member
markwallace-microsoft commented Feb 16, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/azure-ai/agent_framework_azure_ai
   _foundry_memory_provider.py880100% 
TOTAL22237347284% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
4285 240 💤 0 ❌ 0 🔥 1m 15s ⏱️

@eavanvalkenburg eavanvalkenburg marked this pull request as ready for review February 16, 2026 17:25
Copilot AI review requested due to automatic review settings February 16, 2026 17:25
Copy link
Contributor
Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Python context provider that integrates Azure AI Foundry Memory Store into Agent Framework’s context-provider pipeline, along with public exports, tests, and documentation/sample usage.

Changes:

  • Introduces FoundryMemoryProvider (BaseContextProvider) backed by azure.ai.projects memory store APIs.
  • Exposes FoundryMemoryProvider via agent_framework.azure and agent_framework_azure_ai package exports/stubs.
  • Adds unit tests and a runnable sample demonstrating memory store creation, usage, and cleanup.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
python/packages/azure-ai/agent_framework_azure_ai/_foundry_memory_provider.py Implements Foundry memory search + update hooks and session-state namespacing.
python/packages/azure-ai/tests/test_foundry_memory_provider.py Adds unit tests covering init, hook behavior, state, and async context manager behavior.
python/packages/core/agent_framework/azure/init.py Adds lazy export for FoundryMemoryProvider from agent_framework_azure_ai.
python/packages/core/agent_framework/azure/init.pyi Adds typing export for FoundryMemoryProvider.
python/packages/azure-ai/agent_framework_azure_ai/init.py Re-exports FoundryMemoryProvider from the azure-ai integration package.
python/packages/azure-ai/README.md Documents the new provider and links to the sample.
python/samples/02-agents/context_providers/azure_ai_foundry_memory.py Adds an end-to-end sample showing Foundry memory store setup and agent usage.

@eavanvalkenburg eavanvalkenburg force-pushed the copilot/add-foundry-memory-provider branch from add1492 to 919fa08 Compare February 17, 2026 08:32
@markwallace-microsoft markwallace-microsoft added the lab Agent Framework Lab label Feb 17, 2026
@eavanvalkenburg eavanvalkenburg changed the title Python: Add Foundry Memory Context Provider Python: [BREAKING] Add Foundry Memory Context Provider Feb 17, 2026
@eavanvalkenburg eavanvalkenburg force-pushed the copilot/add-foundry-memory-provider branch from 8b709ee to 1179457 Compare February 18, 2026 08:25
@eavanvalkenburg eavanvalkenburg changed the title Python: [BREAKING] Add Foundry Memory Context Provider Python: Add Foundry Memory Context Provider Feb 19, 2026
Copilot AI and others added 9 commits February 23, 2026 13:23
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
…ger, move state to session.state

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eavanvalkenburg eavanvalkenburg force-pushed the copilot/add-foundry-memory-provider branch from 1179457 to 15c9670 Compare February 23, 2026 12:23
eavanvalkenburg and others added 4 commits February 23, 2026 14:23
- Use Mock objects with memory_item.content for memory mocks
- Assert 'content' instead of 'text' on SDK message items
- Update exception types from ServiceInitializationError to ValueError
- Remove unused ServiceInitializationError import

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add type: ignore[arg-type] for scope (str | None vs str) and items
(list variance) passed to Azure SDK methods.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Feb 23, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 23, 2026
@giles17 giles17 added this pull request to the merge queue Feb 24, 2026
github-merge-queue bot pushed a commit that referenced this pull request Feb 24, 2026
* Initial plan

* Add FoundryMemoryProvider and tests

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Add sample and documentation for FoundryMemoryProvider

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Address code review feedback for FoundryMemoryProvider

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Address PR review comments: Add DEFAULT_SOURCE_ID, use logging.getLogger, move state to session.state

Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>

* Fix Foundry memory ItemParam usage and exports

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

* Refactor provider hook state and standardize source IDs

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

* Support endpoint-based Foundry memory init

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

* updated implementation and sample

* updated code and samples

* Fix foundry memory provider tests: mock structure and field names

- Use Mock objects with memory_item.content for memory mocks
- Assert 'content' instead of 'text' on SDK message items
- Update exception types from ServiceInitializationError to ValueError
- Remove unused ServiceInitializationError import

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

* Fix mypy errors in foundry memory provider

Add type: ignore[arg-type] for scope (str | None vs str) and items
(list variance) passed to Azure SDK methods.

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

* fix import

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com>
Co-authored-by: eavanvalkenburg <github@vanvalkenburg.eu>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 24, 2026
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Feb 24, 2026
Merged via the queue into main with commit 7b24d91 Feb 24, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation lab Agent Framework Lab python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: Add Foundry Memory Context Provider

7 participants

0