diff --git a/Claude outputs/main.py b/Claude outputs/main.py index a8c2856..3a7cb4f 100644 --- a/Claude outputs/main.py +++ b/Claude outputs/main.py @@ -56,11 +56,6 @@ EMAIL_SMTP_HOST = os.getenv("EMAIL_SMTP_HOST") EMAIL_SMTP_PORT = int(os.getenv("EMAIL_SMTP_PORT", "465")) EMAIL_USER = os.getenv("EMAIL_USER") EMAIL_PASSWORD = os.getenv("EMAIL_PASSWORD") -CLAUDE_SYSTEM_PROMPT = os.getenv( - "CLAUDE_SYSTEM_PROMPT", - "Du bist JARVIS, ein KI-Assistent fuer Business-Automatisierung.", -) - # ============ INITIALIZATION ============ app = FastAPI( title="JARVIS API", @@ -1070,12 +1065,21 @@ async def execute_tool(name: str, tool_input: dict) -> str: MAX_TOOL_ROUNDS = 5 +async def _identity_system_prompt() -> str: + settings = await get_all_settings() + return ( + f"Du bist {settings['assistant_name']}, der KI-Assistent von " + f"{settings['company_name']}. Bei Fragen zur Erreichbarkeit kannst " + f"du auf {settings['contact_email']} verweisen." + ) + + async def run_chat_completion(claude_messages: list, conversation_id: int): latest_user_message = claude_messages[-1]["content"] memory_context = await build_memory_context(latest_user_message, conversation_id) system_prompt = ( - f"{CLAUDE_SYSTEM_PROMPT}\n\n{_current_datetime_context()}\n\n{CALENDAR_ASSISTANT_INSTRUCTIONS}\n\n" + f"{await _identity_system_prompt()}\n\n{_current_datetime_context()}\n\n{CALENDAR_ASSISTANT_INSTRUCTIONS}\n\n" f"{MEMORY_ASSISTANT_INSTRUCTIONS}\n\n{ORDER_ASSISTANT_INSTRUCTIONS}" ) if memory_context: diff --git a/Claude outputs/tests/test_chat_tools.py b/Claude outputs/tests/test_chat_tools.py index e344117..b8ed9a6 100644 --- a/Claude outputs/tests/test_chat_tools.py +++ b/Claude outputs/tests/test_chat_tools.py @@ -43,7 +43,9 @@ async def test_run_chat_completion_without_tool_use(): main.claude_client = MagicMock() main.claude_client.messages.create.return_value = completion - with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")): + with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")), patch.object( + main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.") + ): text, output_tokens, total_tokens = await main.run_chat_completion( [{"role": "user", "content": "Hi"}], conversation_id=1 ) @@ -70,7 +72,7 @@ async def test_run_chat_completion_executes_tool_and_returns_followup(): with patch.object(main, "list_upcoming_events", new=AsyncMock(return_value=[])), patch.object( main, "build_memory_context", new=AsyncMock(return_value="") - ): + ), patch.object(main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.")): text, output_tokens, total_tokens = await main.run_chat_completion( [{"role": "user", "content": "Was steht diese Woche an?"}], conversation_id=1 ) @@ -108,7 +110,9 @@ async def test_run_chat_completion_handles_two_sequential_tool_calls(): with patch.object(main, "list_upcoming_events", new=AsyncMock(return_value=[{"uid": "abc"}])), patch.object( main, "update_event", new=AsyncMock(return_value={"uid": "abc"}) - ), patch.object(main, "build_memory_context", new=AsyncMock(return_value="")): + ), patch.object(main, "build_memory_context", new=AsyncMock(return_value="")), patch.object( + main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.") + ): text, output_tokens, total_tokens = await main.run_chat_completion( [{"role": "user", "content": "Verschiebe den Termin X"}], conversation_id=1 ) @@ -136,7 +140,7 @@ async def test_run_chat_completion_lists_recent_emails(): with patch.object(main, "list_recent_emails", new=AsyncMock(return_value=[])), patch.object( main, "build_memory_context", new=AsyncMock(return_value="") - ): + ), patch.object(main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.")): text, output_tokens, total_tokens = await main.run_chat_completion( [{"role": "user", "content": "Was ist neu im Postfach?"}], conversation_id=1 ) @@ -168,7 +172,7 @@ async def test_run_chat_completion_includes_current_datetime_in_system_prompt(): with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")), patch.object( main, "_current_datetime_context", return_value="Aktuelles Datum und Uhrzeit: TESTMARKER" - ): + ), patch.object(main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.")): await main.run_chat_completion([{"role": "user", "content": "Hi"}], conversation_id=1) _, kwargs = main.claude_client.messages.create.call_args diff --git a/Claude outputs/tests/test_memory.py b/Claude outputs/tests/test_memory.py index 6ed0aad..61c48ec 100644 --- a/Claude outputs/tests/test_memory.py +++ b/Claude outputs/tests/test_memory.py @@ -206,7 +206,7 @@ async def test_run_chat_completion_includes_memory_context_in_system_prompt(): with patch.object( main, "build_memory_context", new=AsyncMock(return_value="Bekannte Fakten ueber den Nutzer:\n- Hund heisst Bruno") - ): + ), patch.object(main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.")): await main.run_chat_completion([{"role": "user", "content": "Wie geht es meinem Hund?"}], conversation_id=1) _, kwargs = main.claude_client.messages.create.call_args diff --git a/Claude outputs/tests/test_orders.py b/Claude outputs/tests/test_orders.py index 7156fa8..cda7956 100644 --- a/Claude outputs/tests/test_orders.py +++ b/Claude outputs/tests/test_orders.py @@ -328,7 +328,9 @@ async def test_run_chat_completion_includes_order_tools_and_instructions(): main.claude_client = MagicMock() main.claude_client.messages.create.return_value = completion - with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")): + with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")), patch.object( + main, "_identity_system_prompt", new=AsyncMock(return_value="Du bist JARVIS.") + ): await main.run_chat_completion( [{"role": "user", "content": "Neue Bestellung fuer Feuerwehr Onza"}], conversation_id=1 ) diff --git a/Claude outputs/tests/test_settings.py b/Claude outputs/tests/test_settings.py index d8f88f7..db792d1 100644 --- a/Claude outputs/tests/test_settings.py +++ b/Claude outputs/tests/test_settings.py @@ -113,3 +113,14 @@ def test_put_settings_endpoint_rejects_unknown_key(client): def test_put_settings_endpoint_requires_admin_key(client): response = client.put("/api/v1/settings", json={"assistant_name": "X"}) assert response.status_code == 401 + + +@pytest.mark.asyncio +async def test_identity_system_prompt_uses_settings(): + settings = {"assistant_name": "FRIDAY", "company_name": "Stark Industries", "contact_email": "info@stark.example"} + with patch.object(main, "get_all_settings", new=AsyncMock(return_value=settings)): + prompt = await main._identity_system_prompt() + + assert "FRIDAY" in prompt + assert "Stark Industries" in prompt + assert "info@stark.example" in prompt