shared by marriageAI & outreachAI

What the AI remembers

A WhatsApp conversation has no memory of its own, and the agent can only read the last 30 messages. Everything older is gone. Agent Memory is the one place a customer's durable facts survive โ€” rewritten after every reply, read back before every answer. LIVE rebuilt 7 Aug 2026

โœ…
One rule decides everything on this page. Memory stores only what a customer said that no database table already holds. Their name, age, city, payment status and profile progress are already handed to the agent from source on every single message โ€” copying those into a note doesn't help it remember, it just creates a second, unverified version of the truth.

The whole pipeline, end to end

flowchart TD
    IN["๐Ÿ“ฑ Customer sends a message"] --> CTX["Agent gathers context
โ€” 12 sources at once โ€”"] CTX --> SRC1[("๐Ÿ“‡ Profile + account
name, age, city, payment,
onboarding step")] CTX --> SRC2[("๐Ÿ’ฌ Last 30 messages")] CTX --> MEM[("๐Ÿง  Memory note
THIS PAGE")] SRC1 --> PROMPT["Everything is assembled
into the agent's prompt"] SRC2 --> PROMPT MEM --> PROMPT PROMPT --> WHICH{"Which brain answers?"} WHICH -->|"complex / onboarding"| SEES["โœ… Sees the memory note"] WHICH -->|"greeting or quick FAQ"| BLIND["โŒ Memory loaded but not used"] SEES --> DRAFT["โœ๏ธ Reply written"] BLIND --> DRAFT DRAFT --> SENT["๐Ÿ“ค Sent to the customer"] SENT --> BG["๐Ÿ”„ In the background, after sending"] BG --> WRITER["The writer re-reads:
the CURRENT note +
last 10 messages + the reply"] WRITER --> NEWNOTE["Returns the COMPLETE
updated note"] NEWNOTE --> GATE{"3 automatic checks"} GATE -->|"passes"| SAVE["๐Ÿ’พ Saved โ€” replaces the old note
(old text kept as a backup)"] GATE -->|"fails"| KEEP["๐Ÿ›ก๏ธ Rejected โ€”
the old note stands, untouched"] SAVE -.->|"read again next message"| MEM KEEP -.-> MEM classDef hi fill:#e7f2ec,stroke:#166b4e,color:#182420 classDef bad fill:#fdeaea,stroke:#a33,color:#3a1f1f class MEM,SEES,SAVE,WRITER hi class BLIND,KEEP bad

The complete loop. Memory is one of 12 context sources going in, and is rewritten in the background after the reply goes out โ€” never before, so it can never delay or break an answer.

1 ยท What goes in, and what is banned

Kept โ€” no table owns theseBanned โ€” already in the database
"Also looking for a rishta for his sister in Karachi, needs a separate registration"

"Says he will decide after Eid"

"His wife's family decides; he only relays"

"Used the service last year on a different number"

"Will not consider anyone outside Lahore"
Name, age, city, gender, profession

Biradri, marital status, partner preferences

Profile completeness or step

Payment, fees, subscription, membership

Proposal counts, funnel stage, engagement tier

Money is banned in code, not merely discouraged in an instruction โ€” and that is deliberate. A note once claimed "Payment (PKR 5,000) received" while the payment records for that number were empty, handing the agent two contradictory versions of the truth. A note that is not permitted to hold an opinion about money cannot contradict the ledger.

2 ยท How a note gets written

After every reply is sent โ€” never before โ€” a background step runs. It is handed three things and asked for one:

flowchart LR
    A["๐Ÿ“ The note as it
stands right now"] --> M{{"The AI"}} B["๐Ÿ’ฌ Last 10 messages
of the conversation"] --> M C["โœ๏ธ The reply just sent"] --> M M --> OUT["Returns the COMPLETE
updated note"] OUT --> V1{"Under 2500
characters?"} V1 -->|"no"| REJ["๐Ÿ›ก๏ธ REJECTED
previous note kept unchanged
logged, never shown to the customer"] V1 -->|"yes"| V2{"Mentions money,
fees, payment?"} V2 -->|"yes"| REJ V2 -->|"no"| V3["Collapse to a single line"] V3 --> OK["๐Ÿ’พ Saved
previous text kept as a backup"] classDef hi fill:#e7f2ec,stroke:#166b4e,color:#182420 classDef bad fill:#fdeaea,stroke:#a33,color:#3a1f1f class OUT,OK hi class REJ bad

The AI decides the wording; the system only checks the result. It never edits the note itself โ€” it either accepts what came back or keeps what was already there.

The instruction it works under: keep every existing fact unless the customer has contradicted it; add anything newly said that is in scope; return the note unchanged if nothing worth keeping was said โ€” which is the normal outcome; and you have 2500 characters, so you are not short of room.

That last clause matters more than it looks. The previous version of this system was told to fit everything into "five short lines", and after a few hundred rewrites on a long conversation it had quietly squeezed out a preference recorded months earlier. Giving it room is what stops that.

It now runs from the very first message. It used to wait until a conversation reached 25 messages โ€” but the writer only ever sees the last 10, so anything said in the opening exchanges would never have reached it at all. Starting immediately closes that blind spot.

3 ยท How the note reaches the agent

flowchart TD
    STORE[("๐Ÿง  One note per customer")]

    STORE --> R1["marriageAI
the conversation agent"] STORE --> R2["outreachAI
the proactive agent"] STORE --> R3["Staff Dashboard
conversation panel"] R1 --> D1["Loaded on EVERY message,
alongside 11 other sources"] D1 --> D2{"Which brain?"} D2 -->|"complex / onboarding"| D3["Written into the prompt as
'Agent's Notes About This User'
with how old the note is"] D2 -->|"greeting / quick FAQ"| D4["Not used โ€” those replies
don't need it"] D3 --> D5["Phone numbers, emails and links
stripped out first"] R2 --> E1["Read when deciding whether
to message someone proactively"] E1 --> E2["Same stripping applied"] R3 --> F1["Agent Inbox: VIEW only
Config page: edit + delete"] F1 --> F2["Gated by agent_memory.manage
โ€” grantable per person, enforced
by the server not the UI"] classDef hi fill:#e7f2ec,stroke:#166b4e,color:#182420 class D3,D5,E2,F1,F2 hi

Three readers, one store. Everything reaching a model is stripped of phone numbers, emails and links first.

4 ยท Who can see it, and where

Until this rebuild, nothing could correct a memory. Both writers were machines, the Dashboard could show notes but not change them, and a wrong fact would persist because each rewrite carried the previous note forward. The only remedy was an engineer editing the database by hand.

WhereWhat you can doWho
Agent Inbox
conversation view
View only. Read the note and how old it is. No editing here โ€” deliberately. Anyone granted agent_memory.manage. Admins and above hold it by default; it can be given to or taken from any individual, exactly like the Question Bank and Corrections permissions.
marriageAI Config
conversation panel
Edit and delete, with a confirmation step, because it is customer data. Requires the broader "edit user records" permission.

Splitting those two apart was the point. Viewing used to require the same permission as editing customer records, so letting an agent read a note meant also letting them rewrite the customer's details. Worse, the older read path had no permission check at all. Now a read is its own grantable key and the server enforces it โ€” a caller without it gets a refusal, not a hidden button.

Safeguards on an edit. A save carries the version the operator started from, so if the agent rewrote the note while they were typing, the save is refused rather than silently overwriting it. There is also a master switch and a length setting, so the whole feature can be turned off without a code change.

And deleting a customer now deletes their memory. Previously it did not, and six records already belonged to numbers with no account.

The limits, stated plainly

๐Ÿ“‹
Rebuilt 7 August 2026. The old version copied profile and payment details the agent already had, and lost genuine facts over long conversations. It was replaced: one writer instead of two, a strict rule about what may be stored, checks in code rather than requests in a prompt, staff correction, deletion on account close, and a starting point of the first message rather than the twenty-fifth. The 13 old records were deleted rather than carried over โ€” they were mostly duplicated profile data, and six belonged to accounts that no longer exist.