
A memory system can retrieve a hundred relevant facts and still make someone less prepared for a meeting. I designed this interface around a narrower question: what does the user need to see first, and what should be available only when they want to inspect the evidence?
The application prepares users for recurring client meetings. It captures rough notes after a meeting, extracts decisions and other durable facts, retains those facts with Hindsight, and recalls relevant context against the next meeting’s agenda. The user experience is the part that turns this backend loop into something usable: a short, structured brief by default, with a path to the recalled material when the user wants to verify it.
The interface follows the meeting lifecycle
The Streamlit application separates work by the moment the user is in. The dashboard shows the schedule, pending follow-ups, and recent activity. Meeting Preparation lets someone select a client and meeting, edit the agenda, and generate a brief. Post-Meeting Memory Capture provides a place to enter notes and review extracted intelligence. Memory Explorer offers a more direct way to search and inspect what Hindsight has retained.
That separation is intentional. A person preparing for a meeting has a different question from someone recording its outcomes. The first asks, “What do I need to know before I join?” The second asks, “What should the system carry forward?” Mixing those jobs would put extraction controls, raw notes, search results, and the final brief into one long screen.
SQLite supports the visible workflow: client and meeting selection, meeting status, cached briefs, and follow-up task state. Hindsight provides long-term recall across meetings. An LLM extracts structure from notes and synthesizes recalled context with the agenda. The UI does not expose that entire pipeline as a sequence of technical operations; it presents a small number of actions tied to what the user is trying to do.

Put the brief first and the memory trail behind it
The preparation screen starts with client and meeting selection. The user can edit the agenda context before asking for preparation. That matters because “prepare me for the project review” is a more useful retrieval and synthesis prompt than a generic request to summarize every interaction with a client.
After preparation, the interface makes two layers visible. First, a banner says Hindsight memory was used and reports how many items were recalled. Second, an initially collapsed expander contains the recalled context, including each item’s text, meeting context, and tags. The generated brief remains the main content of the page.
This is a deliberate information hierarchy: show the result and the amount of context behind it, then let the user open the source material. If I put every recalled memory inline before the brief, the user would have to do the retrieval system’s ranking work manually. If I hid the memory completely, the brief would feel ungrounded and hard to correct. A count and a closed inspection panel make the middle ground explicit.
The implementation makes that choice visible:
with st.expander(f"Inspect Recalled Context from Hindsight ({len(recalled_mems)} items)", expanded=False):
if recalled_mems:
for i, m in enumerate(recalled_mems, 1):
tags_html = " ".join([f"<span class='tag-pill'>{t}</span>" for t in m.tags])
st.markdown(
f"""
<div class="memory-item-card">
<div>#{i}. {m.text}</div>
<div>Context: {m.context or 'General'} | Tags: {tags_html}</div>
</div>
""",
unsafe_allow_html=True,
)
When expanded, this is not just a list of text snippets. Each recalled item carries context and tags, helping a user distinguish a deadline from a preference and see which meeting it came from. Hindsight’s recall gives the application context; the interface makes enough provenance visible to judge whether the context belongs in this meeting.
Use hierarchy to make changes hard to miss
The brief itself is not a single generated paragraph. It has an objective, a conditional “What Changed Since Last Meeting” callout, and separate sections for prior discussions, decisions, commitments, deadlines, preferences, blockers, talking points, suggested questions, and risks. Some sections only appear when there is content to show. In the main view, historical and delivery information share one column, while preferences, unresolved issues, and conversational guidance occupy another.
The order reflects how I expect someone to scan before a call. First: why are we meeting? Next: what changed? Then: what decisions, promises, dates, and problems should I carry into the conversation? A changed deadline or newly unresolved blocker should not be buried inside a generic recap. Giving change its own alert-style section makes it visually distinct from static context.
The brief schema encodes that hierarchy rather than leaving the UI to parse prose:
class MeetingBrief(BaseModel):
objective: str = ""
previous_discussions: str = ""
key_decisions: List[str] = Field(default_factory=list)
deadlines: List[str] = Field(default_factory=list)
client_preferences: List[str] = Field(default_factory=list)
unresolved_issues: List[str] = Field(default_factory=list)
what_changed_since_last_meeting: str = ""
The UI can therefore omit empty sections instead of making the user scan a template full of “none” values. The structured model also makes the brief exportable as Markdown, so the user can take the same hierarchy outside the app.
Hindsight makes the interface contextual, not crowded
Hindsight is useful here because the job is not merely finding a sentence similar to the agenda. It is carrying forward experience across interactions: what the client decided, what changed, what they prefer, and what is still unresolved. The application retains structured memory units with client, meeting, and category tags, then asks Hindsight for relevant context for the current topic.
I use Hindsight’s agent memory repository and Hindsight documentation as the basis for retain and recall. Its role in this interface is to provide persistent context for a current task. That connects to the broader idea of agent memory for persistent context: the system should bring forward useful information from prior work, rather than force the user to repeat it or search old notes unaided.
The preparation workflow passes recalled memory alongside the current agenda to the brief generator. The query is framed around background, preferences, commitments, decisions, deadlines, and requirements for the selected client and topic. This is a UX decision as much as a retrieval decision: the agenda constrains the context to the task at hand, and the brief summarizes that context in categories the user can act on.
The interface also keeps an escape hatch for users who want to inspect memory directly. Memory Explorer lets a user select a client, ask a natural-language question, and browse all memories or tabs for decisions, preferences, deadlines, and blockers. The normal prep flow does not require this deeper exploration, but it exists when the summary is insufficient or the user wants to understand what has been retained.
A concrete interaction across three meetings
Suppose an earlier meeting established an October 15 launch target and a preference for concise bullet updates. In the next conversation, the client expands the dashboard scope to include regional filtering, moves the API documentation deadline to October 25, asks for twice-weekly updates, and reports that SSO is blocked by a security review.

