Skip to main content

Local privacy protection and model server

Project description

Aegis AI — Privacy-First Chat Interface

Aegis AI is a privacy-first chat application that de-identifies sensitive information before sending prompts to cloud-based LLMs (Gemini / Claude), then reconstructs the original data into the response — ensuring PII never leaves your device.

Architecture

┌──────────────────────────────────────────────────────────────────────┐
│  BROWSER (React + Vite)                                              │
│                                                                      │
│  User types prompt ──► ChatInput ──► Index.tsx handleSendMessage     │
│                                            │                         │
│                                            ▼                         │
│                                  ┌─────────────────┐                 │
│                                  │ Privacy Pipeline │                 │
│                                  │ (localhost:3001) │                 │
│                                  └────────┬────────┘                 │
│                                           │                          │
│              ┌────────────────────────────┼────────────────────┐     │
│              │  LOCAL PROCESSING ONLY     │                    │     │
│              │                            ▼                    │     │
│              │  ┌──────────────────────────────────────────┐   │     │
│              │  │  deembeder.py                            │   │     │
│              │  │                                          │   │     │
│              │  │  PHASE 1: Regex Detection (fast)         │   │     │
│              │  │    • Structured PII: emails, phones,     │   │     │
│              │  │      IBANs, SSNs, cards, VAT, postcodes  │   │     │
│              │  │    • Addresses, PO Boxes, signatures     │   │     │
│              │  │    • Company names, passwords, secrets   │   │     │
│              │  │    • Names via salutations & labels      │   │     │
│              │  │                                          │   │     │
│              │  │  PHASE 2a: Focused LLM Pass (Ollama)     │   │     │
│              │  │    • Names + company names combined      │   │     │
│              │  │                                          │   │     │
│              │  │  PHASE 2b: Broad LLM Pass (Ollama)       │   │     │
│              │  │    • All remaining PII categories        │   │     │
│              │  │                                          │   │     │
│              │  │  PHASE 3: Replacement engine             │   │     │
│              │  │    • Whitespace-flexible substitution    │   │     │
│              │  │    • Cascading root-word replacement     │   │     │
│              │  └──────────────────────────────────────────┘   │     │
│              └─────────────────────────────────────────────────┘     │
│                                           │                          │
│                    sensitive_info map + desensitized_prompt           │
│                                           │                          │
│                                           ▼                          │
│                              ┌──────────────────────┐                │
│                              │  Cloud LLM (Gemini   │                │
│                              │  or Claude) receives  │    SAFE       │
│                              │  ONLY [NAME_1],       │◄── No PII    │
│                              │  [ADDRESS_1], etc.    │    leaves     │
│                              └──────────┬───────────┘                │
│                                         │                            │
│                                         ▼                            │
│                              ┌──────────────────────┐                │
│                              │  reconstructor.py     │                │
│                              │  Restores [NAME_1]    │                │
│                              │  → real values back   │                │
│                              │  into LLM response    │                │
│                              └──────────┬───────────┘                │
│                                         │                            │
│                                         ▼                            │
│                              Final response shown to user            │
│                              (with real names, addresses, etc.)      │
└──────────────────────────────────────────────────────────────────────┘

Tech Stack

Layer Technology
Frontend React 18, TypeScript, Vite
UI Components shadcn/ui, Tailwind CSS, Framer Motion
Markdown react-markdown
Auth & Database Firebase (Auth + Firestore)
Privacy Pipeline Python Flask server (port 3001)
Local LLM Ollama — Gemma3 240M (runs entirely on-device)
Cloud LLMs Google Gemini (gemini-2.5-flash), Anthropic Claude

Privacy Pipeline — Detection Categories

The deembeder uses a two-layer approach: regex for structured/patterned PII, then Gemma3 240M (via Ollama) for semantic, context-dependent detection that regex cannot catch.

Layer What it catches
Regex — Identifiers Emails, phone numbers, IBANs, credit/debit cards, SSNs (incl. masked), VAT numbers, account numbers
Regex — Locations Street addresses, PO Boxes, postcodes (UK/US/IE), country names
Regex — Names Salutation names (Dear X), field labels (Borrowers: X), middle initials, capitalized word heuristic, signature blocks
Regex — Credentials Passwords & alphanumeric tokens, API keys, env vars, secrets
Regex — Companies Legal suffix patterns (Ltd, Inc, LLC), CamelCase brands (MediMatch, PayPal)
Gemma3 LLM — Semantic Person names in natural context, organization names without suffixes, and any remaining PII the regex layer missed — uses a focused prompt for thorough, context-aware extraction

Getting Started

