@memclaw/memclaw 0.9.17 → 0.9.19

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.
@@ -1,319 +1,242 @@
1
1
  # MemClaw Best Practices
2
2
 
3
- This guide provides proven strategies and decision frameworks for using MemClaw effectively in OpenClaw.
3
+ ## Token Optimization Strategy
4
4
 
5
- ## Tool Selection Decision Tree
5
+ ### The Layer Selection Decision Tree
6
6
 
7
7
  ```
8
- ┌─────────────────────────────────────────────────────────────────┐
9
- What do you need to do? │
10
- └─────────────────────────────────────────────────────────────────┘
11
-
12
- ┌─────────────────────┼─────────────────────┐
13
- ▼ ▼ ▼
14
- Find Info Save Info Manage Sessions
15
- │ │
16
- ▼ ▼ ▼
17
- ┌───────────────┐ ┌───────────────┐ ┌───────────────┐
18
- │ Need context? │ │ What kind? │ │ What? │
19
- └───────────────┘ └───────────────┘ └───────────────┘
20
- │ │ │
21
- ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
22
- ▼ ▼ ▼ ▼ ▼ ▼
23
- Quick Full Facts Conversation List Close &
24
- Search Context History Sessions Extract
25
- │ │ │ │ │ │
26
- ▼ ▼ ▼ ▼ ▼ ▼
27
- cortex_ cortex_ cortex_ cortex_ cortex_ cortex_
28
- search recall add_ add_ list_ close_
29
- memory memory sessions session
8
+ Start → What do you need?
9
+
10
+ ├── Quick relevance check?
11
+ └── Use L0 (cortex_get_abstract or cortex_search with return_layers=["L0"])
12
+
13
+ ├── Understanding gist or context?
14
+ └── Use L1 (cortex_get_overview or return_layers=["L0","L1"])
15
+
16
+ └── Exact details, quotes, or full implementation?
17
+ └── Use L2 (cortex_get_content or return_layers=["L0","L1","L2"])
30
18
  ```
31
19
 
32
- ### Quick Reference
20
+ ### Token Budget Guidelines
33
21
 
34
- | Scenario | Tool | Why |
35
- |----------|------|-----|
36
- | Quick lookup, need summary only | `cortex_search` | Fast, returns snippets |
37
- | Need full context/details | `cortex_recall` | Returns content + snippet |
38
- | User stated preference/decision | `cortex_add_memory` | Explicit persistence |
39
- | Important conversation content | Let it accumulate | Auto-stored in session |
40
- | Task/topic completed | `cortex_close_session` | Trigger extraction |
41
- | Check if memories exist | `cortex_list_sessions` | Verify before search |
22
+ | Layer | Tokens | Use Case |
23
+ |-------|--------|----------|
24
+ | L0 | ~100 | Filtering, quick preview, relevance check |
25
+ | L1 | ~2000 | Understanding context, moderate detail |
26
+ | L2 | Full | Exact quotes, complete code, full conversation |
42
27
 
43
- ## Session Lifecycle Management
28
+ **Recommended Pattern:**
29
+ 1. Start with L0 to filter candidates
30
+ 2. Use L1 for promising matches
31
+ 3. Use L2 only when absolutely necessary
44
32
 
45
- ### The Golden Rule
33
+ ### Example: Efficient Search Flow
46
34
 
