-- Agent conversations (#56): multi-turn chat with the garden assistant. -- -- "Now do the same to the north bed" needs the previous exchange, and history -- held only by the client would be lost on a refresh — which is exactly when -- someone reloads to see whether the agent's change actually landed. -- -- One conversation per (user, garden). Two people editing a shared garden get -- separate threads: a conversation is a dialogue with one person, and merging -- them would put words in someone's mouth. CREATE TABLE agent_conversations ( id INTEGER PRIMARY KEY, garden_id INTEGER NOT NULL REFERENCES gardens (id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users (id) ON DELETE CASCADE, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')), UNIQUE (garden_id, user_id) ); -- Only the user/assistant TEXT of each turn is kept, not the full model -- transcript with its tool calls. Continuity needs what was said and what came -- back; replaying a stored tool call would be replaying a decision made against -- a garden that has since moved on. It also keeps the schema free of majordomo's -- message shape, which is a dependency's business, not the database's. CREATE TABLE agent_messages ( conversation_id INTEGER NOT NULL REFERENCES agent_conversations (id) ON DELETE CASCADE, id INTEGER PRIMARY KEY, role TEXT NOT NULL CHECK (role IN ('user', 'assistant')), body TEXT NOT NULL, -- The change set this turn produced, so the panel can offer Undo on the -- message that caused it. SET NULL rather than CASCADE: losing the history -- entry must not delete what was said about it. change_set_id INTEGER REFERENCES change_sets (id) ON DELETE SET NULL, created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')) ); CREATE INDEX idx_agent_messages_conversation ON agent_messages (conversation_id, id);