187 Commits

Author SHA1 Message Date
59c45ff1fb fix google docs bugs 2025-12-29 15:40:05 +00:00
c08a10da28 Merge branch 'proactive' 2025-12-29 14:20:26 +00:00
1fbcadcab5 tools 2025-12-29 14:07:58 +00:00
f042f9aed8 proactive stuff 2025-12-29 14:07:12 +00:00
Daniel O'Connell
849f03877a google docs + frontend 2025-12-29 15:01:45 +01:00
Daniel O'Connell
a238ca6329 Add proactive check-in functionality for Discord
- Add proactive_cron, proactive_prompt, last_proactive_at fields to Discord models
- Add /proactive command handler for configuring check-in schedules
- Add evaluate_proactive_checkins task (runs every minute via celery beat)
- Add execute_proactive_checkin task that evaluates interest and sends messages
- Smart bot selection finds the correct bot for each server
- Channel selection defaults to "general" text channel for servers
- Add database migration for new fields
- Add comprehensive tests for commands and tasks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-25 09:21:30 +01:00
Daniel O'Connell
9088997295 enable people tasks 2025-12-25 08:19:20 +01:00
Daniel O'Connell
48c380b903 migrate to fastmcp 2025-12-24 23:19:41 +01:00
Daniel O'Connell
d3d71edf1d Add deployer 2025-12-24 16:25:53 +01:00
47180e1e71 fixes 2025-12-24 14:52:12 +00:00
5d79fa349e synch people 2025-12-24 14:38:14 +00:00
47629fc5fb add PRs and People 2025-12-24 13:25:34 +00:00
efbc469ee3 proper modality for github items 2025-12-23 22:13:11 +00:00
526bfa5f6b more github ingesting 2025-12-23 20:02:10 +00:00
f729122754 github tracking 2025-12-23 19:11:10 +00:00
0cc1d7f6c7 Add LLM-recalled content for half-remembered searches
- Query analysis now extracts recalled_content (titles/essays the LLM
  recognizes as relevant, e.g., "predetermined conclusions" → "The Bottom Line")
- Added title-based chunk fetching to ensure recalled content appears in
  results even when BM25/embedding search doesn't rank it highly
- Fixed BM25 to run separate searches for each query variant and merge
  results (was concatenating into one AND query)
- Added RECALLED_TITLE_BOOST (0.05) for sources matching recalled titles

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 17:48:42 +00:00
7e1770f384 Enable query analysis by default (runs in parallel with HyDE)
Query analysis and HyDE are both LLM-based operations that run in
parallel via asyncio.gather, so enabling query analysis adds no
extra latency when HyDE is also enabled.

Query analysis provides:
- Modality detection from query content
- Query cleaning and reformulation
- Query variants for better recall

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:29:28 +00:00
f9e9ad5f4b Fix search enhancement UI to show actual server defaults
Initialize checkboxes to match server defaults (BM25, HyDE, Reranking
enabled; Query Analysis disabled) so the UI accurately reflects what
the server is actually doing. Previously showed all as unchecked which
was confusing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:22:22 +00:00
1c621e53fc Add search enhancement options to frontend
- Add collapsible "Search Enhancements" section with toggles for:
  - BM25 (keyword search)
  - HyDE (hypothetical document expansion)
  - Reranking (cross-encoder)
  - Query Analysis (LLM-based)
- Update SearchConfig type to include new options
- Add CSS styling for the enhancement options panel

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:18:04 +00:00
4a6bef31f2 Add query embedding cache for 11x speedup on repeated queries
- Add TTL-based cache for query embeddings (5 min TTL, 100 entries max)
- Cache hit avoids VoyageAI API call entirely
- First call: ~1s, subsequent calls: ~0.09s
- Only caches single-query embeddings (the common search case)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 16:07:25 +00:00
548a81e21d Optimize search: parallelize BM25 and embedding, fix word filter
- Run BM25 and embedding searches in parallel with asyncio.gather
- Fix word filter in both search.py and bm25.py: >= 2 chars instead of > 2
  (allows important 2-letter terms like "AI", "ML" to be included)