Prerequisites

  • Node.js ≥ 18 and npm — install with nvm
  • Ollamainstall from ollama.ai with the Gemma3 240M model pulled
  • Firebase project with Firestore and Authentication enabled
  • API Keys for Gemini and/or Claude

Installation

# Clone the repository
git clone https://github.com/lukasnoelss/chatty-front.git
cd chatty-front

# Install frontend dependencies
npm install

# Install local Python backend package
pip install -e .

# Pull the Ollama model
ollama pull gemma3:270m

Environment Setup

Create a .env file (see .env.example):

VITE_GEMINI_API_KEY=your_gemini_api_key
VITE_CLAUDE_API_KEY=your_claude_api_key
VITE_FIREBASE_API_KEY=your_firebase_key
VITE_FIREBASE_AUTH_DOMAIN=your_project.firebaseapp.com
VITE_FIREBASE_PROJECT_ID=your_project_id
VITE_FIREBASE_STORAGE_BUCKET=your_project.appspot.com
VITE_FIREBASE_MESSAGING_SENDER_ID=your_sender_id
VITE_FIREBASE_APP_ID=your_app_id

Running

# Terminal 1: Start the privacy pipeline server
npm run server

# Terminal 2: Start the frontend dev server
npm run dev

The app will be available at http://localhost:8080.

Standalone Executable (Distribution)

If you want to build a single standalone binary that doesn't require a Python/Node environment:

# For macOS:
npm run build:mac

# For Windows:
npm run build:windows

# For Linux:
npm run build:linux

The output will be placed in dist/ and copied to public/downloads/ for web-based distribution.

Project Structure

chatty-front/
├── server.py                 # Flask server — routes /api/deembed and /api/reconstruct
├── build_mac.sh              # Build script for standalone Mac binary
├── build_windows.ps1         # Build script for standalone Windows binary
├── build_linux.sh            # Build script for standalone Linux binary
├── src/
│   ├── components/
│   │   └── chat/
│   │       ├── ChatInput.tsx     # Message input with privacy status
│   │       ├── ChatMessage.tsx   # Message bubble with copy/rerun buttons
│   │       ├── PrivacyDebugPanel.tsx  # Expandable pipeline visualization
│   │       ├── Sidebar.tsx       # Conversation history sidebar
│   │       ├── TypingIndicator.tsx
│   │       └── WelcomeScreen.tsx
│   ├── gemma/
│   │   ├── deembeder.py         # PII detection and replacement (Python)
│   │   └── reconstructor.py     # PII restoration (Python)
│   ├── hooks/
│   │   ├── useAuth.ts           # Firebase authentication hook
│   │   └── useChat.ts           # Firestore chat persistence hook
│   ├── lib/
│   │   ├── gemini.ts            # Gemini API client
│   │   ├── claude.ts            # Claude API client
│   │   ├── privacyPipeline.ts   # Frontend API calls to privacy server
│   │   └── firebase.ts          # Firebase configuration
│   ├── pages/
│   │   └── Index.tsx            # Main chat page — orchestrates pipeline
│   └── types/
│       └── chat.ts              # Message and Conversation types
└── package.json

How It Works

  1. User types a prompt → saved to Firestore as-is
  2. Deembeder strips all sensitive data locally (regex + Ollama), producing a sanitized prompt and a sensitive_info map
  3. Sanitized prompt is sent to the cloud LLM (Gemini or Claude) — no PII leaves the device
  4. LLM responds using placeholders like [NAME_1], [ADDRESS_1]
  5. Reconstructor swaps placeholders back to real values
  6. Final response is shown to the user with all personal data intact

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

aegis_local-0.1.0.tar.gz (18.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

aegis_local-0.1.0-py3-none-any.whl (16.6 kB view details)

Uploaded Python 3

File details

Details for the file aegis_local-0.1.0.tar.gz.

File metadata

  • Download URL: aegis_local-0.1.0.tar.gz
  • Upload date:
  • Size: 18.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for aegis_local-0.1.0.tar.gz
Algorithm Hash digest
SHA256 4eeaa031f1506a52cf2df5eb09d0e20b4ec4644109b92351283b8857e711fbc8
MD5 e881262bb861adbbed68c799022fb178
BLAKE2b-256 d5da4ea73193197b5f052bb39e55b17573cd29959338649e81c62571aef44567

See more details on using hashes here.

File details

Details for the file aegis_local-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: aegis_local-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for aegis_local-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 84ee4bbc7c6bd32d53e6589e404e7c9356005cc0c4855cd7dcdaf8e1e0a58bae
MD5 c2a1df4f892b2653623414a4e358facf
BLAKE2b-256 ff88620f6d5bcd850920270e9fdf7e521a897c46b817c256afd7e3be8d28a198

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page