This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Documentation

This set of docs serves as a reference for the catb project, which is an LLM-based chatbot designed to assist cat owners with theit pets’ health and well-being.

1 - Overview

Description of what the catb project is

Catb is a chatbot helping cat owners understand their cats behaviorial issues so they can take action to solve them.

Catb asks discovery questions about owners’ cats and provides explanations and guidance.

The call to action can range from adapting their interactions or home setting to help with their pets reach optimal mental health all the way to taking their pets to emergency care facilities.

Catb acts as a informed friend that soothes the owners’s anxiety while providing qualified guidance.

Where should I go next?

2 - CATB MVP Technical Specifications

Technical specifications for the CATB MVP implementation

CATB MVP Technical Specifications

Table of Contents

  1. System Overview
  2. Architecture
  3. Frontend Architecture
  4. Backend Architecture
  5. Database Schema
  6. Authentication System
  7. AI Integration
  8. Infrastructure & Deployment
  9. Security
  10. API Reference
  11. Development & Operations
  12. Cost Structure

System Overview

Project Description

catb (Cat Health Chatbot) is a production-ready full-stack application providing empathetic cat health guidance through an AI-powered chat interface. The system uses Anthropic’s Claude Sonnet 4 with a custom “Mu” system prompt to deliver personalized, context-aware responses using a progressive discovery approach.

Brand Name: Ask Mü Production URL: https://askmu.live Status: ✅ Fully Operational Deployment Date: September 2025 Last Major Update: October 2025 (Session-email association fix, ProfileService integration)

Current Production Status

  • Frontend: React SPA deployed in Docker container (port 3001)
  • Backend: Express 5.1.0 API deployed in Docker container (port 3000)
  • Database: Supabase PostgreSQL (connected and operational)
  • AI: Claude Sonnet 4 with Mu system prompt v3
  • Infrastructure: Hostinger VPS at 89.116.170.226
  • Domain: askmu.live with SSL (Let’s Encrypt)
  • Authentication: Magic link email system with 24-hour sessions

Technology Stack Summary

Layer Technology Version Purpose
Frontend React 18+ UI framework
Tailwind CSS 3+ Styling
Radix UI Latest Accessible components
Framer Motion Latest Animations
Vite Latest Build tool
Backend Node.js 20 LTS Runtime
Express 5.1.0 Web framework
@anthropic-ai/sdk 0.17.1 Claude API client
@langchain/anthropic 0.3.28 LangChain integration
@supabase/supabase-js 2.39.0 Database client
Resend 2.1.0 Email service
Database PostgreSQL 15 Supabase managed
Infrastructure Ubuntu 24.04 LTS VPS OS
Nginx Latest Reverse proxy
Docker Latest Containerization
Let’s Encrypt - SSL certificates

Access Points


Architecture

High-Level System Architecture

