test(core): git-backed memory repo integration (real object store) (#9298)
--------- Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
committed by
Caren Thomas
parent
0bdedb3c0f
commit
93249b96f5
3
.github/workflows/core-integration-tests.yml
vendored
3
.github/workflows/core-integration-tests.yml
vendored
@@ -41,7 +41,8 @@ jobs:
|
||||
"integration_test_batch_api_cron_jobs.py",
|
||||
"integration_test_builtin_tools.py",
|
||||
"integration_test_turbopuffer.py",
|
||||
"integration_test_human_in_the_loop.py"
|
||||
"integration_test_human_in_the_loop.py",
|
||||
"integration_test_git_memory_repo_http.py"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
4
.github/workflows/reusable-test-workflow.yml
vendored
4
.github/workflows/reusable-test-workflow.yml
vendored
@@ -381,6 +381,10 @@ jobs:
|
||||
GOOGLE_CLOUD_PROJECT: ${{ secrets.GOOGLE_CLOUD_PROJECT }}
|
||||
GOOGLE_CLOUD_LOCATION: ${{ secrets.GOOGLE_CLOUD_LOCATION }}
|
||||
|
||||
# Real object store (required for git-backed memory integration test)
|
||||
# Use DEV bucket/prefix variable to avoid prod resources.
|
||||
LETTA_OBJECT_STORE_URI: ${{ vars.LETTA_OBJECT_STORE_URI_DEV }}
|
||||
|
||||
# Feature flags (shared across all test types)
|
||||
LETTA_ENABLE_BATCH_JOB_POLLING: true
|
||||
|
||||
|
||||
@@ -465,12 +465,14 @@ async def _sync_after_push(actor_id: str, agent_id: str) -> None:
|
||||
logger.exception("Failed to read repo files from storage for post-push block sync (agent=%s)", agent_id)
|
||||
files = {}
|
||||
|
||||
expected_labels = set()
|
||||
synced = 0
|
||||
for file_path, content in files.items():
|
||||
if not file_path.startswith("blocks/") or not file_path.endswith(".md"):
|
||||
continue
|
||||
|
||||
label = file_path[len("blocks/") : -3]
|
||||
expected_labels.add(label)
|
||||
await _server_instance.block_manager._sync_block_to_postgres(
|
||||
agent_id=agent_id,
|
||||
label=label,
|
||||
@@ -482,6 +484,36 @@ async def _sync_after_push(actor_id: str, agent_id: str) -> None:
|
||||
|
||||
if synced == 0:
|
||||
logger.warning("No blocks/*.md files found in repo HEAD during post-push sync (agent=%s)", agent_id)
|
||||
else:
|
||||
# Detach blocks that were removed in git.
|
||||
#
|
||||
# We treat git as the source of truth for which blocks are attached to
|
||||
# this agent. If a blocks/*.md file disappears from HEAD, detach the
|
||||
# corresponding block from the agent in Postgres.
|
||||
try:
|
||||
existing_blocks = await _server_instance.agent_manager.list_agent_blocks_async(
|
||||
agent_id=agent_id,
|
||||
actor=actor,
|
||||
before=None,
|
||||
after=None,
|
||||
limit=1000,
|
||||
ascending=True,
|
||||
)
|
||||
existing_by_label = {b.label: b for b in existing_blocks}
|
||||
removed_labels = set(existing_by_label.keys()) - expected_labels
|
||||
|
||||
for label in sorted(removed_labels):
|
||||
block = existing_by_label.get(label)
|
||||
if not block:
|
||||
continue
|
||||
await _server_instance.agent_manager.detach_block_async(
|
||||
agent_id=agent_id,
|
||||
block_id=block.id,
|
||||
actor=actor,
|
||||
)
|
||||
logger.info("Detached block %s from agent (removed from git)", label)
|
||||
except Exception:
|
||||
logger.exception("Failed detaching removed blocks during post-push sync (agent=%s)", agent_id)
|
||||
|
||||
# Cleanup local cache
|
||||
_repo_cache.pop(cache_key, None)
|
||||
|
||||
Reference in New Issue
Block a user