47
- > **OpenClaw does NOT automatically trigger memory extraction.** You must proactively call `cortex_close_session` at natural checkpoints.
35
+ ```typescript
36
+ // Step 1: Quick search with L0 only
37
+ const results = cortex_search({
38
+ query: "database schema design",
39
+ return_layers: ["L0"],
40
+ limit: 10
41
+ });
48
42
 
49
- ### When to Close a Session
43
+ // Step 2: Identify top 2-3 relevant URIs
44
+ const topUris = results.results
45
+ .filter(r => r.score > 0.7)
46
+ .slice(0, 3)
47
+ .map(r => r.uri);
50
48
 
51
- ```
52
- ┌────────────────────────────────────────────────────────────────┐
53
- │ Timing Decision Flow │
54
- └────────────────────────────────────────────────────────────────┘
55
-
56
-
57
- ┌─────────────────┐
58
- │ Task completed? │
59
- └─────────────────┘
60
- │ │
61
- Yes No
62
- │ │
63
- ▼ ▼
64
- ┌──────────┐ ┌─────────────────┐
65
- │ CLOSE IT │ │ Topic shifted? │
66
- └──────────┘ └─────────────────┘
67
- │ │
68
- Yes No
69
- │ │
70
- ▼ ▼
71
- ┌──────────┐ ┌─────────────────┐
72
- │ CLOSE IT │ │ 10+ exchanges? │
73
- └──────────┘ └─────────────────┘
74
- │ │
75
- Yes No
76
- │ │
77
- ▼ ▼
78
- ┌──────────┐ ┌────────┐
79
- │ CLOSE IT │ │ WAIT │
80
- └──────────┘ └────────┘
81
- ```
82
-
83
- ### Rhythm Guidelines
84
-
85
- | Conversation Type | Close Frequency | Reason |
86
- |-------------------|-----------------|--------|
87
- | Quick Q&A | End of conversation | Minimal content to extract |
88
- | Task-oriented | After each task completion | Captures task-specific memories |
89
- | Long discussion | Every 10-20 exchanges | Prevents memory loss |
90
- | Exploratory chat | When topic shifts | Organizes memories by topic |
91
-
92
- ### Anti-Patterns to Avoid
93
-
94
- | ❌ Don't Do This | ✅ Do This Instead |
95
- |-------------------|-------------------|
96
- | Call `close_session` after every message | Call at natural checkpoints |
97
- | Wait until conversation ends (user may forget) | Proactively close during conversation |
98
- | Close without accumulating content | Let 5-10 exchanges happen first |
99
- | Never close sessions | Establish a rhythm |
100
-
101
- ## Memory Storage Strategy
102
-
103
- ### What to Explicitly Store
104
-
105
- Use `cortex_add_memory` for:
106
-
107
- 1. **Explicit User Preferences**
108
- ```
109
- "User prefers dark theme in all editors"
110
- "User wants commit messages in conventional format"
111
- ```
112
-
113
- 2. **Important Decisions**
114
- ```
115
- "Decided to use PostgreSQL instead of MySQL for this project"
116
- "User chose React over Vue for the frontend"
117
- ```
118
-
119
- 3. **Key Information That May Be Lost**
120
- ```
121
- "User's timezone is UTC+8"
122
- "Project deadline: March 30, 2026"
123
- ```
124
-
125
- ### What to Let Accumulate
126
-
127
- Don't use `cortex_add_memory` for:
128
-
129
- - Regular conversation content (auto-stored in session)
130
- - Contextual information (captured on close_session)
131
- - Temporary preferences (not worth persisting)
49
+ // Step 3: Get L1 overview for top candidates
50
+ for (const uri of topUris) {
51
+ const overview = cortex_get_overview({ uri });
52
+ // Process overview...
53
+ }
132
54
 
133
- ### Role Parameter Usage
134
-
135
- | Role | When to Use |
136
- |------|-------------|
137
- | `user` | User's statements, preferences, questions (default) |
138
- | `assistant` | Your responses, explanations, code you wrote |
139
- | `system` | Important context, rules, constraints |
140
-
141
- ## Search Strategies
142
-
143
- ### Query Formulation
144
-
145
- ```
146
- ┌────────────────────────────────────────────────────────────────┐
147
- │ Query Formulation Tips │
148
- └────────────────────────────────────────────────────────────────┘
149
-
150
- BAD: "it" — Too vague
151
- GOOD: "database choice" — Specific topic
152
-
153
- BAD: "the user said something" — Unfocused
154
- GOOD: "user preference for testing" — Clear intent
155
-
156
- BAD: "code" — Too broad
157
- GOOD: "authentication implementation" — Specific domain
55
+ // Step 4: If needed, get L2 for the most relevant
56
+ const fullContent = cortex_get_content({ uri: mostRelevantUri });
158
57
  ```
159
58
 
160
- ### Score Threshold Guidelines
161
-
162
- | Score | Use Case |
163
- |-------|----------|
164
- | 0.8+ | Need high-confidence matches only |
165
- | 0.6 (default) | Balanced precision/recall |
166
- | 0.4-0.5 | Exploratory search, finding related items |
167
- | <0.4 | Usually too noisy, not recommended |
59
+ ## Tool Selection Patterns
168
60
 
169
- ### Scope Parameter Usage
61
+ ### Pattern 1: Discovery (Don't know where information is)
170
62
 
171
63
  ```
