Conversation State, Persistence, and Turn Ordering

Conversation state may include messages, tool calls and results, attachments, summaries, and safety metadata. Persist only what is needed and define tenant/user ownership on every read and write. Concurrent turns can race: two requests may read the same history and append responses in the wrong order. Use per-conversation locking, optimistic versions, or a turn sequence number when ordering matters.

A client-provided conversation ID is not proof of access. Load the conversation through an authorization-scoped query. For long conversations, maintain a compact summary plus recent turns and retrieve older facts only when needed.

Versioned conversation update
async function appendTurn({ conversationId, userId, expectedVersion, message }) {
  return db.conversations.updateOne(
    { id: conversationId, userId, version: expectedVersion },
    {
      $push: { messages: message },
      $inc: { version: 1 }
    }
  );
}
💡 This MongoDB-style pseudocode uses ownership and a version check to prevent a stale write. Check the update result and handle version conflicts explicitly; the exact syntax depends on your data layer.
Key Takeaways
  • Persist conversations with ownership checks.
  • Handle concurrent turn ordering.
  • Use summaries and retrieval to manage long history.
Knowledge Check

Why is a conversation ID not sufficient authorization by itself?