% Required:
% \usetikzlibrary{positioning,calc,shadows}

\begin{tikzpicture}[
box/.style={
    draw,
    fill=white,
    drop shadow={shadow xshift=0.08cm, shadow yshift=-0.08cm},
    font=\small,
    align=center
},
smallmsg/.style={
    draw,
    fill=white,
    font=\small,
    align=left,
    minimum height=0.9cm,
    text width=4.2cm
},
memitem/.style={
    draw,
    fill=white,
    font=\small,
    align=left,
    minimum height=0.7cm,
    text width=3.2cm
},
opseg/.style={
    draw,
    fill=white,
    font=\small\bfseries,
    align=center,
    minimum height=1.1cm,
    minimum width=2.5cm
},
arrow/.style={
    ->,
    thick
}
]

% =======================
% Conversation container
% =======================
\node[box, minimum width=7.6cm, minimum height=6.5cm] (conv) at (0,0) {};
\node[font=\small\bfseries, rotate=90] at ($(conv.east)+(0.35,0)$) {Conversation};

\node[smallmsg, anchor=north] (usermsg) at ($(conv.north)+(0,-0.8)$) {
\textbf{User message:}\\
Plan a trip to Kyoto next week.
};

\node[smallmsg, anchor=north] (assistantmsg) at ($(usermsg.south)+(0,-0.65)$) {
\textbf{Assistant:}\\
I will check your travel preferences and past choices.
};

\node[smallmsg, anchor=north] (usedmem) at ($(assistantmsg.south)+(0,-0.95)$) {
\textbf{Used memories:}\\
$\bullet$ prefers window seat\\
$\bullet$ vegetarian meals\\
$\bullet$ budget hotel
};

% =======================
% Memory bank
% =======================
\node[box, minimum width=4.8cm, minimum height=4.1cm] (memory) at (8.2,-0.3) {};
\node[font=\small\bfseries] at ($(memory.north)+(0,-0.35)$) {Memory Bank};

\node[memitem, anchor=north] (m1) at ($(memory.north)+(0,-0.9)$) {Key 1: prefers vegetarian meals};
\node[memitem, anchor=north] (m2) at ($(m1.south)+(0,-0.15)$) {Key 2: prefers window seat};
\node[memitem, anchor=north] (m3) at ($(m2.south)+(0,-0.15)$) {Key 3: usually books budget hotels};

% =======================
% Operation box
% =======================
\node[opseg] (add) at (1.4,-5.0) {ADD};
\node[opseg, right=0cm of add] (update) {UPDATE};
\node[opseg, right=0cm of update] (delete) {DELETE};
\node[opseg, right=0cm of delete] (noop) {NOOP};

% outer frame for the operation bar
\draw[thick] 
    ($(add.north west)+(-0.08,0.08)$) rectangle
    ($(noop.south east)+(0.08,-0.08)$);

% =======================
% Arrows and labels
% =======================

% retrieval: conversation -> memory
\draw[arrow] ($(conv.east)+(0,-0.25)$) -- node[above, font=\small] {retrieve relevant memories} ($(memory.west)+(0,0.45)$);

% use retrieved memory: memory -> conversation
\draw[arrow] ($(memory.west)+(0,-0.45)$) -- node[below, font=\small] {use memories} ($(conv.east)+(0,-1.1)$);

% new / updated memory from conversation -> operations
\draw[arrow]
    ($(conv.south)+(-2.0,0)$) -- ++(0,-0.75) -- ++(0,-0.7)
    -- node[above, font=\small] {new or updated memories} ($(add.west)+(-0.65,0)$);

% operation -> memory
\draw[arrow]
    ($(update.north)+(0,0.08)$) -- ++(0,1.55)
    -- node[right, font=\small] {update} ($(memory.south)+(0,-0.05)$);

\end{tikzpicture}