feat: inject remembered facts and similar summaries into chat system prompt
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V57jSQPqwkGG8BuAXg59X5
This commit is contained in:
parent
33016bdf0a
commit
2d9bf6a42b
|
|
@ -731,8 +731,14 @@ async def execute_tool(name: str, tool_input: dict) -> str:
|
|||
MAX_TOOL_ROUNDS = 5
|
||||
|
||||
|
||||
async def run_chat_completion(claude_messages: list):
|
||||
system_prompt = f"{CLAUDE_SYSTEM_PROMPT}\n\n{CALENDAR_ASSISTANT_INSTRUCTIONS}"
|
||||
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{CALENDAR_ASSISTANT_INSTRUCTIONS}\n\n{MEMORY_ASSISTANT_INSTRUCTIONS}"
|
||||
if memory_context:
|
||||
system_prompt = f"{system_prompt}\n\n{memory_context}"
|
||||
|
||||
messages = list(claude_messages)
|
||||
total_input = 0
|
||||
total_output = 0
|
||||
|
|
@ -743,7 +749,7 @@ async def run_chat_completion(claude_messages: list):
|
|||
model=CLAUDE_MODEL,
|
||||
max_tokens=1024,
|
||||
system=system_prompt,
|
||||
tools=CALENDAR_TOOLS,
|
||||
tools=CALENDAR_TOOLS + MEMORY_TOOLS,
|
||||
messages=messages,
|
||||
)
|
||||
total_input += completion.usage.input_tokens
|
||||
|
|
@ -900,7 +906,7 @@ async def chat(request: ChatRequest):
|
|||
claude_messages = [{"role": m["role"], "content": m["content"]} for m in history]
|
||||
claude_messages.append({"role": "user", "content": request.message})
|
||||
|
||||
response_text, output_tokens, tokens_used = await run_chat_completion(claude_messages)
|
||||
response_text, output_tokens, tokens_used = await run_chat_completion(claude_messages, conversation_id)
|
||||
|
||||
await save_message(conversation_id, DEFAULT_USER_ID, "assistant", response_text, output_tokens)
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,10 @@ async def test_run_chat_completion_without_tool_use():
|
|||
main.claude_client = MagicMock()
|
||||
main.claude_client.messages.create.return_value = completion
|
||||
|
||||
text, output_tokens, total_tokens = await main.run_chat_completion([{"role": "user", "content": "Hi"}])
|
||||
with patch.object(main, "build_memory_context", new=AsyncMock(return_value="")):
|
||||
text, output_tokens, total_tokens = await main.run_chat_completion(
|
||||
[{"role": "user", "content": "Hi"}], conversation_id=1
|
||||
)
|
||||
|
||||
assert text == "Hallo!"
|
||||
assert output_tokens == 5
|
||||
|
|
@ -64,9 +67,11 @@ async def test_run_chat_completion_executes_tool_and_returns_followup():
|
|||
main.claude_client = MagicMock()
|
||||
main.claude_client.messages.create.side_effect = [first, second]
|
||||
|
||||
with patch.object(main, "list_upcoming_events", new=AsyncMock(return_value=[])):
|
||||
with patch.object(main, "list_upcoming_events", new=AsyncMock(return_value=[])), patch.object(
|
||||
main, "build_memory_context", new=AsyncMock(return_value="")
|
||||
):
|
||||
text, output_tokens, total_tokens = await main.run_chat_completion(
|
||||
[{"role": "user", "content": "Was steht diese Woche an?"}]
|
||||
[{"role": "user", "content": "Was steht diese Woche an?"}], conversation_id=1
|
||||
)
|
||||
|
||||
assert text == "Naechste Woche steht nichts an."
|
||||
|
|
@ -102,9 +107,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="")):
|
||||
text, output_tokens, total_tokens = await main.run_chat_completion(
|
||||
[{"role": "user", "content": "Verschiebe den Termin X"}]
|
||||
[{"role": "user", "content": "Verschiebe den Termin X"}], conversation_id=1
|
||||
)
|
||||
|
||||
assert text == "Termin verschoben."
|
||||
|
|
@ -128,9 +133,11 @@ async def test_run_chat_completion_lists_recent_emails():
|
|||
main.claude_client = MagicMock()
|
||||
main.claude_client.messages.create.side_effect = [first, second]
|
||||
|
||||
with patch.object(main, "list_recent_emails", new=AsyncMock(return_value=[])):
|
||||
with patch.object(main, "list_recent_emails", new=AsyncMock(return_value=[])), patch.object(
|
||||
main, "build_memory_context", new=AsyncMock(return_value="")
|
||||
):
|
||||
text, output_tokens, total_tokens = await main.run_chat_completion(
|
||||
[{"role": "user", "content": "Was ist neu im Postfach?"}]
|
||||
[{"role": "user", "content": "Was ist neu im Postfach?"}], conversation_id=1
|
||||
)
|
||||
|
||||
assert text == "Du hast 5 neue Mails."
|
||||
|
|
|
|||
|
|
@ -186,3 +186,29 @@ async def test_build_memory_context_skips_summaries_when_embedding_fails():
|
|||
context = await main.build_memory_context("Hallo", conversation_id=1)
|
||||
|
||||
assert context == ""
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_run_chat_completion_includes_memory_context_in_system_prompt():
|
||||
completion = MagicMock()
|
||||
completion.stop_reason = "end_turn"
|
||||
text_block = MagicMock()
|
||||
text_block.type = "text"
|
||||
text_block.text = "Bruno geht es gut."
|
||||
completion.content = [text_block]
|
||||
usage = MagicMock()
|
||||
usage.input_tokens = 10
|
||||
usage.output_tokens = 5
|
||||
completion.usage = usage
|
||||
|
||||
main.claude_client = MagicMock()
|
||||
main.claude_client.messages.create.return_value = completion
|
||||
|
||||
with patch.object(
|
||||
main, "build_memory_context", new=AsyncMock(return_value="Bekannte Fakten ueber den Nutzer:\n- Hund heisst Bruno")
|
||||
):
|
||||
await main.run_chat_completion([{"role": "user", "content": "Wie geht es meinem Hund?"}], conversation_id=1)
|
||||
|
||||
_, kwargs = main.claude_client.messages.create.call_args
|
||||
assert "Hund heisst Bruno" in kwargs["system"]
|
||||
assert kwargs["tools"] == main.CALENDAR_TOOLS + main.MEMORY_TOOLS
|
||||
|
|
|
|||
Loading…
Reference in New Issue