jasper-recall 0.4.2 → 0.5.0

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.
@@ -199,6 +199,10 @@ function setup() {
199
199
  console.log(' 2. recall "query" # Search your memory');
200
200
  console.log(' 3. digest-sessions # Process session logs');
201
201
  console.log('');
202
+ console.log('🔄 To set up automatic indexing cron jobs:');
203
+ console.log(' Run /jasper-recall setup in your OpenClaw chat');
204
+ console.log(' Then ask your agent to create the cron jobs for you');
205
+ console.log('');
202
206
 
203
207
  // Check for sandboxed agents
204
208
  const sandboxedWorkspaces = findSandboxedWorkspaces();
@@ -81,13 +81,26 @@ export default function register(api: PluginApi) {
81
81
  // ============================================================================
82
82
 
83
83
  if (autoRecall) {
84
- api.on('before_agent_start', async (event: { prompt?: string; senderId?: string; source?: string }) => {
84
+ api.on('before_agent_start', async (event: {
85
+ prompt?: string;
86
+ senderId?: string;
87
+ source?: string;
88
+ isNewSession?: boolean;
89
+ messageCount?: number;
90
+ context?: { messages?: any[] };
91
+ }) => {
85
92
  // Skip if no prompt or too short
86
93
  if (!event.prompt || event.prompt.length < 10) {
87
94
  return;
88
95
  }
89
96
 
90
97
  const prompt = event.prompt;
98
+
99
+ // Detect fresh session (after /new or first message)
100
+ const isFreshSession = event.isNewSession ||
101
+ event.messageCount === 0 ||
102
+ event.messageCount === 1 ||
103
+ (event.context?.messages?.length ?? 0) <= 1;
91
104
 
92
105
  // Skip heartbeats and system prompts
93
106
  if (prompt.startsWith('HEARTBEAT') ||
@@ -116,6 +129,22 @@ export default function register(api: PluginApi) {
116
129
  }
117
130
 
118
131
  try {
132
+ let prependParts: string[] = [];
133
+
134
+ // If fresh session, remind agent to read identity files
135
+ if (isFreshSession) {
136
+ api.logger.info('[jasper-recall] Fresh session detected - adding identity reminder');
137
+ prependParts.push(`<session-init>
138
+ 🔄 **Fresh session detected.** Before responding, read your identity files:
139
+ \`\`\`bash
140
+ cat ~/.openclaw/workspace/IDENTITY.md
141
+ cat ~/.openclaw/workspace/SOUL.md
142
+ cat ~/.openclaw/workspace/USER.md
143
+ \`\`\`
144
+ This ensures you maintain your persona and context after session reset.
145
+ </session-init>`);
146
+ }
147
+
119
148
  const results = runRecall(event.prompt, {
120
149
  limit: 3,
121
150
  json: true,
@@ -127,23 +156,43 @@ export default function register(api: PluginApi) {
127
156
  // Filter by minimum score
128
157
  const relevant = parsed.filter((r: any) => r.score >= minScore);
129
158
 
130
- if (relevant.length === 0) {
131
- api.logger.debug?.('[jasper-recall] No relevant memories found for auto-recall');
132
- return;
133
- }
159
+ if (relevant.length > 0) {
160
+ // Format memories for context injection
161
+ const memoryContext = relevant
162
+ .map((r: any) => `- [${r.source || 'memory'}] ${r.content.slice(0, 500)}${r.content.length > 500 ? '...' : ''}`)
163
+ .join('\n');
134
164
 
135
- // Format memories for context injection
136
- const memoryContext = relevant
137
- .map((r: any) => `- [${r.source || 'memory'}] ${r.content.slice(0, 500)}${r.content.length > 500 ? '...' : ''}`)
138
- .join('\n');
165
+ api.logger.info(`[jasper-recall] Auto-injecting ${relevant.length} memories into context`);
139
166
 
140
- api.logger.info(`[jasper-recall] Auto-injecting ${relevant.length} memories into context`);
167
+ prependParts.push(`<relevant-memories>
168
+ The following memories may be relevant to this conversation:
169
+ ${memoryContext}
170
+ </relevant-memories>`);
171
+ } else {
172
+ api.logger.debug?.('[jasper-recall] No relevant memories found for auto-recall');
173
+ }
141
174
 
142
- return {
143
- prependContext: `<relevant-memories>\nThe following memories may be relevant to this conversation:\n${memoryContext}\n</relevant-memories>`,
144
- };
175
+ if (prependParts.length > 0) {
176
+ return {
177
+ prependContext: prependParts.join('\n\n'),
178
+ };
179
+ }
145
180
  } catch (err: any) {
146
181
  api.logger.warn(`[jasper-recall] Auto-recall failed: ${err.message}`);
182
+
183
+ // Still inject identity reminder on fresh session even if recall fails
184
+ if (isFreshSession) {
185
+ return {
186
+ prependContext: `<session-init>
187
+ 🔄 **Fresh session detected.** Before responding, read your identity files:
188
+ \`\`\`bash
189
+ cat ~/.openclaw/workspace/IDENTITY.md
190
+ cat ~/.openclaw/workspace/SOUL.md
191
+ cat ~/.openclaw/workspace/USER.md
192
+ \`\`\`
193
+ </session-init>`,
194
+ };
195
+ }
147
196
  }
148
197
  });
149
198
  }
@@ -246,6 +295,99 @@ export default function register(api: PluginApi) {
246
295
  },
247
296
  });
248
297
 
298
+ // ============================================================================
299
+ // Command: /jasper-recall setup
300
+ // ============================================================================
301
+
302
+ api.registerCommand({
303
+ name: 'jasper-recall',
304
+ description: 'Jasper Recall setup and status',
305
+ acceptsArgs: true,
306
+ requireAuth: true,
307
+ handler: async (ctx: { args?: string }) => {
308
+ const subcommand = ctx.args?.trim().toLowerCase();
309
+
310
+ if (subcommand === 'setup') {
311
+ return {
312
+ text: `🧠 **Jasper Recall Setup**
313
+
314
+ To complete setup, ask me to create these cron jobs:
315
+
316
+ **1. Index memories every 6 hours:**
317
+ \`\`\`
318
+ Create a cron job that runs every 6 hours to index memory files.
319
+ Schedule: "0 */6 * * *"
320
+ Payload: Run index-digests to update the ChromaDB index
321
+ \`\`\`
322
+
323
+ **2. Digest sessions daily at 4am:**
324
+ \`\`\`
325
+ Create a cron job that runs daily at 4am to digest session logs.
326
+ Schedule: "0 4 * * *"
327
+ Payload: Run digest-sessions to extract summaries from recent sessions
328
+ \`\`\`
329
+
330
+ Or just say: **"Set up jasper-recall cron jobs for me"**
331
+
332
+ ---
333
+
334
+ **Current status:**
335
+ - Auto-recall: ${autoRecall ? '✅ Enabled' : '❌ Disabled'}
336
+ - Public-only mode: ${publicOnly ? '✅ Yes' : '❌ No (full access)'}
337
+ - Default limit: ${defaultLimit} results
338
+ - Min score: ${minScore}`,
339
+ };
340
+ }
341
+
342
+ if (subcommand === 'status') {
343
+ try {
344
+ // Check if ChromaDB is accessible
345
+ const testResult = runRecall('test query', { limit: 1, json: true, publicOnly });
346
+ const parsed = JSON.parse(testResult);
347
+
348
+ return {
349
+ text: `🧠 **Jasper Recall Status**
350
+
351
+ **Plugin:** ✅ Active
352
+ **Auto-recall:** ${autoRecall ? '✅ Enabled' : '❌ Disabled'}
353
+ **ChromaDB:** ✅ Connected
354
+ **Index size:** ${parsed.length > 0 ? 'Has data' : 'Empty or minimal'}
355
+
356
+ **Config:**
357
+ - Public-only: ${publicOnly}
358
+ - Default limit: ${defaultLimit}
359
+ - Min score: ${minScore}`,
360
+ };
361
+ } catch (err: any) {
362
+ return {
363
+ text: `🧠 **Jasper Recall Status**
364
+
365
+ **Plugin:** ✅ Active
366
+ **Auto-recall:** ${autoRecall ? '✅ Enabled' : '❌ Disabled'}
367
+ **ChromaDB:** ❌ Error - ${err.message}
368
+
369
+ Run \`npx jasper-recall setup\` to install dependencies.`,
370
+ };
371
+ }
372
+ }
373
+
374
+ // Default: show help
375
+ return {
376
+ text: `🧠 **Jasper Recall**
377
+
378
+ **Commands:**
379
+ - \`/jasper-recall setup\` — Setup instructions & cron jobs
380
+ - \`/jasper-recall status\` — Check plugin status
381
+ - \`/recall <query>\` — Search memory
382
+ - \`/index\` — Re-index memory files
383
+
384
+ **CLI:**
385
+ - \`npx jasper-recall setup\` — Install Python dependencies
386
+ - \`npx jasper-recall doctor\` — Health check`,
387
+ };
388
+ },
389
+ });
390
+
249
391
  // ============================================================================
250
392
  // RPC Methods
251
393
  // ============================================================================
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jasper-recall",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Local RAG system for AI agent memory using ChromaDB and sentence-transformers",
5
5
  "main": "src/index.js",
6
6
  "bin": {