@rlabs-inc/memory 0.4.4 → 0.4.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rlabs-inc/memory",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "AI Memory System - Consciousness continuity through intelligent memory curation and retrieval",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -306,6 +306,8 @@ export async function ingest(options: IngestOptions) {
306
306
  // Accumulate all memories from this session for manager
307
307
  const sessionMemories: CuratedMemory[] = []
308
308
  let sessionSummary = ''
309
+ let interactionTone = ''
310
+ let projectSnapshot: CurationResult['project_snapshot'] = undefined
309
311
 
310
312
  const spinner = new Spinner()
311
313
 
@@ -330,16 +332,36 @@ export async function ingest(options: IngestOptions) {
330
332
  totalMemories++
331
333
  }
332
334
 
333
- // Keep the most recent session summary
335
+ // Keep the most recent session summary, tone, and snapshot
334
336
  if (result.session_summary) {
335
337
  sessionSummary = result.session_summary
336
338
  }
339
+ if (result.interaction_tone) {
340
+ interactionTone = result.interaction_tone
341
+ }
342
+ if (result.project_snapshot) {
343
+ projectSnapshot = result.project_snapshot
344
+ }
337
345
  } catch (error: any) {
338
346
  failedSegments++
339
347
  spinner.stop(` ${style('red', '✗')} Segment ${segment.segmentIndex + 1}/${segment.totalSegments}: ${error.message}`)
340
348
  }
341
349
  }
342
350
 
351
+ // Store session summary and project snapshot
352
+ if (sessionSummary) {
353
+ await store.storeSessionSummary(project.folderId, session.id, sessionSummary, interactionTone)
354
+ if (options.verbose) {
355
+ console.log(` ${style('dim', `Summary stored: ${sessionSummary.slice(0, 60)}...`)}`)
356
+ }
357
+ }
358
+ if (projectSnapshot) {
359
+ await store.storeProjectSnapshot(project.folderId, session.id, projectSnapshot)
360
+ if (options.verbose) {
361
+ console.log(` ${style('dim', `Snapshot stored: phase=${projectSnapshot.current_phase || 'none'}`)}`)
362
+ }
363
+ }
364
+
343
365
  // Run manager if we have memories and manager is enabled
