@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 +1 -1
- package/src/cli/commands/ingest.ts +25 -2
- package/src/core/curator.ts +46 -6
package/package.json
CHANGED
|
@@ -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
|
-
|
|
375
|
+
interaction_tone: interactionTone,
|
|
376
|
+
project_snapshot: projectSnapshot,
|
|
354
377
|
}
|
|
355
378
|
|
|
356
379
|
const managerResult = await manager.manageWithSDK(
|
package/src/core/curator.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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: [] }
|