172
- # Search across all sessions (default)
173
- { "query": "database decisions" }
174
-
175
- # Search within specific session
176
- { "query": "preferences", "scope": "project-alpha" }
64
+ cortex_search(query="...", return_layers=["L0"])
65
+
66
+ Identify relevant URIs
67
+
68
+ cortex_get_overview(uri="...") for more context
69
+
70
+ cortex_get_content(uri="...") if needed
177
71
  ```
178
72
 
179
- Use `scope` when:
180
- - You know the relevant session ID
181
- - Working within a specific project context
182
- - Want to limit noise from other sessions
183
-
184
- ## Common Pitfalls
185
-
186
- ### 1. Memory Not Found After Close
187
-
188
- **Symptom:** You closed a session but search returns nothing.
189
-
190
- **Cause:** Memory extraction is asynchronous and may take 30-60 seconds.
73
+ ### Pattern 2: Browsing (Know the structure)
191
74
 
192
- **Solution:** Wait briefly after close_session before searching, or:
193
75
  ```
194
- 1. Close session
195
- 2. Continue with other work
196
- 3. Memory will be indexed automatically
76
+ cortex_ls(uri="cortex://session")
77
+
78
+ cortex_ls(uri="cortex://session/{id}", include_abstracts=true)
79
+
80
+ cortex_get_abstract(uri="...") for quick check
81
+
82
+ cortex_get_content(uri="...") for details
197
83
  ```
198
84
 
199
- ### 2. Duplicate Memories
85
+ ### Pattern 3: Guided Exploration
200
86
 
201
- **Symptom:** Same information appears multiple times.
202
-
203
- **Cause:** Both explicit `add_memory` and `close_session` extraction captured the same content.
204
-
205
- **Solution:** Use `add_memory` only for information that:
206
- - Won't naturally be captured in conversation
207
- - Needs explicit emphasis
208
- - Is a correction or override of previous information
209
-
210
- ### 3. Irrelevant Search Results
211
-
212
- **Symptom:** Search returns unrelated content.
213
-
214
- **Cause:** Query too vague or score threshold too low.
215
-
216
- **Solution:**
217
- - Make queries more specific
218
- - Increase `min_score` threshold
219
- - Use `scope` to limit search range
220
-
221
- ### 4. Lost Session Content
222
-
223
- **Symptom:** Important conversation not in memory.
224
-
225
- **Cause:** Session was never closed.
226
-
227
- **Solution:** Establish a habit of closing sessions at checkpoints. If you realize too late, the raw messages may still exist in the session - close it now.
228
-
229
- ### 5. Configuration Issues
230
-
231
- **Symptom:** Tools return errors about service/API.
232
-
233
- **Cause:** LLM/Embedding credentials not configured.
234
-
235
- **Solution:** See SKILL.md → Troubleshooting section.
236
-
237
- ## Workflow Examples
238
-
239
- ### Example 1: New Project Discussion
240
-
241
- ```
242
- 1. User starts discussing a new project
243
- → Just listen and respond naturally
244
-
245
- 2. User makes architecture decisions
246
- → Optionally: cortex_add_memory for explicit decisions
247
-
248
- 3. Discussion shifts to another topic
249
- → cortex_close_session (captures project discussion memories)
250
-
251
- 4. Continue with new topic
252
- → Fresh start, memories from step 3 are now searchable
253
87
  ```
254
-
255
- ### Example 2: Finding Previous Context
256
-
88
+ cortex_explore(query="...", start_uri="...", return_layers=["L0"])
89
+
90
+ Review exploration_path for relevance scores
91
+
92
+ Use matches with higher return_layers if needed
257
93
  ```
258
- 1. User asks: "What did we decide about auth?"
259
94
 
260
- 2. cortex_search({ query: "authentication decision" })
95
+ ## Session Management Best Practices
261
96
 
262
- 3. If results show snippets but need details:
263
- cortex_recall({ query: "authentication implementation details" })
97
+ ### When to Close Sessions
264
98
 
