Skip to content
noamaanMulla-03Public

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

23 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NeuronApp: AI Personal Assistant

NeuronApp is a React Native mobile application that acts as a proactive, context-aware personal assistant. It integrates deeply with Google Workspace to understand your schedule, communications, documents, and tasks — then uses that context to provide semantic recall, daily intelligence briefings, and real-time background indexing.

Built around the Cognitive Sanctuary design system: tonally layered UI with no hard borders, asymmetric layout, and Manrope/Inter typography optimised for deep focus.


Features

Real-Time Google Workspace Sync

Eight Google services are synced automatically in the background without any user interaction after initial permission grant. Sync uses a hybrid push + polling architecture:

  Push-based (real-time): 

  • Gmail — Google pushes change notifications via Cloud Pub/Sub (gmail-push topic). Each notification triggers an incremental sync of new/modified messages. Extracts subject, sender, date, body, labels, importance markers, and category.
  • Google Drive — HTTP webhook channel on the Drive Changes endpoint. On every file change, Drive metadata is synced and document content extraction is triggered automatically.
  • Google Calendar — HTTP webhook channel on the primary calendar. Syncs all calendars and events including RSVP status, attendees, video links, and multi-calendar support with per-event timezone handling.

Scheduled polling (every 15 minutes):

  • Contacts — Incremental sync via People API using sync tokens. Extracts name, emails, phones, organisations, biographical notes, and photo URL. On 410 (token expired), falls back to full sync.
  • Tasks — All task lists with completion status, due dates (midnight UTC), parent/child relationships, and position ordering.
  • Google Keep — Note titles and body text. Fails gracefully if the account lacks Workspace Enterprise access.
  • Google Chat — Space metadata (DMs, group chats, named spaces).

Watch renewal (every 6 hours): A scheduled function checks all active watch channels and renews any expiring within 12 hours. Gmail and Calendar watches expire after ~7 days; Drive watches after ~24 hours.


Server-Side Token Management

The client never passes access tokens to sync functions. On first sign-in:

  1. The React Native Google Sign-In SDK returns a serverAuthCode (available because offlineAccess: true).
  2. The app sends this one-time code to the storeRefreshToken Cloud Function.
  3. The backend exchanges it for a long-lived refresh token via the Google OAuth2 token endpoint and stores it at users/{uid}/tokens/google in Firestore (admin SDK only — clients are blocked by security rules).
  4. Before every automated sync, the backend calls refreshAccessTokenServer() to obtain a fresh access token (~60 min lifetime) without any client involvement.

Semantic Memory (RAG)

All synced documents are automatically embedded using Vertex AI text-embedding-004 and stored as Firestore vector fields. Embeddings are generated asynchronously via a Cloud Tasks queue with retry on failure.

Collections indexed:

  • gmail_messages — Email body prepended with [Email], subject, sender, date
  • docs_content — Document title, extracted plain text (Docs/Sheets/Slides exported via Drive API), and unresolved comments
  • keep_notes — Note title and body
  • chat_messages — Text content

Semantic Chat (semanticChat Cloud Function) is a multi-stage RAG pipeline with a ReAct agent:

  1. Guardrails — a fast regex check rejects prompt-injection patterns (zero LLM cost) before any model call.
  2. Intent classification — hybrid keyword heuristics handle the common 80% instantly; an LLM fallback classifies ambiguous queries into search, calendar, task_manage, briefing, general, or unsafe.
  3. Routing — briefing reads the pre-generated daily brief directly from Firestore (no agent overhead); general gets a simple LLM response; search/calendar/task_manage run the full ReAct agent.
  4. Multi-stage RAG (the searchWorkspace tool):
    • Query expansion — Gemini generates 2–3 semantically diverse search variants from the user's query.
    • Multi-query retrieval — fires (expanded queries × 4 collections) in parallel, then deduplicates by a composite key.
    • LLM reranking — scores each candidate 0–10 for relevance, filters below threshold 6, and returns the top 5.
  5. ReAct agent — Gemini 2.5 Flash reasons in a Thought → Action → Observation loop (max 5 turns) with four tools:
    • searchWorkspace — full multi-stage RAG over indexed GSuite data
    • getCalendarEvents — reads synced calendar events for a date
    • getTasksByStatus — reads synced Google Tasks by completion status
    • getEmailDetail — retrieves specific emails by subject keyword search
  6. Reasoning trace — the Thought/Action/Observation steps are extracted from Genkit's message history and sent to the frontend, where they're rendered inline in the chat UI.
  7. Synthesis — Gemini 2.5 Flash produces a grounded answer with a 45-second timeout.
  8. Returns { answer, sources, steps } with human-readable citations (Email: Subject — from sender, Document: Title, etc.) and the reasoning trace.

Idempotency: Firestore triggers skip re-embedding documents whose text content hasn't changed since the last embedding pass.


Daily Briefing

A scheduled Cloud Function runs every hour and generates a personalised morning brief for each user once per day after 07:00 in their local timezone.

Data aggregated (in parallel from Firestore, no Google API calls):

  • Today's calendar events (all-day and timed, filtered by IANA timezone)
  • Pending tasks due today or overdue
  • Important emails from the last 24 hours

LLM synthesis: Gemini 2.5 Flash produces a structured output validated by Zod:

greeting        — warm one-line greeting referencing the date
summary         — 2–3 sentence synthesis of the day's priorities
eventHighlights — up to 3 most important calendar items
priorityTasks   — up to 3 most urgent tasks
importantEmails — up to 3 emails needing attention

Idempotency: if a brief already exists for today (users/{uid}/daily_briefings/YYYY-MM-DD), the function skips that user. Per-user failures are isolated and logged without aborting the full fan-out.


Calendar Conflict Resolution

After calendar sync, the backend detects overlapping timed events and uses Gemini 2.5 Flash to classify which event takes precedence (rules: external > internal, more attendees > fewer, one-time > recurring, video calls indicate importance). It produces a { highPriorityEvent, lowPriorityEvent, reason, suggestedAction } resolution written to users/{uid}/calendar_conflicts/. Pending conflicts surface in the Daily Briefing card on the home screen, where the user can acknowledge or dismiss them.


Ghostwriter Agent

A full email drafting agent that learns the user's writing voice and automates replies. Implemented across 14 Cloud Functions in functions/src/services/ghostwriter.ts with a dedicated screen at app/home/ghostwriter.tsx.

Style extraction: extractStyle analyses up to 30 of the user's sent emails (requires ≥3) and produces a StyleProfile (tone, greeting style, sign-off, formatting quirks, average length, vocabulary notes) validated by Zod, persisted at users/{uid}/settings/style_profile. A scheduled function (refreshStyleProfiles) re-extracts monthly.

Drafting & replies:

  • generateSmartReplies — 3 context-aware, style-aligned reply options for an email (labels + bodies)
  • generateDraft — full email draft from a short natural-language instruction (max 1,000 chars), injecting the Style Profile
  • refineDraft — iterative refinement of an existing draft with follow-up instructions
  • summarizeThread — condenses an email thread into key points
  • sendDraft — sends a draft via the Gmail API (validates recipient format to prevent header injection)

Draft history & templates:

  • listDraftHistory / deleteDraftHistory — every generated/sent draft is persisted for review
  • saveTemplate / listTemplates / deleteTemplate / applyTemplate — reusable email templates

Follow-up detection: detectFollowUps (scheduled) scans the last 7 days of sent emails and flags any thread unanswered for 3+ days, writing reminders to users/{uid}/follow_ups/.


Episodic Memory & Multi-turn Conversations

Semantic Chat maintains conversational continuity across turns and remembers past interactions:

  • Conversation persistence — each exchange is saved to users/{uid}/conversations/{conversationId}/messages. Recent history (up to 10 messages) is injected into the system prompt as context.
  • Episodic memory — summarizeConversations (scheduled) condenses conversation histories into summary documents stored in users/{uid}/episodic_memory/ with vector embeddings. On each new query, searchEpisodicMemory performs a vector similarity search over these summaries and injects relevant past context into the prompt.
  • The episodic_memory collection has its own 768-dimension vector index in firestore.indexes.json.