┌─────────────────────────────────────────────────────────────────┐
│                          Internet                                │
│                     (HTTPS - Port 443)                           │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                    Hostinger VPS                                 │
│                  (89.116.170.226)                                │
│                                                                   │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │  Nginx Reverse Proxy (Ports 80/443)                       │  │
│  │  • SSL Termination (Let's Encrypt)                        │  │
│  │  • Request Routing                                        │  │
│  │  • Security Headers                                       │  │
│  └──────┬────────────────────────────────┬──────────────────┘  │
│         │                                 │                      │
│         ▼                                 ▼                      │
│  ┌──────────────────┐            ┌──────────────────┐          │
│  │ Frontend         │            │ Backend API      │          │
│  │ Docker Container │            │ Docker Container │          │
│  │ Port 3001        │            │ Port 3000        │          │
│  │ (React SPA)      │◄──────────►│ (Express 5.1.0)  │          │
│  └──────────────────┘            └────────┬─────────┘          │
│                                            │                      │
└────────────────────────────────────────────┼─────────────────────┘
                                             │
                    ┌────────────────────────┼──────────────────┐
                    │                        │                  │
                    ▼                        ▼                  ▼
           ┌────────────────┐    ┌────────────────┐  ┌──────────────┐
           │ Supabase       │    │ Anthropic      │  │ Resend       │
           │ PostgreSQL     │    │ Claude API     │  │ Email API    │
           │ (Database)     │    │ (AI Service)   │  │ (Magic Links)│
           └────────────────┘    └────────────────┘  └──────────────┘

Component Relationships

Frontend (React)
    │
    ├──> State Management (React Hooks + localStorage)
    ├──> UI Components (Radix UI + Tailwind)
    ├──> API Client (fetch)
    │
    └──> Backend API (Express)
            │
            ├──> Authentication Layer
            │    ├──> Magic Link System (Resend)
            │    ├──> Session Management (Supabase)
            │    └──> Token Validation
            │
            ├──> Chat Endpoint
            │    ├──> Mu Prompt System
            │    │    ├──> Context Analyzer
            │    │    ├──> Memory System
            │    │    └──> LangChain User Profiler
            │    │
            │    ├──> Claude AI Integration
            │    ├──> ProfileService
            │    └──> Conversation History
            │
            ├──> Database Layer (db.js)
            │    ├──> User Management
            │    ├──> Session Management
            │    ├──> Message Storage
            │    └──> Context Tracking
            │
            └──> Enhanced Systems
                 ├──> Pattern Detection Engine
                 ├──> Feedback System
                 └──> Smart Deployment System

Data Flow

User → Frontend → Nginx → Backend API → Claude AI
                                    ↓
                                    Supabase DB
                                    ↓
                          Backend API → Frontend → User

Detailed Flow:

  1. User sends message from React interface
  2. Frontend sends authenticated request to backend
  3. Nginx routes /api/* requests to backend (port 3000)
  4. Backend validates session token via Supabase
  5. Backend retrieves conversation history
  6. Mu Prompt System generates dynamic prompt
  7. LangChain profiler analyzes user communication style
  8. Backend sends context + message to Claude API
  9. Claude generates empathetic response
  10. Backend saves message pair to database
  11. Backend returns response to frontend
  12. Frontend displays reply with animations

Frontend Architecture

Technology Stack

  • Framework: React 18+
  • Styling: Tailwind CSS 3+
  • UI Components: Radix UI (accessible primitives)
  • Animations: Framer Motion
  • Build Tool: Vite
  • Deployment: Docker container (Nginx serving static files)

Application Structure

catb-frontend/
├── src/
│   ├── components/         # Reusable UI components
│   │   ├── ChatBubble.jsx
│   │   ├── ChatInput.jsx
│   │   ├── LoadingIndicator.jsx
│   │   └── EmergencyAlert.jsx
│   │
│   ├── pages/             # Application pages
│   │   ├── Home.jsx
│   │   ├── Chat.jsx
│   │   └── Auth.jsx
│   │
│   ├── lib/               # Utilities and helpers
│   │   ├── api.js         # API client
│   │   └── auth.js        # Auth helpers
│   │
│   ├── hooks/             # Custom React hooks
│   │   ├── useAuth.js
│   │   └── useChat.js
│   │
│   ├── styles/            # Global styles
│   │   └── globals.css
│   │
│   ├── App.jsx            # Main app component
│   └── main.jsx           # Entry point
│
├── public/                # Static assets
│   ├── favicon.svg
│   ├── mascot.png
│   └── doctor.gif
│
├── Dockerfile             # Frontend Docker config
├── nginx.conf             # Nginx configuration
├── tailwind.config.js     # Tailwind configuration
├── vite.config.js         # Vite configuration
└── package.json

Key Features

Mobile-First Responsive Design

  • Optimized for mobile devices (primary use case: worried pet owners)
  • Touch-friendly UI elements
  • Responsive breakpoints for tablet and desktop

State Management

  • React hooks for local state
  • localStorage for session persistence
  • No external state management library (keeping it simple)

API Integration

// API client pattern
const apiClient = {
  baseURL: 'https://askmu.live/api',

  async chat(message, sessionToken) {
    const response = await fetch(`${this.baseURL}/chat`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message, sessionToken })
    });
    return response.json();
  }
};

Docker Containerization

Dockerfile (Multi-stage build):

# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Deployment:

  • Container name: catb-frontend
  • Internal port: 80
  • External port: 3001
  • Served by Nginx within container
  • Static assets included in image

Backend Architecture

Express 5.1.0 Application Structure

catb-backend/
├── server.js                    # Main Express application
├── db.js                        # Database abstraction layer
├── auth-routes.js               # Authentication endpoints
├── auth-utils.js                # Auth utilities
├── email-service.js             # Magic link email service
├── profile-service.js           # User/cat profile management
│
├── lib/                         # Core libraries
│   ├── mu-prompt-system.js      # Main prompt orchestrator
│   ├── conversation-context-analyzer.js
│   ├── conversation-memory-system.js
│   ├── simple-template-engine.js
│   ├── enhanced-feedback-system.js
│   ├── pattern-detection-engine.js
│   ├── smart-deployment-system.js
│   └── langchain/
│       └── langchain-user-profiler.js
│
├── prompts/                     # PromptL templates
│   ├── base-prompt.promptl
│   └── [additional templates]
│
├── migrations/                  # Database migrations
│   └── 000-complete-fresh-schema.sql
│
├── scripts/                     # Utility scripts
│   ├── deploy-to-vps.sh
│   ├── db-connection-helper.js
│   ├── execute-sql.js
│   └── run-daily-workflow.js
│
├── test/                        # Test files
│   ├── test-session-email-fix.js
│   └── comprehensive-auth-test.js
│
├── Dockerfile
├── docker-compose.yml
├── package.json
└── .env

Core Dependencies

{
  "dependencies": {
    "express": "^5.1.0",
    "@anthropic-ai/sdk": "^0.17.1",
    "@langchain/anthropic": "^0.3.28",
    "@langchain/core": "^0.3.77",
    "@langchain/langgraph": "^0.4.9",
    "@supabase/supabase-js": "^2.39.0",
    "cors": "^2.8.5",
    "helmet": "^7.1.0",
    "express-rate-limit": "^7.1.5",
    "resend": "^2.1.0",
    "redis": "^5.8.2",
    "pg": "^8.16.3",
    "validator": "^13.15.15",
    "zod": "^3.25.76"
  }
}

API Endpoints

Public Endpoints

Method Endpoint Description Auth Required
GET /health System health check No
POST /session/create Create authenticated session No
POST /auth/request-invite Request magic link No
GET /auth/verify Verify magic link token No

Protected Endpoints (Require sessionToken)

Method Endpoint Description Rate Limit
POST /chat or /api/chat Main chat endpoint 10 req/min
POST /api/feedback/submit Submit user feedback 10 req/min
GET /api/dashboard/metrics System metrics 10 req/min
GET /api/patterns/recent Recent patterns 10 req/min

Middleware Stack

// server.js middleware chain
app.use(helmet());                    // Security headers
app.use(cors(corsOptions));           // CORS policy
app.use(express.json());              // JSON body parser
app.use(rateLimiter);                 // Rate limiting (Redis + memory fallback)
app.use(inputValidator);              // Input sanitization

Session Management

Modern Authentication Flow (October 2025 Update):

  • ✅ Uses user_sessions table with proper foreign keys
  • ✅ All sessions linked to email addresses
  • ❌ Legacy sessions table fallback removed
  • Session validation: db.validateUserSession(sessionToken)
// Session validation (server.js)
const userSession = await db.validateUserSession(sessionToken);
if (!userSession.valid) {
  return res.status(401).json({
    error: 'Invalid or expired session'
  });
}

sessionId = userSession.sessionId;
userId = userSession.userId;  // Always available!

Claude AI Integration

Configuration:

import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic({
  apiKey: process.env.ANTHROPIC_API_KEY
});

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 300,
  messages: conversationHistory
});

Cost Control:

  • Max tokens per response: 300
  • Input tokens: $3 per 1M tokens
  • Output tokens: $15 per 1M tokens
  • Average cost per interaction: $0.001-0.005

ProfileService Integration

Features:

  • User profile management (name, email, preferences)
  • Cat profile management (name, age, breed, gender, medical history)
  • Profile restoration across sessions
  • Validation with Zod schemas
  • LangChain integration for behavioral profiling
// ProfileService usage
const profiles = await profileService.restoreProfileForSession(userId);
// Returns: { userProfile, catProfile }

Security Features

  1. Input Validation: All inputs sanitized with validator library
  2. Rate Limiting: Redis-backed with in-memory fallback (10 req/min)
  3. CORS: Strict origin policy (https://askmu.live)
  4. Helmet: Security headers (CSP, HSTS, X-Frame-Options)
  5. Container Security: Non-root user, read-only filesystem
  6. Port Binding: Backend only accessible via nginx (127.0.0.1:3000)

Database Schema

Supabase PostgreSQL Configuration

Connection:

  • URL: https://PROJECT_REF.supabase.co
  • Client: @supabase/supabase-js (JavaScript CRUD)
  • Direct: PostgreSQL client (DDL operations)
  • Authentication: Service role key

Core Tables

users

CREATE TABLE users (
  user_id SERIAL PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  last_login TIMESTAMP WITH TIME ZONE,
  is_active BOOLEAN DEFAULT true,
  invitation_sent_at TIMESTAMP WITH TIME ZONE,
  first_login_at TIMESTAMP WITH TIME ZONE,
  CONSTRAINT email_format CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
);

CREATE INDEX idx_users_email ON users(email);
CREATE TABLE magic_links (
  link_id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
  token TEXT UNIQUE NOT NULL,
  expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
  used_at TIMESTAMP WITH TIME ZONE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  ip_address INET,
  user_agent TEXT,
  CONSTRAINT token_length CHECK (length(token) >= 32)
);

user_sessions

CREATE TABLE user_sessions (
  session_id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
  session_token TEXT UNIQUE NOT NULL,
  expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
  is_active BOOLEAN DEFAULT true,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  last_activity TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  ip_address INET,
  user_agent TEXT,
  CONSTRAINT session_token_length CHECK (length(session_token) >= 32)
);

CREATE INDEX idx_user_sessions_token ON user_sessions(session_token);
CREATE INDEX idx_user_sessions_user ON user_sessions(user_id, is_active);
CREATE INDEX idx_user_sessions_active ON user_sessions(is_active, expires_at);

messages

CREATE TABLE messages (
  message_id SERIAL PRIMARY KEY,
  session_id INTEGER REFERENCES user_sessions(session_id) ON DELETE CASCADE,
  user_id INTEGER REFERENCES users(user_id) ON DELETE CASCADE,
  sender VARCHAR(20) NOT NULL CHECK (sender IN ('user', 'assistant')),
  message_text TEXT NOT NULL,
  token_count INTEGER,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  message_metadata JSONB DEFAULT '{}'::jsonb
);

CREATE INDEX idx_messages_user ON messages(user_id, created_at DESC);
CREATE INDEX idx_messages_session ON messages(session_id, created_at DESC);

conversation_context

CREATE TABLE conversation_context (
  context_id SERIAL PRIMARY KEY,
  session_id INTEGER REFERENCES user_sessions(session_id) ON DELETE CASCADE,
  message_id INTEGER,
  context_type VARCHAR(50) NOT NULL DEFAULT 'general',
  context_data JSONB NOT NULL DEFAULT '{}',
  user_id INTEGER REFERENCES users(user_id),
  cat_name VARCHAR(100),
  cat_age INTEGER,
  cat_breed VARCHAR(100),
  cat_gender VARCHAR(20),
  current_symptoms TEXT[],
  anxiety_level VARCHAR(20),
  experience_level VARCHAR(20),
  communication_style VARCHAR(20),
  emotional_state VARCHAR(30),
  conversation_phase VARCHAR(30),
  question_count INTEGER DEFAULT 0,
  topics_discussed TEXT[],
  urgency_indicators TEXT[],
  information_completeness JSONB DEFAULT '{}',
  confidence_score DECIMAL(3,2),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT conversation_context_session_message_type_key
    UNIQUE(session_id, message_id, context_type)
);

CREATE INDEX idx_conversation_context_session ON conversation_context(session_id);
CREATE INDEX idx_conversation_context_user ON conversation_context(user_id);

Profile Tables

user_profiles

CREATE TABLE user_profiles (
  profile_id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
  full_name VARCHAR(255),
  timezone VARCHAR(50),
  notification_preferences JSONB DEFAULT '{}',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT unique_user_profile UNIQUE(user_id)
);

cat_profiles

CREATE TABLE cat_profiles (
  cat_id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users(user_id) ON DELETE CASCADE,
  cat_name VARCHAR(100) NOT NULL,
  cat_age INTEGER,
  cat_breed VARCHAR(100),
  cat_gender VARCHAR(20),
  medical_history JSONB DEFAULT '[]',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

Enhanced Tables

feedback_submissions

CREATE TABLE feedback_submissions (
  feedback_id SERIAL PRIMARY KEY,
  session_id INTEGER REFERENCES user_sessions(session_id),
  user_id INTEGER REFERENCES users(user_id),
  feedback_type VARCHAR(50) NOT NULL,
  feedback_data JSONB NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

detected_patterns

CREATE TABLE detected_patterns (
  pattern_id SERIAL PRIMARY KEY,
  pattern_type VARCHAR(100) NOT NULL,
  pattern_data JSONB NOT NULL,
  confidence_score DECIMAL(5,4),
  detected_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

Cleanup Functions

-- Cleanup expired sessions
CREATE OR REPLACE FUNCTION cleanup_expired_user_sessions()
RETURNS void AS $$
BEGIN
  UPDATE user_sessions
  SET is_active = false
  WHERE expires_at < CURRENT_TIMESTAMP AND is_active = true;
END;
$$ LANGUAGE plpgsql;

-- Cleanup expired magic links
CREATE OR REPLACE FUNCTION cleanup_expired_magic_links()
RETURNS void AS $$
BEGIN
  DELETE FROM magic_links
  WHERE expires_at < CURRENT_TIMESTAMP;
END;
$$ LANGUAGE plpgsql;

Authentication System

┌─────────┐                                                    ┌──────────┐
│  User   │                                                    │ Backend  │
└────┬────┘                                                    └────┬─────┘
     │                                                              │
     │ 1. Request Access (email)                                   │
     ├─────────────────────────────────────────────────────────────►
     │                                                              │
     │                                                    2. Create user
     │                                                    3. Generate token
     │                                                    4. Save magic_link
     │                                                              │
     │ 5. Email with magic link ◄───────────────────────────────────┤
     ├──────────────────────────┐                                  │
     │                          │ 6. Click link                     │
     │◄─────────────────────────┘                                  │
     │                                                              │
     │ 7. Verify token                                             │
     ├─────────────────────────────────────────────────────────────►
     │                                                              │
     │                                                    8. Validate token
     │                                                    9. Create session
     │                                                   10. Generate sessionToken
     │                                                              │
     │ 11. Redirect with sessionToken ◄─────────────────────────────┤
     │                                                              │
     │ 12. Store in localStorage                                   │
     ├──────────────────────────┐                                  │
     │◄─────────────────────────┘                                  │
     │                                                              │
     │ 13. Chat with sessionToken                                  │
     ├─────────────────────────────────────────────────────────────►

Endpoints

POST /auth/request-invite

// Request
{
  "email": "user@example.com"
}

// Response
{
  "success": true,
  "message": "Check your email for the invitation link"
}

GET /auth/verify?token=MAGIC_LINK_TOKEN

  • Validates token from database
  • Checks expiration (1 hour)
  • Creates user session (24 hours)
  • Redirects to frontend with sessionToken

3. Create Session (Direct API)

POST /session/create

// Request
{
  "email": "user@example.com"
}

// Response
{
  "sessionToken": "64-character-hex-string",
  "expiresAt": "2025-10-02T18:30:00.000Z",
  "sessionId": 171,
  "userId": 425,
  "isNewUser": false,
  "profiles": {
    "userProfile": { ... },
    "catProfile": { ... }
  }
}

Session Management

Session Lifecycle:

  1. Creation: Generated when user verifies magic link or via /session/create
  2. Duration: 24 hours from creation
  3. Storage: user_sessions table in database
  4. Client Storage: localStorage in browser
  5. Validation: Every API request validates via db.validateUserSession()
  6. Expiration: Automatic after 24 hours
  7. Cleanup: Background job marks expired sessions inactive

Token Format:

  • Length: 64 characters
  • Type: Hexadecimal string
  • Generation: crypto.randomBytes(32).toString('hex')
  • Uniqueness: Database constraint ensures uniqueness

Session Validation (server.js):

// Modern session validation (October 2025)
const userSession = await db.validateUserSession(sessionToken);

if (!userSession.valid) {
  return res.status(401).json({
    error: 'Invalid or expired session',
    message: 'Please request a new invitation to access Ask Mü'
  });
}

// userSession contains:
// - valid: true/false
// - sessionId: integer
// - userId: integer (always present!)
// - email: string (linked via users table)

Email Service (Resend)

Configuration:

import { Resend } from 'resend';

const resend = new Resend(process.env.RESEND_API_KEY);

await resend.emails.send({
  from: 'mu@transactional.askmu.live',
  to: userEmail,
  subject: 'Your invitation to Ask Mü',
  html: magicLinkEmailTemplate
});

DNS Records (configured at Namecheap):

  • SPF: v=spf1 include:_spf.resend.com ~all
  • DKIM: Resend-provided keys
  • DMARC: v=DMARC1; p=none

AI Integration

Anthropic Claude API

Model: claude-sonnet-4-20250514 API Version: @anthropic-ai/sdk 0.17.1 Max Tokens: 300 per response Temperature: 0.7 (balanced creativity)

API Call Pattern:

const response = await anthropic.messages.create({
  model: 'claude-sonnet-4-20250514',
  max_tokens: 300,
  messages: conversationHistory,  // Array of {role, content}
  system: generatedPrompt          // Dynamic Mu prompt
});

Mu Prompt System

Architecture:

MuPromptSystem (Orchestrator)
    │
    ├──> ConversationContextAnalyzer
    │    ├── Analyzes user messages
    │    ├── Extracts cat profile info
    │    ├── Detects urgency signals
    │    └── Identifies communication style
    │
    ├──> ConversationMemorySystem
    │    ├── Retrieves conversation history
    │    ├── Updates context in database
    │    └── Manages conversation phases
    │
    ├──> LangChainUserProfiler
    │    ├── Behavioral profiling (2+ messages)
    │    ├── Communication style detection
    │    ├── Anxiety level assessment
    │    └── Experience level classification
    │
    └──> SimpleTemplateEngine
         ├── Loads PromptL templates
         ├── Interpolates context data
         └── Generates final prompt

Progressive Discovery Protocol:

  1. Max 2 Questions Per Response: Core constraint to avoid overwhelming users
  2. Context-Aware: Analyzes existing information before asking
  3. Urgency-Sensitive: Prioritizes emergency symptoms
  4. Adaptive Tone: Adjusts based on user’s communication style

Example Prompt Structure:

You are Mu, an empathetic cat health assistant.

CURRENT CONTEXT:
- Cat: Luna, 3 years old, female
- Symptoms: vomiting, lethargy
- Anxiety Level: high
- Communication Style: emotional support seeker

CONVERSATION PHASE: symptom_gathering
QUESTIONS ASKED: 1/2

INSTRUCTIONS:
- Ask maximum 2 questions
- Prioritize emergency symptoms
- Use warm, empathetic tone
- Provide actionable guidance

LangChain Integration

User Profiling (lib/langchain/langchain-user-profiler.js):

// Triggered after 2+ user messages
const profile = await langchainProfiler.analyzeUserProfile(
  conversationHistory,
  currentMessage
);

// Returns:
{
  profile: {
    communicationStyle: 'emotional' | 'factual' | 'low-literacy',
    anxietyLevel: 'low' | 'moderate' | 'high' | 'panic',
    experienceLevel: 'first-time' | 'beginner' | 'experienced',
    preferredResponseStyle: 'concise' | 'detailed',
    confidenceLevel: 'low' | 'moderate' | 'high',
    learningPreference: 'step-by-step' | 'overview'
  },
  confidence: {
    overall: 0.85,
    factorScores: { ... }
  },
  personalityProfile: {
    name: 'Anxious First-Timer',
    traits: [...],
    responseGuidance: '...'
  },
  adaptationTriggers: [...]
}

Early Profiling (October 2025):

  • Enabled by default
  • Activates at 2nd user message (previously 3rd)
  • Provides faster personalization
  • Fallback to basic analysis if LangChain fails

Conversation Context

Tracked Data:

  • Cat Profile: name, age, breed, gender
  • Symptoms: current and historical
  • Urgency Signals: emergency, urgent, routine indicators
  • User Traits: anxiety level, experience level, communication style
  • Conversation State: phase, question count, topics discussed
  • Information Completeness: gaps in critical information

Context Updates:

await memorySystem.updateConversationContext(sessionId, {
  catProfile: { name: 'Luna', age: 3 },
  symptoms: ['vomiting', 'lethargy'],
  anxietyLevel: 'high',
  conversationPhase: 'symptom_gathering',
  questionCount: 1
});

Infrastructure & Deployment

VPS Configuration

Provider: Hostinger IP Address: 89.116.170.226 Operating System: Ubuntu 24.04 LTS Resources: Shared VPS plan (~$20-50/month)

Installed Software:

  • Docker & Docker Compose
  • Nginx
  • Certbot (Let’s Encrypt)
  • UFW (Uncomplicated Firewall)
  • fail2ban (brute force protection)

Port Configuration

Port Service Binding Purpose
22 SSH 0.0.0.0 Server access
80 Nginx 0.0.0.0 HTTP → HTTPS redirect
443 Nginx 0.0.0.0 HTTPS termination
3000 Backend 127.0.0.1 Internal only (via nginx)
3001 Frontend 127.0.0.1 Internal only (via nginx)

Nginx Configuration

File: /etc/nginx/sites-enabled/askmu-live

Routing Rules:

# API endpoints → Backend (port 3000)
location ~ ^/api/(.*)$ {
    proxy_pass http://127.0.0.1:3000/$1;  # Rewrite /api/* → /*
}

location /auth/ {
    proxy_pass http://127.0.0.1:3000;
}

location /session/ {
    proxy_pass http://127.0.0.1:3000;
}

location /chat {
    proxy_pass http://127.0.0.1:3000;
}

location /health {
    proxy_pass http://127.0.0.1:3000;
}

# Frontend → React SPA (port 3001)
location / {
    proxy_pass http://127.0.0.1:3001;
    try_files $uri $uri/ /index.html;  # SPA routing
}

# Static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    proxy_pass http://127.0.0.1:3001;
    expires 1y;
    add_header Cache-Control "public, immutable";
}

Docker Configuration

Backend (docker-compose.yml)

version: '3.8'

services:
  app:
    build: .
    container_name: catb-api
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"  # Bind to localhost only
    environment:
      - NODE_ENV=production
      - PORT=3000
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - SUPABASE_URL=${SUPABASE_URL}
      - SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}
      - RESEND_API_KEY=${RESEND_API_KEY}
      - FRONTEND_URL=https://askmu.live
    volumes:
      - ./logs:/app/logs
    healthcheck:
      test: ["CMD", "node", "-e", "fetch('http://localhost:3000/health')"]
      interval: 30s
      timeout: 10s
      retries: 3

Frontend (Dockerfile)

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Deployment Commands:

# Backend
cd /root/catb/
docker-compose down
docker-compose build --no-cache
docker-compose up -d

# Frontend
cd /root/catb-frontend/
docker stop catb-frontend
docker rm catb-frontend
docker build -t catb-frontend . --no-cache
docker run -d --name catb-frontend --restart unless-stopped -p 127.0.0.1:3001:80 catb-frontend

SSL/TLS Configuration

Provider: Let’s Encrypt Auto-Renewal: Certbot cron job Certificate Path: /etc/letsencrypt/live/askmu.live/

Initial Setup:

certbot --nginx -d askmu.live -d www.askmu.live

Renewal:

certbot renew  # Auto-scheduled via cron

Deployment Script

File: scripts/deploy-to-vps.sh

#!/bin/bash
# Deployment script for catb backend

VPS="root@89.116.170.226"
APP_DIR="/root/catb"

# Sync files
rsync -av --exclude 'node_modules' --exclude '.git' \
  ./ ${VPS}:${APP_DIR}/

# Deploy on VPS
ssh ${VPS} << 'EOF'
  cd /root/catb
  docker-compose down
  docker-compose build --no-cache
  docker-compose up -d
  docker ps | grep catb
EOF

echo "✅ Deployment complete"

Directory Structure (VPS)

/root/
├── catb/                      # Backend directory
│   ├── server.js
│   ├── db.js
│   ├── lib/
│   ├── prompts/
│   ├── migrations/
│   ├── scripts/
│   ├── docker-compose.yml
│   ├── Dockerfile
│   ├── .env
│   └── package.json
│
├── catb-frontend/             # Frontend directory
│   ├── src/
│   ├── public/
│   ├── Dockerfile
│   ├── nginx.conf
│   └── package.json
│
└── scripts/                   # System scripts
    ├── setup-ssl.sh
    └── setup-domain.sh

Security

Authentication Security

  1. Magic Link Tokens:

    • 64-character cryptographically secure random strings
    • 1-hour expiration
    • Single-use only (marked as used_at after verification)
    • Stored with user_agent and IP for audit trail
  2. Session Tokens:

    • 64-character cryptographically secure random strings
    • 24-hour expiration
    • Validated on every request
    • Linked to user_id (email association enforced)
  3. Password-less Authentication:

    • No passwords to leak or crack
    • Email-based access control
    • Reduces attack surface

Input Validation

Library: validator v13.15.15

import validator from 'validator';

// Email validation
const isValidEmail = validator.isEmail(email);

// Message sanitization
const sanitizedMessage = validator.escape(message);
validator.isLength(message, { max: 2000 });

// Token validation
const isValidToken = /^[a-f0-9]{64}$/.test(token);

Rate Limiting

Strategy: Redis-backed with in-memory fallback

import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';

const chatLimiter = rateLimit({
  windowMs: 60 * 1000,      // 1 minute
  max: 10,                  // 10 requests per minute
  store: new RedisStore({
    client: redisClient,
    prefix: 'rl:chat:'
  }),
  // Fallback to memory if Redis unavailable
  skipFailedRequests: false,
  standardHeaders: true,
  legacyHeaders: false
});

app.post('/chat', chatLimiter, chatHandler);

Current Status:

  • Redis not deployed (falls back to in-memory)
  • Sufficient for single-instance VPS deployment
  • Consider Redis when scaling horizontally

CORS Configuration

import cors from 'cors';

const corsOptions = {
  origin: 'https://askmu.live',     // Strict origin
  credentials: true,                 // Allow cookies
  methods: ['GET', 'POST', 'OPTIONS'],
  allowedHeaders: ['Content-Type']
};

app.use(cors(corsOptions));

Security Headers (Helmet)

import helmet from 'helmet';

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", "'unsafe-inline'"],
      styleSrc: ["'self'", "'unsafe-inline'"],
      imgSrc: ["'self'", "data:", "https:"]
    }
  },
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  frameguard: {
    action: 'deny'
  }
}));

Container Security

  1. Non-Root User:

    RUN addgroup -g 1001 nodejs && \
        adduser -S chatbot -u 1001
    USER chatbot
    
  2. Read-Only Filesystem: Most directories read-only

  3. Resource Limits:

    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
    
  4. Network Isolation: Backend not exposed to internet (only via nginx)

Environment Variables

Location: /root/catb/.env Permissions: 600 (owner read/write only)

Required Variables:

NODE_ENV=production
PORT=3000
ANTHROPIC_API_KEY=sk-ant-...
SUPABASE_URL=https://...supabase.co
SUPABASE_SERVICE_KEY=eyJ...
DATABASE_URL=postgresql://postgres:...
RESEND_API_KEY=re_...
FRONTEND_URL=https://askmu.live

Security Practices:

  • Never commit .env to git (.gitignore)
  • Use service role keys for backend (not anon keys)
  • Rotate keys periodically
  • Audit access logs

Firewall Configuration

UFW Rules:

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp    # SSH
ufw allow 80/tcp    # HTTP
ufw allow 443/tcp   # HTTPS
ufw enable

API Reference

Authentication Endpoints

POST /session/create

Create authenticated session with email.

Request:

{
  "email": "user@example.com"
}

Response (200):

{
  "sessionToken": "a1b2c3...",
  "expiresAt": "2025-10-02T18:30:00.000Z",
  "sessionId": 171,
  "userId": 425,
  "isNewUser": false,
  "profiles": {
    "userProfile": {
      "full_name": "Jane Doe",
      "timezone": "America/New_York"
    },
    "catProfile": {
      "cat_name": "Luna",
      "cat_age": 3,
      "cat_breed": "Domestic Shorthair"
    }
  }
}

Error Responses:

  • 400: Invalid email format
  • 500: Database error

POST /auth/request-invite

Request magic link via email.

Request:

{
  "email": "user@example.com"
}

Response (200):

{
  "success": true,
  "message": "Check your email for the invitation link"
}

GET /auth/verify

Verify magic link token.

Query Parameters:

  • token: Magic link token (64 characters)

Response:

  • Redirects to frontend with sessionToken
  • Error page if token invalid/expired

Chat Endpoints

POST /chat

Main chat endpoint for user messages.

Authentication: Required (sessionToken in body)

Request:

{
  "message": "My cat has been vomiting",
  "sessionToken": "a1b2c3..."
}

Response (200):

{
  "reply": "I'm sorry to hear Luna isn't feeling well. How long has the vomiting been going on?",
  "timestamp": "2025-10-01T18:30:00.000Z",
  "sessionActive": true,
  "usage": {
    "input_tokens": 142,
    "output_tokens": 183,
    "estimated_cost": "0.000264"
  }
}

Error Responses:

  • 400: Missing message or invalid format
  • 401: Invalid or expired session
  • 429: Rate limit exceeded
  • 500: Server error

Rate Limit: 10 requests per minute

Health Check

GET /health

System health check (no authentication required).

Response (200):

{
  "status": "healthy",
  "timestamp": "2025-10-01T18:30:00.000Z",
  "service": "catb-backend",
  "database": {
    "connected": true,
    "status": "operational"
  },
  "anthropic": {
    "configured": true,
    "status": "ready"
  },
  "promptSystem": {
    "status": "operational"
  },
  "security": {
    "status": "HEALTHY",
    "alerts": 0
  }
}

Error Codes

Code Meaning Common Causes
400 Bad Request Missing required fields, invalid format
401 Unauthorized Invalid/expired session token
403 Forbidden Session expired (>24 hours)
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Database error, Claude API error
503 Service Unavailable Database connection failed

Development & Operations

Local Development Setup

Prerequisites

  • Node.js 20 LTS
  • npm 10+
  • PostgreSQL 15+ (optional, can use Supabase)

Backend Setup

# Clone repository
git clone <repo-url>
cd catb-backend

# Install dependencies
npm install

# Configure environment
cp .env.example .env
# Edit .env with your API keys

# Run locally
npm start
# Server runs on http://localhost:3000

Frontend Setup

cd catb-frontend

# Install dependencies
npm install

# Run development server
npm run dev
# Frontend runs on http://localhost:5173

Testing

Test Scripts

# Backend tests
npm test                    # Run all tests
npm run test:watch          # Watch mode
npm run test:coverage       # Coverage report

# Integration tests
node test/test-session-email-fix.js
node test/comprehensive-auth-test.js

Testing Without curl

Important: curl commands are denied in this environment.

Alternative: Use Node.js test scripts:

# Start local server
PORT=3002 npm start

# Run test in another terminal
node test/test-session-email-fix.js

Example Test Script:

import fetch from 'node-fetch';

const API_BASE = 'http://localhost:3002';

async function testChat() {
  // Create session
  const sessionRes = await fetch(`${API_BASE}/session/create`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ email: 'test@example.com' })
  });
  const { sessionToken } = await sessionRes.json();

  // Send chat message
  const chatRes = await fetch(`${API_BASE}/chat`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      message: 'Test message',
      sessionToken
    })
  });
  const { reply } = await chatRes.json();

  console.log('Reply:', reply);
}

testChat();

Deployment Procedures

Backend Deployment

# Option 1: Use deployment script
./scripts/deploy-to-vps.sh

# Option 2: Manual deployment
rsync -av --exclude 'node_modules' ./ root@89.116.170.226:/root/catb/

ssh root@89.116.170.226 << 'EOF'
  cd /root/catb
  docker-compose down
  docker-compose build --no-cache
  docker-compose up -d
EOF

Critical: Always rebuild Docker images after code changes:

# ❌ WRONG - doesn't pick up code changes
docker-compose restart

# ✅ CORRECT - rebuilds with fresh code
docker-compose down && docker-compose build --no-cache && docker-compose up -d

Frontend Deployment

# Build and deploy frontend
cd ~/dev/catb-frontend/
npm run build

# Transfer to VPS
rsync -av --exclude 'node_modules' --exclude '.git' \
  ./ root@89.116.170.226:/root/catb-frontend/

# Rebuild container on VPS
ssh root@89.116.170.226 << 'EOF'
  cd /root/catb-frontend
  docker stop catb-frontend
  docker rm catb-frontend
  docker build -t catb-frontend . --no-cache
  docker run -d --name catb-frontend --restart unless-stopped \
    -p 127.0.0.1:3001:80 catb-frontend
EOF

Monitoring & Logging

View Logs

# Backend logs
ssh root@89.116.170.226 "docker logs catb-api --tail 100"
ssh root@89.116.170.226 "docker logs -f catb-api"  # Follow

# Frontend logs
ssh root@89.116.170.226 "docker logs catb-frontend --tail 100"

# Nginx logs
ssh root@89.116.170.226 "tail -f /var/log/nginx/access.log"
ssh root@89.116.170.226 "tail -f /var/log/nginx/error.log"

Container Status

# Check all containers
ssh root@89.116.170.226 "docker ps -a"

# Check specific container
ssh root@89.116.170.226 "docker inspect catb-api"

Common Troubleshooting

Issue: Port Binding Conflict

Error: bind: address already in use

Solution: Remove port 80/443 from docker-compose.yml (nginx handles these):

ports:
  - "127.0.0.1:3000:3000"  # ✅ Correct
  # - "80:80"  # ❌ Remove this

Issue: Changes Not Appearing

Cause: Docker using cached images

Solution:

docker-compose down
docker-compose build --no-cache
docker-compose up -d

Issue: Authentication Failing

Common Mistakes:

  • Token in Authorization header (should be in body)
  • Using wrong field name (use sessionToken, not token)
  • Session expired (>24 hours)

Correct Format:

// ✅ CORRECT
body: {
  message: "user message",
  sessionToken: "TOKEN"
}

// ❌ WRONG
headers: {
  'Authorization': 'Bearer TOKEN'
}

Issue: Database Connection Error

Checks:

  1. Verify .env has correct SUPABASE_URL and SUPABASE_SERVICE_KEY
  2. Check Supabase project status (dashboard)
  3. Test connection: node scripts/test-db-connection.js
  4. Ensure tables exist: node scripts/execute-sql.js list

Issue: Blank Frontend Page

Symptoms: Page loads but shows blank screen, assets return HTML

Cause: Nginx misconfiguration or missing SPA routing

Solution: Ensure nginx.conf has:

location / {
    proxy_pass http://127.0.0.1:3001;
    try_files $uri $uri/ /index.html;
}

Database Management

Run Migrations

# Using Supabase Dashboard (recommended)
# 1. Go to SQL Editor
# 2. Copy contents of migrations/000-complete-fresh-schema.sql
# 3. Click "Run"

# Using direct PostgreSQL access (if DATABASE_URL configured)
node scripts/execute-sql.js file migrations/000-complete-fresh-schema.sql

Execute SQL Queries

# List tables
node scripts/execute-sql.js list

# Describe table
node scripts/execute-sql.js describe user_sessions

# Execute query
node scripts/execute-sql.js exec "SELECT COUNT(*) FROM messages"

Cost Structure

Monthly Costs (Production)

Service Tier Cost Notes
Hostinger VPS Shared $20-50 Dual container deployment
Supabase Free $0 50k MAU, 500MB database
Resend Email Free $0 3k emails/month
Claude API Pay-as-you-go $30-100 Depends on usage
Domain (askmu.live) Namecheap ~$1/mo Paid annually (~$10/year)
SSL Certificate Let’s Encrypt $0 Free auto-renewal
Total - $50-150/mo Most variable is Claude API

Claude API Cost Breakdown

Pricing (Sonnet 4):

  • Input tokens: $3 per 1M tokens
  • Output tokens: $15 per 1M tokens

Typical Chat Interaction:

  • Input: ~200 tokens (conversation history + user message)
  • Output: ~200 tokens (Mu response, 300 token max)
  • Cost per interaction: ~$0.003-0.005

Monthly Estimates:

  • 100 conversations/day: ~$15-30/month
  • 500 conversations/day: ~$75-150/month
  • 1000 conversations/day: ~$150-300/month

Cost Control Measures:

  • Max tokens per response: 300 (hard limit)
  • Conversation history pruning (last 10 messages)
  • Efficient prompt design (minimal system prompt)

Scaling Considerations

Current Capacity (Single VPS):

  • Concurrent users: ~50-100
  • Daily conversations: ~500-1000
  • Database: 500MB free tier (plenty of room)

When to Scale:

  • VPS CPU consistently >70%
  • Database approaching 500MB
  • Email sending approaching 3k/month
  • API costs exceeding budget

Scaling Options:

  1. Vertical: Upgrade VPS plan ($50-100/month)
  2. Horizontal: Add load balancer + multiple VPS instances
  3. Database: Upgrade Supabase to Pro ($25/month)
  4. Email: Upgrade Resend to paid tier ($20/month for 50k emails)

Appendix

Quick Reference

Production URLs:

SSH Access:

ssh root@89.116.170.226

Common Commands:

# Restart backend
ssh root@89.116.170.226 "cd /root/catb && docker-compose restart"

# Rebuild backend
ssh root@89.116.170.226 "cd /root/catb && docker-compose down && docker-compose build --no-cache && docker-compose up -d"

# View logs
ssh root@89.116.170.226 "docker logs catb-api --tail 100"

# Check health
# Note: curl commands denied - use browser or test scripts

Environment Files:

  • Backend: /root/catb/.env
  • Frontend: Build-time only (Vite)

Recent Updates

October 2025:

  • ✅ Session-email association fix (removed legacy fallback)
  • ✅ ProfileService integration with LangChain
  • ✅ Early profiling enabled (2-message threshold)
  • ✅ Direct PostgreSQL access configured
  • ✅ Test suite reorganization

September 2025:

  • ✅ Express 5.1.0 upgrade (security remediation)
  • ✅ Local asset deployment (replaced CDN)
  • ✅ Enhanced pattern detection system
  • ✅ Smart deployment system
  • ✅ Feedback collection system

Support

For issues or questions:

  1. Check logs: docker logs catb-api
  2. Review health endpoint: https://askmu.live/api/health
  3. Check database connection: node scripts/test-db-connection.js
  4. Verify environment variables in /root/catb/.env

Document Version: 1.0 Last Updated: October 1, 2025 System Status: ✅ Fully Operational

3 - CatBot Technical Architecture Specifications

Describes catb’s upcoming versions

Executive Summary

Pet health triage chatbot using freemium model with Anthropic LLM integration. Focus on ethical anxiety management through practical competence building.

System Architecture Overview

High-Level Architecture

Details
[Frontend] → [API Gateway] → [Application Layer] → [LLM Service] → [Anthropic API]
     ↓              ↓               ↓                    ↓
[CDN/Media] → [Load Balancer] → [Database Layer] → [Cache Layer]

Technology Stack

  • Frontend: React/Next.js with TypeScript
  • Backend: Node.js with Express or Python with FastAPI
  • Database: PostgreSQL (primary), Redis (cache/sessions)
  • LLM Integration: Anthropic Claude API
  • Media Storage: AWS S3 or Cloudflare R2
  • Infrastructure: Docker containers on AWS/GCP
  • Monitoring: DataDog, Sentry for error tracking

Data Architecture

Database Schema Design

Users Table

Details
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT NOW(),
    subscription_tier VARCHAR(50) DEFAULT 'free',
    subscription_expires_at TIMESTAMP,
    data_retention_consent BOOLEAN DEFAULT false,
    last_active TIMESTAMP
);

Cat Profiles Table

Details
CREATE TABLE cat_profiles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    name VARCHAR(100) NOT NULL,
    age_months INTEGER,
    breed VARCHAR(100),
    weight_kg DECIMAL(4,2),
    medical_history JSONB,
    current_medications JSONB,
    created_at TIMESTAMP DEFAULT NOW(),
    updated_at TIMESTAMP DEFAULT NOW()
);

Conversations Table

Details
CREATE TABLE conversations (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    cat_id UUID REFERENCES cat_profiles(id),
    session_id VARCHAR(255),
    triage_outcome VARCHAR(50), -- emergency, urgent, routine, monitor
    symptoms_reported JSONB,
    recommendations_given JSONB,
    follow_up_scheduled TIMESTAMP,
    vet_visit_occurred BOOLEAN DEFAULT false,
    created_at TIMESTAMP DEFAULT NOW(),
    expires_at TIMESTAMP -- for data retention
);

Messages Table

Details
    CREATE TABLE messages (
        id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
        conversation_id UUID REFERENCES conversations(id) ON DELETE CASCADE,
        role VARCHAR(20) NOT NULL, -- user, assistant, system
    content TEXT NOT NULL,
    metadata JSONB, -- tokens used, response time, etc.
    created_at TIMESTAMP DEFAULT NOW()
);

Media Attachments Table

Details
CREATE TABLE media_attachments (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    conversation_id UUID REFERENCES conversations(id) ON DELETE CASCADE,
    message_id UUID REFERENCES messages(id),
    file_type VARCHAR(50), -- image, video
    file_url VARCHAR(500),
    file_size_bytes INTEGER,
    analysis_results JSONB, -- AI-generated descriptions
    created_at TIMESTAMP DEFAULT NOW()
);

Data Flow Architecture

Request Processing Flow

  1. User Input → API Gateway (rate limiting, auth)
  2. Session Management → Redis lookup/creation
  3. Context Building → Fetch cat profile + conversation history
  4. LLM Preparation → Structure prompt with context
  5. Anthropic API Call → Send structured request
  6. Response Processing → Parse, validate, store response
  7. Client Response → Return formatted response + metadata

Data Retention Strategy

  • Free Users: 48-hour conversation retention
  • Premium Users: Full history retention with user control
  • Media Files: 30-day retention (free), unlimited (premium)
  • Analytics Data: Anonymized, indefinite retention

LLM Integration Architecture

Anthropic API Integration

Prompt Engineering Structure

Details
SYSTEM_PROMPT_TEMPLATE = """
You are a professional pet health triage assistant specializing in cats.

CONTEXT:
Cat Profile: {cat_profile}
Medical History: {medical_history}
Current Conversation: {conversation_summary}

GUIDELINES:
1. Provide practical, actionable guidance
2. Clear urgency assessment (emergency/urgent/routine/monitor)
3. Suggest specific documentation to help veterinarians
4. Offer appropriate reassurance through competence building
5. Never provide definitive diagnosis - always recommend veterinary consultation

RESPONSE FORMAT:
- Urgency Level: [level]
- Immediate Actions: [numbered list]
- Documentation Suggestions: [what to observe/record]
- Veterinary Recommendation: [timing and type]
- Follow-up Guidance: [what to monitor]
"""

Conversation State Management

Details
class ConversationContext:
    def __init__(self, conversation_id):
        self.conversation_id = conversation_id
        self.cat_profile = self.load_cat_profile()
        self.message_history = self.load_recent_messages()
        self.session_metadata = self.load_session_data()

    def build_prompt(self, user_message):
        context = {
            'cat_profile': self.cat_profile,
            'medical_history': self.get_relevant_history(),
            'conversation_summary': self.summarize_conversation(),
            'user_message': user_message
        }
        return SYSTEM_PROMPT_TEMPLATE.format(**context)

    def process_response(self, llm_response):
        # Parse structured response
        # Extract triage decision
        # Store recommendations
        # Update conversation state
        pass

Cost Optimization Strategies

Response Caching System

Details
class ResponseCache:
    def __init__(self, redis_client):
        self.redis = redis_client
        self.cache_ttl = 3600  # 1 hour

    def get_cache_key(self, symptoms, cat_profile_hash):
        # Generate hash of symptoms + basic cat info
        return f"response:{hash(symptoms)}:{cat_profile_hash}"

    def should_cache_response(self, urgency_level):
        # Cache routine responses, not emergencies
        return urgency_level in ['routine', 'monitor']

Token Usage Optimization

  • Conversation summarization after 10+ exchanges
  • Context pruning for long conversations
  • Batch processing for multiple questions
  • Response streaming for better UX

Security & Privacy Architecture

Data Protection Measures

  • Encryption at Rest: AES-256 for database
  • Encryption in Transit: TLS 1.3 for all communications
  • API Security: Rate limiting, JWT authentication
  • Data Anonymization: Hash personal identifiers for analytics

Privacy Compliance

  • Data Minimization: Collect only necessary information
  • User Control: Data export, deletion on request
  • Consent Management: Granular permissions for data use
  • Audit Logging: Track data access and modifications

Error Handling & Fallbacks

Details
class LLMService:
    async def get_triage_response(self, prompt, context):
        try:
            response = await self.anthropic_client.complete(prompt)
            return self.parse_structured_response(response)
        except AnthropicAPIError as e:
            if e.status_code == 429:  # Rate limit
                return self.get_cached_fallback(context)
            elif e.status_code >= 500:  # Server error
                return self.get_emergency_fallback()
            else:
                raise
        except Exception as e:
            logger.error(f"Unexpected error: {e}")
            return self.get_safe_fallback()

Monitoring & Analytics

Key Metrics to Track

  • Usage Metrics: Sessions/day, messages/session, user retention
  • Quality Metrics: Triage accuracy, user satisfaction scores
  • Business Metrics: Conversion rate (free→premium), revenue per user
  • Technical Metrics: API response times, error rates, cache hit rates

Logging Strategy

Details
LOGGING_CONFIG = {
    'conversation_events': {
        'conversation_started',
        'triage_provided',
        'emergency_detected',
        'vet_referral_made',
        'follow_up_scheduled'
    },
    'business_events': {
        'user_upgraded',
        'subscription_renewed',
        'feature_accessed'
    },
    'technical_events': {
        'api_call_made',
        'cache_hit',
        'error_occurred'
    }
}

Deployment Architecture

Infrastructure Components

  • Application Servers: Auto-scaling container groups
  • Database: Primary/replica PostgreSQL setup
  • Cache Layer: Redis cluster for session management
  • CDN: Cloudflare for static assets and media
  • Load Balancer: Application-level load balancing

CI/CD Pipeline

  1. Code Commit → GitHub/GitLab
  2. Automated Testing → Unit, integration, end-to-end tests
  3. Security Scanning → Dependency vulnerabilities, secrets detection
  4. Staging Deployment → Automated deployment to staging
  5. Production Deployment → Manual approval + blue-green deployment

Backup & Disaster Recovery

  • Database Backups: Daily automated backups with 30-day retention
  • Media Backups: Cross-region replication
  • Application Recovery: Infrastructure as code for rapid rebuilding
  • Data Export: User data export functionality for compliance

Learning Resources & Implementation Guide

Core Technologies

LLM Integration

Security & Compliance

  • OWASP Security Guidelines: OWASP Top 10
  • Data Privacy: GDPR compliance guides, privacy by design principles
  • API Security: JWT implementation, rate limiting strategies

Business & Analytics

  • SaaS Metrics: Cohort analysis, customer lifetime value calculation
  • A/B Testing: Statistical significance testing, experiment design
  • User Experience: Conversational interface design principles

Implementation Phases

Phase 1: MVP (4-6 weeks)

  • Basic conversation interface
  • Simple triage logic
  • Free tier functionality
  • Core database schema

Phase 2: Enhanced Features (6-8 weeks)

  • Premium subscription system
  • Advanced triage algorithms
  • Media upload capability
  • User profiles and cat management

Phase 3: Business Features (4-6 weeks)

  • Vet referral system
  • Analytics dashboard
  • Automated follow-up system
  • Advanced caching and optimization

Phase 4: Scale & Optimize (Ongoing)

  • Performance optimization
  • Advanced analytics
  • A/B testing framework
  • Additional monetization features

Risk Assessment & Mitigation

Technical Risks

  • Anthropic API Limitations: Implement caching and fallback responses
  • Scaling Challenges: Design for horizontal scaling from start
  • Data Loss: Comprehensive backup and replication strategy

Business Risks

  • Liability Concerns: Clear disclaimers, professional insurance
  • Regulatory Changes: Monitor pet health app regulations
  • Competition: Focus on unique value proposition and user experience

Operational Risks

  • User Safety: Robust emergency detection and escalation
  • Data Breaches: Security-first architecture and regular audits
  • Service Reliability: High availability design and monitoring

4 - MVP high level description

Describes catb MVP, what it does, and what it doesn’t

Catb is a chatbot helping cat owners understand their cats behavior so they can build a deeper bond with them and make them happy.

Catb asks discovery questions about owners’ cats and provides explanations and guidance.

The call to action can range from adapting their interactions or home setting to help with their pets reach optimal mental health.

Catb acts as a informed friend that soothes the owners’s anxiety while providing qualified guidance.

Goal

The MVP is meant for internal testing, it’s a website allowing interactions with an LLM.

The LLM will allow users to have conversations about their cats’ behavior, and get responses helping them understand their cats’ behavior and communication and what’s the best course of actions.

private

  • private url
  • no login

Limited data processing

  • Only logs interactions for analysis

Not commercial

  • No affiliated links

Effective

  • Give proper guidance
  1. Asks questions to assess what the behavioral issue might be, or the misunderstanding from the user’s end.
  2. Only answers when enough answers are provided
  3. Helps owners understand their cat’s behavior and the best response if an issue is identified.

Uses Claude’s API

The interactions with the model are scoped down to cats’ behavior thanks to a single, dedicated system prompt.

  • Always mentions at the end of the conversation that:
    1. It is an LLM and can make mistakes
    2. It is not a substitute for a certified veterinarian

Ethical

  • No sycophantic/complacent responses
    1. Catb be will tell the objective truths about the owners’ cat issues
      1. Example: if the cat demonstrates stress because of the owner’ behavior, Catb will say so, although in diplomatic terms.

Sources from non-biased docs

  • Provides links to 3 sources per final answer
    1. no .com domains
    2. no blogs
    3. publicly accessible peer-reviewed papers
    4. vets websites and vets info sources

Alleviates end-users anxiety about their pets

  • Acts as an informed friend

  • Reassures the owner if the problem doesn’t require medical attention

5 - Mu Prompt Management Framework

Dynamic prompt generation system with LangChain user profiling and progressive discovery

Mu Prompt Management Framework

Table of Contents

  1. Overview
  2. System Architecture
  3. Core Components
  4. LangChain User Profiling
  5. Context Analysis
  6. Progressive Discovery Protocol
  7. Template System
  8. Prompt Generation Flow
  9. Adaptive Response System
  10. Emergency Detection
  11. Integration with Claude
  12. Development Guide

Overview

What is the Mu Prompt System?

The Mu Prompt System is a sophisticated dynamic prompt generation framework that powers the Ask Mü cat health chatbot. Unlike static prompts, every response is generated from a fresh analysis of:

  • User communication patterns (via LangChain AI profiling)
  • Conversation context (symptoms, cat profile, urgency)
  • Conversation phase (greeting → symptom gathering → assessment)
  • User traits (anxiety level, experience, preferred style)

Key Innovation: Progressive Discovery Protocol

  • Maximum 2 questions per response
  • Context-aware: Analyzes existing information before asking
  • Urgency-sensitive: Emergency symptoms prioritized
  • Adaptive tone: Matches user’s communication style

Production Status

  • Status: ✅ Fully Operational
  • Deployed: https://askmu.live
  • Model: Claude Sonnet 4
  • Version: Mu Prompt System v3 with LangChain
  • Last Update: October 2025 (Early profiling enabled)

Design Goals

  1. Empathy-First: Understand user’s emotional state and adapt tone
  2. Efficient Discovery: Gather critical information without overwhelming
  3. Safety-Conscious: Detect emergencies and escalate appropriately
  4. Personalized: Adapt to each user’s communication style and experience
  5. Context-Aware: Build on previous interactions, avoid redundancy

System Architecture

High-Level Architecture

User Message
    │
    ▼
┌────────────────────────────────────────────────────────┐
│              Mu Prompt System                           │
│                                                         │
│  ┌──────────────────────────────────────────────────┐ │
│  │  1. Conversation Context Analyzer                 │ │
│  │     - Extract cat profile (name, age, breed)      │ │
│  │     - Detect symptoms and urgency                 │ │
│  │     - Assess anxiety level                        │ │
│  │     - Identify experience level                   │ │
│  └──────────────────────────────────────────────────┘ │
│                      │                                  │
│                      ▼                                  │
│  ┌──────────────────────────────────────────────────┐ │
│  │  2. LangChain User Profiler (2+ messages)        │ │
│  │     - Communication style analysis                │ │
│  │     - Personality profile matching                │ │
│  │     - Confidence level detection                  │ │
│  │     - Learning preference identification          │ │
│  └──────────────────────────────────────────────────┘ │
│                      │                                  │
│                      ▼                                  │
│  ┌──────────────────────────────────────────────────┐ │
│  │  3. Conversation Memory System                    │ │
│  │     - Retrieve conversation history               │ │
│  │     - Update context in database                  │ │
│  │     - Track conversation phases                   │ │
│  └──────────────────────────────────────────────────┘ │
│                      │                                  │
│                      ▼                                  │
│  ┌──────────────────────────────────────────────────┐ │
│  │  4. Template Engine                               │ │
│  │     - Load PromptL templates                      │ │
│  │     - Interpolate context variables               │ │
│  │     - Apply conditional sections                  │ │
│  │     - Assemble final prompt                       │ │
│  └──────────────────────────────────────────────────┘ │
│                      │                                  │
└──────────────────────┼──────────────────────────────────┘
                       │
                       ▼
              Dynamic System Prompt
                       │
                       ▼
         Claude Sonnet 4 API (300 token max)
                       │
                       ▼
            Empathetic, Adaptive Response

Component Interaction

┌─────────────────┐
│ User Message    │
└────────┬────────┘
         │
         ▼
┌─────────────────────────────────────────────────┐
│ MuPromptSystem.generateDynamicPrompt()          │
│                                                  │
│  1. getConversationContext(sessionId)           │
│     └─> Returns: history, catProfile, context   │
│                                                  │
│  2. contextAnalyzer.analyze(history, message)   │
│     └─> Returns: urgency, symptoms, traits      │
│                                                  │
│  3. langchainProfiler.analyzeUserProfile()      │
│     └─> Returns: style, anxiety, personality    │
│                                                  │
│  4. memorySystem.updateConversationContext()    │
│     └─> Saves updated context to database       │
│                                                  │
│  5. templateEngine.render(promptData)           │
│     └─> Returns: final system prompt            │
└──────────────────────┬──────────────────────────┘
                       │
                       ▼
                System Prompt for Claude

Core Components

1. MuPromptSystem (Orchestrator)

File: lib/mu-prompt-system.js

Purpose: Main orchestration class that coordinates all components to generate dynamic prompts.

Key Features:

  • Integrates all subsystems (context, profiling, memory, templates)
  • Manages early profiling (2-message threshold)
  • Handles fallback when LangChain unavailable
  • Logs profiling status and decisions

Initialization:

const promptSystem = new MuPromptSystem(
  supabaseClient,
  anthropicApiKey,
  { earlyProfiling: true }  // Enable 2-message profiling
);

Main Method:

const promptData = await promptSystem.generateDynamicPrompt(
  sessionId,
  userMessage
);
// Returns: Complete data structure for template rendering

2. ConversationContextAnalyzer

File: lib/conversation-context-analyzer.js

Purpose: Analyzes messages to extract actionable context (symptoms, urgency, traits).

Analysis Dimensions:

Dimension Values Purpose
Conversation Phase initial, context_building, detail_gathering, assessment, guidance Determines appropriate response type
Urgency Level emergency, urgent, routine Prioritizes response content
Anxiety Level low, moderate, high, panic Adjusts empathy and tone
Experience Level first-time, beginner, experienced Adjusts complexity
Communication Style emotional, factual, low-literacy Matches response style
Emotional State calm, concerned, worried, panicked Fine-tunes empathy

Keyword Detection:

{
  emergency: [
    'trouble breathing', 'gasping', 'blue gums',
    'unconscious', 'seizure', 'severe bleeding',
    'collapsed', 'paralyzed'
  ],
  urgent: [
    'not eating', 'vomiting', 'diarrhea',
    'lethargy', 'hiding', 'blood', 'pain'
  ],
  routine: [
    'scratching', 'grooming', 'sleeping more',
    'different behavior'
  ]
}

Cat Profile Extraction:

{
  name: /(?:my cat|his name|her name is|called)\s+(\w+)/i,
  age: /(\d+)\s*(?:years?|months?)\s*old/i,
  breed: /(persian|siamese|maine coon|tabby|calico)/i,
  gender: /\b(he|she|male|female|boy|girl)\b/i
}

3. ConversationMemorySystem

File: lib/conversation-memory-system.js

Purpose: Database-backed persistence for conversation context.

Database Operations:

// Retrieve context
const context = await memorySystem.getConversationContext(sessionId);
// Returns: { catProfile, symptoms, history, phase, ... }

// Update context
await memorySystem.updateConversationContext(sessionId, {
  catProfile: { name: 'Luna', age: 3 },
  symptoms: ['vomiting', 'lethargy'],
  anxietyLevel: 'high',
  conversationPhase: 'symptom_gathering'
});

Context Storage:

  • Table: conversation_context
  • Indexed by: session_id
  • Includes: cat profile, symptoms, user traits, phase, question count

Phase Management:

const maxQuestions = memorySystem.getMaxQuestionsForPhase(phase);
// initial: 2 questions
// context_building: 2 questions
// detail_gathering: 1 question (already have context)
// assessment: 0 questions (provide guidance)

4. SimpleTemplateEngine

File: lib/simple-template-engine.js

Purpose: Processes PromptL templates with variable interpolation.

Template Location: prompts/ directory

Syntax:

# Variable interpolation
{{catProfile.name}}

# Conditional sections
{{#if urgencySignals.emergency}}
EMERGENCY PROTOCOL ACTIVATED
{{/if}}

{{#unless catProfile.name}}
Ask for cat's name
{{/unless}}

# Loops
{{#each symptoms}}
- {{this}}
{{/each}}

Rendering:

const prompt = await templateEngine.render('base-prompt', {
  catProfile: { name: 'Luna', age: 3 },
  urgencySignals: { emergency: [], urgent: ['vomiting'] },
  anxietyLevel: 'high'
});

LangChain User Profiling

Overview

File: lib/langchain/langchain-user-profiler.js

Purpose: AI-powered semantic analysis of user communication patterns using Claude Sonnet 4.

Activation: Starts at 2nd user message (early profiling enabled October 2025)

Previous Threshold: 3rd message (before October 2025 update)

Why Early Profiling?

  • Faster personalization (one message sooner)
  • Better first impressions (adapt tone earlier)
  • Improved user experience for anxious users

Profiling Dimensions

1. Communication Style

Style Description Response Adaptation
emotional Seeks empathy and support Warm, reassuring tone; emotional validation
factual Wants direct information Concise, evidence-based responses
low-literacy Uses simple language Plain language, short sentences, avoid jargon

2. Anxiety Level

Level Indicators Response Adaptation
low Calm, routine inquiry Standard empathetic tone
moderate Some concern Extra reassurance
high Worried, multiple questions High empathy, structured guidance
panic “HELP!”, “emergency”, excessive punctuation Immediate calm-down, clear next steps

3. Experience Level

Level Indicators Response Adaptation
first-time “never had a cat”, “new owner” Detailed explanations, extra context
beginner Basic questions, uncertainty Moderate detail, encouraging
experienced Mentions other cats, vet visits Higher complexity, less hand-holding

4. Preferred Response Style

Style Description
concise Brief, to-the-point answers
detailed Comprehensive explanations with background

5. Confidence Level

Level Description
confident Trusts their judgment, wants validation
uncertain Second-guessing, needs guidance
overwhelmed Feeling lost, needs structured support
building Growing confidence, needs reinforcement

6. Learning Preference

Preference Adaptation
visual Use analogies and examples
analytical Provide logical reasoning and evidence
practical Focus on actionable steps
contextual Give background and situational understanding

Personality Profiles

The system matches users to personality archetypes for tone guidance:

File: lib/langchain/personality-profiles.js

Profiles:

  1. Anxious First-Timer

    • High anxiety + low experience
    • Needs: Calm reassurance, step-by-step guidance
    • Tone: Gentle, patient, structured
  2. Concerned Experienced Owner

    • Moderate anxiety + high experience
    • Needs: Validation, differential diagnosis
    • Tone: Respectful, collaborative
  3. Calm Information Seeker

    • Low anxiety + factual style
    • Needs: Direct facts, evidence
    • Tone: Professional, concise
  4. Panicked Emergency

    • Panic level + emergency keywords
    • Needs: Immediate clear instructions
    • Tone: Authoritative, calming, directive
  5. Building Confidence

    • Improving confidence + beginner
    • Needs: Positive reinforcement
    • Tone: Encouraging, supportive

Analysis Process

LangChain Invocation:

const profile = await langchainProfiler.analyzeUserProfile(
  conversationHistory,
  currentMessage
);

Analysis Prompt (sent to Claude Sonnet 4):

You are an expert at analyzing communication patterns to understand
user profiles for adaptive AI responses about cat behavior.

Analyze this cat owner's communication style and needs based on
their messages:

MESSAGE COUNT: 2
IMPORTANT: This is early analysis with only 2 message(s). Focus on
clear indicators while being conservative about confidence levels.

USER MESSAGES:
"""
Help! My cat Luna has been vomiting all morning. I'm really scared,
is this serious? She's only 3 years old.

I've tried giving her water but she won't drink. Should I take her
to the vet right away?
"""

ANALYSIS FRAMEWORK:
[Communication style, anxiety level, experience level descriptors...]

Respond with a JSON profile analysis.

Response Structure:

{
  "communicationStyle": "emotional",
  "anxietyLevel": "high",
  "experienceLevel": "beginner",
  "preferredResponseStyle": "detailed",
  "confidenceLevel": "uncertain",
  "learningPreference": "practical"
}

Confidence Scoring:

{
  overall: 0.75,  // Confidence in the entire profile
  factorScores: {
    communicationStyle: 0.9,  // Very clear emotional language
    anxietyLevel: 0.95,       // "Help!", "scared", exclamation
    experienceLevel: 0.6,     // Limited data, conservative estimate
    // ...
  }
}

Personality Selection:

const personality = selectPersonality(profile);
// Returns: "Anxious First-Timer"

const instructions = getPersonalityInstructions(personality);
// Returns: Detailed guidance for response tone and structure

Fallback Mechanism

If LangChain analysis fails (API error, timeout):

getFallbackProfile() {
  return {
    profile: {
      communicationStyle: 'emotional',
      anxietyLevel: 'moderate',
      experienceLevel: 'beginner',
      preferredResponseStyle: 'concise',
      confidenceLevel: 'uncertain',
      learningPreference: 'practical'
    },
    confidence: { overall: 0.5 },
    personalityProfile: {
      name: 'Default Concerned Owner',
      description: 'Fallback profile when analysis unavailable'
    }
  };
}

Progressive Discovery Protocol

Core Principle

Maximum 2 Questions Per Response

This is the fundamental constraint of the Mu system, designed to:

  • Avoid overwhelming worried pet owners
  • Maintain conversation flow
  • Build trust through attentive listening
  • Respect user’s emotional state

Question Budget System

Phase-Based Limits:

{
  initial: 2,              // Greeting, get basic context
  context_building: 2,     // Gather cat profile + symptoms
  detail_gathering: 1,     // Already have context, refine details
  assessment: 0,           // Provide guidance, no more questions
  guidance: 0              // Final recommendations
}

Question Prioritization

Priority Order:

  1. Emergency Verification (if emergency symptoms)

    • “Have you contacted a veterinarian?”
    • “Is [cat] still breathing normally?”
  2. Timeline (if missing)

    • “How long has this been going on?”
    • “When did you first notice this?”
  3. Severity (if unclear)

    • “How often is this happening?”
    • “Is it getting worse?”
  4. Context (after basics covered)

    • “Any recent changes in food or environment?”
    • “Is [cat] eating/drinking normally?”
  5. Clarification (lowest priority)

    • “You mentioned [X], can you describe it more?”

Example Progressive Discovery

Message 1 (User):

“Help! My cat has been vomiting”

Mu Response (2 questions):

I’m sorry to hear your cat isn’t feeling well. Vomiting can be concerning.

To help you better:

  1. How long has the vomiting been going on?
  2. What’s your cat’s name and age?

Message 2 (User):

“Her name is Luna, she’s 3. Started this morning, maybe 4-5 times already.”

Mu Response (1 question):

Thank you for that information. I’m concerned about Luna vomiting 4-5 times this morning. This is more frequent than normal and warrants attention.

Has she been able to keep any water down, or is she vomiting everything?

[Assessment and guidance…]

Message 3 (User):

“She won’t drink at all. Just tried and she vomited again.”

Mu Response (0 questions - assessment phase):

This is concerning, and I recommend contacting your veterinarian today. Multiple vomiting episodes combined with refusing water can lead to dehydration…

[Detailed guidance, no questions]


Emergency Detection

Emergency Symptom Keywords

Immediate Veterinary Attention Required:

const EMERGENCY_SYMPTOMS = [
  // Respiratory
  'trouble breathing', 'difficulty breathing', 'gasping for air',

  // Circulatory
  'pale gums', 'blue gums', 'gray gums',

  // Neurological
  'unconscious', 'seizure', 'convulsing',

  // Trauma
  'severe bleeding', 'hit by car',

  // Mobility
  'can\'t walk', 'paralyzed', 'collapsed'
];

Emergency Protocol

When Emergency Detected:

⚠️ EMERGENCY PROTOCOL ACTIVATED ⚠️

SYMPTOMS DETECTED: {{#each urgencySignals.emergency}}{{this}}, {{/each}}

IMMEDIATE RESPONSE REQUIRED:

CRITICAL INSTRUCTIONS:
1. Contact emergency veterinary clinic immediately
2. If after hours, contact 24-hour emergency vet
3. Do NOT wait to see if it improves
4. Transport safely - avoid unnecessary movement

TIME IS CRITICAL. Please act now.

Response Characteristics:

  • Directive tone: Clear commands, not suggestions
  • Urgent but not panicking: Calm authority
  • Action-focused: Immediate steps only
  • Minimal questions: Ask ONLY “Have you contacted a vet?”
  • Short sentences: Easy to process under stress

Integration with Claude

API Configuration

Model: claude-sonnet-4-20250514 Temperature: 0.7 (balanced creativity and consistency) Max Output Tokens: 300 (cost control + concise responses)

System Prompt

Structure:

{
  model: 'claude-sonnet-4-20250514',
  max_tokens: 300,
  temperature: 0.7,
  system: generatedPrompt,  // Dynamic prompt from template
  messages: conversationHistory
}

Token Budget:

System Prompt: ~1500 tokens
Conversation History (10 messages): ~1000 tokens
Current User Message: ~100 tokens
---
Total Input: ~2600 tokens

Max Output: 300 tokens

Total per request: ~2900 tokens
Cost: ~$0.003 per interaction

Development Guide

Adding New Templates

1. Create Template File:

touch prompts/new-scenario.promptl

2. Define Template:

# New Scenario Template

You are Mu, helping with [specific scenario].

CONTEXT:
{{catProfile.name}} is experiencing {{primarySymptom}}.

[Template content...]

3. Register in Template Engine:

// lib/simple-template-engine.js
const TEMPLATES = {
  'base-prompt': 'base-prompt.promptl',
  'new-scenario': 'new-scenario.promptl'  // Add here
};

Testing Prompt Variations

Enable Detailed Logging:

// Set environment variable
LOG_PROMPT_GENERATION=true npm start

Log Output:

🔍 LangChain User Profiler: Performing semantic analysis...
🧠 LangChain profile analysis completed (2 messages): {
  style: 'emotional',
  anxiety: 'high',
  experience: 'beginner',
  confidence: 0.75,
  personality: 'Anxious First-Timer'
}

Example Scenarios

Scenario 1: Anxious First-Time Owner

User Message:

“HELP!! My cat isn’t eating and I don’t know what to do! Is she dying??”

Context Analysis:

{
  anxietyLevel: 'panic',
  experienceLevel: 'first-time',
  communicationStyle: 'emotional'
}

Mu Response:

First, take a deep breath. Not eating for a short time doesn’t always mean something serious, but I can see how worried you are, and I’m here to help.

To better understand what’s happening:

  1. How long has it been since your cat last ate?
  2. What’s your cat’s name and age?

You’re doing the right thing by reaching out. We’ll figure this out together.


Scenario 2: Emergency Situation

User Message:

“My cat just collapsed and won’t get up! Her gums look pale!”

Emergency Protocol Activated:

Mu Response:

⚠️ THIS IS AN EMERGENCY ⚠️

Your cat needs immediate veterinary attention. DO NOT WAIT.

IMMEDIATE ACTIONS:

  1. Call your emergency vet or 24-hour clinic NOW
  2. Keep your cat warm with a light blanket
  3. Minimize movement - transport carefully

Have you contacted a veterinary clinic yet?


Conclusion

The Mu Prompt Management Framework represents a sophisticated, adaptive system that:

  1. Analyzes user communication patterns with AI-powered LangChain profiling
  2. Tracks conversation context across multiple dimensions
  3. Adapts response style based on user needs
  4. Prioritizes information gathering through progressive discovery
  5. Templates dynamic prompts for consistent responses
  6. Integrates seamlessly with Claude Sonnet 4

Production Impact:

  • More personalized user experiences
  • Faster emergency detection
  • Better information gathering efficiency
  • Higher user satisfaction

Document Version: 1.0 Last Updated: October 1, 2025 System Status: ✅ Production (https://askmu.live) Framework Version: Mu Prompt System v3 with LangChain

6 - Concepts

Glossary and explanations on catbs concepts

This page will contain all the jargon we’ll use for catb. As the project grows and the contributors multiply, it’ll save time with exchanges and onboarding