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:
parent
023698b57c
commit
dece6d838d
|
|
@ -409,6 +409,25 @@ def _as_calendar_local(dt: datetime) -> datetime:
|
||||||
return dt
|
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:
|
def _create_event_sync(summary: str, start: str, end: str, description: str = "", calendar: str = DEFAULT_CALENDAR) -> dict:
|
||||||
cal = _caldav_calendar(calendar)
|
cal = _caldav_calendar(calendar)
|
||||||
cal.save_event(
|
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)
|
memory_context = await build_memory_context(latest_user_message, conversation_id)
|
||||||
|
|
||||||
system_prompt = (
|
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}"
|
f"{MEMORY_ASSISTANT_INSTRUCTIONS}\n\n{ORDER_ASSISTANT_INSTRUCTIONS}"
|
||||||
)
|
)
|
||||||
if memory_context:
|
if memory_context:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
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 text == "Du hast 5 neue Mails."
|
||||||
assert output_tokens == 6 + 8
|
assert output_tokens == 6 + 8
|
||||||
assert total_tokens == 15 + 6 + 20 + 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"]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue