Memory, profile and context: what the bot rests on
The basis of this bot isn’t one prompt but its own memory in SQLite.
Here’s one of the basic fragments:
c.execute("""
CREATE TABLE IF NOT EXISTS ann_messages(
id INTEGER PRIMARY KEY AUTOINCREMENT,
chat_id INTEGER, msg_id INTEGER,
user_id INTEGER, date TEXT, text TEXT,
reply_to_msg_id INTEGER, entities_json TEXT
)
""")
— CREATE TABLE IF NOT EXISTS ann_messages Creates the ann_messages table if it doesn’t exist yet. This is where the bot stores the dialogue history.
— id INTEGER PRIMARY KEY AUTOINCREMENT The internal sequence number of a row. The database itself needs it so that each record has a unique ID.
— chat_id INTEGER The ID of the chat the message came from. This is needed so messages from different chats don’t mix.
— msg_id INTEGER The ID of the message itself in Telegram. It tells you exactly which message is meant.
— user_id INTEGER The ID of the user who sent the message. So the bot remembers not only the text but also the author.
— date TEXT The date and time of the message. Needed for chronology: who said what and when.
— text TEXT The message text itself.
— reply_to_msg_id INTEGER If the message was a reply to another message, the ID of that original message is stored here. This is no longer just memory of text but memory of the structure of a conversation.
— entities_json TEXT Telegram service data: mentions, links, formatting and other entities. So the bot can, if needed, remember not only the text but also its form.
Now the moment a message is written to the database:
def ann_touch_message(user_id: int, chat_id: int, msg_id: int|None, text: str|None, dt_iso: str|None,
reply_to_msg_id: int|None, entities_json: str|None):
c.execute("""
INSERT INTO ann_messages(chat_id, msg_id, user_id, date, text, reply_to_msg_id, entities_json)
VALUES(?,?,?,?,?,?,?)
""", (int(chat_id), int(msg_id or 0), int(user_id), dt_iso or _utc_now_iso(), (text or "").strip(), reply_to_msg_id, entities_json))
— def ann_touch_message(…) The function that saves a new message into the bot’s memory.
— INSERT INTO ann_messages(…) The command inserts a new row into the ann_messages table.
— VALUES(?,?,?,?,?,?,?) The real values go here: chat, message, user, date, text, reply and entities.
— int(chat_id) Converts chat_id to a number. This is protection against wrong types.
— int(msg_id or 0) If there’s no msg_id, 0 is used. So the function can still save the record.
— dt_iso or _utc_now_iso() If no date is passed, the current time is taken.
— (text or “”).strip() If there’s no text, an empty string is used. strip() removes extra spaces at the edges.
This is exactly where the bot stops being an ordinary chatbot. It doesn’t just answer the last message, it stacks the conversation into its own memory: who wrote, when they wrote, what they wrote and what they were replying to.
Profile and context are then built on top of this memory. But the foundation starts right here.