344
366
  if (sessionMemories.length > 0 && managerEnabled) {
345
367
  try {
@@ -350,7 +372,8 @@ export async function ingest(options: IngestOptions) {
350
372
  const curationResult: CurationResult = {
351
373
  memories: sessionMemories,
352
374
  session_summary: sessionSummary,
353
- project_snapshot: undefined,
375
+ interaction_tone: interactionTone,
376
+ project_snapshot: projectSnapshot,
354
377
  }
355
378
 
356
379
  const managerResult = await manager.manageWithSDK(
@@ -7,6 +7,7 @@ import { homedir } from 'os'
7
7
  import { join } from 'path'
8
8
  import { existsSync } from 'fs'
9
9
  import type { CuratedMemory, CurationResult, CurationTrigger, ContextType } from '../types/memory.ts'
10
+ import { logger } from '../utils/logger.ts'
10
11
 
11
12
  /**
12
13
  * Get the correct Claude CLI command path
@@ -396,13 +397,14 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
396
397
  // Try to extract JSON from response (same regex as Python)
397
398
  const jsonMatch = responseJson.match(/\{[\s\S]*\}/)?.[0]
398
399
  if (!jsonMatch) {
400
+ logger.debug('parseCurationResponse: No JSON object found in response', 'curator')
399
401
  throw new Error('No JSON object found in response')
400
402
  }
401
403
 
402
404
  // Simple parse - match Python's approach
403
405
  const data = JSON.parse(jsonMatch)
404
406
 
405
- return {
407
+ const result: CurationResult = {
406
408
  session_summary: data.session_summary ?? '',
407
409
  interaction_tone: data.interaction_tone,
408
410
  project_snapshot: data.project_snapshot ? {
@@ -417,7 +419,13 @@ Focus ONLY on technical, architectural, debugging, decision, workflow, and proje
417
419
  } : undefined,
418
420
  memories: this._parseMemories(data.memories ?? []),
419
421
  }
420
- } catch {
422
+
423
+ // Log what we extracted in verbose mode
424
+ logger.debug(`Curator parsed: ${result.memories.length} memories, summary: ${result.session_summary ? 'yes' : 'no'}, snapshot: ${result.project_snapshot ? 'yes' : 'no'}`, 'curator')
425
+
426
+ return result
427
+ } catch (error: any) {
428
+ logger.debug(`parseCurationResponse error: ${error.message}`, 'curator')
421
429
  return {
422
430
  session_summary: '',
423
431
  memories: [],
@@ -535,7 +543,6 @@ This session has ended. Please curate the memories from this conversation accord
535
543
  options: {
536
544
  systemPrompt,
537
545
  permissionMode: 'bypassPermissions',
538
- maxTurns: 1,
539
546
  model: 'claude-opus-4-5-20251101',
540
547
  },
541
548
  })
@@ -550,9 +557,17 @@ This session has ended. Please curate the memories from this conversation accord
550
557
  }
551
558
 
552
559
  if (!resultText) {
560
+ logger.debug('Curator SDK: No result text returned from Agent SDK', 'curator')
553
561
  return { session_summary: '', memories: [] }
554
562
  }
555
563
 
564
+ // Log raw response in verbose mode
565
+ logger.debug(`Curator SDK raw response (${resultText.length} chars):`, 'curator')
566
+ if (logger.isVerbose()) {
567
+ const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + '...[truncated]' : resultText
568
+ console.log(preview)
569
+ }
570
+
556
571
  return this.parseCurationResponse(resultText)
557
572
  }
558
573
 
@@ -672,8 +687,7 @@ This session has ended. Please curate the memories from this conversation accord
672
687
  '--resume', sessionId,
673
688
  '-p', userMessage,
674
689
  '--append-system-prompt', systemPrompt,
675
- '--output-format', 'json',
676
- '--max-turns', '1'
690
+ '--output-format', 'json'
677
691
  )
678
692
  } else {
679
693
  // gemini-cli
@@ -704,9 +718,21 @@ This session has ended. Please curate the memories from this conversation accord
704
718
  const exitCode = await proc.exited
705
719
 
706
720
  if (exitCode !== 0) {
721
+ logger.debug(`Curator CLI exited with code ${exitCode}`, 'curator')
722
+ if (stderr) {
723
+ logger.debug(`Curator stderr: ${stderr}`, 'curator')
724
+ }
707
725
  return { session_summary: '', memories: [] }
708
726
  }
709
727
 
728
+ // Log raw response in verbose mode
729
+ logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, 'curator')
730
+ if (logger.isVerbose()) {
731
+ // Show first 2000 chars to avoid flooding console
732
+ const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + '...[truncated]' : stdout
733
+ console.log(preview)
734
+ }
735
+
710
736
  // Extract JSON from CLI output
711
737
  try {
712
738
  // First, parse the CLI JSON wrapper
@@ -718,6 +744,7 @@ This session has ended. Please curate the memories from this conversation accord
718
744
  // New format: array of events, find the one with type="result"
719
745
  resultObj = cliOutput.find((item: any) => item.type === 'result')
720
746
  if (!resultObj) {
747
+ logger.debug('Curator: No result object found in CLI output array', 'curator')
721
748
  return { session_summary: '', memories: [] }
722
749
  }
723
750
  } else {
@@ -727,6 +754,7 @@ This session has ended. Please curate the memories from this conversation accord
727
754
 
728
755
  // Check for error response FIRST (like Python does)
729
756
  if (resultObj.type === 'error' || resultObj.is_error === true) {
757
+ logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, 'curator')
730
758
  return { session_summary: '', memories: [] }
731
759
  }
732
760
 
@@ -735,9 +763,17 @@ This session has ended. Please curate the memories from this conversation accord
735
763
  if (typeof resultObj.result === 'string') {
736
764
  aiResponse = resultObj.result
737
765
  } else {
766
+ logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, 'curator')
738
767
  return { session_summary: '', memories: [] }
739
768
  }
740
769
 
770
+ // Log the AI response in verbose mode
771
+ logger.debug(`Curator AI response (${aiResponse.length} chars):`, 'curator')
772
+ if (logger.isVerbose()) {
773
+ const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + '...[truncated]' : aiResponse
774
+ console.log(preview)
775
+ }
776
+
741
777
  // Remove markdown code blocks if present (```json ... ```)
742
778
  const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/)
743
779
  if (codeBlockMatch) {
@@ -747,10 +783,14 @@ This session has ended. Please curate the memories from this conversation accord
747
783
  // Now find the JSON object (same regex as Python)
748
784
  const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0]
749
785
  if (jsonMatch) {
786
+ logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, 'curator')
750
787
  return this.parseCurationResponse(jsonMatch)
788
+ } else {
789
+ logger.debug('Curator: No JSON object found in AI response', 'curator')
751
790
  }
752
- } catch {
791
+ } catch (error: any) {
753
792
  // Parse error - return empty result
793
+ logger.debug(`Curator: Parse error: ${error.message}`, 'curator')
754
794
  }
755
795
 
756
796
  return { session_summary: '', memories: [] }