audrey 0.20.0 → 0.23.1

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.
Files changed (156) hide show
  1. package/CHANGELOG.md +191 -0
  2. package/README.md +216 -117
  3. package/SECURITY.md +29 -0
  4. package/dist/mcp-server/config.d.ts +29 -4
  5. package/dist/mcp-server/config.d.ts.map +1 -1
  6. package/dist/mcp-server/config.js +100 -17
  7. package/dist/mcp-server/config.js.map +1 -1
  8. package/dist/mcp-server/index.d.ts +302 -25
  9. package/dist/mcp-server/index.d.ts.map +1 -1
  10. package/dist/mcp-server/index.js +1077 -74
  11. package/dist/mcp-server/index.js.map +1 -1
  12. package/dist/src/adaptive.d.ts.map +1 -1
  13. package/dist/src/adaptive.js +3 -1
  14. package/dist/src/adaptive.js.map +1 -1
  15. package/dist/src/affect.d.ts +4 -1
  16. package/dist/src/affect.d.ts.map +1 -1
  17. package/dist/src/affect.js +6 -4
  18. package/dist/src/affect.js.map +1 -1
  19. package/dist/src/audrey.d.ts +58 -4
  20. package/dist/src/audrey.d.ts.map +1 -1
  21. package/dist/src/audrey.js +469 -62
  22. package/dist/src/audrey.js.map +1 -1
  23. package/dist/src/capsule.d.ts +2 -1
  24. package/dist/src/capsule.d.ts.map +1 -1
  25. package/dist/src/capsule.js +14 -4
  26. package/dist/src/capsule.js.map +1 -1
  27. package/dist/src/causal.d.ts.map +1 -1
  28. package/dist/src/causal.js +20 -2
  29. package/dist/src/causal.js.map +1 -1
  30. package/dist/src/confidence.d.ts.map +1 -1
  31. package/dist/src/confidence.js +3 -0
  32. package/dist/src/confidence.js.map +1 -1
  33. package/dist/src/consolidate.d.ts +1 -0
  34. package/dist/src/consolidate.d.ts.map +1 -1
  35. package/dist/src/consolidate.js +35 -19
  36. package/dist/src/consolidate.js.map +1 -1
  37. package/dist/src/controller.d.ts +38 -0
  38. package/dist/src/controller.d.ts.map +1 -0
  39. package/dist/src/controller.js +169 -0
  40. package/dist/src/controller.js.map +1 -0
  41. package/dist/src/db.d.ts.map +1 -1
  42. package/dist/src/db.js +12 -0
  43. package/dist/src/db.js.map +1 -1
  44. package/dist/src/decay.d.ts.map +1 -1
  45. package/dist/src/decay.js +57 -50
  46. package/dist/src/decay.js.map +1 -1
  47. package/dist/src/embedding.d.ts.map +1 -1
  48. package/dist/src/embedding.js +31 -3
  49. package/dist/src/embedding.js.map +1 -1
  50. package/dist/src/encode.d.ts +9 -2
  51. package/dist/src/encode.d.ts.map +1 -1
  52. package/dist/src/encode.js +21 -8
  53. package/dist/src/encode.js.map +1 -1
  54. package/dist/src/export.d.ts.map +1 -1
  55. package/dist/src/export.js +5 -3
  56. package/dist/src/export.js.map +1 -1
  57. package/dist/src/feedback.d.ts +29 -0
  58. package/dist/src/feedback.d.ts.map +1 -0
  59. package/dist/src/feedback.js +123 -0
  60. package/dist/src/feedback.js.map +1 -0
  61. package/dist/src/forget.d.ts.map +1 -1
  62. package/dist/src/forget.js +58 -50
  63. package/dist/src/forget.js.map +1 -1
  64. package/dist/src/fts.js +1 -1
  65. package/dist/src/fts.js.map +1 -1
  66. package/dist/src/hybrid-recall.d.ts +2 -1
  67. package/dist/src/hybrid-recall.d.ts.map +1 -1
  68. package/dist/src/hybrid-recall.js +35 -26
  69. package/dist/src/hybrid-recall.js.map +1 -1
  70. package/dist/src/impact.d.ts +47 -0
  71. package/dist/src/impact.d.ts.map +1 -0
  72. package/dist/src/impact.js +146 -0
  73. package/dist/src/impact.js.map +1 -0
  74. package/dist/src/import.d.ts +177 -1
  75. package/dist/src/import.d.ts.map +1 -1
  76. package/dist/src/import.js +206 -17
  77. package/dist/src/import.js.map +1 -1
  78. package/dist/src/index.d.ts +8 -0
  79. package/dist/src/index.d.ts.map +1 -1
  80. package/dist/src/index.js +4 -0
  81. package/dist/src/index.js.map +1 -1
  82. package/dist/src/interference.d.ts +5 -2
  83. package/dist/src/interference.d.ts.map +1 -1
  84. package/dist/src/interference.js +27 -20
  85. package/dist/src/interference.js.map +1 -1
  86. package/dist/src/llm.d.ts.map +1 -1
  87. package/dist/src/llm.js +1 -0
  88. package/dist/src/llm.js.map +1 -1
  89. package/dist/src/migrate.d.ts.map +1 -1
  90. package/dist/src/migrate.js +21 -9
  91. package/dist/src/migrate.js.map +1 -1
  92. package/dist/src/preflight.d.ts +52 -0
  93. package/dist/src/preflight.d.ts.map +1 -0
  94. package/dist/src/preflight.js +221 -0
  95. package/dist/src/preflight.js.map +1 -0
  96. package/dist/src/profile.d.ts +23 -0
  97. package/dist/src/profile.d.ts.map +1 -0
  98. package/dist/src/profile.js +51 -0
  99. package/dist/src/profile.js.map +1 -0
  100. package/dist/src/promote.d.ts.map +1 -1
  101. package/dist/src/promote.js +2 -3
  102. package/dist/src/promote.js.map +1 -1
  103. package/dist/src/prompts.d.ts.map +1 -1
  104. package/dist/src/prompts.js +76 -47
  105. package/dist/src/prompts.js.map +1 -1
  106. package/dist/src/recall.d.ts +9 -6
  107. package/dist/src/recall.d.ts.map +1 -1
  108. package/dist/src/recall.js +182 -40
  109. package/dist/src/recall.js.map +1 -1
  110. package/dist/src/redact.d.ts +7 -1
  111. package/dist/src/redact.d.ts.map +1 -1
  112. package/dist/src/redact.js +94 -11
  113. package/dist/src/redact.js.map +1 -1
  114. package/dist/src/reflexes.d.ts +35 -0
  115. package/dist/src/reflexes.d.ts.map +1 -0
  116. package/dist/src/reflexes.js +87 -0
  117. package/dist/src/reflexes.js.map +1 -0
  118. package/dist/src/rollback.d.ts.map +1 -1
  119. package/dist/src/rollback.js +9 -4
  120. package/dist/src/rollback.js.map +1 -1
  121. package/dist/src/routes.d.ts +1 -0
  122. package/dist/src/routes.d.ts.map +1 -1
  123. package/dist/src/routes.js +267 -11
  124. package/dist/src/routes.js.map +1 -1
  125. package/dist/src/rules-compiler.d.ts.map +1 -1
  126. package/dist/src/rules-compiler.js +36 -6
  127. package/dist/src/rules-compiler.js.map +1 -1
  128. package/dist/src/server.d.ts +2 -1
  129. package/dist/src/server.d.ts.map +1 -1
  130. package/dist/src/server.js +42 -4
  131. package/dist/src/server.js.map +1 -1
  132. package/dist/src/tool-trace.d.ts.map +1 -1
  133. package/dist/src/tool-trace.js +42 -29
  134. package/dist/src/tool-trace.js.map +1 -1
  135. package/dist/src/types.d.ts +28 -1
  136. package/dist/src/types.d.ts.map +1 -1
  137. package/dist/src/ulid.d.ts.map +1 -1
  138. package/dist/src/ulid.js +52 -2
  139. package/dist/src/ulid.js.map +1 -1
  140. package/dist/src/utils.d.ts.map +1 -1
  141. package/dist/src/utils.js +8 -1
  142. package/dist/src/utils.js.map +1 -1
  143. package/dist/src/validate.d.ts +2 -0
  144. package/dist/src/validate.d.ts.map +1 -1
  145. package/dist/src/validate.js +60 -29
  146. package/dist/src/validate.js.map +1 -1
  147. package/docs/assets/audrey-feature-grid.jpg +0 -0
  148. package/docs/assets/audrey-logo.svg +45 -0
  149. package/docs/assets/audrey-wordmark.png +0 -0
  150. package/examples/ollama-memory-agent.js +326 -0
  151. package/package.json +35 -22
  152. package/docs/assets/benchmarks/local-benchmark.svg +0 -45
  153. package/docs/assets/benchmarks/operations-benchmark.svg +0 -45
  154. package/docs/assets/benchmarks/published-memory-standards.svg +0 -50
  155. package/docs/benchmarking.md +0 -151
  156. package/docs/production-readiness.md +0 -124