Before the following meeting, the user selects that meeting, confirms or edits its agenda, and chooses “Prepare Me.” The page indicates how many Hindsight memories were recalled. The user first sees the objective and a distinct change summary, then the decisions and deadlines, with preferences and blockers nearby. If the October 25 date or the SSO issue looks surprising, the user can expand recalled context and inspect the underlying memory text, tags, and meeting context. They can download the resulting brief as Markdown for use elsewhere.
The before-and-after is straightforward. Before this interface, the useful context existed as separate retained memories and meeting notes that a user would have to find and interpret. After the preparation flow, the user starts with a focused brief containing the objective, changes, decisions, deadlines, preferences, and blockers, while the underlying Hindsight memories remain one interaction away for verification.
That flow avoids two bad extremes. Showing every retained fact up front would turn preparation into memory triage. Showing only a polished answer would ask the user to trust an opaque synthesis. Instead, the brief is the default reading surface and the recalled items are one interaction away.
The Post-Meeting screen makes the other side of the loop visible. It accepts rough notes or a transcript, runs extraction into decisions, commitments, deadlines, preferences, requirements, follow-ups, and unresolved issues, and retains the structured result. This gives the user a chance to work with notes in their natural, imperfect form while the system organizes the information for later use. The UI’s job is not to make users author a perfect memory record; it is to help them capture outcomes and review the structured interpretation.
What I learned designing around long-term memory
One limitation is that a memory count is not the same thing as useful context. The interface can tell the user that Hindsight recalled several items, but the user still needs the inspection path when a detail looks surprising or needs verification. I chose not to treat the generated brief as the final source of truth; keeping the recalled items available makes the system easier to inspect and correct.
- Optimize the default view for the user’s immediate task. Meeting prep should lead with an objective and actionable context, not a dump of everything ever recalled.
- Make provenance available at the point of doubt. A collapsed source panel keeps the page focused while letting users inspect text, tags, and meeting context when needed.
- Give changing facts their own visual treatment. A moved deadline is more important to notice than another paragraph of background. Dedicated hierarchy helps users scan for what is new.
- Use structure to make empty states disappear cleanly. Typed sections let the interface show what applies without filling the page with empty categories.
- Provide both summary and exploration paths. Most users need the brief; some need to search or inspect the memory bank. Those are different interaction depths and should not compete for the same screen space.
The hard UX problem in a system with long-term memory is not how to show more recall. It is how to make the relevant context legible, inspectable, and easy to act on without making the user read the entire history. I treat Hindsight as the context source, the brief as the working view, and the memory explorer as the route back to the details. That separation keeps preparation useful while leaving the user in control of what they trust.
Top comments (0)