Persistent sessions

The simplest bot forgets you the moment you press enter. A real assistant needs to remember what you said earlier in the conversation and what you said yesterday. The cheapest way to do that is a plain text file per user.

Flashcards: Flashcards

Loading practice…

02-persistent-sessions/bot.py
python
from pathlib import Path
import json

SESSIONS_DIR = Path('sessions')
SESSIONS_DIR.mkdir(exist_ok=True)

def load_session(user_id: str) -> list[dict]:
    path = SESSIONS_DIR / f'{user_id}.jsonl'
    if not path.exists():
        return []
    return [json.loads(line) for line in path.read_text().splitlines() if line.strip()]

def save_session(user_id: str, messages: list[dict]) -> None:
    path = SESSIONS_DIR / f'{user_id}.jsonl'
    with open(path, 'w') as f:
        for msg in messages:
            f.write(json.dumps(msg) + '\n')

Sessions are just files. Load them as a list, append the new turn, save them back. No ORM, no server.

02-persistent-sessions/bot.py
python
async def handle_message(update, context):
    user_id = str(update.effective_user.id)
    user_text = update.message.text

    messages = load_session(user_id)
    messages.append({'role': 'user', 'content': user_text})

    response = client.messages.create(
        model=MODEL,
        max_tokens=1024,
        messages=messages,
    )

    reply = response.content[0].text
    messages.append({'role': 'assistant', 'content': reply})
    save_session(user_id, messages)

    await update.message.reply_text(reply)

The handler is still small. The only new idea is that history is loaded, extended, and saved on every turn.

Files are enough until they are not. A JSONL per user is crash-safe, trivial to back up, trivial to inspect, and easy to swap for a database later. Most personal assistants never need more than this. Start simple, upgrade when the pressure is real.

Quiz: Quiz

Loading practice…