diff --git a/mateclaw-ui/src/i18n/locales/en-US.ts b/mateclaw-ui/src/i18n/locales/en-US.ts index 7204bfb0..1bb5f70e 100644 --- a/mateclaw-ui/src/i18n/locales/en-US.ts +++ b/mateclaw-ui/src/i18n/locales/en-US.ts @@ -1985,6 +1985,13 @@ export default { header: 'Overview', empty: 'No memory content yet', userEdited: 'User edited', + files: { + memory: 'Memory', + profile: 'Profile', + soul: 'Soul', + userFacts: 'User facts', + references: 'References', + }, }, time: { justNow: 'just now', diff --git a/mateclaw-ui/src/i18n/locales/zh-CN.ts b/mateclaw-ui/src/i18n/locales/zh-CN.ts index 2b280468..3aeb3d35 100644 --- a/mateclaw-ui/src/i18n/locales/zh-CN.ts +++ b/mateclaw-ui/src/i18n/locales/zh-CN.ts @@ -1995,6 +1995,13 @@ export default { header: '概述', empty: '暂无记忆内容', userEdited: '用户编辑', + files: { + memory: '记忆', + profile: '档案', + soul: '灵魂', + userFacts: '用户事实', + references: '参考资料', + }, }, time: { justNow: '刚刚', diff --git a/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue b/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue index b8fc4846..498e36ce 100644 --- a/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue +++ b/mateclaw-ui/src/views/Memory/components/MemoryBrowser.vue @@ -4,10 +4,10 @@
@@ -64,7 +64,7 @@ import { ref, watch } from 'vue' import { useI18n } from 'vue-i18n' import { ElMessage } from 'element-plus' -import { http } from '@/api' +import { http, agentContextApi } from '@/api' const props = defineProps<{ agentId: number }>() const { t } = useI18n() @@ -84,14 +84,15 @@ watch(() => props.agentId, () => { loadFileList() }, { immediate: true }) async function loadFileList() { try { - const res = await http.get(`/agents/${props.agentId}/workspace/files`) + const res: any = await agentContextApi.listFiles(props.agentId) const allFiles: FileInfo[] = res.data || [] - // Show memory-relevant files: MEMORY.md, PROFILE.md, SOUL.md, structured/*.md - files.value = allFiles.filter((f: FileInfo) => + // Memory-relevant files only: MEMORY.md, PROFILE.md, SOUL.md, structured/*.md + const filtered = allFiles.filter((f: FileInfo) => ['MEMORY.md', 'PROFILE.md', 'SOUL.md'].includes(f.filename) || f.filename.startsWith('structured/') ) - // Auto-load MEMORY.md + // Order by importance: brain → persona → extracted facts (alpha within group) + files.value = filtered.sort((a, b) => fileRank(a.filename) - fileRank(b.filename) || a.filename.localeCompare(b.filename)) if (files.value.some(f => f.filename === 'MEMORY.md')) { loadFile('MEMORY.md') } else if (files.value.length > 0) { @@ -105,7 +106,7 @@ async function loadFile(filename: string) { loading.value = true editingIdx.value = -1 try { - const res = await http.get(`/agents/${props.agentId}/workspace/files/${encodeURIComponent(filename)}`) + const res: any = await agentContextApi.getFile(props.agentId, filename) const content: string = res.data?.content || '' sections.value = parseSections(content) } catch { sections.value = [] } @@ -174,33 +175,59 @@ function fileIcon(filename: string): string { if (filename === 'MEMORY.md') return '🧠' if (filename === 'PROFILE.md') return '👤' if (filename === 'SOUL.md') return '💫' + if (filename === 'structured/user.md') return '📋' + if (filename === 'structured/reference.md') return '🔗' if (filename.startsWith('structured/')) return '📋' return '📄' } -function formatSize(bytes: number): string { - if (!bytes) return '0B' - if (bytes < 1024) return bytes + 'B' - return (bytes / 1024).toFixed(1) + 'KB' +// Rank for display order: 0 = primary brain, 1 = persona, 2 = extracted facts. +function fileRank(filename: string): number { + if (filename === 'MEMORY.md') return 0 + if (filename === 'PROFILE.md' || filename === 'SOUL.md') return 1 + return 2 +} + +// Friendly label — hides directory paths and the .md extension from the user. +function fileLabel(filename: string): string { + const key = ({ + 'MEMORY.md': 'memory', + 'PROFILE.md': 'profile', + 'SOUL.md': 'soul', + 'structured/user.md': 'userFacts', + 'structured/reference.md': 'references', + } as Record)[filename] + if (key) { + const i18nKey = `memory.memoryBrowser.files.${key}` + const translated = t(i18nKey) + if (translated !== i18nKey) return translated + } + // Fallback: strip path prefix and .md extension. + const base = filename.includes('/') ? filename.slice(filename.lastIndexOf('/') + 1) : filename + return base.replace(/\.md$/i, '') }