diff --git a/python/samples/02-agents/context_providers/synap/README.md b/python/samples/02-agents/context_providers/synap/README.md new file mode 100644 index 0000000000..8ef41a4e26 --- /dev/null +++ b/python/samples/02-agents/context_providers/synap/README.md @@ -0,0 +1,47 @@ +# Synap Context Provider Sample + +Demonstrates [SynapContextProvider](https://docs.maximem.ai/integrations/microsoft-agent) — a Microsoft Agent Framework `ContextProvider` backed by [Synap](https://maximem.ai), a managed memory layer for AI agents. + +## How It Works + +`SynapContextProvider` implements two lifecycle hooks: +- **`before_run`**: fetches Synap context relevant to the user's input and appends it to the agent's instructions +- **`after_run`**: records input and response messages to Synap via `sdk.conversation.record_message(...)` for future retrieval + +Read failures degrade gracefully. Write failures are logged but never re-raised. + +## Setup + +**1. Install dependencies** + +```bash +pip install maximem-synap-microsoft-agent azure-identity python-dotenv +``` + +**2. Configure Azure credentials** + +This sample uses [Azure AI Foundry](https://ai.azure.com) as the model provider. Run `az login` to authenticate, or replace `AzureCliCredential` with your preferred credential. + +Set the following in a `.env` file or as environment variables: + +``` +AZURE_AI_FOUNDRY_PROJECT_ENDPOINT= +``` + +**3. Get a Synap API key** + +Sign up at [synap.maximem.ai](https://synap.maximem.ai) and set `SYNAP_API_KEY` in your `.env`, or pass it directly to `MaximemSynapSDK(api_key=...)`. + +## Run + +```bash +python synap_basic.py +``` + +## More Resources + +- [Synap Documentation](https://docs.maximem.ai) +- [Microsoft Agent Framework Integration Guide](https://docs.maximem.ai/integrations/microsoft-agent) +- [Dashboard](https://synap.maximem.ai) +- [PyPI: maximem-synap-microsoft-agent](https://pypi.org/project/maximem-synap-microsoft-agent/) +- [Open source integration package](https://github.com/maximem-ai/maximem_synap_sdk/tree/main/packages/integrations) diff --git a/python/samples/02-agents/context_providers/synap/synap_basic.py b/python/samples/02-agents/context_providers/synap/synap_basic.py new file mode 100644 index 0000000000..6f5940c8e3 --- /dev/null +++ b/python/samples/02-agents/context_providers/synap/synap_basic.py @@ -0,0 +1,65 @@ +# Copyright (c) Microsoft. All rights reserved. + +import asyncio +import os + +from agent_framework import Agent +from agent_framework.foundry import FoundryChatClient +from azure.identity.aio import AzureCliCredential +from dotenv import load_dotenv +from maximem_synap import MaximemSynapSDK +from synap_microsoft_agent import SynapContextProvider + +# Load environment variables from .env file +load_dotenv() + + +async def main() -> None: + """Example of persistent cross-session memory with SynapContextProvider.""" + print("=== Synap Context Provider Example ===") + + # Stable user_id so memories persist across runs. + # In production, derive this from the authenticated user's identity. + user_id = "demo-user-001" + + sdk = MaximemSynapSDK(api_key=os.environ["SYNAP_API_KEY"]) + + # For Azure authentication, run `az login` or replace AzureCliCredential with + # your preferred authentication option. + async with ( + AzureCliCredential() as credential, + Agent( + client=FoundryChatClient(credential=credential), + name="MemoryAssistant", + instructions="You are a helpful assistant with long-term memory.", + context_providers=[ + SynapContextProvider( + sdk=sdk, + user_id=user_id, + customer_id="acme_corp", + ) + ], + ) as agent, + ): + # First turn — teach the agent something about the user + query = "I always prefer concise answers and I'm a software engineer." + print(f"User: {query}") + result = await agent.run(query) + print(f"Agent: {result}\n") + + # Synap stores memories asynchronously. Allow time for processing + # before querying in a new session — the agent should recall preferences. + print("Waiting for Synap to process memories...") + await asyncio.sleep(5) + + # Second turn in a new session — agent recalls from Synap + print("Request within a new session:") + session = agent.create_session() + query = "How should you answer my questions?" + print(f"User: {query}") + result = await agent.run(query, session=session) + print(f"Agent: {result}") + + +if __name__ == "__main__": + asyncio.run(main())