chatbot1-4 Exercise 1: Memory That Survives a Restart ======================================================= ex1.py (save in the project root): import asyncio, os, tempfile from bot.core import Bot from bot.providers import FakeProvider from bot.store import Store async def main(): path = os.path.join(tempfile.mkdtemp(), "bot.db") fake1 = FakeProvider() bot1 = Bot(fake1, store=Store(path)) await bot1.handle("s", "My name is Ada") await bot1.handle("s", "I live in Edinburgh") bot1.store.close() print("before the restart, messages sent per call:", [len(c) for c in fake1.calls]) # "restart": new Store object on the same file, new Bot, new provider fake2 = FakeProvider() bot2 = Bot(fake2, store=Store(path)) await bot2.handle("s", "Where do I live?") print("after the restart, the first call was sent", len(fake2.calls[0]), "messages:") for m in fake2.calls[0]: print(" ", m["role"], "-", m["content"][:50]) asyncio.run(main()) Run with: py ex1.py Output: before the restart, messages sent per call: [1, 3] after the restart, the first call was sent 5 messages: user - My name is Ada assistant - (fake) I was sent 1 message(s); the last was: 'My user - I live in Edinburgh assistant - (fake) I was sent 3 message(s); the last was: 'I l user - Where do I live? Answer: five messages, in order: the two earlier exchanges (four messages, including the fake's own earlier replies) and the new question. WHY THIS WORKS AS AN ANSWER --------------------------- The first Bot wrote each exchange to the SQLite file as soon as its provider had answered. Closing the store and opening a new Store on the same file gives the new Bot the same rows, so its first call is sent the earlier conversation plus the new question: 4 + 1 = 5 messages, where a bot with only an in-memory dictionary (chapter 1) would have sent 1. The new provider is a different object that has never seen the conversation, which is the point: the memory lives in the database, not in the provider and not in the process.