@rlabs-inc/memory 0.4.4 → 0.4.5
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 +45 -3
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: [],
|
|
@@ -550,9 +558,17 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
550
558
|
}
|
|
551
559
|
|
|
552
560
|
if (!resultText) {
|
|
561
|
+
logger.debug('Curator SDK: No result text returned from Agent SDK', 'curator')
|
|
553
562
|
return { session_summary: '', memories: [] }
|
|
554
563
|
}
|
|
555
564
|
|
|
565
|
+
// Log raw response in verbose mode
|
|
566
|
+
logger.debug(`Curator SDK raw response (${resultText.length} chars):`, 'curator')
|
|
567
|
+
if (logger.isVerbose()) {
|
|
568
|
+
const preview = resultText.length > 3000 ? resultText.slice(0, 3000) + '...[truncated]' : resultText
|
|
569
|
+
console.log(preview)
|
|
570
|
+
}
|
|
571
|
+
|
|
556
572
|
return this.parseCurationResponse(resultText)
|
|
557
573
|
}
|
|
558
574
|
|
|
@@ -704,9 +720,21 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
704
720
|
const exitCode = await proc.exited
|
|
705
721
|
|
|
706
722
|
if (exitCode !== 0) {
|
|
723
|
+
logger.debug(`Curator CLI exited with code ${exitCode}`, 'curator')
|
|
724
|
+
if (stderr) {
|
|
725
|
+
logger.debug(`Curator stderr: ${stderr}`, 'curator')
|
|
726
|
+
}
|
|
707
727
|
return { session_summary: '', memories: [] }
|
|
708
728
|
}
|
|
709
729
|
|
|
730
|
+
// Log raw response in verbose mode
|
|
731
|
+
logger.debug(`Curator CLI raw stdout (${stdout.length} chars):`, 'curator')
|
|
732
|
+
if (logger.isVerbose()) {
|
|
733
|
+
// Show first 2000 chars to avoid flooding console
|
|
734
|
+
const preview = stdout.length > 2000 ? stdout.slice(0, 2000) + '...[truncated]' : stdout
|
|
735
|
+
console.log(preview)
|
|
736
|
+
}
|
|
737
|
+
|
|
710
738
|
// Extract JSON from CLI output
|
|
711
739
|
try {
|
|
712
740
|
// First, parse the CLI JSON wrapper
|
|
@@ -718,6 +746,7 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
718
746
|
// New format: array of events, find the one with type="result"
|
|
719
747
|
resultObj = cliOutput.find((item: any) => item.type === 'result')
|
|
720
748
|
if (!resultObj) {
|
|
749
|
+
logger.debug('Curator: No result object found in CLI output array', 'curator')
|
|
721
750
|
return { session_summary: '', memories: [] }
|
|
722
751
|
}
|
|
723
752
|
} else {
|
|
@@ -727,6 +756,7 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
727
756
|
|
|
728
757
|
// Check for error response FIRST (like Python does)
|
|
729
758
|
if (resultObj.type === 'error' || resultObj.is_error === true) {
|
|
759
|
+
logger.debug(`Curator: Error response from CLI: ${JSON.stringify(resultObj).slice(0, 500)}`, 'curator')
|
|
730
760
|
return { session_summary: '', memories: [] }
|
|
731
761
|
}
|
|
732
762
|
|
|
@@ -735,9 +765,17 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
735
765
|
if (typeof resultObj.result === 'string') {
|
|
736
766
|
aiResponse = resultObj.result
|
|
737
767
|
} else {
|
|
768
|
+
logger.debug(`Curator: result field is not a string: ${typeof resultObj.result}`, 'curator')
|
|
738
769
|
return { session_summary: '', memories: [] }
|
|
739
770
|
}
|
|
740
771
|
|
|
772
|
+
// Log the AI response in verbose mode
|
|
773
|
+
logger.debug(`Curator AI response (${aiResponse.length} chars):`, 'curator')
|
|
774
|
+
if (logger.isVerbose()) {
|
|
775
|
+
const preview = aiResponse.length > 3000 ? aiResponse.slice(0, 3000) + '...[truncated]' : aiResponse
|
|
776
|
+
console.log(preview)
|
|
777
|
+
}
|
|
778
|
+
|
|
741
779
|
// Remove markdown code blocks if present (```json ... ```)
|
|
742
780
|
const codeBlockMatch = aiResponse.match(/```(?:json)?\s*([\s\S]*?)```/)
|
|
743
781
|
if (codeBlockMatch) {
|
|
@@ -747,10 +785,14 @@ This session has ended. Please curate the memories from this conversation accord
|
|
|
747
785
|
// Now find the JSON object (same regex as Python)
|
|
748
786
|
const jsonMatch = aiResponse.match(/\{[\s\S]*\}/)?.[0]
|
|
749
787
|
if (jsonMatch) {
|
|
788
|
+
logger.debug(`Curator: Found JSON object (${jsonMatch.length} chars), parsing...`, 'curator')
|
|
750
789
|
return this.parseCurationResponse(jsonMatch)
|
|
790
|
+
} else {
|
|
791
|
+
logger.debug('Curator: No JSON object found in AI response', 'curator')
|
|
751
792
|
}
|
|
752
|
-
} catch {
|
|
793
|
+
} catch (error: any) {
|
|
753
794
|
// Parse error - return empty result
|
|
795
|
+
logger.debug(`Curator: Parse error: ${error.message}`, 'curator')
|
|
754
796
|
}
|
|
755
797
|
|
|
756
798
|
return { session_summary: '', memories: [] }
|