@rlabs-inc/memory 0.4.14 → 0.4.15
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/README.md +5 -0
- package/package.json +1 -1
- package/src/core/engine.ts +36 -0
- package/src/core/store.ts +107 -0
- package/src/server/index.ts +46 -0
package/README.md
CHANGED
|
@@ -398,6 +398,11 @@ This isn't just about remembering facts. It's about preserving:
|
|
|
398
398
|
|
|
399
399
|
## Changelog
|
|
400
400
|
|
|
401
|
+
### v0.4.15
|
|
402
|
+
- **Feature**: PATCH `/memory/:id` endpoint for updating memory metadata
|
|
403
|
+
- Supports: `importance_weight`, `exclude_from_retrieval`, `status`, `action_required`, and more
|
|
404
|
+
- Enables dashboards and tools for memory curation (promote/demote/bury)
|
|
405
|
+
|
|
401
406
|
### v0.4.14
|
|
402
407
|
- **Feature**: Action items signal (`***`) - add to end of message to retrieve all pending items
|
|
403
408
|
- **Feature**: New `getActionItems()` retrieval function with special formatting
|
package/package.json
CHANGED
package/src/core/engine.ts
CHANGED
|
@@ -404,6 +404,42 @@ export class MemoryEngine {
|
|
|
404
404
|
return [...projectMemories, ...globalMemories]
|
|
405
405
|
}
|
|
406
406
|
|
|
407
|
+
/**
|
|
408
|
+
* Update a memory's metadata
|
|
409
|
+
* Used for curation actions: promote/demote, bury, archive
|
|
410
|
+
*/
|
|
411
|
+
async updateMemory(
|
|
412
|
+
projectId: string,
|
|
413
|
+
memoryId: string,
|
|
414
|
+
updates: {
|
|
415
|
+
importance_weight?: number
|
|
416
|
+
confidence_score?: number
|
|
417
|
+
exclude_from_retrieval?: boolean
|
|
418
|
+
status?: 'active' | 'pending' | 'superseded' | 'deprecated' | 'archived'
|
|
419
|
+
action_required?: boolean
|
|
420
|
+
awaiting_implementation?: boolean
|
|
421
|
+
awaiting_decision?: boolean
|
|
422
|
+
semantic_tags?: string[]
|
|
423
|
+
trigger_phrases?: string[]
|
|
424
|
+
},
|
|
425
|
+
projectPath?: string
|
|
426
|
+
): Promise<{ success: boolean; updated_fields: string[] }> {
|
|
427
|
+
const store = await this._getStore(projectId, projectPath)
|
|
428
|
+
return store.updateMemory(projectId, memoryId, updates)
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Get a single memory by ID
|
|
433
|
+
*/
|
|
434
|
+
async getMemory(
|
|
435
|
+
projectId: string,
|
|
436
|
+
memoryId: string,
|
|
437
|
+
projectPath?: string
|
|
438
|
+
): Promise<StoredMemory | null> {
|
|
439
|
+
const store = await this._getStore(projectId, projectPath)
|
|
440
|
+
return store.getMemory(projectId, memoryId)
|
|
441
|
+
}
|
|
442
|
+
|
|
407
443
|
// ================================================================
|
|
408
444
|
// FORMATTING
|
|
409
445
|
// ================================================================
|
package/src/core/store.ts
CHANGED
|
@@ -534,6 +534,113 @@ export class MemoryStore {
|
|
|
534
534
|
return id
|
|
535
535
|
}
|
|
536
536
|
|
|
537
|
+
/**
|
|
538
|
+
* Update a memory's metadata fields
|
|
539
|
+
* Used for curation actions: promote/demote importance, bury, archive
|
|
540
|
+
*/
|
|
541
|
+
async updateMemory(
|
|
542
|
+
projectId: string,
|
|
543
|
+
memoryId: string,
|
|
544
|
+
updates: {
|
|
545
|
+
importance_weight?: number
|
|
546
|
+
confidence_score?: number
|
|
547
|
+
exclude_from_retrieval?: boolean
|
|
548
|
+
status?: 'active' | 'pending' | 'superseded' | 'deprecated' | 'archived'
|
|
549
|
+
action_required?: boolean
|
|
550
|
+
awaiting_implementation?: boolean
|
|
551
|
+
awaiting_decision?: boolean
|
|
552
|
+
semantic_tags?: string[]
|
|
553
|
+
trigger_phrases?: string[]
|
|
554
|
+
}
|
|
555
|
+
): Promise<{ success: boolean; updated_fields: string[] }> {
|
|
556
|
+
const { memories } = await this.getProject(projectId)
|
|
557
|
+
|
|
558
|
+
// Check memory exists
|
|
559
|
+
const existing = memories.get(memoryId)
|
|
560
|
+
if (!existing) {
|
|
561
|
+
return { success: false, updated_fields: [] }
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// Build update object with only provided fields
|
|
565
|
+
const updateData: Record<string, any> = {}
|
|
566
|
+
const updatedFields: string[] = []
|
|
567
|
+
|
|
568
|
+
if (updates.importance_weight !== undefined) {
|
|
569
|
+
updateData.importance_weight = Math.max(0, Math.min(1, updates.importance_weight))
|
|
570
|
+
updatedFields.push('importance_weight')
|
|
571
|
+
}
|
|
572
|
+
if (updates.confidence_score !== undefined) {
|
|
573
|
+
updateData.confidence_score = Math.max(0, Math.min(1, updates.confidence_score))
|
|
574
|
+
updatedFields.push('confidence_score')
|
|
575
|
+
}
|
|
576
|
+
if (updates.exclude_from_retrieval !== undefined) {
|
|
577
|
+
updateData.exclude_from_retrieval = updates.exclude_from_retrieval
|
|
578
|
+
updatedFields.push('exclude_from_retrieval')
|
|
579
|
+
}
|
|
580
|
+
if (updates.status !== undefined) {
|
|
581
|
+
updateData.status = updates.status
|
|
582
|
+
updatedFields.push('status')
|
|
583
|
+
}
|
|
584
|
+
if (updates.action_required !== undefined) {
|
|
585
|
+
updateData.action_required = updates.action_required
|
|
586
|
+
updatedFields.push('action_required')
|
|
587
|
+
}
|
|
588
|
+
if (updates.awaiting_implementation !== undefined) {
|
|
589
|
+
updateData.awaiting_implementation = updates.awaiting_implementation
|
|
590
|
+
updatedFields.push('awaiting_implementation')
|
|
591
|
+
}
|
|
592
|
+
if (updates.awaiting_decision !== undefined) {
|
|
593
|
+
updateData.awaiting_decision = updates.awaiting_decision
|
|
594
|
+
updatedFields.push('awaiting_decision')
|
|
595
|
+
}
|
|
596
|
+
if (updates.semantic_tags !== undefined) {
|
|
597
|
+
updateData.semantic_tags = updates.semantic_tags
|
|
598
|
+
updatedFields.push('semantic_tags')
|
|
599
|
+
}
|
|
600
|
+
if (updates.trigger_phrases !== undefined) {
|
|
601
|
+
updateData.trigger_phrases = updates.trigger_phrases
|
|
602
|
+
updatedFields.push('trigger_phrases')
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (updatedFields.length === 0) {
|
|
606
|
+
return { success: true, updated_fields: [] }
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
// Perform update
|
|
610
|
+
memories.update(memoryId, updateData)
|
|
611
|
+
|
|
612
|
+
return { success: true, updated_fields: updatedFields }
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Get a single memory by ID
|
|
617
|
+
*/
|
|
618
|
+
async getMemory(projectId: string, memoryId: string): Promise<StoredMemory | null> {
|
|
619
|
+
const { memories } = await this.getProject(projectId)
|
|
620
|
+
const record = memories.get(memoryId)
|
|
621
|
+
if (!record) return null
|
|
622
|
+
|
|
623
|
+
return {
|
|
624
|
+
id: record.id,
|
|
625
|
+
headline: record.headline ?? '',
|
|
626
|
+
content: record.content,
|
|
627
|
+
reasoning: record.reasoning,
|
|
628
|
+
importance_weight: record.importance_weight,
|
|
629
|
+
confidence_score: record.confidence_score,
|
|
630
|
+
context_type: record.context_type as StoredMemory['context_type'],
|
|
631
|
+
status: record.status as StoredMemory['status'],
|
|
632
|
+
exclude_from_retrieval: record.exclude_from_retrieval,
|
|
633
|
+
action_required: record.action_required,
|
|
634
|
+
awaiting_implementation: record.awaiting_implementation,
|
|
635
|
+
awaiting_decision: record.awaiting_decision,
|
|
636
|
+
semantic_tags: record.semantic_tags,
|
|
637
|
+
trigger_phrases: record.trigger_phrases,
|
|
638
|
+
project_id: record.project_id,
|
|
639
|
+
created_at: record.created_at,
|
|
640
|
+
updated_at: record.updated_at,
|
|
641
|
+
} as StoredMemory
|
|
642
|
+
}
|
|
643
|
+
|
|
537
644
|
/**
|
|
538
645
|
* Get all memories for a project
|
|
539
646
|
*/
|
package/src/server/index.ts
CHANGED
|
@@ -387,6 +387,52 @@ export async function createServer(config: ServerConfig = {}) {
|
|
|
387
387
|
})
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
// PATCH memory - update metadata for curation (promote/demote/bury)
|
|
391
|
+
const patchMatch = path.match(/^\/memory\/([a-zA-Z0-9_-]+)$/)
|
|
392
|
+
if (patchMatch && req.method === 'PATCH') {
|
|
393
|
+
const memoryId = patchMatch[1]
|
|
394
|
+
const body = await req.json() as {
|
|
395
|
+
project_id: string
|
|
396
|
+
importance_weight?: number
|
|
397
|
+
confidence_score?: number
|
|
398
|
+
exclude_from_retrieval?: boolean
|
|
399
|
+
status?: 'active' | 'pending' | 'superseded' | 'deprecated' | 'archived'
|
|
400
|
+
action_required?: boolean
|
|
401
|
+
awaiting_implementation?: boolean
|
|
402
|
+
awaiting_decision?: boolean
|
|
403
|
+
semantic_tags?: string[]
|
|
404
|
+
trigger_phrases?: string[]
|
|
405
|
+
project_path?: string
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (!body.project_id) {
|
|
409
|
+
return Response.json(
|
|
410
|
+
{ success: false, error: 'project_id is required' },
|
|
411
|
+
{ status: 400, headers: corsHeaders }
|
|
412
|
+
)
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
logger.request('PATCH', `/memory/${memoryId}`, body.project_id)
|
|
416
|
+
|
|
417
|
+
const { project_id, project_path, ...updates } = body
|
|
418
|
+
const result = await engine.updateMemory(project_id, memoryId, updates, project_path)
|
|
419
|
+
|
|
420
|
+
if (!result.success) {
|
|
421
|
+
return Response.json(
|
|
422
|
+
{ success: false, error: 'Memory not found', memory_id: memoryId },
|
|
423
|
+
{ status: 404, headers: corsHeaders }
|
|
424
|
+
)
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
logger.info(`Updated memory ${memoryId}: ${result.updated_fields.join(', ')}`)
|
|
428
|
+
|
|
429
|
+
return Response.json({
|
|
430
|
+
success: true,
|
|
431
|
+
memory_id: memoryId,
|
|
432
|
+
updated_fields: result.updated_fields,
|
|
433
|
+
}, { headers: corsHeaders })
|
|
434
|
+
}
|
|
435
|
+
|
|
390
436
|
// 404
|
|
391
437
|
return Response.json(
|
|
392
438
|
{ error: 'Not found', path },
|