fix: remove extra vertical spacing between memory block tabs (#749)

Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
Charles Packer
2026-01-29 20:23:51 -08:00
committed by GitHub
parent 382a7d34f5
commit 2f1943f41d
4 changed files with 592 additions and 23 deletions

View File

@@ -186,14 +186,22 @@ async function saveSyncState(
await writeFile(statePath, JSON.stringify(state, null, 2));
}
async function scanMdFiles(dir: string, baseDir = dir): Promise<string[]> {
async function scanMdFiles(
dir: string,
baseDir = dir,
excludeDirs: string[] = [],
): Promise<string[]> {
const entries = await readdir(dir, { withFileTypes: true });
const results: string[] = [];
for (const entry of entries) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
results.push(...(await scanMdFiles(fullPath, baseDir)));
// Skip excluded directories (e.g., "system" when scanning for detached files)
if (excludeDirs.includes(entry.name)) {
continue;
}
results.push(...(await scanMdFiles(fullPath, baseDir, excludeDirs)));
} else if (entry.isFile() && entry.name.endsWith(".md")) {
results.push(relative(baseDir, fullPath));
}
@@ -254,8 +262,9 @@ export function parseBlockFromFileContent(
async function readMemoryFiles(
dir: string,
excludeDirs: string[] = [],
): Promise<Map<string, { content: string; path: string }>> {
const files = await scanMdFiles(dir);
const files = await scanMdFiles(dir, dir, excludeDirs);
const entries = new Map<string, { content: string; path: string }>();
for (const relativePath of files) {
@@ -466,7 +475,7 @@ export async function syncMemoryFilesystem(
const systemDir = getMemorySystemDir(agentId, homeDir);
const detachedDir = getMemoryDetachedDir(agentId, homeDir);
const systemFiles = await readMemoryFiles(systemDir);
const detachedFiles = await readMemoryFiles(detachedDir);
const detachedFiles = await readMemoryFiles(detachedDir, [MEMORY_SYSTEM_DIR]);
systemFiles.delete(MEMORY_FILESYSTEM_BLOCK_LABEL);
const attachedBlocks = await fetchAgentBlocks(agentId);
@@ -513,6 +522,11 @@ export async function syncMemoryFilesystem(
if (MANAGED_BLOCK_LABELS.has(block.label)) {
continue;
}
// Skip blocks whose label matches a system block (prevents duplicates)
// This can happen when a system block is detached but keeps its owner tag
if (systemBlockMap.has(block.label)) {
continue;
}
detachedBlockIds[block.label] = block.id;
detachedBlockMap.set(block.label, block);
}
@@ -613,8 +627,10 @@ export async function syncMemoryFilesystem(
if (resolution?.resolution === "file") {
if (blockEntry.id) {
// Parse frontmatter to extract just the body for the block value
const blockData = parseBlockFromFileContent(fileEntry.content, label);
await client.blocks.update(blockEntry.id, {
value: fileEntry.content,
value: blockData.value,
});
updatedBlocks.push(label);
}
@@ -630,8 +646,10 @@ export async function syncMemoryFilesystem(
if (fileChanged && !blockChanged) {
if (blockEntry.id) {
try {
// Parse frontmatter to extract just the body for the block value
const blockData = parseBlockFromFileContent(fileEntry.content, label);
await client.blocks.update(blockEntry.id, {
value: fileEntry.content,
value: blockData.value,
});
updatedBlocks.push(label);
} catch (err) {
@@ -743,8 +761,10 @@ export async function syncMemoryFilesystem(
if (resolution?.resolution === "file") {
if (blockEntry.id) {
// Parse frontmatter to extract just the body for the block value
const blockData = parseBlockFromFileContent(fileEntry.content, label);
await client.blocks.update(blockEntry.id, {
value: fileEntry.content,
value: blockData.value,
label,
});
}
@@ -760,8 +780,10 @@ export async function syncMemoryFilesystem(
if (fileChanged && !blockChanged) {
if (blockEntry.id) {
// Parse frontmatter to extract just the body for the block value
const blockData = parseBlockFromFileContent(fileEntry.content, label);
await client.blocks.update(blockEntry.id, {
value: fileEntry.content,
value: blockData.value,
label,
});
}
@@ -788,7 +810,9 @@ export async function syncMemoryFilesystem(
const updatedSystemFilesMap = await readMemoryFiles(systemDir);
updatedSystemFilesMap.delete(MEMORY_FILESYSTEM_BLOCK_LABEL);
const updatedUserFilesMap = await readMemoryFiles(detachedDir);
const updatedUserFilesMap = await readMemoryFiles(detachedDir, [
MEMORY_SYSTEM_DIR,
]);
const refreshedUserBlocks = new Map<string, { value: string }>();
for (const [label, blockId] of Object.entries(detachedBlockIds)) {
@@ -829,7 +853,7 @@ export async function updateMemoryFilesystemBlock(
const detachedDir = getMemoryDetachedDir(agentId, homeDir);
const systemFiles = await readMemoryFiles(systemDir);
const detachedFiles = await readMemoryFiles(detachedDir);
const detachedFiles = await readMemoryFiles(detachedDir, [MEMORY_SYSTEM_DIR]);
const tree = renderMemoryFilesystemTree(
Array.from(systemFiles.keys()).filter(
@@ -838,6 +862,10 @@ export async function updateMemoryFilesystemBlock(
Array.from(detachedFiles.keys()),
);
// Prepend memory directory path (tilde format for readability)
const memoryPath = `~/.letta/agents/${agentId}/memory`;
const content = `Memory Directory: ${memoryPath}\n\n${tree}`;
const client = await getClient();
const blocks = await fetchAgentBlocks(agentId);
const memfsBlock = blocks.find(
@@ -845,10 +873,10 @@ export async function updateMemoryFilesystemBlock(
);
if (memfsBlock?.id) {
await client.blocks.update(memfsBlock.id, { value: tree });
await client.blocks.update(memfsBlock.id, { value: content });
}
await writeMemoryFile(systemDir, MEMORY_FILESYSTEM_BLOCK_LABEL, tree);
await writeMemoryFile(systemDir, MEMORY_FILESYSTEM_BLOCK_LABEL, content);
}
export async function ensureMemoryFilesystemBlock(agentId: string) {
@@ -933,7 +961,7 @@ export async function checkMemoryFilesystemStatus(
const systemDir = getMemorySystemDir(agentId, homeDir);
const detachedDir = getMemoryDetachedDir(agentId, homeDir);
const systemFiles = await readMemoryFiles(systemDir);
const detachedFiles = await readMemoryFiles(detachedDir);
const detachedFiles = await readMemoryFiles(detachedDir, [MEMORY_SYSTEM_DIR]);
systemFiles.delete(MEMORY_FILESYSTEM_BLOCK_LABEL);
const attachedBlocks = await fetchAgentBlocks(agentId);
@@ -964,6 +992,10 @@ export async function checkMemoryFilesystemStatus(
if (MANAGED_BLOCK_LABELS.has(block.label)) {
continue;
}
// Skip blocks whose label matches a system block (prevents duplicates)
if (systemBlockMap.has(block.label)) {
continue;
}
detachedBlockMap.set(block.label, block);
}
}