Trace how your organization's decisions were made. Ask one question and reconstruct the full decision journey across Slack, Gmail, meetings, and final documentation.
Memora is an organizational memory and decision intelligence platform that combines real-time communication data with structured documentation to answer "Why did we decide this?" questions.
Instead of scrolling through months of Slack threads and email chains, Memora:
- Ingests Slack conversations, Gmail threads, meeting notes, and final decisions
- Embeds everything into a semantic vector database (ChromaDB)
- Retrieves relevant evidence using semantic search
- Ranks sources by organizational weight (Final Document > Meeting > Email > Slack)
- Reasons with Gemini AI to synthesize a grounded explanation
- Traces back to the original sources with full provenance
- ๐ Lost institutional knowledge โ "Why did we choose FastAPI?"
- โฐ Decision archaeology โ Decisions disappear from Slack after 30 days
- ๐ค Onboarding friction โ New team members can't find decision rationale
- ๐ Audit trails โ No clear evidence of how decisions were made
- ๐งฉ Scattered context โ Decision history lives in 5+ different places
- Only fetches new messages since last sync (no full resets)
- Deduplicates automatically
- Tracks sync state in
data/sync_state.json - No wasted API calls
- Slack โ Real-time channel discussions
- Gmail โ Email thread context and formal decisions
- Meeting Notes โ Structured discussion points
- Final Documents โ Authoritative decision records
Final Document (strongest authority)
โ
Meeting Notes (consensus discussion)
โ
Gmail Threads (formal reasoning)
โ
Slack (informal context)
- Powered by Google Gemini Embedding-001 for semantic understanding
- Gemini 2.5 Flash for reasoning and synthesis
- ChromaDB for sub-millisecond vector search
- Evidence cards with source provenance
- Reasoning timeline showing how decisions evolved
- Confidence scoring based on source diversity
- Full traceability โ click any source to see original context
- Manual "Sync Now" button for on-demand updates
- Auto-sync every 60-120 seconds (configurable)
- Last sync timestamp visible in sidebar
- Real-time status feedback
- Unified view โ Single "All" tab shows combined records from all sources (Slack, Gmail, meetings, documents)
- Per-source filtering โ Switch to individual source tabs for focused browsing
- Full-text reading โ Always show complete source content in the detail pane
- Quick identification โ Count badges on tabs show results per source
- Clear selection โ Highlighted cards with visual accent bar make selection obvious
- Internal scrolling โ Clean, compact record list with smooth pagination
- Source badges โ Quick visual distinction of record origin (Slack, Gmail, Meeting, Document)
- Responsive layout โ Reader pane dominates the right side for better scanning
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Memora Application โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Frontend (Streamlit) โ
โ โโ Query Interface โ
โ โโ Evidence Cards โ
โ โโ Decision Timeline โ
โ โโ Sync Control Panel โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Ingestion Pipeline โ
โ โโ fetch_slack.py โโโโโโโบ Slack API โ
โ โโ fetch_gmail.py โโโโโโโบ Gmail API โ
โ โโ ingest.py โ
โ โโ Semantic Chunking โ
โ โโ Gemini Embeddings โ
โ โโ ChromaDB Upsert โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Vector Store (ChromaDB) โ
โ โโ slack_messages โ
โ โโ gmail_messages โ
โ โโ meeting_notes (chunked) โ
โ โโ final_documents (chunked) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ โ
โ Reasoning Engine โ
โ โโ Retrieval (semantic search) โ
โ โโ Ranking (source priority) โ
โ โโ Synthesis (Gemini reasoning) โ
โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
- Python 3.8+
- Google Cloud credentials (Gmail API, Gemini API)
- Slack Bot Token
- Internet connection
git clone https://github.com/yourusername/memora.git
cd memora
pip install -r requirements.txtCreate a .env file in the root directory:
# Google APIs
GEMINI_API_KEY=your_gemini_api_key_here
GMAIL_GROUP=[email protected]
# Slack
SLACK_TOKEN=xoxb-your-slack-bot-token
SLACK_CHANNEL=all-memora-labs
# Authentication (optional but recommended)
ADMIN_EMAIL=[email protected]Place credentials.json in the root directory (from Google Cloud Console OAuth 2.0 setup):
# First run creates token.json after browser auth
python fetch_gmail.py# Fetches current Slack messages, Gmail threads, and ingests static docs
python ingest.pyThis creates:
chroma_data/โ Vector store with embeddingsdata/raw/โ Raw JSON from Slack/Gmaildata/sync_state.jsonโ Tracks last sync timestamp
streamlit run app.pyVisit http://localhost:8501 in your browser.
Step 1: Retrieval
Query: "Why did we choose FastAPI over MERN/Node?"
โ
ChromaDB semantic search returns:
โ Slack: @alice "FastAPI is async-first"
โ Meeting Notes: "Team consensus on FastAPI"
โ Gmail: "Final decision approved FastAPI"
โ Final Document: "Tech Stack: FastAPI + React"
Step 2: Ranking
Sources prioritized by weight:
1st โญโญโญ Final Document (authoritative)
2nd โญโญ Meeting Notes (consensus)
3rd โญ Gmail (formal reasoning)
4th Slack (informal context)
Step 3: Reasoning
Gemini synthesizes:
"We chose FastAPI because:
- Async performance (Slack discussion)
- Team consensus in meeting
- Formally approved in final document
- Confidence: High"
Step 4: Traceability
User clicks "Final Document" โ
Reads full context immediately
User clicks "Meeting Notes" โ
Sees exact discussion points
User clicks "Gmail" โ
Reads formal approval email
memora/
โโโ app.py # Main Streamlit application
โโโ ingest.py # Incremental ingestion pipeline
โโโ fetch_slack.py # Slack API integration
โโโ fetch_gmail.py # Gmail API integration
โโโ requirements.txt # Python dependencies
โโโ credentials.json # Google OAuth (โ ๏ธ gitignore)
โโโ token.json # Gmail token (โ ๏ธ gitignore)
โ
โโโ data/
โ โโโ raw/
โ โ โโโ slack_messages.json
โ โ โโโ slack_users.json
โ โ โโโ gmail_messages.json
โ โ โโโ gmail_threads.json
โ โ โโโ meeting_notes.txt
โ โ โโโ final_document.txt
โ โโโ sync_state.json # Tracks last sync timestamps
โ โโโ config.json
โ
โโโ chroma_data/ # Vector store (persistent)
โ โโโ [auto-created]
โ
โโโ pages/
โ โโโ 1_Login.py # Authentication page
โ โโโ 2_My_Organization.py # Org settings page
โ โโโ source_explorer.py # Browse sources
โ
โโโ utils/
โ โโโ auth.py # Session management
โ
โโโ README.md
In the Streamlit sidebar, select sync frequency:
- 60 sec โ Check for new messages very frequently
- 90 sec โ Balanced (default)
- 120 sec โ Less frequent network calls
Place these in data/raw/ for one-time ingestion:
meeting_notes.txtโ Structured meeting minutesfinal_document.txtโ Decision records
Set in .env:
SLACK_CHANNEL=important-decisionsSet in .env:
GMAIL_GROUP=[email protected]Before (โ Full Reset)
# Old approach: wasteful
reset_chroma() # Delete everything
fetch_all_slack()
fetch_all_gmail()
re-embed everythingAfter (โ Incremental)
# New approach: efficient
last_ts = load_sync_state()["slack"]["last_ts"]
new_messages = fetch_slack(oldest=last_ts)
upsert(new_messages) # Only add new docs
save_sync_state(last_ts)Benefits:
- โก 10-100x faster (only new items)
- ๐ฐ Fewer API calls
- ๐ No downtime for ingestion
- ๐ Full history preserved
Why ChromaDB?
- โ Persistent local storage
- โ Semantic search (cosine similarity)
- โ Metadata filtering
- โ No external dependencies (SQLite)
Schema:
{
"id": "slack_1712742600.123456",
"document": "Complete message text...",
"metadata": {
"source": "slack",
"channel": "general",
"user": "U123456",
"user_name": "Alice",
"ts": "1712742600.123456"
}
}Embeddings:
- Model:
gemini-embedding-001 - Dimension: 768
- Update: Only on new documents (incremental)
Ranking Function:
def source_priority(source: str) -> int:
return {
"final_document": 1, # Strongest
"meeting": 2,
"gmail": 3,
"slack": 4, # Weakest
}.get(source, 99)Ingest static files manually:
from ingest import run_incremental_ingestion
result = run_incremental_ingestion(include_static_docs=True)
# Returns: {"new_slack": 5, "new_gmail": 3, "meeting_chunks": 12, ...}from chromadb import PersistentClient
client = PersistentClient(path="./chroma_data")
collection = client.get_collection("org_memory")
results = collection.query(
query_texts=["Why did we choose FastAPI?"],
n_results=5
)Edit the prompt in app.py (around line 700) to change reasoning behavior:
prompt = f"""
You are Memora, an organizational reasoning engine.
[Customize instructions here]
Evidence:
{context}
"""- Slack messages & emails are sensitive
- Store
credentials.jsonandtoken.jsonin.gitignore - Use environment variables for API keys
- Implement row-level access control in
utils/auth.py
- Built-in session management
- Role-based access (Admin, Member, Viewer)
- User profile stored in
st.session_state
Every decision answer includes:
- Source documents
- Retrieval confidence
- Timestamp of analysis
- Slack + Gmail integration
- Incremental sync
- Vector search & ranking
- Gemini reasoning
- Decision traceability
- Calendar integration (calendar events as context)
- Jira/Linear issue tracking
- Slack thread replies (nested discussions)
- Multi-org support
- Advanced filtering (date range, users, channels)
- Decision workflow automation
- Confidence scoring ML model
- Custom LLM fine-tuning
- GraphQL API for external tools
- Slack bot for inline answers
Q: "Why did we choose React over Vue?" A: Best explanation sourced from Final Document + Meeting Notes + Gmail + Slack
Q: "How did we decide on our deployment pipeline?" A: Timeline shows Slack discussions โ Email approvals โ Meeting consensus โ Final doc
Q: "What was the rationale for microservices?" A: Ranks sources by authority; explains evolution of thinking
Contributions welcome! To add features:
- Fork the repo
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make changes (update tests if needed)
- Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License โ see LICENSE.md for details.
- Documentation: See DESIGN.md for UI/UX specs
- Issues: Open a GitHub issue for bugs
- Discussions: Start a discussion for feature requests
- Email: [email protected]
Built with โค๏ธ for organizational transparency and decision intelligence.
Technologies:
- Streamlit โ UI framework
- ChromaDB โ Vector database
- Google Gemini โ LLM & embeddings
- Slack SDK โ Slack integration
- Google API Client โ Gmail integration
- Lines of Code: ~2000
- API Integrations: 3 (Slack, Gmail, Gemini)
- Vector Dimensions: 768
- Supported Data Sources: 2 (+ static)
- Reasoning Model: Gemini 2.5 Flash
- Database: ChromaDB + SQLite
Made with ๐ง for better organizational memory.