Base Chat Reference Application

repository·main·Indexed 41 days ago

https://github.com/ragieai/basechat

A multi-tenant RAG (Retrieval-Augmented Generation) chatbot reference application that connects knowledgebases via Ragie Connect. It supports standard and agentic (Deep Search) retrieval modes, integrates with multiple LLM providers, and includes features for tenant management, file uploads up to 500MB, and authentication.

Tokens
6.4K
Snippets
24
Records
29
Agent score
50%

What's inside Base Chat

  1. Deploy Base Chat using Docker

    main

    You can build and run Base Chat using Docker. Ensure you have a .env file prepared with the required environment variables before running the container.

    # Build Docker image
    docker build -t basechat .
    
    # Run container (adjust environment variables as needed)
    docker run -p 3000:3000 --env-file .env basechat
  2. Install and set up Base Chat locally

    main

    To run Base Chat locally, you need Node.js 22+, a PostgreSQL database, a Ragie API key, LLM provider keys, and Google OAuth credentials. Follow these steps:

    1. Clone and install dependencies:

      git clone https://github.com/ragieai/basechat.git
      cd basechat
      npm install
    2. Database setup: Create a PostgreSQL database named basechat:

      createdb basechat
    3. Environment configuration: Copy the template and edit .env with your credentials:

      cp env.example .env
    4. Run migrations:

      npm run db:migrate
    5. Start the server:

      npm run dev

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

    git clone https://github.com/ragieai/basechat.git
    cd basechat
    npm install
    createdb basechat
    cp env.example .env
    npm run db:migrate
    npm run dev
  3. Configure environment variables for Base Chat

    main

    Base Chat requires several environment variables to function. You must provide a database connection, a Ragie API key, Google OAuth credentials for authentication, an encryption key, and at least one LLM provider key.

    Required Minimums:

    • DATABASE_URL: PostgreSQL connection string.
    • RAGIE_API_KEY: API key from Ragie.
    • AUTH_GOOGLE_ID: Google OAuth client ID.
    • AUTH_GOOGLE_SECRET: Google OAuth client secret.
    • ENCRYPTION_KEY: A 32-byte hex key. Generate it using: openssl rand -hex 32.
    • At least one LLM key: OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, ANTHROPIC_API_KEY, or GROQ_API_KEY.
  4. How Chatbot handles standard vs agentic retrieval

    main

    The Chatbot component supports two distinct interaction modes:

    1. Standard Retrieval: Uses the submit function from useObject to send a CreateConversationMessageRequest to /api/conversations/${conversationId}/messages. This mode supports settings like isBreadth, rerankEnabled, and prioritizeRecent.

    2. Agentic Retrieval (Deep Search): Triggered when retrievalMode is set to 'agentic'. Instead of a standard API call, it uses agenticSubmit from the useAgenticRetrieverContext. It constructs a context-rich query by concatenating previous messages with a CONTEXT_END_DELIMITER and the new user message. It also manages specialized lifecycle callbacks (onStart, onDone, onError) to update the UI with step-by-step reasoning and final results.

    When in agentic mode, the component uses AgenticResponse to visualize the reasoning steps and AgenticResponseContainer to reconstruct past agentic runs from the conversation history.

  5. Disable import order linting via environment variable

    main

    The ESLint configuration for this project includes a rule for import/order. You can bypass this rule by setting the DISABLE_IMPORT_ORDER environment variable to "true". When enabled, the rule enforces specific grouping (builtin, external, internal, parent, sibling, index), mandatory newlines between groups, and ascending alphabetical order.

    DISABLE_IMPORT_ORDER=true npm run lint
  6. Configure Drizzle ORM with PostgreSQL

    main

    The project uses Drizzle ORM for database management. To configure the Drizzle Kit environment, you must provide a DATABASE_URL via an environment variable. The configuration specifies the postgresql dialect, points to the schema definition at ./lib/server/db/schema.ts, and uses the DATABASE_URL for credentials.

    import { defineConfig } from "drizzle-kit";
    import "dotenv";
    
    export default defineConfig({
      dialect: "postgresql",
      schema: "./lib/server/db/schema.ts",
      dbCredentials: {
        url: process.env.DATABASE_URL,
      },
    });
  7. Configure LLM Providers and Models via PROVIDER_CONFIG

    main

    The PROVIDER_CONFIG object is the central registry for all supported LLM providers, their available models, logos, display names, and specific model configurations (like temperature and systemPrompt).

    Supported providers include:

    • openai
    • google
    • anthropic
    • groq

    When adding a new provider, you must define its models, logo, modelLogos, displayNames, and modelConfigs within this object. Note that some models (like gpt-5 or meta-llama/llama-4-scout-17b-16e-instruct) use specialized systemPrompt values to enforce JSON output formats.

    export const PROVIDER_CONFIG = {
      openai: {
        models: ["gpt-4o", "gpt-4.1-2025-04-14", "o3-2025-04-16", "gpt-5", "gpt-5.1"] as const,
        logo: "/openai.svg",
        // ...
        modelConfigs: {
          "gpt-5": { temperature: 1, systemPrompt: GPT_5_PROMPT },
          // ...
        },
      },
      // ...
    } as const;
  8. Reference: Environment Variables

    main

    The following environment variables are used to configure Base Chat. Refer to env.example for the full list.

    | Variable                     | Description                              | Required         |
    | ---------------------------- | ---------------------------------------- | ---------------- |
    | DATABASE_URL                 | PostgreSQL connection string             | Yes              |
    | RAGIE_API_KEY                | API key from Ragie                       | Yes              |
    | OPENAI_API_KEY               | OpenAI API key                           | One LLM required |
    | GOOGLE_GENERATIVE_AI_API_KEY | Google AI API key                        | One LLM required |
    | ANTHROPIC_API_KEY            | Anthropic API key                        | One LLM required |
    | GROQ_API_KEY                 | Groq API key                             | One LLM required |
    | AUTH_GOOGLE_ID               | Google OAuth client ID                   | Yes              |
    | AUTH_GOOGLE_SECRET           | Google OAuth client secret               | Yes              |
    | ENCRYPTION_KEY               | 32-byte hex key for encryption           | Yes              |
    | STORAGE_*                     | Object storage settings for logo uploads | No               |
  9. Reference: Available npm scripts

    main

    Use these scripts to manage the development and production lifecycle of Base Chat.

    - `npm run dev` - Start development server
    - `npm run build` - Build for production
    - `npm run start` - Start production server
    - `npm run db:migrate` - Run database migrations
    - `npm run update-api-key` - Update your Ragie API key
  10. Use the Chatbot component

    main

    The Chatbot component is the primary UI entrypoint for user interaction. It manages conversation state, handles both standard and agentic (Deep Search) retrieval modes, and integrates with a backend via API calls. It requires a conversationId and a tenant object to manage context and permissions.

    Key props:

    • conversationId: The unique identifier for the current chat session.
    • tenant: The tenant object (inferred from the database schema) containing configuration like name, slug, logoUrl, and id.
    • initMessage (optional): A string to trigger an initial message upon mounting.
    • onSelectedSource: A callback function invoked when a user selects a source from an assistant message.
    • onMessageConsumed (optional): A callback invoked after an initMessage is processed.
    import Chatbot from "./components/chatbot";
    
    // Example usage:
    <Chatbot 
      conversationId="conv_123" 
      tenant={tenantData} 
      onSelectedSource={(source) => console.log(source)} 
    />
  11. Validate a file for upload

    main

    Use validateFile to check if a File object meets the application's requirements regarding extension, MIME type, and size. It returns a FileValidationResult object.

    Validation Rules:

    • The file extension must be present in VALID_FILE_TYPES.
    • The file's MIME type must be present in VALID_FILE_TYPES.
    • The file size must be less than 500MB.

    Returns:

    • { isValid: true } if valid.
    • { isValid: false, error: string } if invalid, where the error string provides the reason (e.g., "Please upload a supported file type" or "File size must be less than 500MB").
    const result = validateFile(myFile);
    if (!result.isValid) {
      console.error(result.error);
    }
  12. Retrieve the active plan using getCurrentPlan()

    main

    The getCurrentPlan function extracts the currently active TenantPlan from a TenantMetadata object. A plan is considered active if its endedAt property is null. This is useful for determining a tenant's current subscription tier and seat limits during runtime.

    import { getCurrentPlan, TenantMetadata } from './lib/billing/tenant';
    
    const metadata: TenantMetadata = {
      plans: [
        { id: 'sub_123', name: 'developer', endedAt: null, startedAt: new Date(), tier: 'tier_dev', seats: 1 },
        { id: 'sub_456', name: 'pro', endedAt: new Date(), startedAt: new Date(), tier: 'tier_pro', seats: 10 }
      ]
    };
    
    const activePlan = getCurrentPlan(metadata);
    // activePlan will be the 'developer' plan because endedAt is null