fix: remove extra vertical spacing between memory block tabs (#749)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user