- Better error handling for parallel search failures

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 15:58:39 +00:00
5b997cc397 Fix search bugs: query terms, index validation, chunk loss
- Include 2-letter terms (AI, ML) in query term extraction (was > 2, now >= 2)
- Add guard for empty data before accessing data[0].data[0] in scorer
- Preserve chunks without content in reranking instead of silently dropping
- Remove legacy wrapper functions (apply_title_boost, apply_popularity_boost)
- Update tests to use apply_source_boosts directly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 15:01:03 +00:00
782b56939f Refactor search: add LLM query analysis, extract constants
- Add query_analysis.py for LLM-based query preprocessing
  - Detects modalities from natural language ("on lesswrong" -> forum)
  - Cleans meta-language ("I remember reading..." -> core query)
  - Generates query variants for better recall
  - Dynamically discovers modalities and domains from database

- Extract constants to constants.py
  - STOPWORDS, RRF_K, boost values, etc.
  - Cleaner separation of configuration from logic

- Refactor search_chunks into focused helper functions
  - _run_llm_analysis: parallel query analysis + HyDE
  - _apply_query_analysis: apply analysis results
  - _build_search_data: construct search data with variants
  - _run_searches: embedding + BM25 with RRF fusion
  - _fetch_chunks: database retrieval with scoring
  - _apply_boosts: title, popularity, recency boosts
  - _apply_reranking: cross-encoder reranking

- Remove redundant regex-based modality detection
- Remove static QUERY_EXPANSIONS (LLM handles this better)
- Add comprehensive tests for query_analysis module

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 14:43:17 +00:00
60e6e18284 Add modality detection and family term expansion for search
- Add useModalityDetection config flag to detect content type hints
  from natural language queries (e.g., "on lesswrong" → forum,
  "comic about" → comic)
- Strip meta-language noise from queries ("there was something about")
- Add family term expansion (father ↔ son, parent ↔ child, etc.)
- Modality detection is off by default, configurable per-request

TODO: Replace regex-based detection with LLM-based query analysis
(Haiku) that can run in parallel with HyDE for better accuracy.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 13:32:10 +00:00
a10f93cb3c Add per-request configuration for search enhancements
Allow callers to enable/disable BM25, HyDE, reranking, and query
expansion on a per-request basis via SearchConfig. When not specified,
falls back to global settings from environment variables.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 12:38:01 +00:00
d9fcfe3878 more search improvements 2025-12-21 12:29:44 +00:00
f3d8b6602b Add popularity boosting to search based on karma
- Add `popularity` property to SourceItem base class (default 1.0)
- Override in ForumPost with karma-based calculation:
  - Uses KARMA_REFERENCES dict mapping URL patterns to reference values
  - LessWrong: 100 (90th percentile from actual data)
  - Reference karma gives popularity=2.0, caps at 2.5
- Add apply_popularity_boost() to search pipeline
- POPULARITY_BOOST = 0.02 (2% score adjustment per popularity unit)
- Add comprehensive tests for popularity boost

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 22:44:06 +00:00
09215adf9a Add comprehensive tests for search improvements
- Add tests for extract_query_terms (stopword filtering, short words)
- Add tests for apply_query_term_boost (boost calculations, edge cases)
- Add tests for deduplicate_by_source (keeps highest per source)
- Add tests for apply_title_boost (title matching with mocked DB)
- Add tests for fuse_scores_rrf (RRF score fusion, ranking behavior)
- Add tests for rerank module (VoyageAI reranker mocking)

Uses pytest.mark.parametrize for concise, data-driven tests.
77 tests total covering all new search functionality.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 22:26:16 +00:00
c6cb793cdf Add HyDE (Hypothetical Document Embeddings) for query expansion
HyDE generates a hypothetical document passage that would answer the user's
query, then embeds that alongside the original query. This bridges the gap
between how users describe what they're looking for and the actual document
terminology.

