From e44eb185d54bf29862021f5b92df3d804fd5dc16 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 25 Mar 2026 10:31:25 -0400 Subject: [PATCH] feat(briefing): extend post_message() to accept optional metadata dict Co-Authored-By: Claude Sonnet 4.6 --- .../services/briefing_conversations.py | 8 +++++- tests/test_briefing_pipeline.py | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/fabledassistant/services/briefing_conversations.py b/src/fabledassistant/services/briefing_conversations.py index b521af7..08bb0cb 100644 --- a/src/fabledassistant/services/briefing_conversations.py +++ b/src/fabledassistant/services/briefing_conversations.py @@ -41,7 +41,12 @@ async def get_or_create_today_conversation(user_id: int, model: str) -> Conversa return conv -async def post_message(conversation_id: int, role: str, content: str) -> Message: +async def post_message( + conversation_id: int, + role: str, + content: str, + metadata: dict | None = None, +) -> Message: """Append a message to a briefing conversation.""" async with async_session() as session: msg = Message( @@ -49,6 +54,7 @@ async def post_message(conversation_id: int, role: str, content: str) -> Message role=role, content=content, status="complete", + msg_metadata=metadata, ) session.add(msg) # Bump conversation updated_at diff --git a/tests/test_briefing_pipeline.py b/tests/test_briefing_pipeline.py index 80a284e..f642b6b 100644 --- a/tests/test_briefing_pipeline.py +++ b/tests/test_briefing_pipeline.py @@ -27,3 +27,30 @@ def test_slot_greeting(): assert "morning" in slot_greeting("compilation").lower() or slot_greeting("compilation") assert slot_greeting("morning") != slot_greeting("midday") assert slot_greeting("midday") != slot_greeting("afternoon") + + +@pytest.mark.asyncio +async def test_post_message_accepts_metadata(): + """post_message should accept an optional metadata dict and store it.""" + from unittest.mock import AsyncMock, patch, MagicMock + + mock_msg = MagicMock() + mock_msg.id = 1 + + with patch("fabledassistant.services.briefing_conversations.async_session") as mock_session_cls: + mock_session = AsyncMock() + mock_session.__aenter__ = AsyncMock(return_value=mock_session) + mock_session.__aexit__ = AsyncMock(return_value=False) + mock_session.add = MagicMock() + mock_session.get = AsyncMock(return_value=None) + mock_session.commit = AsyncMock() + mock_session.refresh = AsyncMock() + mock_session_cls.return_value = mock_session + + from fabledassistant.services.briefing_conversations import post_message + metadata = {"weather": {"location": "Berlin"}, "rss_item_ids": [1, 2]} + await post_message(1, "assistant", "Hello", metadata=metadata) + + # Verify Message was constructed with msg_metadata + call_args = mock_session.add.call_args[0][0] + assert call_args.msg_metadata == metadata