feat(memory): add nightly vault index rebuild and agent docs
Add maybeRebuildVaultIndex() to heartbeat service for nightly full index rebuilds during quiet hours (2-5am). Uses a date stamp file to run at most once per day. Update AGENT.md with memory vault conventions, note format, and tool usage guidelines.
This commit is contained in:
parent
1102a64715
commit
ac5b384f16
2 changed files with 70 additions and 2 deletions
|
|
@ -17,6 +17,7 @@ import (
|
|||
"github.com/sipeed/picoclaw/pkg/bus"
|
||||
"github.com/sipeed/picoclaw/pkg/constants"
|
||||
"github.com/sipeed/picoclaw/pkg/logger"
|
||||
"github.com/sipeed/picoclaw/pkg/memory"
|
||||
"github.com/sipeed/picoclaw/pkg/state"
|
||||
"github.com/sipeed/picoclaw/pkg/tools"
|
||||
)
|
||||
|
|
@ -159,6 +160,9 @@ func (hs *HeartbeatService) executeHeartbeat() {
|
|||
|
||||
logger.DebugC("heartbeat", "Executing heartbeat")
|
||||
|
||||
// Nightly vault index rebuild (runs once per day between 2-5am)
|
||||
hs.maybeRebuildVaultIndex()
|
||||
|
||||
prompt := hs.buildPrompt()
|
||||
if prompt == "" {
|
||||
logger.InfoC("heartbeat", "No heartbeat prompt (HEARTBEAT.md empty or missing)")
|
||||
|
|
@ -341,6 +345,37 @@ func (hs *HeartbeatService) parseLastChannel(lastChannel string) (platform, user
|
|||
return platform, userID
|
||||
}
|
||||
|
||||
// maybeRebuildVaultIndex performs a nightly full rebuild of the memory vault
|
||||
// index. It runs at most once per day, during quiet hours (2-5am local time),
|
||||
// to catch any inconsistencies from incremental updates.
|
||||
func (hs *HeartbeatService) maybeRebuildVaultIndex() {
|
||||
memoryDir := filepath.Join(hs.workspace, "memory")
|
||||
stampFile := filepath.Join(memoryDir, ".last_rebuild")
|
||||
today := time.Now().Format("2006-01-02")
|
||||
|
||||
// Check if already rebuilt today
|
||||
if data, err := os.ReadFile(stampFile); err == nil {
|
||||
if strings.TrimSpace(string(data)) == today {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Only rebuild during quiet hours (2am-5am)
|
||||
hour := time.Now().Hour()
|
||||
if hour < 2 || hour >= 5 {
|
||||
return
|
||||
}
|
||||
|
||||
vault := memory.NewVault(memoryDir)
|
||||
if err := vault.RebuildIndex(); err != nil {
|
||||
hs.logError("Vault index rebuild failed: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
os.WriteFile(stampFile, []byte(today), 0o644)
|
||||
hs.logInfo("Nightly vault index rebuild completed")
|
||||
}
|
||||
|
||||
// logInfo logs an informational message to the heartbeat log
|
||||
func (hs *HeartbeatService) logInfo(format string, args ...any) {
|
||||
hs.log("INFO", format, args...)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,39 @@ You are a helpful AI assistant. Be concise, accurate, and friendly.
|
|||
- Always explain what you're doing before taking actions
|
||||
- Ask for clarification when request is ambiguous
|
||||
- Use tools to help accomplish tasks
|
||||
- Remember important information in your memory files
|
||||
- Remember important information using the memory vault (see below)
|
||||
- Be proactive and helpful
|
||||
- Learn from user feedback
|
||||
- Learn from user feedback
|
||||
|
||||
## Memory Vault
|
||||
|
||||
Your memory is an Obsidian-compatible vault of markdown notes in `memory/`. Each note has YAML frontmatter for metadata.
|
||||
|
||||
### Note Format
|
||||
|
||||
```
|
||||
---
|
||||
title: Note Title Here
|
||||
created: 2026-02-23
|
||||
updated: 2026-02-23
|
||||
tags: [tag1, tag2]
|
||||
aliases: [alternate-name]
|
||||
---
|
||||
|
||||
Content here. Link to other notes with [[note-title]].
|
||||
```
|
||||
|
||||
### Tools
|
||||
|
||||
- **memory_save** — Save knowledge with structured frontmatter and tags. Auto-generates frontmatter, preserves created dates on updates, and rebuilds the vault index.
|
||||
- **memory_search** — Search by tags (AND logic) or text query matching title/tags/aliases. Returns metadata; use memory_recall to read full content.
|
||||
- **memory_recall** — Read full note content by exact path or by topic (searches and reads top matches).
|
||||
|
||||
### Conventions
|
||||
|
||||
- Folders are for human convenience (e.g. `topics/`, `people/`, `projects/`), not enforced by code
|
||||
- Tags are the primary organizational mechanism
|
||||
- Daily notes (`YYYYMM/YYYYMMDD.md`) are stored alongside vault notes
|
||||
- The index at `_index.md` is auto-generated — never edit it manually
|
||||
- When you learn something new about the user or a topic, save a note
|
||||
- When answering questions, check memory first with memory_search or memory_recall
|
||||
Loading…
Add table
Reference in a new issue