265
- 4. Summarize findings to user
266
- ```
99
+ **DO close sessions:**
100
+ - ✅ After completing a significant task or topic
101
+ - ✅ After user shares important preferences/decisions
102
+ - ✅ When conversation topic shifts significantly
103
+ - ✅ Every 10-20 exchanges during long conversations
267
104
 
268
- ### Example 3: User States Preference
105
+ **DON'T close sessions:**
106
+ - ❌ After every message (too frequent)
107
+ - ❌ Only at the very end (user might forget)
269
108
 
270
- ```
271
- 1. User: "I always want TypeScript strict mode"
109
+ ### Memory Metadata
272
110
 
273
- 2. cortex_add_memory({
274
- content: "User requires TypeScript strict mode in all projects",
275
- role: "user"
276
- })
111
+ Use metadata to enrich stored memories:
277
112
 
278
- 3. Acknowledge and remember for future
113
+ ```typescript
114
+ cortex_add_memory({
115
+ content: "User prefers functional programming style over OOP",
116
+ role: "assistant",
117
+ metadata: {
118
+ tags: ["preference", "programming-style"],
119
+ importance: "high",
120
+ category: "technical-preference"
121
+ }
122
+ })
279
123
  ```
280
124
 
281
- ## Memory Architecture Reference
125
+ **Recommended metadata fields:**
126
+ - `tags`: Array of searchable tags
127
+ - `importance`: "high", "medium", "low"
128
+ - `category`: Custom categorization
129
+ - `source`: Where the information came from
282
130
 
283
- ### L0/L1/L2 Tier System
131
+ ## Common Workflows
284
132
 
285
- | Tier | Content | Size | Purpose | Search Role |
286
- |------|---------|------|---------|-------------|
287
- | L0 | Abstract summary | ~100 tokens | Quick filtering | First pass |
288
- | L1 | Key points + context | ~2000 tokens | Context refinement | Second pass |
289
- | L2 | Full original content | Complete | Exact matching | Final retrieval |
133
+ ### Finding User Preferences
290
134
 
291
- ### How Search Works Internally
135
+ ```typescript
136
+ // 1. Search for preference-related content
137
+ const results = cortex_search({
138
+ query: "user preferences settings configuration",
139
+ return_layers: ["L0"],
140
+ limit: 10
141
+ });
292
142
 
143
+ // 2. Get overviews for relevant results
144
+ for (const result of results.results.slice(0, 3)) {
145
+ if (result.snippet.includes("preference")) {
146
+ const overview = cortex_get_overview({ uri: result.uri });
147
+ // Extract preferences from overview
148
+ }
149
+ }
293
150
  ```
294
- Query → L0 Filter → L1 Refine → L2 Retrieve → Ranked Results
295
- │ │ │
296
- ▼ ▼ ▼
297
- Quick scan Contextual Full content
298
- by summary refinement for precision
299
- ```
300
-
301
- ### Automatic Processes
302
151
 
303
- | Process | Trigger | Duration |
304
- |---------|---------|----------|
305
- | Vector embedding | On `add_memory` | Seconds |
306
- | L0/L1 generation | On `add_memory` (async) | Seconds |
307
- | Full extraction | On `close_session` | 30-60s |
308
- | Maintenance | Every 3 hours (auto) | Minutes |
152
+ ### Error Context Retrieval
309
153
 
310
- ## Summary Checklist
154
+ ```typescript
155
+ // Search for error-related content
156
+ const results = cortex_search({
157
+ query: "TypeError: Cannot read property",
158
+ return_layers: ["L0"]
159
+ });
311
160
 