Changes:
- Add hyde.py with expand_query_hyde() function
- Integrate HyDE into search_chunks() pipeline
- Add ENABLE_HYDE_EXPANSION and HYDE_TIMEOUT settings
- Only expand queries with 4+ words (short queries are specific enough)
- Simple in-memory cache to avoid re-generating for repeated queries

Example:
- Query: "saying what you mean not using specific words"
- HyDE generates: "Clear communication requires expressing your thoughts
  directly and honestly, even when you lack the precise terminology..."
- This finds articles about word meaning and clear communication

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 16:01:03 +00:00
e414c3311c Improve RAG search quality with PostgreSQL FTS and hybrid scoring
Major changes:
- Replace OOM-causing in-memory BM25 with PostgreSQL full-text search
- Add tsvector column and GIN index for fast keyword search
- Implement hybrid score fusion (70% embedding + 30% FTS + 15% bonus)
- Add CANDIDATE_MULTIPLIER (5x) to search more candidates before fusion
- Add stopword filtering to FTS queries for less strict matching
- Make search limit configurable (default 20, max 100)
- Propagate relevance scores through the search pipeline

Search improvements:
- "clowns iconoclasts" → finds target at rank 1 (score 0.815)
- "replacing words with definitions" → finds target at rank 1
- Vague queries now find results with limit=30 that were previously missed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-20 15:54:30 +00:00
f2161e09f3 Fix 11 high-priority bugs from third deep dive
- Add IMAP connection cleanup on logout failure (email.py)
- Handle IntegrityError for concurrent email processing (tasks/email.py)
- Recover stale scheduled calls stuck in "executing" state (scheduled_calls.py)
- Move git operations outside DB transaction in notes sync (notes.py)
- Add null checks for recipient_user/from_user in Discord (discord.py)
- Add OAuth state and session cleanup tasks (maintenance.py)
- Add distributed lock for backup tasks (backup.py)
- Add /tmp storage warning in settings (settings.py)
- Fix health check error exposure (app.py)
- Remove sensitive data from logs (auth.py)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 22:15:25 +00:00
8251ad1d6e Document second deep dive findings in INVESTIGATION.md
- Added 38 new issues from comprehensive security audit
- Documented 8 fixes applied in this pass
- Listed remaining issues requiring further investigation
- Updated fix count to 53+

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:57:03 +00:00
b9d6ff8745 Fix 8 security and code quality issues from deep dive
Security fixes:
- Issue #1: Improved path traversal validation using pathlib.relative_to()
- Issue #4: Added timing attack prevention for user enumeration
- Issue #5: Added constant-time API key comparison using secrets.compare_digest()

Performance fixes:
- Issue #20: Cache database engine and session factory for proper connection pooling

Code quality fixes:
- Issue #28: Fixed string literal without effect (now proper comment)
- Issue #29: Removed duplicate db_session.add() call
- Issue #30: Fixed incorrect docstring parameter name
- Issue #31: Added parentheses for clear operator precedence in set operations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:55:59 +00:00
92dad5b9fd Update bug classifications in INVESTIGATION.md
- BUG-023: Mark as acceptable design (SHA256 for exact dedup)
- BUG-026: Mark as acceptable design (BM25/embedding for recall, LLM for ranking)

These are architectural decisions, not bugs - semantic dedup and hybrid scoring would be feature enhancements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:46:52 +00:00
be3963b02f Update INVESTIGATION.md with completed improvements
- Mark BUG-059 as N/A (MockRedis is sufficient for actual usage)
- Update improvement suggestions to reflect completed fixes:
  - Retry logic (BUG-015)
  - Health checks (BUG-043)
  - Rate limiting (BUG-030)
  - CSRF protection (BUG-049)
  - Resource limits (BUG-067)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:45:03 +00:00
