A self‑hosted NestJS + Angular stack that ingests every transcript from your Limitless Pendant, enriches them with embeddings, detects actionable commands with an LLM‑powered agent, and prepares them for execution (Google Calendar, Gmail drafts, …).
| Status | Feature |
|---|---|
| ✅ | Continuous pull of lifelogs from the Limitless API |
| ✅ | Qdrant vector store + similarity search for rich context windows |
| ✅ | Function‑calling agent that can invoke typed server functions |
| ✅ | Gemini‑powered extraction of summaries, tasks, emails & reminders |
| 🚧 | Hooks for Google Calendar, Gmail, Notion, … |
┌────────────┐ HTTPS / WebSocket ┌────────────────┐
│ Limitless │──────────────────────▶│ NestJS API │
│ Pendant │ (pull today) │ (src/) │
└────────────┘ ├──────────┬─────┤
│ Postgres │ │
│ (raw) │ │
└──┬──────┬─┘ │
│ │ │
│ └─▶ Qdrant (embeddings)
│
└─▶ GeminiService (LLM)
│
└─▶ Action Items- Node 20+ & npm 10+
- PostgreSQL 15+
- Docker (for Qdrant) or a running Qdrant 1.8+ instance
git clone https://github.com/your‑org/limitless‑lifelog.git
cd limitless‑lifelog
npm install# Required
LIMITLESS_API_KEY= # ↔ pendant
GEMINI_API_KEY= # ↔ gemini.google.com
OPENAI_API_KEY= # ↔ function‑calling agent (already coded)
DATABASE_URL=postgres://user:pass@localhost:5432/limitless
QDRANT_URL=http://localhost:6333
# Optional
LOG_LEVEL=debug# launch infra
docker compose up -d postgres qdrant
# start backend (NestJS)
npm run start:back
# start frontend (Angular)
npm run start:frontOpen http://localhost:4200 to explore the UI. The server logs will show Gemini extractions whenever new lifelogs arrive.
-
SyncService polls the Limitless API every minute and persists raw lifelogs.
-
Each
LifelogEntityinsert triggers LifelogSubscriber, which:- Builds a 90‑minute context window using Qdrant similarity search.
- Invokes GeminiService.extractRelevant() to get structured
ActionItem[]. - Logs the results (ready for downstream automations).
-
The AgentService can now call typed server functions (calendar, email, …) based on those items.
| Need | Where to tweak |
|---|---|
| Change context size | src/app/lifelog-subscriber.ts → windowStart.setMinutes(...) |
Persist ActionItems |
Add ActionItemEntity + save inside subscriber |
| Add Google Calendar | Implement GoogleCalendarService & map in agent.actions.ts |
| Build new commands | Extend ActionSchema (used by the function‑calling agent) |
- Batch embeddings before pushing to Qdrant to cut network round‑trips.
- Cache
extractRelevant()onhash(context)to avoid re‑prompting Gemini for identical windows. - Use upsert on duplicate lifelogs to keep writes idempotent.
- Persist
ActionItems and expose them via GraphQL - Push‑based pendant webhook (no polling)
- Gmail Draft integration
- Notion daily journal export
- Mobile PWA
PRs are welcome! Please run npm run lint & npm test before opening a pull request.