22
33import { useState , useEffect , useRef } from "react"
44import { API_BASE_URL , getHeaders } from "@/lib/api"
5+ import { MemoryAIEngine , type MemoryReference as AIMemoryRef } from "@/lib/memory-ai-engine"
56
67interface ChatMessage {
78 role : "user" | "assistant"
@@ -15,6 +16,7 @@ interface MemoryReference {
1516 content : string
1617 salience : number
1718 title : string
19+ last_seen_at ?: number
1820}
1921
2022export default function ChatPage ( ) {
@@ -47,131 +49,33 @@ export default function ChatPage() {
4749 }
4850
4951 const data = await response . json ( )
50- return data . matches . map ( ( match : any ) => ( {
52+ const raw : MemoryReference [ ] = data . matches . map ( ( match : any ) => ( {
5153 id : match . id ,
5254 sector : match . primary_sector || "semantic" ,
5355 content : match . content ,
54- salience : match . salience || match . score ,
55- title : match . content . substring ( 0 , 50 ) + ( match . content . length > 50 ? "..." : "" )
56+ salience : match . salience || match . score || 0 ,
57+ title : match . content . substring ( 0 , 50 ) + ( match . content . length > 50 ? "..." : "" ) ,
58+ last_seen_at : match . last_seen_at
5659 } ) )
60+ return raw
5761 } catch ( error ) {
5862 console . error ( "Error querying memories:" , error )
5963 return [ ]
6064 }
6165 }
6266
6367 const generateResponse = async ( userQuery : string , relevantMemories : MemoryReference [ ] ) : Promise < string > => {
64- if ( relevantMemories . length === 0 ) {
65- return "I don't have any memories that directly relate to your question. Try asking about topics you've previously stored in your memory system, or add more memories to help me answer better."
66- }
67-
68- const queryLower = userQuery . toLowerCase ( )
69- const isQuestion = queryLower . includes ( '?' ) ||
70- queryLower . startsWith ( 'what' ) ||
71- queryLower . startsWith ( 'how' ) ||
72- queryLower . startsWith ( 'why' ) ||
73- queryLower . startsWith ( 'when' ) ||
74- queryLower . startsWith ( 'where' ) ||
75- queryLower . startsWith ( 'who' ) ||
76- queryLower . startsWith ( 'can' ) ||
77- queryLower . startsWith ( 'is' ) ||
78- queryLower . startsWith ( 'do' ) ||
79- queryLower . startsWith ( 'does' )
80-
81- const sectorGroups : Record < string , MemoryReference [ ] > = { }
82- relevantMemories . forEach ( mem => {
83- if ( ! sectorGroups [ mem . sector ] ) {
84- sectorGroups [ mem . sector ] = [ ]
85- }
86- sectorGroups [ mem . sector ] . push ( mem )
87- } )
88-
89- const hasSemantic = sectorGroups [ 'semantic' ] ?. length > 0
90- const hasEpisodic = sectorGroups [ 'episodic' ] ?. length > 0
91- const hasProcedural = sectorGroups [ 'procedural' ] ?. length > 0
92- const hasEmotional = sectorGroups [ 'emotional' ] ?. length > 0
93- const hasReflective = sectorGroups [ 'reflective' ] ?. length > 0
94-
95- let response = ""
96-
97- if ( isQuestion ) {
98- if ( hasSemantic ) {
99- response += "Based on what I know:\n\n"
100- const topSemantic = sectorGroups [ 'semantic' ] . slice ( 0 , 3 )
101- topSemantic . forEach ( ( mem , idx ) => {
102- response += `${ mem . content } `
103- if ( idx < topSemantic . length - 1 ) response += "\n\n"
104- } )
105- } else if ( hasEpisodic ) {
106- response += "From your past experiences:\n\n"
107- const topEpisodic = sectorGroups [ 'episodic' ] . slice ( 0 , 2 )
108- topEpisodic . forEach ( ( mem , idx ) => {
109- response += `${ mem . content } `
110- if ( idx < topEpisodic . length - 1 ) response += "\n\n"
111- } )
112- } else if ( hasProcedural ) {
113- response += "Here's what I remember about the process:\n\n"
114- const topProcedural = sectorGroups [ 'procedural' ] . slice ( 0 , 2 )
115- topProcedural . forEach ( ( mem , idx ) => {
116- response += `${ mem . content } `
117- if ( idx < topProcedural . length - 1 ) response += "\n\n"
118- } )
119- }
120-
121- if ( hasEpisodic && hasSemantic ) {
122- response += "\n\n**Related experience:**\n"
123- response += sectorGroups [ 'episodic' ] [ 0 ] . content
124- }
125-
126- if ( hasProcedural && ( hasSemantic || hasEpisodic ) ) {
127- response += "\n\n**How to apply this:**\n"
128- response += sectorGroups [ 'procedural' ] [ 0 ] . content
129- }
130-
131- if ( hasEmotional ) {
132- response += "\n\n**Emotional context:**\n"
133- response += sectorGroups [ 'emotional' ] [ 0 ] . content
134- }
135-
136- if ( hasReflective ) {
137- response += "\n\n**Insight:**\n"
138- response += sectorGroups [ 'reflective' ] [ 0 ] . content
139- }
140- } else {
141- const allMemories = relevantMemories . slice ( 0 , 5 )
142-
143- if ( hasSemantic && hasEpisodic ) {
144- response += `${ sectorGroups [ 'semantic' ] [ 0 ] . content } \n\n`
145- response += `This connects to when ${ sectorGroups [ 'episodic' ] [ 0 ] . content . toLowerCase ( ) } `
146- } else if ( hasSemantic ) {
147- response += sectorGroups [ 'semantic' ] . slice ( 0 , 2 ) . map ( m => m . content ) . join ( '\n\n' )
148- } else if ( hasEpisodic ) {
149- response += "Based on your experiences:\n\n"
150- response += sectorGroups [ 'episodic' ] . slice ( 0 , 3 ) . map ( m => m . content ) . join ( '\n\n' )
151- } else {
152- response += allMemories . map ( m => m . content ) . join ( '\n\n' )
153- }
154-
155- if ( hasProcedural && response . length < 500 ) {
156- response += "\n\n**Steps involved:**\n"
157- response += sectorGroups [ 'procedural' ] [ 0 ] . content
158- }
159-
160- if ( hasReflective && response . length < 600 ) {
161- response += "\n\n**Reflection:**\n"
162- response += sectorGroups [ 'reflective' ] [ 0 ] . content
163- }
164- }
165-
166- const avgSalience = relevantMemories . reduce ( ( sum , m ) => sum + m . salience , 0 ) / relevantMemories . length
167- const confidence = avgSalience > 0.7 ? "high" : avgSalience > 0.4 ? "moderate" : "low"
168-
169- const memoryCount = relevantMemories . length
170- const sectorCount = Object . keys ( sectorGroups ) . length
171-
172- response += `\n\n---\n*Retrieved ${ memoryCount } ${ memoryCount === 1 ? 'memory' : 'memories' } from ${ sectorCount } ${ sectorCount === 1 ? 'sector' : 'sectors' } • Confidence: ${ confidence } *`
173-
174- return response
68+ const aiMemories : AIMemoryRef [ ] = relevantMemories . map ( m => ( {
69+ id : m . id ,
70+ sector : m . sector ,
71+ content : m . content ,
72+ salience : m . salience ,
73+ title : m . title ,
74+ last_seen_at : m . last_seen_at ,
75+ score : ( m as any ) . score
76+ } ) )
77+
78+ return await MemoryAIEngine . generateResponse ( userQuery , aiMemories )
17579 }
17680
17781 const sendMessage = async ( ) => {
@@ -190,11 +94,8 @@ export default function ChatPage() {
19094 setBusy ( true )
19195
19296 try {
193- // Query memories from backend
19497 const relevantMemories = await queryMemories ( currentInput )
19598 setMemories ( relevantMemories )
196-
197- // Generate response based on memories
19899 const responseContent = await generateResponse ( currentInput , relevantMemories )
199100
200101 const assistantMessage : ChatMessage = {
@@ -219,7 +120,6 @@ export default function ChatPage() {
219120
220121 const addMemoryToBag = async ( memory : MemoryReference ) => {
221122 try {
222- // Reinforce the memory by increasing its salience
223123 await fetch ( `${ API_BASE_URL } /memory/reinforce` , {
224124 method : "POST" ,
225125 headers : getHeaders ( ) ,
0 commit comments