One durable fact an agent has recorded about the person it works for. Agents are otherwise amnesiac between conversations: an administrator who explains on Monday which region they look after, or that their fiscal year starts in April, explains it again on Tuesday. A memory is that explanation kept - a short, self-contained statement the agent puts in front of itself at the start of every later conversation. Scoped to the triple (tenant, owner, agent definition), which is exactly an Agent's identity, so a fact recorded by the administrator's copilot is not visible to some other agent the same person also runs. It is deliberately not scoped to the Agent row itself: an Agent is created on demand, and a memory should outlive one being deleted and recreated. Nor is it scoped to a conversation - a fact that only holds within one conversation is not a memory, it is context, and the conversation already carries that. The key is what makes a memory correctable rather than merely accumulable. Recording against a key that already exists replaces it, so an agent told "actually it is the Northern region now" ends up with one fact rather than two contradictory ones. Nothing here decides what is worth remembering; that judgement belongs to the agent, and the count ceiling belongs to whatever writes. SCOPE. A memory is either about the person (SCOPE_USER) or about the account (SCOPE_ACCOUNT) - "this account runs a channel loyalty program to defend market share" is true of the tenant, not of whoever happened to say it, and every administrator should have it. The two are the same shape and deliberately the same table, but they differ in blast radius, and that is what the proposal states exist for: a wrong fact about one person misleads that person, who can notice and correct it, whereas a wrong fact about the account silently shapes every administrator's answers and nobody knows it is there. So an account fact is written as SCOPE_ACCOUNT_PROPOSED, where it behaves exactly like a user memory - visible only to the person who stated it - until an administrator confirms it. Confirmation, not writing, is what gives a fact reach. Owner stays set on every row, including confirmed account facts: it records who stated it, which is the provenance that makes an account fact reviewable at all. Scope decides who it applies to; owner records where it came from. Account facts are scoped per agent definition, like user memories. A definition is a context - what is a useful standing fact for the administrators' copilot may be misleading to an agent doing something else entirely - and sharing them across definitions trades a small saving in re-stating for a large class of confusions.

Group: Database Entities

Implements: Serializable, Relational


Properties

PropertyReturnsDescription
adminOrgOrganisationThe tenant this memory belongs to. Never null for a persisted memory.
agentDefNameStringThe name of the AgentDef whose agent recorded this, eg KademiCopilot.xml. Named rather than referenced for the same reason Agent names its definition: definitions come from apps and have no row to point at.
confirmedAccountFactboolean
confirmedByProfileThe administrator who confirmed or rejected this account fact. Null while it is still proposed, and on user memories, which nobody reviews.
confirmedDateDateWhen this account fact was confirmed or rejected.
contentStringThe fact itself, in the agent's own words. Bounded at 2000 characters because a memory is read into every later conversation this owner has with the agent, so it is a standing cost rather than a one-off one.
createdDateDateWhen this fact was first recorded.
idlongDatabase identifier for this memory, assigned when it is first saved.
memoryKeyStringA short, stable identifier for what this fact is about, such as reporting-region. Recording again under the same key replaces the fact rather than adding a second one, which is what lets an agent correct itself.
modifiedDateDateWhen this fact was last recorded or corrected.
ownerProfileThe person the fact is about, which is the owner of the agent that recorded it. Never null for a persisted memory.
scopeStringWho this fact reaches: SCOPE_USER for the owner alone, SCOPE_ACCOUNT for every administrator using this agent definition, with SCOPE_ACCOUNT_PROPOSED and SCOPE_ACCOUNT_REJECTED the states in between. Nullable because rows written before scopes existed have none, and hbm2ddl only adds columns - it never fills them. A null reads as SCOPE_USER, which is what those rows were.

Methods

getId() · getAdminOrg() · getOwner() · getAgentDefName() · getMemoryKey() · getContent() · getCreatedDate() · getModifiedDate() · getScope() · effectiveScope() · isConfirmedAccountFact() · getConfirmedBy() · getConfirmedDate() · rowId()

getId()

Returns: long

Database identifier for this memory, assigned when it is first saved.

getAdminOrg()

Returns: Organisation

The tenant this memory belongs to. Never null for a persisted memory.

getOwner()

Returns: Profile

The person the fact is about, which is the owner of the agent that recorded it. Never null for a persisted memory.

getAgentDefName()

Returns: String

The name of the AgentDef whose agent recorded this, eg KademiCopilot.xml. Named rather than referenced for the same reason Agent names its definition: definitions come from apps and have no row to point at.

getMemoryKey()

Returns: String

A short, stable identifier for what this fact is about, such as reporting-region. Recording again under the same key replaces the fact rather than adding a second one, which is what lets an agent correct itself.

getContent()

Returns: String

The fact itself, in the agent's own words. Bounded at 2000 characters because a memory is read into every later conversation this owner has with the agent, so it is a standing cost rather than a one-off one.

getCreatedDate()

Returns: Date

When this fact was first recorded.

getModifiedDate()

Returns: Date

When this fact was last recorded or corrected.

getScope()

Returns: String

Who this fact reaches: SCOPE_USER for the owner alone, SCOPE_ACCOUNT for every administrator using this agent definition, with SCOPE_ACCOUNT_PROPOSED and SCOPE_ACCOUNT_REJECTED the states in between. Nullable because rows written before scopes existed have none, and hbm2ddl only adds columns - it never fills them. A null reads as SCOPE_USER, which is what those rows were.

effectiveScope()

Returns: String

The scope this row actually has, with a null read as SCOPE_USER. Prefer this to getScope wherever a decision is being made, so a pre-scopes row cannot fall through a switch.

isConfirmedAccountFact()

Returns: boolean

getConfirmedBy()

Returns: Profile

The administrator who confirmed or rejected this account fact. Null while it is still proposed, and on user memories, which nobody reviews.

getConfirmedDate()

Returns: Date

When this account fact was confirmed or rejected.

rowId()

Returns: Long

The database identifier for this memory, as the generic row id used across Kademi entities. Same value as the id.

To get full access to the Kademi Hub existing customers can login here, or new customers can register here.