Skip to content

sidgyl-anz/guardrailsfe

Repository files navigation

Safe Health Chat

Safe Health Chat is a responsive, secure, health-focused chat application built with Next.js and Firebase. It leverages the Perplexity AI API to provide users with safe and informative answers to their health-related questions. The application features user authentication, persistent chat history, configurable information source filtering, integrated safety guardrails, and rich inline citations

Features

  • User Authentication: Secure sign-up and login using Firebase Authentication (email/password).
  • Persistent Chat History: Conversations are automatically saved to Firestore for each user. Users can view, resume, and delete past conversations from a collapsible sidebar.
  • Health-Focused AI Chat: A clean chat interface for interacting with the Perplexity AI API (sonar-pro model).
  • Configurable Information Sources: Users can restrict the AI's search to specific trusted domains (e.g., medlineplus.gov).
  • Safety Guardrails: All user inputs and AI outputs are processed by an external guardrail service to ensure safety and appropriateness. Blocked messages are clearly indicated.
  • Rich Inline Citations: AI responses include inline citations [1][2] that, on click, reveal a popover with links to the source articles.
  • Developer Debug View: A collapsible panel shows the raw JSON for the last API request and response, aiding in development and debugging.
  • Responsive Design: The UI is built with ShadCN UI and Tailwind CSS, ensuring a great experience on both desktop and mobile devices.

Tech Stack

Architecture & Project Structure

The application follows a standard Next.js App Router structure, with Firebase integration for backend services.

.
├── src
│   ├── app
│   │   ├── api/guardrails/route.ts   # Backend proxy for the guardrails service
│   │   ├── globals.css               # Global styles and Tailwind directives
│   │   ├── layout.tsx                # Root layout
│   │   └── page.tsx                  # The main chat page component
│   │
│   ├── components
│   │   ├── ui/                       # ShadCN UI components
│   │   ├── auth-dialog.tsx           # Login/Sign-up modal
│   │   ├── chat-message.tsx          # Renders a single chat message
│   │   ├── conversation-history.tsx  # Sidebar for managing conversations
│   │   ├── debug-view.tsx            # Displays API request/response JSON
│   │   ├── guardrail-result-dialog.tsx # Dialog to show raw guardrail JSON
│   │   ├── settings-dialog.tsx       # Dialog for managing settings
│   │   └── user-menu.tsx             # Dropdown menu for authenticated user
│   │
│   ├── firebase
│   │   ├── client-provider.tsx       # Provides Firebase context to the client
│   │   ├── config.ts                 # Firebase project configuration
│   │   ├── firestore/                # Firestore-related hooks (useCollection)
│   │   └── index.ts                  # Firebase initialization and exports
│   │
│   ├── hooks
│   │   ├── use-settings.ts           # Custom hook to manage and persist user settings
│   │   └── use-toast.ts              # Custom hook for displaying toast notifications
│   │
│   ├── lib
│   │   └── types.ts                  # TypeScript type definitions
│   │
│   └── ai
│       ├── flows/chat.ts             # Genkit flow to call the Perplexity AI API
│       └── genkit.ts                 # Genkit initialization and configuration
│
├── .env                              # Environment variables (for API keys)
├── firestore.rules                   # Firestore security rules
├── next.config.ts                    # Next.js configuration
└── tailwind.config.ts                # Tailwind CSS configuration