Authentication & Security

  • Google Sign-In with Firebase Auth. Session persisted to device via AsyncStorage with Firebase's built-in token refresh.
  • Biometric gating (Face ID / Touch ID / Android Biometrics): on first app launch after sign-in, the user must authenticate biometrically if enabled. Biometric state stored in Keychain (react-native-keychain).
  • Firestore security rules enforce user-scoped access. users/{uid}/tokens/** and watch_channels/** are hard-blocked from client reads/writes (allow read, write: if false).
  • OAuth scopes are read-only across all eight Google APIs.

Architecture

Mobile App (React Native)
│
├── Sign-in → captures serverAuthCode → storeRefreshToken Cloud Function
│                                         └── stores refresh token in Firestore
│
├── Permission grant → savePermissions → initializeSync Cloud Function
│                                           ├── syncs all enabled services (server-side)
│                                           └── sets up push watch channels
│
├── GSuiteStatus screen ─ onSnapshot(sync_meta/status) → real-time progress
├── GSuiteData screen   ─ browses synced items per service (tonal tab nav)
├── DailyBriefing card  ─ reads today's brief + pending calendar conflicts
├── SemanticChat screen → semanticChat Cloud Function → ReAct agent + Gemini 2.5 Flash
└── Ghostwriter screen  → ghostwriter Cloud Functions → style-aware drafting

Cloud Functions
│
├── onGmailPush (Pub/Sub)         ─┐
├── onCalendarPush (HTTP webhook)  ├── refresh token → sync → update sync_meta
├── onDrivePush (HTTP webhook)    ─┘
│
├── autoSyncPolled (cron: */15 * * * *)  — contacts, tasks, keep, chat
├── renewWatches   (cron: 0 */6 * * *)   — renews expiring watch channels
├── generateDailyBriefings (cron: 0 * * * *) — timezone-aware morning briefs
├── refreshStyleProfiles (cron: monthly)      — re-extracts writing style profiles
├── detectFollowUps (cron: daily)             — flags unanswered sent emails
├── summarizeConversations (cron: scheduled)  — condenses chats into episodic memory
│
├── processEmbedding (Cloud Tasks queue)  — generates + stores vector embeddings
├── onDocsWrittenEmbed  ─┐
├── onGmailWrittenEmbed  ├── Firestore triggers → enqueue processEmbedding
├── onKeepWrittenEmbed  ├── (4 collections: docs, gmail, keep, chat)
├── onChatWrittenEmbed  ─┘
│
├── semanticChat (callable)         — multi-stage RAG + ReAct agent + Gemini synthesis
├── resolveConflict (callable)      — calendar overlap detection + LLM priority classification
└── ghostwriter (callable ×11)      — extractStyle, smartReplies, draft, refine, send,
                                       threadSummary, draftHistory, templates, follow-ups

Firestore Data Model
users/{uid}/
  tokens/google          — refresh token (admin SDK only)
  settings/
    timezone             — IANA timezone string (written on sign-in)
    gsuite_permissions   — per-service enabled booleans
    style_profile        — extracted writing voice (tone, sign-off, quirks)
  sync_meta/status       — real-time sync progress per service
  watches/               — active push channel metadata
  calendar_events/       — synced events
  calendar_calendars/    — calendar list
  calendar_conflicts/    — detected overlaps with LLM priority classification
  gmail_messages/        — messages with embeddings
  drive_files/           — file metadata with folder paths
  docs_content/          — extracted document text with embeddings
  contacts_people/       — contact records
  tasks_items/           — tasks with list context
  tasks_lists/           — task list metadata
  keep_notes/            — note text with embeddings
  chat_spaces/           — Chat space metadata
  chat_messages/         — Chat text with embeddings
  daily_briefings/       — one document per day (YYYY-MM-DD)
  conversations/         — chat sessions
    {conversationId}/messages — per-turn message history
  episodic_memory/       — conversation summaries with embeddings
  draft_history/         — ghostwriter draft history
  email_templates/       — saved reusable email templates
  follow_ups/            — unanswered sent email reminders

watch_channels/{channelId}   — channelId → {uid, service} reverse lookup

Tech Stack

Layer Technology
Mobile React Native 0.84.1 (TypeScript)
State Zustand 5 (authStore, gsuiteStore)
Forms react-hook-form + Zod
Navigation React Navigation v7 (native stack)
Auth Firebase Auth 12 + Google Sign-In 16
Biometric react-native-biometrics + react-native-keychain
Persistence @react-native-async-storage
Backend Firebase Cloud Functions v2 (Node 22)
Database Cloud Firestore
Vector Search Firestore Vector Search
AI Orchestration Firebase Genkit 1.32
LLM Gemini 2.5 Flash (via Vertex AI)
Embeddings Vertex AI text-embedding-004
Async Jobs Google Cloud Tasks
Push Sync Google Pub/Sub + HTTP webhook channels
Secrets Firebase Secret Manager

Getting Started

Prerequisites

  • Node.js v22+
  • React Native environment (Android Studio / Xcode)
  • Firebase CLI: npm install -g firebase-tools
  • gcloud CLI authenticated to the project

1. Clone & Install

git clone https://github.com/your-org/NeuronApp.git
cd NeuronApp
npm install
cd functions && npm install && cd ..

2. One-Time GCP Setup

# Store the OAuth web client secret
echo "YOUR_CLIENT_SECRET" | firebase functions:secrets:set GOOGLE_CLIENT_SECRET --project neuron-bb594

# Create the Gmail Pub/Sub topic
gcloud pubsub topics create gmail-push --project=neuron-bb594

