# Copyright (c) Microsoft. All rights reserved. """Tests for shared state management.""" import pytest from ag_ui.core import StateSnapshotEvent from agent_framework import ChatAgent, TextContent from agent_framework._types import ChatResponseUpdate from agent_framework_ag_ui._agent import AgentFrameworkAgent from agent_framework_ag_ui._events import AgentFrameworkEventBridge @pytest.fixture def mock_agent(): """Create a mock agent for testing.""" class MockChatClient: async def get_streaming_response(self, messages, chat_options, **kwargs): yield ChatResponseUpdate(contents=[TextContent(text="Hello!")]) return ChatAgent( name="test_agent", instructions="Test agent", chat_client=MockChatClient(), ) def test_state_snapshot_event(): """Test creating state snapshot events.""" bridge = AgentFrameworkEventBridge(run_id="test-run", thread_id="test-thread") state = { "recipe": { "name": "Chocolate Chip Cookies", "ingredients": ["flour", "sugar", "chocolate chips"], "instructions": ["Mix ingredients", "Bake at 350°F"], "servings": 24, } } event = bridge.create_state_snapshot_event(state) assert isinstance(event, StateSnapshotEvent) assert event.snapshot == state assert event.snapshot["recipe"]["name"] == "Chocolate Chip Cookies" assert len(event.snapshot["recipe"]["ingredients"]) == 3 def test_state_delta_event(): """Test creating state delta events using JSON Patch format.""" bridge = AgentFrameworkEventBridge(run_id="test-run", thread_id="test-thread") # JSON Patch operations (RFC 6902) delta = [ {"op": "add", "path": "/recipe/ingredients/-", "value": "vanilla extract"}, {"op": "replace", "path": "/recipe/servings", "value": 30}, ] event = bridge.create_state_delta_event(delta) assert event.delta == delta assert len(event.delta) == 2 assert event.delta[0]["op"] == "add" assert event.delta[1]["op"] == "replace" async def test_agent_with_initial_state(mock_agent): """Test agent emits state snapshot when initial state provided.""" state_schema = {"recipe": {"type": "object", "properties": {"name": {"type": "string"}}}} agent = AgentFrameworkAgent( agent=mock_agent, state_schema=state_schema, ) initial_state = {"recipe": {"name": "Test Recipe"}} input_data = { "messages": [{"role": "user", "content": "Hello"}], "state": initial_state, } events = [] async for event in agent.run_agent(input_data): events.append(event) # Should have RunStartedEvent, StateSnapshotEvent, RunFinishedEvent at minimum snapshot_events = [e for e in events if isinstance(e, StateSnapshotEvent)] assert len(snapshot_events) == 1 assert snapshot_events[0].snapshot == initial_state async def test_agent_without_state_schema(mock_agent): """Test agent doesn't emit state events without state schema.""" agent = AgentFrameworkAgent(agent=mock_agent) input_data = { "messages": [{"role": "user", "content": "Hello"}], "state": {"some": "state"}, } events = [] async for event in agent.run_agent(input_data): events.append(event) # Should NOT have any StateSnapshotEvent snapshot_events = [e for e in events if isinstance(e, StateSnapshotEvent)] assert len(snapshot_events) == 0