chore: import upstream snapshot with attribution
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
CodeQL / Analyze (csharp) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
dotnet-build-and-test / dotnet-test-functions (push) Has been cancelled
dotnet-build-and-test / paths-filter (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Debug, windows-latest, net9.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, ubuntu-latest, net8.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-build (Release, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, ubuntu-latest, net10.0) (push) Has been cancelled
dotnet-build-and-test / dotnet-test (Release, integration, true, windows-latest, net472) (push) Has been cancelled
dotnet-build-and-test / dotnet-foundry-hosted-it (push) Has been cancelled
dotnet-build-and-test / dotnet-build-and-test-check (push) Has been cancelled
dotnet-build-and-test / Integration Test Report (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from agent_framework import Agent, AgentSession, ContextProvider, SessionContext
|
||||
from agent_framework.foundry import FoundryChatClient
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
"""
|
||||
Agent Memory with Context Providers and Session State
|
||||
|
||||
Context providers inject dynamic context into each agent call. This sample
|
||||
shows a provider that stores the user's name in session state and personalizes
|
||||
responses — the name persists across turns via the session.
|
||||
"""
|
||||
|
||||
|
||||
# <context_provider>
|
||||
class UserMemoryProvider(ContextProvider):
|
||||
"""A context provider that remembers user info in session state."""
|
||||
|
||||
DEFAULT_SOURCE_ID = "user_memory"
|
||||
|
||||
def __init__(self):
|
||||
super().__init__(self.DEFAULT_SOURCE_ID)
|
||||
|
||||
async def before_run(
|
||||
self,
|
||||
*,
|
||||
agent: Any,
|
||||
session: AgentSession | None,
|
||||
context: SessionContext,
|
||||
state: dict[str, Any],
|
||||
) -> None:
|
||||
"""Inject personalization instructions based on stored user info."""
|
||||
user_name = state.get("user_name")
|
||||
if user_name:
|
||||
context.extend_instructions(
|
||||
self.source_id,
|
||||
f"The user's name is {user_name}. Always address them by name.",
|
||||
)
|
||||
else:
|
||||
context.extend_instructions(
|
||||
self.source_id,
|
||||
"You don't know the user's name yet. Ask for it politely.",
|
||||
)
|
||||
|
||||
async def after_run(
|
||||
self,
|
||||
*,
|
||||
agent: Any,
|
||||
session: AgentSession | None,
|
||||
context: SessionContext,
|
||||
state: dict[str, Any],
|
||||
) -> None:
|
||||
"""Extract and store user info in session state after each call."""
|
||||
for msg in context.input_messages:
|
||||
text = msg.text if hasattr(msg, "text") else ""
|
||||
if isinstance(text, str) and "my name is" in text.lower():
|
||||
state["user_name"] = text.lower().split("my name is")[-1].strip().split()[0].capitalize()
|
||||
|
||||
|
||||
# </context_provider>
|
||||
|
||||
|
||||
async def main() -> None:
|
||||
# <create_agent>
|
||||
client = FoundryChatClient(
|
||||
project_endpoint="https://your-project.services.ai.azure.com",
|
||||
model="gpt-4o",
|
||||
credential=AzureCliCredential(),
|
||||
)
|
||||
|
||||
agent = Agent(
|
||||
client=client,
|
||||
name="MemoryAgent",
|
||||
instructions="You are a friendly assistant.",
|
||||
context_providers=[UserMemoryProvider()],
|
||||
)
|
||||
# </create_agent>
|
||||
|
||||
# <run_with_memory>
|
||||
session = agent.create_session()
|
||||
|
||||
# The provider doesn't know the user yet — it will ask for a name
|
||||
result = await agent.run("Hello! What's the square root of 9?", session=session)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
# Now provide the name — the provider stores it in session state
|
||||
result = await agent.run("My name is Alice", session=session)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
# Subsequent calls are personalized — name persists via session state
|
||||
result = await agent.run("What is 2 + 2?", session=session)
|
||||
print(f"Agent: {result}\n")
|
||||
|
||||
# Inspect session state to see what the provider stored
|
||||
provider_state = session.state.get("user_memory", {})
|
||||
print(f"[Session State] Stored user name: {provider_state.get('user_name')}")
|
||||
# </run_with_memory>
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user