@plur-ai/core 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,65 +1,66 @@
1
1
  # @plur-ai/core
2
2
 
3
- The engram engine store, recall, and inject AI memory. Local-first, zero API calls for search, plain YAML storage.
3
+ The engine behind [PLUR](https://plur.ai) persistent memory for AI agents.
4
+
5
+ You correct your agent on Monday. On Tuesday, it makes the same mistake. PLUR fixes this. Corrections, preferences, and conventions persist across sessions. Your data stays on your disk as plain YAML. Search runs locally with zero API calls.
6
+
7
+ The result: **Haiku with PLUR memory outperforms Opus without it** — 2.6x better on tool routing, at 10x less cost. The bottleneck isn't model intelligence. It's context.
8
+
9
+ ## Why @plur-ai/core
10
+
11
+ This is the engine that powers everything. Use it directly when you're building your own agent framework or want programmatic control over memory. If you just want to add memory to Claude Code or Cursor, use [`@plur-ai/mcp`](https://www.npmjs.com/package/@plur-ai/mcp) instead — it wraps this package as MCP tools.
12
+
13
+ ## Install
4
14
 
5
15
  ```bash
6
16
  npm install @plur-ai/core
7
17
  ```
8
18
 
19
+ ## Quick start
20
+
9
21
  ```typescript
10
22
  import { Plur } from '@plur-ai/core'
11
23
 
12
24
  const plur = new Plur()
13
25
 
14
- // Learn from a correction
26
+ // Your agent gets corrected — save it
15
27
  plur.learn('toEqual() in Vitest is strict — use toMatchObject() for partial matching', {
16
28
  type: 'behavioral',
17
29
  scope: 'project:my-app',
18
30
  domain: 'dev/testing'
19
31
  })
20
32
 
21
- // Recall (hybrid: BM25 + embeddings via RRF, zero cost)
33
+ // Next session: recall what was learned (hybrid search, zero cost)
22
34
  const results = await plur.recallHybrid('vitest assertion matching')
23
35
 
24
- // Inject relevant engrams into agent context
25
- const { directives, consider, count, tokens_used } = plur.inject('Write tests for the user service', {
36
+ // Or inject the best engrams into a system prompt, within a token budget
37
+ const { directives, consider, tokens_used } = plur.inject('Write tests for the user service', {
26
38
  scope: 'project:my-app',
27
39
  budget: 2000
28
40
  })
29
41
 
30
- // Feedback trains the system
42
+ // Rate what was useful — the system improves over time
31
43
  plur.feedback(results[0].id, 'positive')
32
44
 
33
- // Sync across machines
45
+ // Sync across machines via git
34
46
  plur.sync('git@github.com:you/plur-memory.git')
35
47
  ```
36
48
 
37
- ## API
49
+ ## How it works
38
50
 
39
- ### `new Plur(options?)`
51
+ Knowledge is stored as **engrams** — small assertions that strengthen with use and decay when irrelevant, modeled on how human memory works (ACT-R activation). The system gets better over time, not just bigger.
40
52
 
41
- ```typescript
42
- const plur = new Plur({ path: '/custom/storage/path' })
43
53
  ```
44
-
45
- Defaults to `~/.plur/`. Override with `PLUR_PATH` env var or `options.path`.
46
-
47
- ### `learn(statement, context?)`
48
-
49
- Create an engram. Detects conflicts with existing engrams in the same scope.
50
-
51
- ```typescript
52
- plur.learn('Always run lint before committing', {
53
- type: 'behavioral', // behavioral | architectural | procedural | terminological
54
- scope: 'project:myapp', // namespace for filtering
55
- domain: 'software.git', // dot-separated domain tag
56
- source: 'user-correction',
57
- })
54
+ You correct your agent → engram created → YAML on your disk
55
+ Next session starts → relevant ones injected → agent remembers
56
+ You rate the result → engram strengthens → quality improves
58
57
  ```
59
58
 
60
- ### Search methods
59
+ Search is fully local: BM25 over enriched text + BGE-small-en-v1.5 embeddings + Reciprocal Rank Fusion. **86.7% on LongMemEval** — on par with cloud solutions that charge per query.
61
60
 
62
- Five search modes, from fastest to most accurate:
61
+ ## Search modes
62
+
63
+ Five modes, from fastest to most accurate:
63
64
 
64
65
  | Method | Speed | API calls | Best for |
65
66
  |--------|-------|-----------|----------|
@@ -67,110 +68,34 @@ Five search modes, from fastest to most accurate:
67
68
  | `recallSemantic(query)` | ~200ms | None | Meaning-based search (local embeddings) |
68
69
  | `recallHybrid(query)` | ~200ms | None | **Best default** — BM25 + embeddings via RRF |
69
70
  | `recallAsync(query, { llm })` | ~1s | 1 LLM call | LLM-assisted semantic filtering |
70
- | `recallExpanded(query, { llm })` | ~3s | 3-5 LLM calls | Query expansion + hybrid + RRF merge |
71
-
72
- All accept the same options:
73
-
74
- ```typescript
75
- const results = await plur.recallHybrid('deployment process', {
76
- scope: 'project:myapp', // includes global + matching scopes
77
- domain: 'software', // prefix match
78
- limit: 10,
79
- min_strength: 0.5,
80
- })
81
- ```
82
-
83
- ### `inject(task, options?)`
84
-
85
- Select and score engrams within a token budget. Returns formatted strings ready to prepend to a system prompt.
86
-
87
- ```typescript
88
- const { directives, consider, count, tokens_used } = plur.inject('refactor the auth module', {
89
- budget: 2000,
90
- scope: 'project:myapp',
91
- })
92
- ```
93
-
94
- ### `feedback(id, signal)`
95
-
96
- Rate an engram's usefulness. Trains injection relevance over time.
97
-
98
- ```typescript
99
- plur.feedback('ENG-001', 'positive') // +0.05 retrieval strength
100
- plur.feedback('ENG-002', 'negative') // -0.10 retrieval strength
101
- ```
102
-
103
- ### `forget(id, reason?)`
104
-
105
- Retire an engram. History preserved, excluded from recall and injection.
106
-
107
- ```typescript
108
- plur.forget('ENG-001', 'API changed')
109
- ```
110
-
111
- ### `sync(remote?)`
112
-
113
- Git-based sync across machines. Initializes on first call, commits + push/pull on subsequent calls.
114
-
115
- ```typescript
116
- // First time — init repo and push
117
- plur.sync('git@github.com:you/plur-memory.git')
118
-
119
- // Later — commit, pull, push
120
- plur.sync()
121
- ```
122
-
123
- ```typescript
124
- // Check sync status (no changes made)
125
- const status = plur.syncStatus()
126
- // { initialized, remote, dirty, branch, ahead, behind }
127
- ```
128
-
129
- ### `capture(summary, context?)` / `timeline(query?)`
130
-
131
- Episodic memory — record what happened, query the timeline.
132
-
133
- ```typescript
134
- plur.capture('Deployed v2.0 to production', {
135
- agent: 'claude-code',
136
- session_id: 'abc123',
137
- tags: ['deploy'],
138
- })
139
-
140
- const episodes = plur.timeline({ since: new Date('2025-01-01'), agent: 'claude-code' })
141
- ```
142
-
143
- ### `ingest(content, options?)`
144
-
145
- Extract engram candidates from text using pattern matching.
146
-
147
- ```typescript
148
- const candidates = plur.ingest(markdownContent, {
149
- extract_only: true, // preview without saving
150
- scope: 'project:myapp',
151
- source: 'docs/architecture.md',
152
- })
153
- ```
154
-
155
- ### `installPack(source)` / `exportPack(...)` / `listPacks()`
156
-
157
- Share engram collections between agents or users.
158
-
159
- ```typescript
160
- plur.installPack('/path/to/pack-directory')
161
- const packs = plur.listPacks()
162
- plur.exportPack(engrams, './output', { name: 'my-pack', version: '1.0.0' })
163
- ```
164
-
165
- ### `status()`
166
-
167
- ```typescript
168
- const { engram_count, episode_count, pack_count, storage_root, config } = plur.status()
169
- ```
71
+ | `recallExpanded(query, { llm })` | ~3s | 3-5 LLM calls | Query expansion for exhaustive retrieval |
72
+
73
+ ## Full API
74
+
75
+ | Method | What it does |
76
+ |--------|-------------|
77
+ | `learn(statement, context?)` | Store an engram (correction, preference, convention, decision) |
78
+ | `recall(query, options?)` | BM25 keyword search — instant, zero cost |
79
+ | `recallHybrid(query, options?)` | BM25 + embeddings merged via RRF — best default |
80
+ | `recallSemantic(query, options?)` | Embedding-only search — meaning over keywords |
81
+ | `recallAsync(query, { llm })` | LLM-assisted semantic filtering |
82
+ | `recallExpanded(query, { llm })` | Query expansion + hybrid + RRF merge |
83
+ | `inject(task, options?)` | Select engrams for a task within a token budget |
84
+ | `feedback(id, signal)` | Rate an engram — trains injection relevance over time |
85
+ | `forget(id, reason?)` | Retire an engram (history preserved) |
86
+ | `sync(remote?)` | Git-based sync across machines |
87
+ | `syncStatus()` | Check sync state without making changes |
88
+ | `capture(summary, context?)` | Record a session event to the episodic timeline |
89
+ | `timeline(query?)` | Query past episodes by time, agent, or search |
90
+ | `ingest(content, options?)` | Extract engram candidates from text via pattern matching |
91
+ | `installPack(source)` | Install a shareable engram pack |
92
+ | `exportPack(engrams, dir, manifest)` | Export engrams as a shareable pack |
93
+ | `listPacks()` | List installed packs |
94
+ | `status()` | System health — counts, storage root, config |
170
95
 
171
96
  ## Storage
172
97
 
173
- Everything is plain YAML. Open it, read it, edit it.
98
+ Everything is plain YAML. Open it, read it, edit it, version it.
174
99
 
175
100
  ```
176
101
  ~/.plur/
@@ -181,6 +106,26 @@ Everything is plain YAML. Open it, read it, edit it.
181
106
  └── packs/ # installed engram packs
182
107
  ```
183
108
 
109
+ Override the location with `PLUR_PATH` env var or `new Plur({ path: '...' })`.
110
+
111
+ ## Benchmark
112
+
113
+ | Metric | Score |
114
+ |--------|-------|
115
+ | LongMemEval overall | **86.7%** |
116
+ | Hit@10 (retrieval) | 93.3% |
117
+ | A/B win rate vs no memory | 89% |
118
+ | House rules accuracy | 100% |
119
+
120
+ [Full methodology →](https://plur.ai/benchmark.html)
121
+
122
+ ## Related packages
123
+
124
+ | Package | For |
125
+ |---------|-----|
126
+ | [`@plur-ai/mcp`](https://www.npmjs.com/package/@plur-ai/mcp) | Claude Code, Cursor, Windsurf (MCP server) |
127
+ | [`@plur-ai/claw`](https://www.npmjs.com/package/@plur-ai/claw) | OpenClaw (automatic memory plugin) |
128
+
184
129
  ## License
185
130
 
186
- Apache-2.0
131
+ Apache-2.0 · [GitHub](https://github.com/plur-ai/plur) · [plur.ai](https://plur.ai)
package/dist/index.d.ts CHANGED
@@ -684,6 +684,17 @@ interface TimelineQuery {
684
684
  /** Build searchable text from all engram fields */
685
685
  declare function engramSearchText(engram: Engram): string;
686
686
 
687
+ interface PlurPaths {
688
+ root: string;
689
+ engrams: string;
690
+ episodes: string;
691
+ candidates: string;
692
+ packs: string;
693
+ exchange: string;
694
+ config: string;
695
+ }
696
+ declare function detectPlurStorage(explicitPath?: string): PlurPaths;
697
+
687
698
  /**
688
699
  * Non-blocking version check against npm registry.
689
700
  * Caches result in memory — one fetch per process lifetime.
@@ -795,4 +806,4 @@ declare class Plur {
795
806
  status(): StatusResult;
796
807
  }
797
808
 
798
- export { type Association, type CaptureContext, type Engram, type Episode, type IngestCandidate, type IngestOptions, type InjectOptions, type InjectionResult, type KnowledgeAnchor, type LearnContext, type LlmFunction, type PackManifest, Plur, type PlurConfig, type RecallOptions, type StatusResult, type SyncResult, type SyncStatus, type TimelineQuery, type VersionCheckResult, checkForUpdate, clearVersionCache, engramSearchText, getCachedUpdateCheck };
809
+ export { type Association, type CaptureContext, type Engram, type Episode, type IngestCandidate, type IngestOptions, type InjectOptions, type InjectionResult, type KnowledgeAnchor, type LearnContext, type LlmFunction, type PackManifest, Plur, type PlurConfig, type PlurPaths, type RecallOptions, type StatusResult, type SyncResult, type SyncStatus, type TimelineQuery, type VersionCheckResult, checkForUpdate, clearVersionCache, detectPlurStorage, engramSearchText, getCachedUpdateCheck };
package/dist/index.js CHANGED
@@ -1468,6 +1468,7 @@ export {
1468
1468
  Plur,
1469
1469
  checkForUpdate,
1470
1470
  clearVersionCache,
1471
+ detectPlurStorage,
1471
1472
  engramSearchText,
1472
1473
  getCachedUpdateCheck
1473
1474
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plur-ai/core",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",