92220f8abc Fix 2 infrastructure bugs in Dockerfile
BUG-057: Remove build dependencies after pip install
- Added apt-get purge for gcc, g++, python3-dev
- Reduces final image size

BUG-044: Make proxy header trust configurable
- Added FORWARDED_ALLOW_IPS environment variable
- Allows secure configuration for production deployments
- Documented recommended settings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:44:00 +00:00
d644281b26 Fix 5 security and quality bugs
BUG-030: Add rate limiting via slowapi middleware
- Added slowapi to requirements
- Configurable limits: 100/min default, 30/min search, 10/min auth
- Rate limit settings in settings.py

BUG-028: Fix filter validation in embeddings.py
- Unknown filter keys now logged and ignored instead of passed through
- Prevents potential filter injection

BUG-034: Fix timezone handling in oauth_provider.py
- Now uses timezone-aware UTC comparison for refresh tokens

BUG-050: Fix SQL injection in test database handling
- Added validate_db_identifier() function
- Validates database names contain only safe characters

Also:
- Updated tests for bcrypt password format
- Updated test for filter validation behavior
- Updated INVESTIGATION.md with fix status

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:41:16 +00:00
d2164a49eb Add TODO note for re-indexing existing book chunks
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:05:29 +00:00
9a0f226972 Fix BUG-002: BookSection chunks now use correct 'book' modality
Root cause: BookSection._chunk_contents() called extract_text() without
specifying modality, which defaults to "text". This caused 9,370 book
chunks to be stored in the 'text' collection instead of 'book'.

Fix: Added modality="book" to all DataChunk creation in BookSection:
- extract_text() call for single-page sections
- Direct DataChunk creation for multi-page sections

Note: The original investigation reported 1,338 mail items, but current
analysis shows those are actually email attachments which correctly go
to text/doc/photo collections based on their content type.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 21:04:19 +00:00
f0195464c8 Complete bug investigation and fix unused appuser in Dockerfile
Investigation complete - verified 35+ bugs as fixed or non-issues:

Medium severity verified:
- BUG-018: N/A - intentional TODO comments for future features
- BUG-022: Low priority - sync_book properly chunks, only extract_ebook affected
- BUG-025: Acceptable - 4 chars/token is common approximation
- BUG-029: N/A - intentional score thresholds documented
- BUG-036: Acceptable - IntegrityError handling correct
- BUG-038: N/A - standard single beat process practice

Low severity fixed:
- BUG-056: Removed unused appuser from Dockerfile

Remaining valid issues documented for future work:
- BUG-002: Collection mismatch (needs data verification)
- BUG-026: BM25 scores discarded
- BUG-030: Rate limiting
- BUG-032: CSRF protection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 20:53:53 +00:00
1932931221 Additional bug verification in INVESTIGATION.md
More bugs verified:
- BUG-021: Chunk validation exists via yield_spans 
- BUG-027: N/A - defaulting to 0.0 is reasonable fallback
- BUG-055: collection_model now returns None instead of "unknown" 

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 20:47:43 +00:00
74e26e1892 Continue bug verification in INVESTIGATION.md
Additional bugs verified as fixed:
- BUG-017: collection_name index exists 
- BUG-020: server_id index exists 
- BUG-039: Email folder errors handled gracefully 
- BUG-041: N/A - reasonable behavior (backup disabled without key)

Updated bug count to 30+ confirmed fixed

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 20:45:43 +00:00
c2be97aad5 Verify and document fixed bugs in INVESTIGATION.md
Updated bug statuses after verification:
- BUG-014: CORS now uses settings.SERVER_URL 
- BUG-015: Celery has global retry config 
- BUG-016: safe_task_execution re-raises exceptions 
- BUG-019: embed_status properly set to STORED 
- BUG-031: SearchConfig enforces limits 
- BUG-033: No print statements in src/memory 
- BUG-035: Task time limits configured 
- BUG-037: Timezone handling fixed 
- BUG-040: Resource limits added (via BUG-067) 
- BUG-043: Health check validates dependencies 
- BUG-054: OAuthToken is intentional mixin design
- BUG-060: Print changed to logger.debug 

