feat: inject current date/time context into chat system prompt

Without this Claude has no grounding for "heute"/"morgen"/"naechste
Woche" and only understands dates the user states explicitly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
Jonny 2026-09-13 21:22:53 +02:00
parent 023698b57c
commit dece6d838d
2 changed files with 50 additions and 1 deletions

View File

@ -409,6 +409,25 @@ def _as_calendar_local(dt: datetime) -> datetime:
return dt
_WEEKDAYS_DE = ["Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag"]
_MONTHS_DE = [
"Januar", "Februar", "Maerz", "April", "Mai", "Juni",
"Juli", "August", "September", "Oktober", "November", "Dezember",
]
def _current_datetime_context(now: datetime = None) -> str:
"""Chat has no other grounding for 'heute'/'morgen'/'naechste Woche' -
without this, Claude only knows dates the user states explicitly."""
now = now or datetime.now(CALENDAR_TIMEZONE)
weekday = _WEEKDAYS_DE[now.weekday()]
month = _MONTHS_DE[now.month - 1]
return (
f"Aktuelles Datum und Uhrzeit: {weekday}, {now.day}. {month} {now.year}, "
f"{now.strftime('%H:%M')} Uhr ({now.strftime('%d.%m.%Y')})."
)
def _create_event_sync(summary: str, start: str, end: str, description: str = "", calendar: str = DEFAULT_CALENDAR) -> dict:
cal = _caldav_calendar(calendar)
cal.save_event(
@ -1026,7 +1045,7 @@ async def run_chat_completion(claude_messages: list, conversation_id: int):
memory_context = await build_memory_context(latest_user_message, conversation_id)
system_prompt = (
f"{CLAUDE_SYSTEM_PROMPT}\n\n{CALENDAR_ASSISTANT_INSTRUCTIONS}\n\n"
f"{CLAUDE_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:

View File

@ -1,5 +1,6 @@
import os
import sys
from datetime import datetime
from unittest.mock import AsyncMock, MagicMock, patch
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
@ -143,3 +144,32 @@ async def test_run_chat_completion_lists_recent_emails():
assert text == "Du hast 5 neue Mails."
assert output_tokens == 6 + 8
assert total_tokens == 15 + 6 + 20 + 8
def test_current_datetime_context_formats_german_weekday_and_month():
fixed = datetime(2026, 9, 13, 21, 15, tzinfo=main.CALENDAR_TIMEZONE)
context = main._current_datetime_context(fixed)
assert context == (
"Aktuelles Datum und Uhrzeit: Sonntag, 13. September 2026, 21:15 Uhr (13.09.2026)."
)
@pytest.mark.asyncio
async def test_run_chat_completion_includes_current_datetime_in_system_prompt():
completion = MagicMock()
completion.stop_reason = "end_turn"
completion.content = [_text_block("Hallo!")]
completion.usage = _usage(10, 5)
main.claude_client = MagicMock()
main.claude_client.messages.create.return_value = completion
with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")), patch.object(
main, "_current_datetime_context", return_value="Aktuelles Datum und Uhrzeit: TESTMARKER"
):
await main.run_chat_completion([{"role": "user", "content": "Hi"}], conversation_id=1)
_, kwargs = main.claude_client.messages.create.call_args
assert "TESTMARKER" in kwargs["system"]