Key Components

  • src/app/page.tsx: The main client component that manages the chat state, user input, and orchestrates calls to the AI, guardrails, and Firestore.
  • src/firebase/*: This directory contains all Firebase-related logic, including initialization, authentication hooks (useUser, useAuth), and real-time Firestore hooks (useCollection).
  • src/components/conversation-history.tsx: A stateful component that fetches and displays the user's conversation history from Firestore, allowing them to switch between or delete chats.
  • src/ai/flows/chat.ts: A server-side Genkit flow that acts as a secure wrapper around the Perplexity AI API. It receives the chat history from the client and forwards the request with the necessary credentials.
  • src/hooks/use-settings.ts: This custom hook manages user-configurable settings. It syncs settings between localStorage (for logged-out users) and Firestore (for logged-in users).

Configuration and Setup

To run this project locally, you need to configure your environment variables and set up Firebase.

1. Environment Variables

Create a .env file in the root of the project and add your API keys and service URLs:

PERPLEXITY_API_KEY="your_perplexity_api_key_here"
NEXT_PUBLIC_FIREBASE_API_KEY="your_firebase_web_api_key"

You can get a Perplexity API key from the Perplexity AI Developer Portal. The Firebase Web API key is available in your Firebase project's web app settings.

2. Firebase Setup

This project uses Firebase for authentication and Firestore as a database.

  1. Create a new Firebase project in the Firebase Console.
  2. Add a new Web App to your project.
  3. Copy the Firebase configuration object and paste it into src/firebase/config.ts, replacing the NEXT_PUBLIC_FIREBASE_API_KEY environment variable value in your .env file.
  4. In the Firebase Console, go to Authentication -> Sign-in method and enable the Email/Password provider.
  5. Go to Firestore Database, create a database, and start in Production mode. You will apply security rules in the next step.

3. Firestore Security Rules

Copy the contents of the firestore.rules file from this project and paste them into the Rules tab of your Firestore database in the Firebase Console. Publish the changes.

4. Install Dependencies

Install the project dependencies using npm:

npm install

5. Running the Development Server

Start the Next.js development server:

npm run dev

The application will be available at http://localhost:9002.

Required Inputs & External Dependencies

The chat flow depends on a few explicit inputs and files. The project will not boot (or will crash at runtime) if any of these requirements are missing:

  • Environment variables
    • PERPLEXITY_API_KEY: Required by the server-side Genkit flow in src/ai/flows/chat.ts. If it is undefined the API call short-circuits with PERPLEXITY_API_KEY is not defined in environment variables.
    • NEXT_PUBLIC_FIREBASE_API_KEY: Used by src/firebase/config.ts to initialize Firebase when running locally. The file throws an error when the value is absent, so populate it even if you rely on Firebase App Hosting defaults in production.
  • .env file
    • Create the file in the project root and define the variables above. Any other Firebase values (auth domain, project ID, etc.) should be duplicated from your Firebase console when you customize src/firebase/config.ts.
  • Firebase configuration file
    • The template in src/firebase/config.ts contains a placeholder project. Replace the projectId, appId, authDomain, and other fields with your project's metadata if you are not using Firebase App Hosting auto-configuration.
  • Firestore security rules
    • The firestore.rules file in the root of the repo must be deployed to the same Firebase project that the app talks to. Without those rules, reads and writes performed by hooks such as useCollection will fail.
  • Firestore data layout
    • User-specific data is stored under the users/{uid} document. The use-settings hook stores searchDomains, systemPrompt, and useGuardrails on that document, so the authenticated user needs write access there.
    • Conversations live at users/{uid}/conversations/{conversationId} with fields title and createdAt (serverTimestamp). Each conversation also contains a messages sub-collection with documents shaped like ChatMessage in src/lib/types.ts (role, content, createdAt, optional references, guardrailResult, and isBlocked). Ensure your Firestore rules allow these nested writes.
  • Guardrails service
    • src/app/actions.ts posts to the Cloud Run URL stored in GUARDRAILS_URL. Update that constant (or replace it with an environment variable) so it points at your guardrail endpoint.
    • The service must accept JSON payloads that include either user_prompt or llm_response (or both) and return a JSON object with at least is_safe: boolean. Optional fields such as prompt_processed or llm_response_processed are honored if present; the UI stores the raw response in guardrailResult for auditing.
  • /api/chat payload contract
    • The frontend sends requests to POST /api/chat (handled by src/app/api/chat/route.ts). The body must be valid JSON that follows the ChatInput schema defined in src/ai/flows/chat.ts: a messages array of {role: 'user' | 'assistant', content: string} objects, an optional system string, and an optional search_domain_filter string array. The server rejects requests that cannot be parsed or do not contain at least one non-empty user message.

6. Deploying to Vercel

You can deploy this project to Vercel in just a few steps:

  1. Create a Vercel Project

    • Sign in to Vercel and click Add New... → Project.
    • Import this GitHub repository (or your fork) and select the main branch.
  2. Configure Environment Variables

    • In the new project's Settings → Environment Variables, add the same variables defined in your local .env file (e.g., PERPLEXITY_API_KEY, Firebase config values, and any custom guardrail URLs).
    • Repeat the variables for each environment (Production, Preview, and optionally Development) so your previews behave like production.
  3. Set the Build Configuration

    • Vercel automatically detects Next.js projects. Ensure the build command is npm run build and the output directory remains the default .next.
    • If you use a custom Node.js version locally, set Environment → General → Node.js Version to match (the project currently targets Node 18 LTS).
  4. Link Firebase

    • Add your Firebase project's authorized domains by navigating to Firebase Console → Authentication → Settings → Authorized Domains and adding your *.vercel.app domain so hosted builds can sign in users.
  5. Trigger the Deployment

    • Click Deploy in Vercel. Each push to the selected branch (and pull requests) will automatically create new deployments. Use the Preview URL to test before promoting to production.

Once deployed, Vercel will handle SSL, CDN caching, and automatic scaling, so no additional infrastructure is required.

How It Works

  1. A user signs up or logs in via the AuthDialog. The useUser hook provides their authentication state throughout the app.
  2. The ConversationHistory component fetches the user's past conversations from /users/{userId}/conversations in Firestore.
  3. The user types a message in the Textarea on the main page. If no conversation is active, a new one is created in Firestore.
  4. On submission, the user's prompt is optionally sent to the guardrails service.
  5. The safe prompt is written as a new document to /users/{userId}/conversations/{convoId}/messages.
  6. The safeHealthChat Genkit flow is invoked with the current conversation history.
  7. The flow calls the Perplexity AI API. The AI's response is optionally sent to the guardrails service.
  8. The safe AI response is written as another new message to Firestore.
  9. The useCollection hook listens for these changes in real-time, and the UI updates automatically to display the new messages.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages