-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemory.json.example
More file actions
282 lines (267 loc) · 11 KB
/
Copy pathmemory.json.example
File metadata and controls
282 lines (267 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
{
"_comment": "Quaid Memory Plugin — Configuration Template. Copy to config/memory.json and customize.",
"adapter": {
"type": "standalone",
"_notes": "Required. Set to 'standalone' for local CLI installs, 'openclaw' when running under OpenClaw, or the relevant adapter id for other host integrations."
},
"plugins": {
"enabled": true,
"strict": true,
"apiVersion": 1,
"paths": ["plugins"],
"allowList": [],
"slots": {
"adapter": "",
"ingest": [],
"dataStores": []
},
"_notes": "Phase-1 plugin runtime foundation. paths are scanned for plugin.json manifests. allowList empty means all discovered plugins are eligible. slots define active plugin IDs by zone. strict=true fails on invalid manifests/conflicts."
},
"systems": {
"memory": true,
"journal": true,
"projects": true,
"workspace": true,
"_notes": "Toggle subsystems on/off. memory: fact extraction+recall, journal: personality snippets+reflective log, projects: auto-update project docs, workspace: core markdown health monitoring. Infrastructure tasks (backup, tests, cleanup) always run."
},
"models": {
"llmProvider": "default",
"deepReasoningProvider": "default",
"fastReasoningProvider": "default",
"embeddingsProvider": "ollama",
"fastReasoning": "default",
"deepReasoning": "default",
"deepReasoningModelClasses": {
"openai-codex": "gpt-5.3-codex",
"openai": "gpt-5.3-codex",
"anthropic": "claude-opus-4-6"
},
"fastReasoningModelClasses": {
"openai-codex": "gpt-5.1-codex-mini",
"openai": "gpt-5.1-codex-mini",
"anthropic": "claude-haiku-4-5"
},
"fastReasoningContext": 200000,
"deepReasoningContext": 200000,
"fastReasoningMaxOutput": 8192,
"deepReasoningMaxOutput": 16384,
"batchBudgetPercent": 0.5,
"_notes": "llmProvider picks the shared default provider. deepReasoningProvider/fastReasoningProvider can override per tier. deepReasoning/fastReasoning allow explicit model IDs or 'default' (mapped via *ReasoningModelClasses for the effective provider)."
},
"capture": {
"enabled": true,
"strictness": "high",
"inactivityTimeoutMinutes": 120,
"autoCompactionOnTimeout": true,
"skipPatterns": [
"^(thanks|ok|sure|yes|no)$",
"^(hi|hello|hey)\\b"
],
"_notes": "strictness: high = only clear facts, medium = default, low = capture more. inactivityTimeoutMinutes: extract after inactivity. autoCompactionOnTimeout: after timeout extraction, compact session to reduce token usage. skipPatterns: regex patterns to skip during extraction."
},
"decay": {
"enabled": true,
"thresholdDays": 30,
"ratePercent": 10,
"minimumConfidence": 0.1,
"protectVerified": true,
"protectPinned": true,
"reviewQueueEnabled": true,
"mode": "exponential",
"baseHalfLifeDays": 60,
"accessBonusFactor": 0.15,
"_notes": "Ebbinghaus exponential decay. baseHalfLifeDays: half-life for facts with 0 accesses. Each access extends half-life by accessBonusFactor (15%). thresholdDays: minimum age before decay starts."
},
"janitor": {
"enabled": true,
"dryRun": false,
"applyMode": "auto",
"parallel": {
"enabled": true,
"llmWorkers": 4,
"llmWorkersByTask": {
"review_pending": 2,
"dedup_review": 2,
"decay_review": 2,
"contradiction_resolution": 2
},
"lifecyclePrepassEnabled": true,
"lifecyclePrepassWorkers": 3,
"lockEnforcementEnabled": true,
"lockWaitSeconds": 120,
"lockRequireRegistration": true
},
"approvalPolicies": {
"coreMarkdownWrites": "ask",
"projectDocsWrites": "ask",
"destructiveMemoryOps": "auto"
},
"taskTimeoutMinutes": 60,
"opusReview": {
"enabled": true,
"batchSize": 50,
"maxTokens": 4000
},
"dedup": {
"similarityThreshold": 0.85,
"highSimilarityThreshold": 0.95,
"autoRejectThreshold": 0.98,
"grayZoneLow": 0.88,
"haikuVerifyEnabled": true
},
"contradiction": {
"enabled": true,
"timeoutMinutes": 60,
"minSimilarity": 0.6,
"maxSimilarity": 0.85
},
"_notes": "Nightly maintenance pipeline. parallel is the global janitor parallelism control (on by default): llmWorkers controls datastore LLM batch concurrency and can be overridden per task via llmWorkersByTask; lifecyclePrepass controls janitor dry-run prepass concurrency. lockEnforcementEnabled requires registered write locks before maintenance routines can modify flat files/DB; lockRequireRegistration blocks routines that do not declare write resources; lockWaitSeconds controls lock timeout. approvalPolicies lets you set ask/auto per sensitive scope. Root markdown writes are usually ask; projects/quaid markdown is auto-managed by janitor. applyMode is a legacy master fallback (auto/ask/dry_run). opusReview: LLM reviews pending facts. dedup: similarity thresholds for duplicate detection. contradiction: detect conflicting facts."
},
"retrieval": {
"defaultLimit": 5,
"maxLimit": 8,
"minSimilarity": 0.6,
"notifyMinSimilarity": 0.85,
"boostRecent": true,
"boostFrequent": true,
"maxTokens": 2000,
"reranker": {
"enabled": true,
"provider": "llm",
"model": "qwen2.5:7b",
"topK": 20,
"instruction": "Given a personal memory query, determine if this memory is relevant to the query",
"_notes": "provider: 'llm' uses the configured fast-reasoning model (~$0.002/recall). 'ollama' uses the local model specified in 'model' field."
},
"rrfK": 60,
"rerankerBlend": 0.5,
"compositeRelevanceWeight": 0.60,
"compositeRecencyWeight": 0.20,
"compositeFrequencyWeight": 0.15,
"multiPassGate": 0.70,
"mmrLambda": 0.7,
"coSessionDecay": 0.6,
"recencyDecayDays": 90,
"preInjectionPass": true,
"routerFailOpen": true,
"failHard": true,
"traversal": {
"useBeam": true,
"beamWidth": 5,
"maxDepth": 2,
"hopDecay": 0.7,
"_notes": "BEAM search for graph traversal. hopDecay: score multiplier per hop depth."
},
"_notes_router": "routerFailOpen=true (recommended default): if total_recall prepass cannot produce valid structured JSON after retry, log loudly and continue with deterministic default recall plan. Set false for strict fail-through behavior. If failHard=true, fallback behavior should be disabled.",
"_notes_fail_hard": "failHard=true (recommended in dev/benchmark): disable fallbacks and fail fast on provider/path errors. Set false only when you explicitly want noisy degrade behavior."
},
"logging": {
"enabled": true,
"level": "info",
"retentionDays": 30,
"components": ["memory", "janitor"]
},
"notifications": {
"level": "normal",
"janitor": { "verbosity": "summary", "channel": "last_used" },
"extraction": { "verbosity": "summary", "channel": "last_used" },
"retrieval": { "verbosity": "off", "channel": "last_used" },
"fullText": true,
"showProcessingStart": true,
"_notes_level": "Master verbosity: 'quiet' (errors only), 'normal' (summaries), 'verbose' (more detail), 'debug' (everything). Default: normal.",
"_notes_features": "Per-feature config — verbosity: 'off', 'summary', or 'full' (null = inherit master level). channel: 'last_used' (follow user's active channel) or a specific channel name like 'telegram', 'discord', 'slack'. Shorthand: set to just a string like 'summary' for verbosity-only (no channel override).",
"_notes_defaults": "quiet: all off. normal: janitor=summary, extraction=off, retrieval=summary. verbose: all summary. debug: all full.",
"_notes_tip": "You can ask your agent to adjust verbosity or channel routing at any time, e.g. 'send janitor reports to discord' or 'make memory notifications quieter'."
},
"docs": {
"autoUpdateOnCompact": true,
"maxDocsPerUpdate": 3,
"stalenessCheckEnabled": true,
"updateTimeoutSeconds": 120,
"coreMarkdown": {
"enabled": true,
"monitorForBloat": true,
"monitorForOutdated": true,
"files": {
"SOUL.md": {
"purpose": "Personality, vibe, values, interaction style",
"maxLines": 80
},
"USER.md": {
"purpose": "About the user — who they are, preferences, context",
"maxLines": 150
},
"MEMORY.md": {
"purpose": "Core memories loaded every session",
"maxLines": 100
},
"TOOLS.md": {
"purpose": "API docs, tool definitions, system configs",
"maxLines": 150
}
},
"_notes": "Janitor monitors these files for bloat and outdated info. These load every turn — keep them concise."
},
"journal": {
"enabled": true,
"snippetsEnabled": true,
"mode": "distilled",
"injectFull": false,
"journalDir": "journal",
"targetFiles": ["SOUL.md", "USER.md", "MEMORY.md"],
"maxEntriesPerFile": 50,
"maxTokens": 8192,
"distillationIntervalDays": 7,
"archiveAfterDistillation": true,
"_notes": "Dual system: snippets (fast path, bullet points merged into core markdown nightly) + journal (slow path, reflective paragraphs distilled weekly). mode: 'distilled' = journal not loaded into context, 'full' = journal injected every turn. injectFull: EXPERIMENTAL — inject full journal text into agent context every turn (warning: journal size is uncapped, may consume significant context window)."
},
"sourceMapping": {},
"docPurposes": {},
"_notes": "sourceMapping: maps source files to their documentation files. docPurposes: describes what each doc covers. Both populated automatically by project discovery."
},
"projects": {
"enabled": true,
"projectsDir": "projects/",
"stagingDir": "projects/staging/",
"definitions": {},
"defaultProject": "default",
"_notes": "Projects are auto-discovered from the projects/ directory. You can also define them manually here."
},
"users": {
"defaultOwner": "default",
"identities": {
"default": {
"channels": {
"cli": ["*"]
},
"speakers": ["User"],
"personNodeName": "User"
}
},
"_notes": "The setup script populates this with your actual identity. personNodeName is used for the Person node in the memory graph."
},
"database": {
"path": "data/memory.db",
"archivePath": "data/memory_archive.db",
"walMode": true
},
"ollama": {
"url": "http://localhost:11434",
"embeddingModel": "nomic-embed-text",
"embeddingDim": 768,
"_WARNING_BEFORE_CHANGING_MODEL": [
"STOP! Changing embeddingModel invalidates ALL existing embeddings.",
"You MUST re-embed everything after changing: run 'quaid re-embed'.",
"embeddingDim must match the new model's output dimension.",
"Common models: nomic-embed-text (768, ~1.5GB RAM), qwen3-embedding:8b (4096, ~6GB), all-minilm (384, ~500MB)."
]
},
"rag": {
"docsDir": "docs",
"chunkMaxTokens": 800,
"chunkOverlapTokens": 100,
"maxResults": 5,
"searchLimit": 5,
"minSimilarity": 0.3
}
}