@@ -0,0 +1,45 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="960" height="300" viewBox="0 0 960 300" role="img" aria-labelledby="title desc">
2
+ <title id="title">Audrey logo</title>
3
+ <desc id="desc">A luminous memory orb and Audrey wordmark for a local-first AI memory runtime.</desc>
4
+ <defs>
5
+ <radialGradient id="orb" cx="42%" cy="35%" r="70%">
6
+ <stop offset="0%" stop-color="#f7dfad"/>
7
+ <stop offset="42%" stop-color="#d08f61"/>
8
+ <stop offset="78%" stop-color="#3b5f72"/>
9
+ <stop offset="100%" stop-color="#172a31"/>
10
+ </radialGradient>
11
+ <linearGradient id="ring" x1="68" x2="242" y1="56" y2="238" gradientUnits="userSpaceOnUse">
12
+ <stop offset="0%" stop-color="#f2c777"/>
13
+ <stop offset="50%" stop-color="#78a6ad"/>
14
+ <stop offset="100%" stop-color="#273d45"/>
15
+ </linearGradient>
16
+ <linearGradient id="word" x1="302" x2="814" y1="94" y2="218" gradientUnits="userSpaceOnUse">
17
+ <stop offset="0%" stop-color="#f4d7a1"/>
18
+ <stop offset="46%" stop-color="#d08f61"/>
19
+ <stop offset="100%" stop-color="#85aeb2"/>
20
+ </linearGradient>
21
+ <filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
22
+ <feGaussianBlur stdDeviation="8" result="blur"/>
23
+ <feMerge>
24
+ <feMergeNode in="blur"/>
25
+ <feMergeNode in="SourceGraphic"/>
26
+ </feMerge>
27
+ </filter>
28
+ </defs>
29
+
30
+ <rect width="960" height="300" rx="36" fill="#0f171a"/>
31
+ <path d="M54 228C131 266 220 247 274 181C324 120 320 61 270 42C224 25 154 50 103 99C56 144 30 193 54 228Z" fill="#122126"/>
32
+ <circle cx="158" cy="150" r="74" fill="url(#orb)" filter="url(#softGlow)"/>
33
+ <path d="M105 163C126 138 151 128 180 134C204 139 219 154 222 177" fill="none" stroke="#f8e7c7" stroke-width="8" stroke-linecap="round"/>
34
+ <path d="M98 132C123 106 153 98 188 108C214 115 233 132 244 159" fill="none" stroke="#1d3037" stroke-width="10" stroke-linecap="round"/>
35
+ <path d="M84 190C113 207 145 212 180 205C217 197 247 176 269 142" fill="none" stroke="url(#ring)" stroke-width="5" stroke-linecap="round"/>
36
+ <path d="M86 109C113 78 149 60 194 57C231 55 261 66 284 90" fill="none" stroke="url(#ring)" stroke-width="4" stroke-linecap="round" opacity="0.85"/>
37
+ <circle cx="83" cy="190" r="7" fill="#f2c777"/>
38
+ <circle cx="284" cy="90" r="6" fill="#85aeb2"/>
39
+ <circle cx="269" cy="142" r="5" fill="#f8e7c7"/>
40
+
41
+ <text x="320" y="150" fill="url(#word)" font-family="Georgia, 'Times New Roman', serif" font-size="88" font-weight="700" letter-spacing="-3">Audrey</text>
42
+ <text x="326" y="198" fill="#c7d0cc" font-family="'Segoe UI', Candara, sans-serif" font-size="24" letter-spacing="4">LOCAL-FIRST MEMORY FOR AGENTS</text>
43
+ <path d="M327 219H811" stroke="#30484d" stroke-width="2"/>
44
+ <text x="326" y="250" fill="#8ea19b" font-family="'Segoe UI', Candara, sans-serif" font-size="20">recall / preflight / reflexes / consolidation / one SQLite brain</text>
45
+ </svg>
Binary file
@@ -0,0 +1,326 @@
1
+ #!/usr/bin/env node
2
+
3
+ const AUDREY_URL = (process.env.AUDREY_URL || 'http://127.0.0.1:7437').replace(/\/$/, '');
4
+ const OLLAMA_URL = (process.env.OLLAMA_URL || 'http://127.0.0.1:11434').replace(/\/$/, '');
5
+ const OLLAMA_MODEL = process.env.OLLAMA_MODEL || 'qwen3';
6
+ const AUDREY_API_KEY = process.env.AUDREY_API_KEY || '';
7
+ const MAX_TOOL_LOOPS = Number.parseInt(process.env.MAX_TOOL_LOOPS || '4', 10);
8
+
9
+ const userPrompt = process.argv.slice(2).join(' ').trim()
10
+ || 'Use Audrey memory to explain how this local Ollama agent should remember useful facts.';
11
+
12
+ function usage() {
13
+ console.log(`
14
+ Audrey + Ollama local memory agent
15
+
16
+ Prerequisites:
17
+ 1. Start Audrey: AUDREY_AGENT=ollama-local-agent npx audrey serve
18
+ 2. Start Ollama and pull a tool-capable model: ollama pull qwen3
19
+
20
+ Run:
21
+ OLLAMA_MODEL=qwen3 node examples/ollama-memory-agent.js "What should you remember about this project?"
22
+
23
+ Environment:
24
+ AUDREY_URL=http://127.0.0.1:7437
25
+ AUDREY_API_KEY=secret
26
+ OLLAMA_URL=http://127.0.0.1:11434
27
+ OLLAMA_MODEL=qwen3
28
+ `);
29
+ }
30
+
31
+ function headers() {
32
+ const h = { 'Content-Type': 'application/json' };
33
+ if (AUDREY_API_KEY) h.Authorization = `Bearer ${AUDREY_API_KEY}`;
34
+ return h;
35
+ }
36
+
37
+ async function jsonFetch(url, options = {}) {
38
+ const response = await fetch(url, options);
39
+ const text = await response.text();
40
+ let data = null;
41
+ if (text.trim()) {
42
+ try {
43
+ data = JSON.parse(text);
44
+ } catch {
45
+ data = { raw: text };
46
+ }
47
+ }
48
+ if (!response.ok) {
49
+ const detail = data?.error || data?.message || text || response.statusText;
50
+ throw new Error(`${response.status} ${response.statusText}: ${detail}`);
51
+ }
52
+ return data;
53
+ }
54
+
55
+ async function audreyGet(path) {
56
+ return jsonFetch(`${AUDREY_URL}${path}`, { headers: headers() });
57
+ }
58
+
59
+ async function audreyPost(path, body) {
60
+ return jsonFetch(`${AUDREY_URL}${path}`, {
61
+ method: 'POST',
62
+ headers: headers(),
63
+ body: JSON.stringify(body),
64
+ });
65
+ }
66
+
67
+ async function memoryRecall({ query, limit = 5 }) {
68
+ if (!query || typeof query !== 'string') {
69
+ throw new Error('memory_recall requires a string query');
70
+ }
71
+ return audreyPost('/v1/recall', { query, limit });
72
+ }
73
+
74
+ async function memoryCapsule({ query, budget_chars = 4000 }) {
75
+ if (!query || typeof query !== 'string') {
76
+ throw new Error('memory_capsule requires a string query');
77
+ }
78
+ return audreyPost('/v1/capsule', { query, budget_chars });
79
+ }
80
+
81
+ async function memoryPreflight({ action, tool, strict = false, include_capsule = false }) {
82
+ if (!action || typeof action !== 'string') {
83
+ throw new Error('memory_preflight requires a string action');
84
+ }
85
+ return audreyPost('/v1/preflight', { action, tool, strict, include_capsule });
86
+ }
87
+
88
+ async function memoryReflexes({ action, tool, strict = false, include_preflight = false }) {
89
+ if (!action || typeof action !== 'string') {
90
+ throw new Error('memory_reflexes requires a string action');
91
+ }
92
+ return audreyPost('/v1/reflexes', { action, tool, strict, include_preflight });
93
+ }
94
+
95
+ async function memoryEncode({ content, source = 'model-generated', tags = ['ollama-agent'] }) {
96
+ if (!content || typeof content !== 'string') {
97
+ throw new Error('memory_encode requires string content');
98
+ }
99
+ return audreyPost('/v1/encode', { content, source, tags });
100
+ }
101
+
102
+ const toolExecutors = {
103
+ memory_preflight: memoryPreflight,
104
+ memory_reflexes: memoryReflexes,
105
+ memory_recall: memoryRecall,
106
+ memory_capsule: memoryCapsule,
107
+ memory_encode: memoryEncode,
108
+ };
109
+
110
+ const tools = [
111
+ {
112
+ type: 'function',
113
+ function: {
114
+ name: 'memory_preflight',
115
+ description: 'Check Audrey memory before taking an action, so prior failures and rules are not repeated.',
116
+ parameters: {
117
+ type: 'object',
118
+ required: ['action'],
119
+ properties: {
120
+ action: { type: 'string', description: 'Action the agent is considering.' },
121
+ tool: { type: 'string', description: 'Optional tool or command family.' },
122
+ strict: { type: 'boolean', description: 'If true, high-severity warnings can block the action.' },
123
+ include_capsule: { type: 'boolean', description: 'Include full capsule context in the result.' },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ {
129
+ type: 'function',
130
+ function: {
131
+ name: 'memory_reflexes',
132
+ description: 'Return Audrey Memory Reflexes: trigger-response rules for the action the agent is considering.',
133
+ parameters: {
134
+ type: 'object',
135
+ required: ['action'],
136
+ properties: {
137
+ action: { type: 'string', description: 'Action the agent is considering.' },
138
+ tool: { type: 'string', description: 'Optional tool or command family.' },
139
+ strict: { type: 'boolean', description: 'If true, high-severity warnings can become blocking reflexes.' },
140
+ include_preflight: { type: 'boolean', description: 'Include the full underlying preflight report.' },
141
+ },
142
+ },
143
+ },
144
+ },
145
+ {
146
+ type: 'function',
147
+ function: {
148
+ name: 'memory_recall',
149
+ description: 'Recall durable Audrey memories relevant to a query.',
150
+ parameters: {
151
+ type: 'object',
152
+ required: ['query'],
153
+ properties: {
154
+ query: { type: 'string', description: 'Search query for Audrey memory.' },
155
+ limit: { type: 'number', description: 'Maximum memories to return.' },
156
+ },
157
+ },
158
+ },
159
+ },
160
+ {
161
+ type: 'function',
162
+ function: {
163
+ name: 'memory_capsule',
164
+ description: 'Build a compact, evidence-backed Audrey Memory Capsule for the current task.',
165
+ parameters: {
166
+ type: 'object',
167
+ required: ['query'],
168
+ properties: {
169
+ query: { type: 'string', description: 'Current task or question.' },
170
+ budget_chars: { type: 'number', description: 'Maximum capsule size in characters.' },
171
+ },
172
+ },
173
+ },
174
+ },
175
+ {
176
+ type: 'function',
177
+ function: {
178
+ name: 'memory_encode',
179
+ description: 'Store a useful lasting observation, decision, preference, or procedure in Audrey.',
180
+ parameters: {
181
+ type: 'object',
182
+ required: ['content'],
183
+ properties: {
184
+ content: { type: 'string', description: 'Memory content to store.' },
185
+ source: {
186
+ type: 'string',
187
+ enum: ['direct-observation', 'told-by-user', 'tool-result', 'inference', 'model-generated'],
188
+ description: 'Source reliability category.',
189
+ },
190
+ tags: {
191
+ type: 'array',
192
+ items: { type: 'string' },
193
+ description: 'Searchable tags for this memory.',
194
+ },
195
+ },
196
+ },
197
+ },
198
+ },
199
+ ];
200
+
201
+ function parseToolArguments(args) {
202
+ if (args == null) return {};
203
+ if (typeof args === 'string') {
204
+ try {
205
+ return JSON.parse(args);
206
+ } catch {
207
+ return { raw: args };
208
+ }
209
+ }
210
+ return args;
211
+ }
212
+
213
+ async function ollamaChat(messages) {
214
+ return jsonFetch(`${OLLAMA_URL}/api/chat`, {
215
+ method: 'POST',
216
+ headers: { 'Content-Type': 'application/json' },
217
+ body: JSON.stringify({
218
+ model: OLLAMA_MODEL,
219
+ stream: false,
220
+ messages,
221
+ tools,
222
+ }),
223
+ });
224
+ }
225
+
226
+ async function main() {
227
+ if (process.argv.includes('--help') || process.argv.includes('-h')) {
228
+ usage();
229
+ return;
230
+ }
231
+
232
+ try {
233
+ await audreyGet('/health');
234
+ } catch (err) {
235
+ console.error(`Audrey is not reachable at ${AUDREY_URL}.`);
236
+ console.error('Start it with: AUDREY_AGENT=ollama-local-agent npx audrey serve');
237
+ console.error(`Details: ${err.message}`);
238
+ process.exit(1);
239
+ }
240
+
241
+ const reflexes = await memoryReflexes({ action: userPrompt, include_preflight: false });
242
+ const preflight = await memoryPreflight({ action: userPrompt, include_capsule: false });
243
+ const capsule = await memoryCapsule({ query: userPrompt, budget_chars: 4000 });
244
+ const messages = [
245
+ {
246
+ role: 'system',
247
+ content: [
248
+ 'You are a local Ollama agent with Audrey long-term memory.',
249
+ 'Use Audrey tools when memory would improve the answer.',
250
+ 'Before taking risky tool actions, call memory_reflexes or memory_preflight and follow any warnings.',
251
+ 'Store only durable preferences, facts, decisions, procedures, and useful lessons.',
252
+ '',
253
+ 'Initial Audrey Memory Reflexes:',
254
+ JSON.stringify(reflexes, null, 2).slice(0, 3000),
255
+ '',
256
+ 'Initial Audrey Preflight:',
257
+ JSON.stringify(preflight, null, 2).slice(0, 3000),
258
+ '',
259
+ 'Initial Audrey Memory Capsule:',
260
+ JSON.stringify(capsule, null, 2).slice(0, 6000),
261
+ ].join('\n'),
262
+ },
263
+ { role: 'user', content: userPrompt },
264
+ ];
265
+
266
+ console.error(`[audrey-ollama] model=${OLLAMA_MODEL} audrey=${AUDREY_URL} ollama=${OLLAMA_URL}`);
267
+
268
+ for (let i = 0; i < MAX_TOOL_LOOPS; i += 1) {
269
+ let response;
270
+ try {
271
+ response = await ollamaChat(messages);
272
+ } catch (err) {
273
+ console.error(`Ollama is not reachable at ${OLLAMA_URL}, or model "${OLLAMA_MODEL}" is not available.`);
274
+ console.error(`Try: ollama pull ${OLLAMA_MODEL}`);
275
+ console.error(`Details: ${err.message}`);
276
+ process.exit(1);
277
+ }
278
+
279
+ const message = response.message || {};
280
+ messages.push(message);
281
+
282
+ const calls = message.tool_calls || [];
283
+ if (calls.length === 0) {
284
+ console.log(message.content || '(model returned no content)');
285
+ await memoryEncode({
286
+ content: `Ollama agent answered: ${userPrompt.slice(0, 240)}`,
287
+ source: 'model-generated',
288
+ tags: ['ollama-agent', 'session-summary'],
289
+ }).catch(() => undefined);
290
+ return;
291
+ }
292
+
293
+ for (const call of calls) {
294
+ const name = call.function?.name;
295
+ const executor = toolExecutors[name];
296
+ if (!executor) {
297
+ messages.push({ role: 'tool', tool_name: name || 'unknown', content: 'Unknown Audrey tool' });
298
+ continue;
299
+ }
300
+
301
+ const args = parseToolArguments(call.function?.arguments);
302
+ console.error(`[audrey-ollama] tool ${name} ${JSON.stringify(args)}`);
303
+ try {
304
+ const result = await executor(args);
305
+ messages.push({
306
+ role: 'tool',
307
+ tool_name: name,
308
+ content: JSON.stringify(result).slice(0, 8000),
309
+ });
310
+ } catch (err) {
311
+ messages.push({
312
+ role: 'tool',
313
+ tool_name: name,
314
+ content: `Audrey tool error: ${err.message}`,
315
+ });
316
+ }
317
+ }
318
+ }
319
+
320
+ console.log('Stopped after MAX_TOOL_LOOPS without a final model answer.');
321
+ }
322
+
323
+ main().catch((err) => {
324
+ console.error(err);
325
+ process.exit(1);
326
+ });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "audrey",
3
- "version": "0.20.0",
4
- "description": "Biological memory architecture for AI agents - encode, consolidate, and recall memories with confidence decay, contradiction detection, and causal graphs",
3
+ "version": "0.23.1",
4
+ "description": "Local-first memory runtime for AI agents with recall, consolidation, memory reflexes, contradiction detection, and tool-trace learning",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
7
7
  "types": "dist/src/index.d.ts",
@@ -25,27 +25,32 @@
25
25
  },
26
26
  "files": [
27
27
  "dist/",
28
- "docs/production-readiness.md",
29
- "docs/benchmarking.md",
30
- "docs/assets/benchmarks/",
28
+ "docs/assets/audrey-feature-grid.jpg",
29
+ "docs/assets/audrey-logo.svg",
30
+ "docs/assets/audrey-wordmark.png",
31
31
  "examples/",
32
+ "CHANGELOG.md",
32
33
  "README.md",
34
+ "SECURITY.md",
33
35
  "LICENSE"
34
36
  ],
35
37
  "scripts": {
36
38
  "build": "tsc",
37
- "prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
38
- "pretest": "npm run build",
39
- "test": "vitest run",
40
- "test:watch": "vitest",
39
+ "prebuild": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist',{recursive:true,force:true})\"",
40
+ "pretest": "npm run build && npm run bench:perf",
41
+ "test": "node scripts/run-vitest.mjs",
42
+ "test:watch": "node scripts/run-vitest.mjs watch",
43
+ "release:gate": "npm run typecheck && npm test && npm run bench:memory:check && npm run pack:check",
44
+ "release:gate:sandbox": "npm run build && npm run typecheck && npm run bench:perf && npm run bench:memory:check && npm run pack:check",
41
45
  "prepack": "npm run build",
42
46
  "pack:check": "npm pack --dry-run",
43
47
  "bench:memory": "node benchmarks/run.js",
48
+ "bench:perf": "node benchmarks/perf.bench.js",
49
+ "bench:perf-snapshot": "node benchmarks/perf-snapshot.js",
44
50
  "bench:memory:retrieval": "node benchmarks/run.js --suite retrieval",
45
51
  "bench:memory:operations": "node benchmarks/run.js --suite operations",
46
52
  "bench:memory:json": "node benchmarks/run.js --json",
47
53
  "bench:memory:check": "node benchmarks/run.js --check",
48
- "bench:memory:readme-assets": "node benchmarks/run.js --readme-assets-dir docs/assets/benchmarks",
49
54
  "typecheck": "tsc --noEmit",
50
55
  "serve": "node dist/mcp-server/index.js serve",
51
56
  "docker:build": "docker build -t audrey:local .",
@@ -76,13 +81,17 @@
76
81
  "confidence",
77
82
  "long-term-memory",
78
83
  "persistent-memory",
84
+ "memory-preflight",
85
+ "memory-reflexes",
86
+ "agent-reflexes",
87
+ "agent-safety",
88
+ "tool-trace-memory",
89
+ "local-first-memory",
79
90
  "rag",
80
91
  "claude",
81
92
  "agent-framework",
82
93
  "rest-api",
83
- "http-server",
84
- "fintech",
85
- "healthcare"
94
+ "http-server"
86
95
  ],
87
96
  "repository": {
88
97
  "type": "git",
@@ -98,19 +107,23 @@
98
107
  },
99
108
  "license": "MIT",
100
109
  "dependencies": {
101
- "@hono/node-server": "^1.19.13",
110
+ "@hono/node-server": "^1.19.14",
102
111
  "@huggingface/transformers": "^3.8.1",
103
- "@modelcontextprotocol/sdk": "^1.26.0",
104
- "better-sqlite3": "^12.6.2",
105
- "hono": "^4.12.12",
106
- "sqlite-vec": "^0.1.7-alpha.2",
112
+ "@modelcontextprotocol/sdk": "^1.29.0",
113
+ "better-sqlite3": "^12.9.0",
114
+ "hono": "^4.12.18",
115
+ "sqlite-vec": "^0.1.9",
107
116
  "ulid": "^3.0.2",
108
- "zod": "^4.3.6"
117
+ "zod": "^4.4.3"
109
118
  },
110
119
  "devDependencies": {
111
120
  "@types/better-sqlite3": "^7.6.13",
112
- "@types/node": "^25.6.0",
113
- "typescript": "^6.0.2",
114
- "vitest": "^4.0.18"
121
+ "@types/node": "^25.6.2",
122
+ "typescript": "^6.0.3",
123
+ "vitest": "^4.1.5"
124
+ },
125
+ "directories": {
126
+ "example": "examples",
127
+ "test": "tests"
115
128
  }
116
129
  }
@@ -1,45 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Audrey vs Local Memory Baselines">
3
- <rect width="100%" height="100%" fill="white" />
4
- <text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Audrey vs Local Memory Baselines</text>
5
-
6
- <line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
7
- <text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
8
-
9
-
10
- <line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
11
- <text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
12
-
13
-
14
- <line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
15
- <text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
16
-
17
-
18
- <line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
19
- <text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
20
-
21
-
22
- <line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
23
- <text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
24
-
25
-
26
- <rect x="64" y="56" width="198" height="276" rx="8" fill="#0f766e" />
27
- <text x="163" y="46" text-anchor="middle" font-size="15" fill="#111827">100.0%</text>
28
- <text x="163" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Audrey</text>
29
-
30
-
31
- <rect x="286" y="217" width="198" height="115.00000000000001" rx="8" fill="#0369a1" />
32
- <text x="385" y="207" text-anchor="middle" font-size="15" fill="#111827">41.7%</text>
33
- <text x="385" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Vector Only</text>
34
-
35
-
36
- <rect x="508" y="217" width="198" height="115.00000000000001" rx="8" fill="#6d28d9" />
37
- <text x="607" y="207" text-anchor="middle" font-size="15" fill="#111827">41.7%</text>
38
- <text x="607" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Keyword + Recency</text>
39
-
40
-
41
- <rect x="730" y="228.5" width="198" height="103.5" rx="8" fill="#b45309" />
42
- <text x="829" y="218.5" text-anchor="middle" font-size="15" fill="#111827">37.5%</text>
43
- <text x="829" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Recent Window</text>
44
-
45
- </svg>
@@ -1,45 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Audrey Memory Operations Benchmark">
3
- <rect width="100%" height="100%" fill="white" />
4
- <text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Audrey Memory Operations Benchmark</text>
5
-
6
- <line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
7
- <text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
8
-
9
-
10
- <line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
11
- <text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
12
-
13
-
14
- <line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
15
- <text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
16
-
17
-
18
- <line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
19
- <text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
20
-
21
-
22
- <line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
23
- <text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
24
-
25
-
26
- <rect x="64" y="56" width="198" height="276" rx="8" fill="#0f766e" />
27
- <text x="163" y="46" text-anchor="middle" font-size="15" fill="#111827">100.0%</text>
28
- <text x="163" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Audrey</text>
29
-
30
-
31
- <rect x="286" y="263" width="198" height="69" rx="8" fill="#6d28d9" />
32
- <text x="385" y="253" text-anchor="middle" font-size="15" fill="#111827">25.0%</text>
33
- <text x="385" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Keyword + Recency</text>
34
-
35
-
36
- <rect x="508" y="297.5" width="198" height="34.5" rx="8" fill="#0369a1" />
37
- <text x="607" y="287.5" text-anchor="middle" font-size="15" fill="#111827">12.5%</text>
38
- <text x="607" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Vector Only</text>
39
-
40
-
41
- <rect x="730" y="297.5" width="198" height="34.5" rx="8" fill="#b45309" />
42
- <text x="829" y="287.5" text-anchor="middle" font-size="15" fill="#111827">12.5%</text>
43
- <text x="829" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Recent Window</text>
44
-
45
- </svg>
@@ -1,50 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <svg xmlns="http://www.w3.org/2000/svg" width="960" height="420" viewBox="0 0 960 420" role="img" aria-label="Published LLM Memory Standards (LoCoMo)">
3
- <rect width="100%" height="100%" fill="white" />
4
- <text x="64" y="34" font-size="24" font-weight="700" fill="#111827">Published LLM Memory Standards (LoCoMo)</text>
5
-
6
- <line x1="64" y1="332" x2="928" y2="332" stroke="#cbd5e1" stroke-dasharray="4 4" />
7
- <text x="54" y="337" text-anchor="end" font-size="13" fill="#6b7280">0%</text>
8
-
9
-
10
- <line x1="64" y1="263" x2="928" y2="263" stroke="#cbd5e1" stroke-dasharray="4 4" />
11
- <text x="54" y="268" text-anchor="end" font-size="13" fill="#6b7280">25%</text>
12
-
13
-
14
- <line x1="64" y1="194" x2="928" y2="194" stroke="#cbd5e1" stroke-dasharray="4 4" />
15
- <text x="54" y="199" text-anchor="end" font-size="13" fill="#6b7280">50%</text>
16
-
17
-
18
- <line x1="64" y1="125" x2="928" y2="125" stroke="#cbd5e1" stroke-dasharray="4 4" />
19
- <text x="54" y="130" text-anchor="end" font-size="13" fill="#6b7280">75%</text>
20
-
21
-
22
- <line x1="64" y1="56" x2="928" y2="56" stroke="#cbd5e1" stroke-dasharray="4 4" />
23
- <text x="54" y="61" text-anchor="end" font-size="13" fill="#6b7280">100%</text>
24
-
25
-
26
- <rect x="64" y="96.29599999999996" width="154" height="235.70400000000004" rx="8" fill="#1d4ed8" />
27
- <text x="141" y="86.29599999999996" text-anchor="middle" font-size="15" fill="#111827">85.4%</text>
28
- <text x="141" y="378" text-anchor="middle" font-size="14" fill="#6b7280">MIRIX</text>
29
-
30
-
31
- <rect x="241.5" y="127.75999999999999" width="154" height="204.24" rx="8" fill="#1d4ed8" />
32
- <text x="318.5" y="117.75999999999999" text-anchor="middle" font-size="15" fill="#111827">74.0%</text>
33
- <text x="318.5" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Letta Filesystem</text>
34
-
35
-
36
- <rect x="419" y="142.94" width="154" height="189.06" rx="8" fill="#1d4ed8" />
37
- <text x="496" y="132.94" text-anchor="middle" font-size="15" fill="#111827">68.5%</text>
38
- <text x="496" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Mem0 Graph Memory</text>
39
-
40
-
41
- <rect x="596.5" y="147.356" width="154" height="184.644" rx="8" fill="#1d4ed8" />
42
- <text x="673.5" y="137.356" text-anchor="middle" font-size="15" fill="#111827">66.9%</text>
43
- <text x="673.5" y="378" text-anchor="middle" font-size="14" fill="#6b7280">Mem0</text>
44
-
45
-
46
- <rect x="774" y="185.99599999999998" width="154" height="146.00400000000002" rx="8" fill="#1d4ed8" />
47
- <text x="851" y="175.99599999999998" text-anchor="middle" font-size="15" fill="#111827">52.9%</text>
48
- <text x="851" y="378" text-anchor="middle" font-size="14" fill="#6b7280">OpenAI Memory</text>
49
-
50
- </svg>