Updated executive summary with fix count (25+)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 20:40:55 +00:00
0da4f03656 Mark BUG-003, 008, 009, 013 as already fixed
Verified in code review:
- BUG-003: BM25 applies all SearchFilters
- BUG-008: yield_spans() guarantees token limits
- BUG-009: Uses FOR UPDATE SKIP LOCKED
- BUG-013: Has retry logic with exponential backoff

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-19 20:28:34 +00:00
2e3371ec4e Update INVESTIGATION.md with verified bug fixes
- Mark BUG-010 (MCP servers) as already fixed
- Mark BUG-011 (User ID type) as already fixed
- Document BUG-061 to BUG-068 fixes from commit 1c43f1a

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-19 20:25:09 +00:00
1c43f1ae62 Fix 7 critical security and code quality bugs (BUG-061 to BUG-068)
Security Fixes:
- BUG-061: Replace insecure SHA-256 password hashing with bcrypt
- BUG-065: Add constant-time comparison for password verification
- BUG-062: Remove full OAuth token logging
- BUG-064: Remove shell=True from subprocess calls

Code Quality:
- BUG-063: Update 24+ deprecated SQLAlchemy .get() calls

Infrastructure:
- BUG-067: Add resource limits to Docker services
- BUG-068: Enable Redis persistence (AOF)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-19 20:22:46 +00:00
Daniel O'Connell
adff8662bb Add investigation findings documentation
Documents 100+ issues found across:
- Data layer (10 issues)
- Content processing (12 issues)
- Search system (14 issues)
- API layer (12 issues)
- Worker tasks (20 issues)
- Infrastructure (12 issues)
- Code quality (20+ issues)

Includes database statistics and improvement suggestions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 19:24:17 +01:00
Daniel O'Connell
52274f82a6 Fix 19 bugs from investigation
Critical/High severity fixes:
- BUG-001: Path traversal vulnerabilities (3 endpoints)
- BUG-003: BM25 filters now apply size/observation_types
- BUG-006: Remove API key from log messages
- BUG-008: Chunk size validation before yielding
- BUG-009: Race condition fix with FOR UPDATE SKIP LOCKED
- BUG-010: Add mcp_servers property to MessageProcessor
- BUG-011: Fix user_id type (BigInteger→Integer)
- BUG-012: Swap inverted score thresholds
- BUG-013: Add retry logic to embedding pipeline
- BUG-014: Fix CORS to use specific origin
- BUG-015: Add Celery retry/timeout defaults
- BUG-016: Re-raise exceptions for Celery retries

Medium severity fixes:
- BUG-017: Add collection_name index on Chunk
- BUG-031: Add SearchConfig limits (max 1000/300s)
- BUG-033: Replace debug prints with logger calls
- BUG-037: Clarify timezone handling in scheduler
- BUG-043: Health check now validates DB + Qdrant
- BUG-055: collection_model returns None not "unknown"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 19:07:10 +01:00
Daniel O'Connell
a1444efaac Add database and file restore tools
tools/restore_databases.sh: Script to restore PostgreSQL and Qdrant
backups from encrypted backup files.

tools/restore_files.py: Python script to restore Fernet-encrypted
file backups.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 18:38:25 +01:00
Daniel O'Connell
116d0362a2 Fix REGISTER_ENABLED always evaluating to True (BUG-005)
Logic error: `boolean_env(...) or True` always evaluates to True,
making the environment variable useless.

Fixed by removing `or True`. Note: This setting is currently unused
in the codebase but the fix ensures correct behavior when it's used.

Also updates DISCORD_MODEL default to claude-haiku-4-5 for faster
and cheaper responses.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-19 18:33:05 +01:00