312
- Before ending a conversation or topic transition, ask yourself:
161
+ // If not found, try broader semantic search
162
+ if (results.results.length === 0) {
163
+ const broader = cortex_search({
164
+ query: "property access error undefined object",
165
+ return_layers: ["L0", "L1"]
166
+ });
167
+ }
168
+ ```
313
169
 
314
- - [ ] Have we accumulated meaningful content?
315
- - [ ] Did the user share important preferences or decisions?
316
- - [ ] Is this a natural checkpoint?
317
- - [ ] Should I close the session now?
170
+ ### Timeline Reconstruction
318
171
 
319
- If yes to any, call `cortex_close_session`.
172
+ ```typescript
173
+ // 1. List timeline directory
174
+ const timeline = cortex_ls({
175
+ uri: "cortex://session/{session_id}/timeline",
176
+ recursive: true,
177
+ include_abstracts: true
178
+ });
179
+
180
+ // 2. Sort by modified date (entries already sorted)
181
+ // 3. Get full content for key moments
182
+ for (const entry of timeline.entries) {
183
+ if (entry.abstract_text?.includes("important decision")) {
184
+ const content = cortex_get_content({ uri: entry.uri });
185
+ // Process important moment
186
+ }
187
+ }
188
+ ```
189
+
190
+ ## Performance Tips
191
+
192
+ ### Minimize API Calls
193
+
194
+ Instead of:
195
+ ```typescript
196
+ // Bad: Multiple L2 calls
197
+ for (const uri of uris) {
198
+ cortex_get_content({ uri });
199
+ }
200
+ ```
201
+
202
+ Do:
203
+ ```typescript
204
+ // Good: Batch with search
205
+ cortex_search({
206
+ query: "specific topic",
207
+ scope: session_id,
208
+ return_layers: ["L0", "L1", "L2"]
209
+ });
210
+ ```
211
+
212
+ ### Use Scope Effectively
213
+
214
+ ```typescript
215
+ // Faster: Search within known session
216
+ cortex_search({
217
+ query: "authentication",
218
+ scope: "project-x-session",
219
+ return_layers: ["L0"]
220
+ });
221
+
222
+ // Slower: Search all sessions
223
+ cortex_search({
224
+ query: "authentication",
225
+ return_layers: ["L0"]
226
+ });
227
+ ```
228
+
229
+ ### Leverage Abstracts for Filtering
230
+
231
+ ```typescript
232
+ // Get abstracts while browsing
233
+ const entries = cortex_ls({
234
+ uri: "cortex://session",
235
+ include_abstracts: true
236
+ });
237
+
238
+ // Filter based on abstracts without additional calls
239
+ const relevantEntries = entries.entries.filter(e =>
240
+ e.abstract_text?.includes("relevant keyword")
241
+ );
242
+ ```
@@ -0,0 +1,160 @@
1
+ # Memory Structure
2
+
3
+ MemClaw organizes memory using a multi-dimensional structure with three-tier retrieval layers.
4
+
5
+ ## URI Structure
6
+
7
+ All memory resources are addressed using the `cortex://` URI scheme:
8
+
9
+ ```
10
+ cortex://
11
+ ├── resources/{resource_name}/ # General resources (facts, knowledge)
12
+ ├── user/
13
+ │ ├── preferences/{name}.md # User preferences
14
+ │ ├── entities/{name}.md # People, projects, concepts
15
+ │ ├── events/{name}.md # Decisions, milestones
16
+ │ └── profile/{name}.md # User profile info
17
+ ├── agent/
18
+ │ ├── cases/{name}.md # Problem-solution cases
19
+ │ ├── skills/{name}.md # Acquired skills
20
+ │ └── instructions/{name}.md # Instructions learned
21
+ └── session/{session_id}/
22
+ ├── timeline/
23
+ │ ├── {YYYY-MM}/ # Year-month directory
24
+ │ │ ├── {DD}/ # Day directory
25
+ │ │ │ ├── {HH_MM_SS}_{id}.md # L2: Original message
26
+ │ │ │ ├── .abstract.md # L0: ~100 token summary
27
+ │ │ │ └── .overview.md # L1: ~2000 token overview
28
+ │ │ └── .abstract.md # Day-level L0 summary
29
+ │ └── .abstract.md # Session-level L0 summary
30
+ │ └── .overview.md # Session-level L1 overview
31
+ └── .session.json # Session metadata
32
+ ```
33
+
34
+ ## Dimensions
35
+
36
+ | Dimension | Purpose | Examples |
37
+ |-----------|---------|----------|
38
+ | `resources` | General knowledge, facts | Documentation, reference materials |
39
+ | `user` | User-specific memories | Preferences, entities, events, profile |
40
+ | `agent` | Agent-specific memories | Cases, skills, instructions |
41
+ | `session` | Conversation memories | Timeline messages, session context |
42
+
43
+ ## Three-Layer Architecture
44
+
45
+ Each memory resource can have three representation layers:
46
+
47
+ | Layer | Filename | Tokens | Purpose |
48
+ |-------|----------|--------|---------|
49
+ | **L0 (Abstract)** | `.abstract.md` | ~100 | Quick relevance check, filtering |
50
+ | **L1 (Overview)** | `.overview.md` | ~2000 | Understanding gist, moderate detail |
51
+ | **L2 (Detail)** | `{name}.md` | Full | Exact quotes, complete implementation |
52
+
53
+ **Layer Resolution:**
54
+ - For files: `cortex://user/preferences/typescript.md` → layers are `.abstract.md` and `.overview.md` in same directory
55
+ - For directories: `cortex://session/default/timeline` → layers are `.abstract.md` and `.overview.md` in that directory
56
+
57
+ **Access Pattern:**
58
+ ```
59
+ 1. Start with L0 (quick relevance check)
60
+ 2. Use L1 if L0 is relevant (more context)
61
+ 3. Use L2 only when necessary (full detail)
62
+ ```
63
+
64
+ ## Session Memory
65
+
66
+ ### session_id Configuration
67
+
68
+ `{session_id}` is a memory isolation identifier for separating different conversation contexts:
69
+
70
+ | Configuration Location | Field Name | Default Value |
71
+ |-----------------------|------------|---------------|
72
+ | OpenClaw plugin config | `defaultSessionId` | `"default"` |
73
+
74
+ **Configuration Example** (`openclaw.json`):
75
+ ```json
76
+ {
77
+ "plugins": {
78
+ "entries": {
79
+ "memclaw": {
80
+ "config": {
81
+ "defaultSessionId": "my-project"
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+ ```
88
+
89
+ **Usage Rules:**
90
+ - `session_id` parameter in tools is optional; defaults to configured value
91
+ - Different session_ids provide memory isolation for multi-project/multi-topic management
92
+ - Replace `{session_id}` in URIs with actual value, e.g., `cortex://session/default/timeline`
93
+
94
+ ### Timeline Organization
95
+
96
+ Timeline messages are organized hierarchically by date:
97
+
98
+ ```
99
+ session/{session_id}/timeline/
100
+ ├── 2024-03/ # Year-Month
101
+ │ ├── 15/ # Day
102
+ │ │ ├── 10_30_45_abc123.md # Message at 10:30:45
103
+ │ │ ├── .abstract.md # Day-level L0
104
+ │ │ └── 16/
105
+ │ │ └── ...
106
+ │ └── .abstract.md # Month-level L0
107
+ ├── .abstract.md # Session-level L0
108
+ └── .overview.md # Session-level L1
109
+ ```
110
+
111
+ **Message File Format:** `{HH_MM_SS}_{random_id}.md`
112
+
113
+ ## User Memory Categories
114
+
115
+ | Category | Description | URI Pattern |
116
+ |----------|-------------|-------------|
117
+ | `preferences` | User preferences by topic | `cortex://user/preferences/{name}.md` |
118
+ | `entities` | People, projects, concepts | `cortex://user/entities/{name}.md` |
119
+ | `events` | Decisions, milestones | `cortex://user/events/{name}.md` |
120
+ | `profile` | User profile information | `cortex://user/profile/{name}.md` |
121
+
122
+ ## Agent Memory Categories
123
+
124
+ | Category | Description | URI Pattern |
125
+ |----------|-------------|-------------|
126
+ | `cases` | Problem-solution pairs | `cortex://agent/cases/{name}.md` |
127
+ | `skills` | Acquired skills | `cortex://agent/skills/{name}.md` |
128
+ | `instructions` | Learned instructions | `cortex://agent/instructions/{name}.md` |
129
+
130
+ ## Session Metadata
131
+
132
+ Each session has a `.session.json` file containing:
133
+
134
+ ```json
135
+ {
136
+ "thread_id": "session_id",
137
+ "status": "active|closed|archived",
138
+ "created_at": "2024-03-15T10:30:00Z",
139
+ "updated_at": "2024-03-15T12:45:00Z",
140
+ "closed_at": null,
141
+ "message_count": 25,
142
+ "participants": ["user_001", "agent_001"],
143
+ "tags": ["typescript", "api-design"],
144
+ "title": "Optional session title",
145
+ "description": "Optional description"
146
+ }
147
+ ```
148
+
149
+ ## Layer Generation
150
+
151
+ Layers are generated **asynchronously** to avoid blocking agent responses:
152
+
153
+ 1. **L2 (Detail)**: Created immediately when memory is added
154
+ 2. **L0/L1**: Generated when `cortex_close_session` is called or via background maintenance
155
+
156
+ **When to call `cortex_close_session`:**
157
+ - After completing a significant task
158
+ - After user shares important preferences
159
+ - When conversation topic shifts
160
+ - Every 10-20 exchanges