# Grant Gmail push notifications permission to publish
gcloud pubsub topics add-iam-policy-binding gmail-push \
  --project=neuron-bb594 \
  --member="serviceAccount:gmail-api-push@system.gserviceaccount.com" \
  --role="roles/pubsub.publisher"

# Create the Cloud Tasks queue for async embedding jobs
gcloud tasks queues create process-embedding \
  --location=us-central1 --project=neuron-bb594

Note: The OAuth web client ID is currently hardcoded in App.tsx (GoogleSignin.configure). Update webClientId to match your own Google Cloud project's OAuth client before running the app.

3. Deploy Backend

cd functions
npm run deploy
cd ..

# Deploy Firestore security rules + vector/composite indexes
firebase deploy --only firestore:rules,firestore:indexes --project neuron-bb594

The firestore.indexes.json defines 5 vector indexes (768-dim, flat, COSINE) for docs_content, gmail_messages, keep_notes, chat_messages, and episodic_memory, plus composite indexes for Gmail queries.

4. Run the App

npm start        # Metro bundler
npm run android  # or open android/ in Android Studio
npm run ios      # or open ios/ in Xcode

5. Test & Lint

npm test         # Jest (snapshot/render test in __tests__/)
npm run lint     # ESLint

Design Philosophy: Cognitive Sanctuary

The UI is built around the concept of a focused, distraction-free mental workspace:

  • Palette: Surgical white #F8F9FA base with Neuron Blue #1A73E8 as the primary accent
  • No-Line Rule: Boundaries defined by tonal background shifts rather than borders
  • Typography: Manrope (headlines) and Inter (body) for high legibility at small sizes
  • Layout: Asymmetric compositions with intentional whitespace to reduce cognitive load

See src/theme/ and Design/DESIGN.md for the full token system.


Project Structure

NeuronApp/
├── App.tsx                  # Root: navigation stack, auth gate, biometric gating
├── index.js                 # React Native entry point
├── app/                     # UI screens (Cognitive Sanctuary design system)
│   ├── auth/
│   │   └── login.tsx        # Google Sign-In onboarding
│   └── home/
│       ├── index.tsx        # Home hub (briefing card, navigation tiles)
│       ├── daily-briefing.tsx  # Daily brief + calendar conflict cards
│       ├── semantic-chat.tsx  # ReAct agent chat with reasoning trace
│       ├── ghostwriter.tsx    # Email drafting, smart replies, templates
│       ├── gsuite-connect.tsx # Permission grant flow
│       ├── gsuite-status.tsx  # Real-time sync progress
│       ├── gsuite-data.tsx    # Synced data browser (tonal tab nav)
│       └── profile.tsx        # User profile & settings
├── src/
│   ├── components/          # Button, Input, PasswordInput
│   ├── lib/                 # firebase, firestore, auth, biometric, google-api, errors
│   ├── services/            # sync-engine (client-side sync orchestration)
│   ├── store/               # Zustand stores: authStore, gsuiteStore
│   └── theme/               # colors, typography, spacing tokens
├── functions/               # Firebase Cloud Functions (Node 22, Genkit)
│   └── src/
│       ├── index.ts         # Function exports (storeRefreshToken, initializeSync, …)
│       ├── lib/             # genkit, google-api, oauth
│       └── services/        # 17 service modules (gmail, drive, calendar, …)
├── android/                 # Native Android project (package: com.neuron)
├── ios/                     # Native iOS project
├── Design/                  # HTML prototypes + DESIGN.md per screen
├── firestore.rules          # Security rules (user-scoped, admin-only tokens)
├── firestore.indexes.json   # Vector + composite indexes
└── firebase.json            # Firebase config (functions, firestore)

App Screens

Screen Route Purpose
Login Login Google Sign-In onboarding
Home Home Hub with daily briefing card and navigation tiles
Profile Profile User profile & settings
GSuiteConnect GSuiteConnect Google Workspace permission grant flow
GSuiteStatus GSuiteStatus Real-time sync progress per service
GSuiteData GSuiteData Browse synced items across 8 services
SemanticChat SemanticChat ReAct agent chat with inline reasoning trace
Ghostwriter Ghostwriter Style-aware email drafting, smart replies, templates

Companion Documentation

  • ROADMAP.md — Strategic evolution from sync tool to agentic assistant
  • GEMINI.md — Design system overview & redesign status
  • Design/DESIGN.md — Full Cognitive Sanctuary token system
  • Design/ — HTML prototypes per screen (Daily Briefing, Onboarding, Project Hubs, Semantic Chat)
  • test-cases-react-rag.md — RAG test cases
  • AGENTS.md — Build & run instructions for Android Studio / CLI

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages