Context Memory System — Architecture
Passive intelligence layer that listens to Slack channel messages, extracts structured facts using Claude Haiku, stores them as vector-embedded observations, and synthesizes per-entity summaries nightly. The bot uses these at query time to inject relevant organizational context into LLM prompts.1. Data Flow — End to End
2. Entity Relationship Diagram
3. Ingestion Detail
Message Flow
- Bot receives every Slack channel message (not DMs)
- Fires
POST /context/ingestwithorganizationId,channelId,channelName,platformUserId,messageTs,threadTs,text - Message inserted into
channel_messageswithprocessedAt = null - URLs extracted from message text via regex, cleaned of Slack formatting (
<url|display>->url) - Each URL queued as
process-urlBullMQ job -> Jina Reader API fetches content -> Claude Haiku summarizes -> stored as observation
Batch Triggers
Extraction Pipeline
- Fetch unprocessed messages (limit
BATCH_SIZE, default 20) - Resolve
platformUserId-> user names viaplatform_identities+userstables - Group messages by channel, format with timestamps and display names
- Send to Claude Haiku 4.5 with extraction prompt
- Parse JSON array of
{ entityType, entityId, category, observation, confidence } - For each observation: generate embedding via OpenAI, insert into
context_observations - Mark source messages as processed (
processedAt = now) - Evaluate proactive actions via
context-actions.tsrules
4. Query Flow — How the Bot Retrieves Context
Context String Format
5. Entity Types and Observation Categories
Entity Types
Observation Categories
Confidence Calibration
- 0.9+: Directly stated fact (“I finished the newsletter”)
- 0.7-0.9: Strong inference (“Rohan always does QC after content — likely a handoff pattern”)
- 0.5-0.7: Weak inference (tone-based mood signals)
- Below 0.5: Not stored
6. Nightly Summarization
Summary Storage
summaryType = "profile"— one per entity, upserted nightly- Unique index on
(entity_type, entity_id, summary_type)— ensures one profile per entity - Embedding generated for the summary text itself (enables semantic search on summaries)
- Old summaries are overwritten, not versioned
7. Cleanup & Retention
8. Backfill Architecture
For new orgs or channels, historical messages can be backfilled from Slack:- Fetches last 1 year of history
- 2-second delay between Slack API calls (rate limit safe)
- Thread replies fetched for threaded messages
- Uses
backfill_statetable to track progress per channel
9. Auto Mood Detection
Context observations withcategory = "mood_signal" feed into automatic mood scoring:
10. API Endpoints
11. Environment Variables
12. Key Files
13. Database Indexes
pgvector/pgvector:pg16 Docker image and CREATE EXTENSION vector migration.