fix(core): stabilize system prompt refresh and expand git-memory coverage (#9438)
* fix(core): stabilize system prompt refresh and expand git-memory coverage Only rebuild system prompts on explicit refresh paths so normal turns preserve prefix-cache stability, including git/custom prompt layouts. Add integration coverage for memory filesystem tree structure and recompile/reset system-message updates via message-id retrieval. 👾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com> * fix(core): recompile system prompt around compaction and stabilize source tests Force system prompt refresh before/after compaction in LettaAgentV3 so repaired system+memory state is used and persisted across subsequent turns. Update source-system prompt tests to explicitly recompile before raw preview assertions instead of assuming automatic rebuild timing. 👾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com> --------- Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
committed by
Caren Thomas
parent
5b7dd15905
commit
d7793a4474
@@ -333,7 +333,7 @@ Some directory content
|
||||
)
|
||||
result = ContextWindowCalculator.extract_system_components(system_message)
|
||||
|
||||
# memory_filesystem should be the tree view only
|
||||
# memory_filesystem should preserve tree connectors with deterministic ordering
|
||||
assert result["memory_filesystem"] is not None
|
||||
assert "\u251c\u2500\u2500 system/" in result["memory_filesystem"]
|
||||
|
||||
|
||||
@@ -27,8 +27,20 @@ from tests.utils import wait_for_server
|
||||
SERVER_PORT = 8283
|
||||
|
||||
|
||||
def get_raw_system_message(client: LettaSDKClient, agent_id: str) -> str:
|
||||
def recompile_agent_system_prompt(client: LettaSDKClient, agent_id: str) -> None:
|
||||
"""Force a system prompt recompilation for deterministic raw-preview assertions."""
|
||||
client.post(
|
||||
f"/v1/agents/{agent_id}/recompile",
|
||||
cast_to=str,
|
||||
body={},
|
||||
)
|
||||
|
||||
|
||||
def get_raw_system_message(client: LettaSDKClient, agent_id: str, recompile: bool = False) -> str:
|
||||
"""Helper function to get the raw system message from an agent's preview payload."""
|
||||
if recompile:
|
||||
recompile_agent_system_prompt(client, agent_id)
|
||||
|
||||
raw_payload = client.post(
|
||||
f"/v1/agents/{agent_id}/messages/preview-raw-payload",
|
||||
cast_to=dict[str, Any],
|
||||
@@ -215,7 +227,7 @@ def test_file_upload_creates_source_blocks_correctly(
|
||||
assert any(re.fullmatch(expected_label_regex, b.label) for b in blocks)
|
||||
|
||||
# verify raw system message contains source information
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert "test_source" in raw_system_message
|
||||
assert "<directories>" in raw_system_message
|
||||
# verify file-specific details in raw system message
|
||||
@@ -234,7 +246,7 @@ def test_file_upload_creates_source_blocks_correctly(
|
||||
assert not any(re.fullmatch(expected_label_regex, b.label) for b in blocks)
|
||||
|
||||
# verify raw system message no longer contains source information
|
||||
raw_system_message_after_removal = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message_after_removal = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
# this should be in, because we didn't delete the source
|
||||
assert "test_source" in raw_system_message_after_removal
|
||||
assert "<directories>" in raw_system_message_after_removal
|
||||
@@ -266,7 +278,7 @@ def test_attach_existing_files_creates_source_blocks_correctly(
|
||||
|
||||
# Attach after uploading the file
|
||||
client.agents.folders.attach(folder_id=source.id, agent_id=agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
|
||||
# Assert that the expected chunk is in the raw system message
|
||||
expected_chunk = """<directories>
|
||||
@@ -307,7 +319,7 @@ def test_attach_existing_files_creates_source_blocks_correctly(
|
||||
assert not any("test" in b.value for b in blocks)
|
||||
|
||||
# Verify no traces of the prompt exist in the raw system message after detaching
|
||||
raw_system_message_after_detach = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message_after_detach = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert expected_chunk not in raw_system_message_after_detach
|
||||
assert "test_source" not in raw_system_message_after_detach
|
||||
assert "<directories>" not in raw_system_message_after_detach
|
||||
@@ -321,7 +333,7 @@ def test_delete_source_removes_source_blocks_correctly(
|
||||
assert len(list(client.folders.list())) == 1
|
||||
|
||||
client.agents.folders.attach(folder_id=source.id, agent_id=agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert "test_source" in raw_system_message
|
||||
assert "<directories>" in raw_system_message
|
||||
|
||||
@@ -330,7 +342,7 @@ def test_delete_source_removes_source_blocks_correctly(
|
||||
|
||||
# Upload the files
|
||||
upload_file_and_wait(client, source.id, file_path)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
# Assert that the expected chunk is in the raw system message
|
||||
expected_chunk = """<directories>
|
||||
<file_limits>
|
||||
@@ -361,7 +373,7 @@ def test_delete_source_removes_source_blocks_correctly(
|
||||
|
||||
# Remove file from source
|
||||
client.folders.delete(folder_id=source.id)
|
||||
raw_system_message_after_detach = get_raw_system_message(client, agent_state.id)
|
||||
raw_system_message_after_detach = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert expected_chunk not in raw_system_message_after_detach
|
||||
assert "test_source" not in raw_system_message_after_detach
|
||||
assert "<directories>" not in raw_system_message_after_detach
|
||||
@@ -1112,7 +1124,7 @@ def test_agent_open_file(disable_pinecone, disable_turbopuffer, client: LettaSDK
|
||||
closed_files = client.agents.files.open(agent_id=agent_state.id, file_id=file_metadata["id"])
|
||||
assert len(closed_files) == 0
|
||||
|
||||
system = get_raw_system_message(client, agent_state.id)
|
||||
system = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert '<file status="open" name="test_source/test.txt">' in system
|
||||
assert "[Viewing file start (out of 1 lines)]" in system
|
||||
|
||||
@@ -1137,7 +1149,7 @@ def test_agent_close_file(disable_pinecone, disable_turbopuffer, client: LettaSD
|
||||
# Test close_file function
|
||||
client.agents.files.close(agent_id=agent_state.id, file_id=file_metadata["id"])
|
||||
|
||||
system = get_raw_system_message(client, agent_state.id)
|
||||
system = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert '<file status="closed" name="test_source/test.txt">' in system
|
||||
|
||||
|
||||
@@ -1160,7 +1172,7 @@ def test_agent_close_all_open_files(disable_pinecone, disable_turbopuffer, clien
|
||||
# Open each file
|
||||
client.agents.files.open(agent_id=agent_state.id, file_id=file_metadata["id"])
|
||||
|
||||
system = get_raw_system_message(client, agent_state.id)
|
||||
system = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert '<file status="open"' in system
|
||||
|
||||
# Test close_all_open_files function
|
||||
@@ -1170,7 +1182,7 @@ def test_agent_close_all_open_files(disable_pinecone, disable_turbopuffer, clien
|
||||
assert isinstance(result, list), f"Expected list, got {type(result)}"
|
||||
assert all(isinstance(item, str) for item in result), "All items in result should be strings"
|
||||
|
||||
system = get_raw_system_message(client, agent_state.id)
|
||||
system = get_raw_system_message(client, agent_state.id, recompile=True)
|
||||
assert '<file status="open"' not in system
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user