@amaster.ai/pi-memory

中文文档
0.1.37发布于 2026/11/09Apache-2.0TypeScriptES Module近 30 天下载 3960

Pi extension providing persistent curated memory (MEMORY.md + USER.md) injected into the system prompt as a frozen snapshot.

原始使用文档
文档目录14 节
  1. Storage
  2. Safety
  3. Tools
  4. Defaults
  5. Integration Modes
  6. Mode 1: Extension auto-discovery (standalone / CLI)
  7. Mode 2: Dependency import (host-controlled)
  8. Drift recovery
  9. Prompt snapshot
  10. Lifecycle reference
  11. Dreaming (Background Memory Consolidation)
  12. How it works
  13. Configuration
  14. Structured results (Pi 0.99+)

@amaster.ai/pi-memory

pi-memory preview

Persistent curated memory for pi agents — MEMORY.md (the agent's own notes) and USER.md (what the agent knows about the user). The extension loads both files at session start and injects a sanitized snapshot into the system prompt. Writes are durable on disk immediately and visible through memory_read right away; the system-prompt snapshot refreshes after successful context compaction or in a new session.

Modeled after hermes' default MemoryStore mechanism (no provider/manager abstraction).

Storage

  • Location: <agentDir>/memories/MEMORY.md and <agentDir>/memories/USER.md
  • Entries separated by \n§\n
  • Atomic writes via temp-file + rename
  • Read-modify-write protected by proper-lockfile
  • Drift detection: if the on-disk file contains content that wouldn't round-trip through the parser/serializer (or any single entry exceeds the per-store char limit), the mutation is refused and a .bak.<unix-ts> snapshot is taken for the user to recover from.

Safety

Every write — and every system-prompt snapshot build — runs the content through the bundled threat-patterns scanner at the strict scope. Patterns cover prompt injection, role hijack, C2 framework names, exfiltration, persistence (SSH backdoor, agent-config edits), and invisible unicode.

ActionOn match
memory_add / memory_replaceReject with the matched pattern id; live state and disk unchanged.
Snapshot build (load)Replace the entry with [BLOCKED: <filename> entry contained threat pattern(s): <ids>...]. The poisoned content never enters the system prompt. Live state keeps the original so memory_read / memory_remove can recover.

Tools

Four LLM-callable tools (separate, not action-multiplexed):

ToolPurpose
memory_addAppend a new entry. Exact duplicates are successful no-ops; empty, over-limit, and threat content is rejected.
memory_replaceUpdate an existing entry by short unique substring (oldText).
memory_removeDelete an entry by short unique substring (oldText).
memory_readReturn live entries, count, and <percent>% — <chars>/<limit> usage string.

target is 'memory' (the agent's own notes) or 'user' (user profile facts).

Defaults

StoreChar limit
MEMORY2200
USER1375

These are total chars after §-joining all entries. The limit is enforced at write time, and at load time as a drift signal (single-entry overflow).

Integration Modes

Mode 1: Extension auto-discovery (standalone / CLI)

When installed as a dependency with the pi.extensions field declared in package.json, the runtime auto-discovers and loads the extension. The extension creates its own MemoryStore with file-based storage at <agentDir>/memories/ — fully self-contained.

pi.extensions → session_start → initialize store → register tools
              → before_agent_start → append frozen snapshot to systemPrompt
              → session_compact → reload MEMORY.md/USER.md for the next agent run
              → session_shutdown → release
  • Storage: <agentDir>/memories/MEMORY.md and <agentDir>/memories/USER.md
  • Lifecycle: capture a fresh system-prompt snapshot for new and forked sessions, restore it on resume or reload, and refresh it after successful compaction
  • Status command: /memory status shows entry counts per file
  • LLM tools: memory_add, memory_replace, memory_remove, memory_read

Configure via the pi-memory settings key:

Project .pi/settings.json values are loaded only after project trust is accepted and are not environment-interpolated. User and agent settings retain environment interpolation.

{
  "pi-memory": {
    "dataDir": "/custom/memory/path",
    "memoryCharLimit": 4000,
    "userCharLimit": 2000
  }
}

Mode 2: Dependency import (host-controlled)

When the host process owns the MemoryStore (e.g. shared across agents, test fixtures, custom storage path), construct the store yourself and register tools directly:

import { MemoryStore, createMemoryTools } from "@amaster.ai/pi-memory";

const store = new MemoryStore({
  dir: "/var/lib/pi/agent-42/memories",
  memoryCharLimit: 4000,
});
await store.loadFromDisk();

// ToolDefinition[] — wire into your tool registry directly
const tools = createMemoryTools(store);

// System prompt fragment (rebuilt by loadFromDisk; freeze it for the session)
const promptBlock = store.formatAllForSystemPrompt();

You can also pass a pre-built store into the extension via injectedConfig to keep the extension lifecycle but use your own storage:

import memoryExtension from "@amaster.ai/pi-memory";

memoryExtension(pi, { store });

Drift recovery

If memory_add / memory_replace / memory_remove returns success: false with driftBackup: ".../MEMORY.md.bak.<ts>", the on-disk file no longer round-trips through the parser. This usually means a patch tool / shell append / manual edit / concurrent session wrote raw content that broke the §-delimited structure.

To recover:

  1. Open the .bak.<ts> snapshot and identify content not yet captured as clean entries.
  2. Add each missing entry via memory_add.
  3. Either delete the original MEMORY.md (the next add will recreate it) or rewrite it as a clean §-delimited list.

The drift guard exists to prevent silent data loss — never bypass it by deleting .bak.<ts> snapshots blindly.

Prompt snapshot

loadFromDisk() refreshes live entries from disk and rebuilds the sanitized system-prompt block. A new or forked session captures that block and persists it in the Pi session; resume and reload restore a saved block after validating it again. Invalid saved blocks fall back to a newly sanitized disk snapshot. The same bytes are reused across agent runs until successful context compaction, while session-tree navigation selects the snapshot saved on that branch. Subsequent add / replace / remove calls update live state and disk, but not the frozen prompt snapshot. Why:

  • Reusing the same system prompt preserves the provider's prefix-cache opportunity across agent runs in the session.
  • Tool responses always reflect live state, so the model still sees its own writes — just via tool-result tail, not system-prompt head.
  • The prompt snapshot picks up changes after successful session_compact or in a new session. A changed snapshot can still cause a cache miss at that boundary.

The extension bounds very large prompt snapshots when capturing them and reserves space for both files when both are present; the memory files and tool reads retain their full content.

Lifecycle reference

HookBehavior
session_startResolve dataDir, build MemoryStore, loadFromDisk(), capture a fresh snapshot for new/forked sessions or restore the saved one, register 4 tools, set status memory: loaded/memory: empty, and start a gated background dream.
before_agent_startAppend the frozen snapshot to assembled systemPrompt (guidance only when empty).
session_compactReload memory from disk and persist a changed snapshot for the next agent run.
session_treeSelect the snapshot saved on the newly active branch.
session_shutdownDrop store references.

Dreaming (Background Memory Consolidation)

On session start, pi-memory checks whether enough Pi session history has accumulated and, when due, starts an isolated background agent that consolidates durable facts into memory. The default global memory store reads Pi sessions across all projects; an injected store or custom dataDir reads only the active session directory. It does not add a turn to the active conversation or install an operating-system scheduled task.

How it works

  1. Session-start trigger — The extension launches the check asynchronously after memory initialization, so the active session is not blocked.

  2. Gate and lock — Each run checks whether enough time and turns have elapsed, then takes a cross-process lock so multiple Pi hosts cannot dream concurrently.

  3. Consolidation — An agentic loop (using pi-agent-core) reviews recent Pi sessions and updates MEMORY.md/USER.md via the memory tools. Follows a 4-phase prompt: Orient → Gather recent signal → Consolidate → Verify and report.

Configuration

Add to settings.json under the pi-memory key:

{
  "pi-memory": {
    "dreaming": {
      "enabled": true,
      "minHoursSinceLastRun": 24,
      "minTurnsSinceLastRun": 5,
      "model": {
        "provider": "openai",
        "model": "gpt-4.1-mini"
      }
    }
  }
}

All fields are optional with sensible defaults. The model field accepts any provider/model pair configured in your ~/.pi/agent/models.json (built-in or custom). minSessionsSinceLastRun is accepted as a deprecated alias for minTurnsSinceLastRun.

Set "enabled": false to disable background dreaming.

Dreaming is opportunistic: it runs while a Pi host is active and catches up on the next session start. It does not run while every Pi host is closed.

Structured results (Pi 0.99+)

memory_read, memory_add, memory_replace, and memory_remove declare outputSchema and return their live store results as structuredContent. Codemode receives entries and usage directly; writes also expose success, target, and entryCount. Failed writes set isError: true and preserve available error, matches, currentEntries, usage, and drift-remediation fields. Entry text remains the existing substring reference used by replace/remove; no new entry-ID format is introduced.

const result = await tools.memory_read({ target: "memory" });
if (result.error || result.truncated) throw new Error("Read a complete memory result before updating");
const entry = result.entries.find(e => e.includes("TypeScript"));
if (entry) text(await tools.memory_replace({ target: "memory", oldText: entry, newContent: "Project uses strict TypeScript" }));

Structured output is limited to 12 KiB and top-level lists to 100 complete records. truncated: true indicates omitted records; total retains the original count where available. Oversized records with an id retain that complete ID and small scalar metadata, omit large fields, and carry truncated: true both on the record and envelope; callers must check that flag before reusing content for an update. Oversized results without a record ID return a typed output-limit error instead of clipped paths or content. A write may already have completed when that happens: inspect saved state before retrying. Readable text and renderer details are independently bounded.

Background turn extraction keeps only a bounded recent-message buffer and drains each batch after scheduling it. The serialized review context is capped at 4,000 characters, including a single oversized message; processed history is not retained in the extraction buffer.

Dreaming checks model availability before discovering history and filters files by modification time. Each pass reads at most 32 eligible session files, oldest first; a persisted cursor resumes remaining pages at the next startup without advancing the completed-scan watermark early. Reads begin with a 256 KiB tail and expand up to 8 MiB when recent turns are hidden behind large records, following the active branch within that window. At most five recent turns per file (160 per page) are retained, with beginning-and-conclusion excerpts for oversized messages and an 8,000-character consolidation prompt shared fairly across the selected sessions. History discovery shares a 5-second budget and stops on session cancellation. Session shutdown also cancels the running consolidation agent. Dangling history links and files removed during discovery are skipped. Malformed session history, permission errors, and I/O errors leave the checkpoint unchanged; restore access before the next run. Content outside these bounds is not consolidation input; omission does not authorize deleting existing facts.

版本与发布记录

@amaster.ai/pi-memory 共发布 119 个版本,首次发布于 2026/05/27;过去 12 个月发布了 119 个版本。

版本发布日期距今
0.1.37latest2026/11/09今天
0.1.2-beta.91beta2026/11/072 天前
0.1.2-beta.902026/11/062 天前
0.1.2-beta.892026/11/053 天前
0.1.2-beta.882026/11/054 天前
0.1.362026/11/054 天前

关于 @amaster.ai/pi-memory 的常见问题

@amaster.ai/pi-memory 是什么?

Pi extension providing persistent curated memory (MEMORY.md + USER.md) injected into the system prompt as a frozen snapshot.

如何安装 @amaster.ai/pi-memory?

在项目目录运行 npm install @amaster.ai/pi-memory,或使用 pnpm add / yarn add / bun add。

@amaster.ai/pi-memory 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@amaster.ai/pi-memory 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@amaster.ai/pi-memory 可以商用吗?

@amaster.ai/pi-memory 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@amaster.ai/pi-memory 的下载量有多少?

根据 npm 官方下载统计,@amaster.ai/pi-memory 在 2026/10/06 – 2026/11/04 这 30 天内被下载 3,960 次,日均约 132 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@amaster.ai/pi-memory 还在维护吗?

最新版本 0.1.37 发布于 2026/11/09(今天);至今共发布 119 个版本,其中过去 12 个月发布了 119 个;首次发布于 2026/05/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。