Interface: UserMemoryStore
Defined in: internal/user-memory-store/UserMemoryStore.ts:101
UserMemoryStore -- what the gateway knows about a user across threads
About
The user says it once; every later thread knows it.
Implements IUserMemoryStore: durable key/value facts about a user (language, role, location), scoped by tenant
- user, kept in the host's
IUserMemoryRepository.
getFactsreads them for every call; they go into the{memory}slot of the system prompt.extracthas the cheap model read the newest turns of a thread and answer with operations (SET,DELETE) that are merged into the stored facts;isExtractDuesays when (after the first answer of a thread, then whenever the thread crosses a multiple ofextractEveryTurns).upsertFact,removeFact,clearare the user's own edits; the model reaches the first two through the built-in tools ofmakeUserMemoryTools.deleteByUseris the GDPR erasure: the record goes, not only the facts.
The caps hold on every write: at most maxFacts facts (the ones updated longest ago are dropped), at most
maxFactChars per key and value (a fact set by hand over it is a 400, an extracted one is cut).
It sits next to the WorkingMemory (per thread) as the memory that spans threads.
Who needs it
prepareCall and AIGateway.getUserFacts read; updateMemory runs isExtractDue and extract in the background
after every answer; AIGateway.upsertUserFact, removeUserFact, clearUserFacts and the two built-in tools edit;
forgetUser calls deleteByUser. A host replaces it with its own IUserMemoryStore in overrides.userMemoryStore.
What needs
config.repository for the facts, llmClient and promptTemplateStore (the MEMORY_USER template) for extract.
Usage
When to use it
Always, through the gateway: createGatewayDeps creates it from IAIGatewayConfig.userMemoryStore.
When shouldn't use it
A host with its own user profile store implements IUserMemoryStore over it and passes it in overrides.
Pitfalls
enabled: false switches the extraction off only: the stored facts are still read into every prompt and still
editable. Every fact enters every prompt of the user: keep the caps low, and never store what the user did not state.
Implements
Methods
clear()
clear(
__namedParameters):Promise<void>
Defined in: internal/user-memory-store/UserMemoryStore.ts:455
clear -- the user forgets every fact
About
"Forget everything about me", by the user, for the user.
Saves an empty list: the facts go, the user's record stays. The erasure that removes the record is deleteByUser.
Who needs it
AIGateway.clearUserFacts, for a "forget all" action of the UI.
Parameters
__namedParameters
tenantId
string
userId
string
Returns
Promise<void>
Implementation of
IUserMemoryStore.clear
deleteByUser()
deleteByUser(
__namedParameters):Promise<number>
Defined in: internal/user-memory-store/UserMemoryStore.ts:485
deleteByUser -- the GDPR erasure of a user's facts
About
Nothing is left, not even an empty record.
Removes the facts of the user and their record through the repository and returns the number of facts removed.
clear is the user's own "forget my facts"; this is the operator's erasure.
Who needs it
forgetUser, behind AIGateway.deleteUserData and AIGateway.anonymizeUserData.
Parameters
__namedParameters
tenantId
string
userId
string
Returns
Promise<number>
Implementation of
IUserMemoryStore.deleteByUser
extract()
extract(
__namedParameters):Promise<IUserMemoryFact[]>
Defined in: internal/user-memory-store/UserMemoryStore.ts:161
extract -- learns durable facts from the newest turns of a thread
About
The cheap model reads the turns and says what to remember and what to forget.
Renders the MEMORY_USER template with the known facts, sends turns as a plain transcript (toTranscript) to the
cheap model and merges its operations into the stored facts: SET adds or replaces the key (a fact repeated
unchanged keeps its date and its source), DELETE removes it. The result is saved under the caps and returned.
The stored facts stay as they are, and are returned, when the extraction is switched off, when there is no turn, when the model call fails (a refusal of the usage adapter is silent, anything else is reported, error 5372598726156) or when the answer is not the expected structure (error 5372598726369).
Who needs it
updateMemory, in the background after an answer, when isExtractDue says so; it passes the turns since the last
extraction.
Pitfalls
A model failure never throws; a failing repository does, the caller's background queue catches it. The facts of a
run with many tool turns cost one cheap call per extractEveryTurns turns, not per answer.
Parameters
__namedParameters
cheapModelId
string
meta
For the usage adapter and the trace; kind = MEMORY_USER.
tenantId
string
threadId
string
The thread the turns belong to; recorded as the source of the facts.
turns
ITurn[]
userId
string
Returns
Promise<IUserMemoryFact[]>
Implementation of
IUserMemoryStore.extract
getFacts()
getFacts(
__namedParameters):Promise<IUserMemoryFact[]>
Defined in: internal/user-memory-store/UserMemoryStore.ts:121
getFacts -- the stored facts of one user
About
What every prompt of this user starts with.
Reads the facts from the repository, as last saved; [] for a user without a record. No model call, no write.
Who needs it
prepareCall, once per call, for the {memory} slot; AIGateway.getUserFacts, for a "what do you know about me" UI.
Parameters
__namedParameters
tenantId
string
userId
string
Returns
Promise<IUserMemoryFact[]>
Implementation of
IUserMemoryStore.getFacts
isExtractDue()
isExtractDue(
__namedParameters):boolean
Defined in: internal/user-memory-store/UserMemoryStore.ts:301
isExtractDue -- whether the thread earned an extraction with its last call
About
Early once, then on a fixed beat.
Due after the first answer of a thread (previousTurnCount 0, turnCount above it: the opening message carries
most facts, name, place, language), and then whenever the thread crossed a multiple of extractEveryTurns with its
last call. Never due while the extraction is switched off. Pure: no read, no write.
Who needs it
updateMemory, after every answer, before it calls extract.
Pitfalls
previousTurnCount is the count before the whole call, not before its last step: a run adds several turns at once
and may jump over a multiple.
Parameters
__namedParameters
previousTurnCount
number
Turns of the thread before the call that just ended; a call adds several turns at once.
turnCount
number
Turns of the thread now.
Returns
boolean
Implementation of
IUserMemoryStore.isExtractDue
removeFact()
removeFact(
__namedParameters):Promise<void>
Defined in: internal/user-memory-store/UserMemoryStore.ts:418
removeFact -- the user forgets one fact
About
"Forget my language."
Removes the fact with key; a key that is not there changes nothing and writes nothing.
Who needs it
AIGateway.removeUserFact, and the dyna_aigw_forget_user_fact tool of makeUserMemoryTools.
Parameters
__namedParameters
key
string
tenantId
string
userId
string
Returns
Promise<void>
Implementation of
IUserMemoryStore.removeFact
upsertFact()
upsertFact(
__namedParameters):Promise<void>
Defined in: internal/user-memory-store/UserMemoryStore.ts:349
upsertFact -- the user or an admin sets one fact by hand
About
"Remember that I …", stored at once.
Trims the key and the value and stores the fact with no source thread and updatedAt now; the same key replaces the
stored fact. Throws a 400 for an empty key or value (error 5372597957094) or one over maxFactChars (error
5377210486159, with a userMessage).
Who needs it
AIGateway.upsertUserFact, and the dyna_aigw_remember_user_fact tool of makeUserMemoryTools (after the user's approval,
D116).
Pitfalls
Over maxFacts, the write drops the fact updated longest ago, never the new one.
Parameters
__namedParameters
key
string
tenantId
string
userId
string
value
string
Returns
Promise<void>
Implementation of
IUserMemoryStore.upsertFact