This document explains the built-in AI chatbot feature in SaasRock. The chatbot uses Vercel AI SDK for streaming responses and provides context-specific tools across three contexts: Tenant, Admin, and Marketing.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CLIENT ACCESS POINTS β
β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ βββββββββββββ β
β β Nav Bar Icon β β Tenant Chat β β Admin Chat β β Marketing β β
β β (Dialog Mode) β β /app/:t/chat β β /admin/chat β β Homepage β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ βββββββββββββ β
β β β β β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β β β β
βΌ βΌ βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β CHATBOT WIDGET (React) β
β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β AI Elements Components (11 reusable) β β
β β conversation | message | response | reasoning | tool | sources β β
β β code-block | loader | actions | prompt-input | suggestion β β
β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β POST with context
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β API ROUTES β
β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β /api/ai/chat β β /api/ai/chat β β /api/ai/chat/marketing β β
β β /:tenant β β /admin β β (No auth required) β β
β β (Auth required) β β (Admin only) β β β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β STREAMING SERVICE β
β (chatbot-stream.server.ts) β
β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β Tenant Tools β β Admin Tools β β Marketing Tools β β
β β - session β β - accounts_list β β - features_list β β
β β - info β β - users_list β β - pricing_info β β
β β - navigate β β - users_find β β β β
β β - logs_recent β β - stats β β β β
β β + MCP tools β β - navigate β β β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββ΄βββββββββββββ
βΌ βΌ
ββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββ
β OPENAI API β β DATABASE (Prisma) β
β β β β
β - GPT-4o (default) β β Chat βββ¬ββ ChatMessage ββ ChatMessagePart β
β - GPT-4o-mini β β β β
β - o1, o1-mini, o1-pro β β βββ GeneratedObject (tracking) β
β - o3-mini β β β
ββββββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββββββββββββββββββββ
app/modules/chatbot/
βββ chatbot-config.ts # Centralized configuration
βββ components/
β βββ chatbot-widget.tsx # Main chat UI component
β βββ chat-list.tsx # Chat history list
βββ lib/
βββ chatbot.db.server.ts # Database operations
βββ chatbot-stream.server.ts # Shared streaming service
βββ chatbot-dtos.ts # Prisma-based DTOs
βββ chatbot-context-dtos.ts # Stream config types
βββ chatbot-cookie.server.ts # Session management (marketing)
βββ tools-admin.server.ts # Admin prompt + tools
βββ tools-tenant.server.ts # Tenant prompt + tools
βββ tools-marketing.server.ts # Marketing prompt + tools
app/modules/ai-gen/
βββ db/
β βββ ai-generation.db.server.ts # Generation tracking
βββ lib/
β βββ ai-models.ts # Available AI models
βββ dtos/
β βββ ai-generation-dto.ts # Generation DTOs
βββ services/
βββ ai-tools.server.ts # AI tool utilities
app/components/ai-elements/ # 11 reusable components
βββ conversation.tsx # Chat container with scroll
βββ message.tsx # Individual message wrapper
βββ prompt-input.tsx # Input with model selector
βββ response.tsx # AI response with markdown
βββ reasoning.tsx # Collapsible reasoning display
βββ tool.tsx # Tool call visualization
βββ sources.tsx # Citation display
βββ code-block.tsx # Syntax highlighting
βββ loader.tsx # Loading indicators
βββ actions.tsx # Message action buttons
βββ suggestion.tsx # Quick suggestion buttons
model Chat {
id String @id @default (cuid () )
createdAt DateTime @default (now () )
updatedAt DateTime @updatedAt
type String // "tenant" | "admin" | "marketing"
tenantId String ? // For tenant chats
userId String ? // For authenticated users
sessionId String ? // For anonymous marketing chats
title String
messages ChatMessage []
tenant Tenant ? @relation (fields : [tenantId ] , references : [id ] , onDelete : Cascade )
user User ? @relation (fields : [userId ] , references : [id ] , onDelete : Cascade )
}
model ChatMessage {
id String @id @default (cuid () )
createdAt DateTime @default (now () )
updatedAt DateTime @updatedAt
chatId String
role String // "user" | "assistant"
parts ChatMessagePart []
chat Chat @relation (fields : [chatId ] , references : [id ] , onDelete : Cascade )
}
model ChatMessagePart {
id String @id @default (cuid () )
createdAt DateTime @default (now () )
messageId String
order Int
type String // "text" | "reasoning" | "tool-*" | "source-url"
content String // JSON stringified
message ChatMessage @relation (fields : [messageId ] , references : [id ] , onDelete : Cascade )
}
model GeneratedObject {
id String @id @default (cuid () )
createdAt DateTime @default (now () )
userId String
chatId String ? // Nullable, SetNull on delete
object String // "ChatMessage"
type String // "chat"
model String
status String // "pending" | "success" | "error"
inputTokens Int @default (0 )
outputTokens Int @default (0 )
costInCents Float @default (0 )
timeMs Int @default (0 )
user User @relation (fields : [userId ] , references : [id ] , onDelete : Cascade )
chat Chat ? @relation (fields : [chatId ] , references : [id ] , onDelete : SetNull )
}
Context
Route
Auth
Tools
Persistence
Tenant
/app/:tenant/chat
Required
session, info, navigate, logs, MCP
User + Tenant ID
Admin
/admin/chat
Admin only
accounts, users, stats, navigate
User ID
Marketing
Homepage dialog
None
features, pricing
Session cookie
Tool
Description
system_session
Get current account and user info
system_info
Platform features and capabilities
system_navigate
Navigate to platform sections
tenant_logs_recent
View recent application logs
+ MCP tools
Extended tools via MCP server at /mcp
Tool
Description
system_session
Get current user profile
admin_accounts_list
List all tenant accounts
admin_users_list
List platform users
admin_users_find
Search users by email/name
admin_stats_platform
Platform statistics
admin_navigate
Navigate to admin sections
Tool
Description
system_session
Visitor session info
marketing_features_list
SaasRock features
marketing_pricing_info
Pricing page link
Endpoint
Method
Context
Auth Required
/api/ai/chat/:tenant
POST
Tenant
Yes
/api/ai/chat/admin
POST
Admin
Yes (admin)
/api/ai/chat/marketing
POST
Marketing
No
{
chatId ?: string ; // Existing chat ID or undefined for new
messages: Message [ ] ; // Conversation history
model?: string ; // Model override (optional)
}
Server-Sent Events (SSE) stream with text deltas, tool calls, and message parts.
Chatbot Config (chatbot-config.ts)
type ChatbotContextConfig = {
enabled : boolean ; // Enable/disable this context
name : string ; // Assistant name (e.g., "Sales Assistant")
defaultModel : LanguageModel ; // Default AI model
maxSteps : number ; // Max tool execution steps
showModelSelector : boolean ; // Show model dropdown in UI
showAttachments : boolean ; // Allow file attachments
showTools : boolean ; // Show tool invocations in chat
suggestions : string [ ] ; // Quick action suggestions
welcomeMessages : string [ ] ; // Welcome messages when chat is empty
pages ?: { path : string ; exact : boolean } [ ] ; // Marketing pages whitelist
} ;
Default Settings by Context
Setting
Marketing
Admin
Tenant
enabled
true
true
true
name
Sales Assistant
Admin Assistant
User Assistant
maxSteps
2
5
5
showModelSelector
false
false
false
showAttachments
false
true
true
showTools
false
true
true
OPENAI_API_KEY=sk-... # Required for OpenAI models
ANTHROPIC_API_KEY=... # Required for Claude models (future)
Configured in app/modules/ai-gen/lib/ai-models.ts:
Model
Provider
Cost (per 1M input tokens)
gpt-4o
OpenAI
$0.25
gpt-4o-mini
OpenAI
$0.015
o1
OpenAI
$1.50
o1-mini
OpenAI
$0.30
o1-pro
OpenAI
$15.00
o3-mini
OpenAI
$1.10
Tools are defined per context in:
app/modules/chatbot/lib/
βββ tools-admin.server.ts
βββ tools-tenant.server.ts
βββ tools-marketing.server.ts
Each file exports:
CONTEXT_SYSTEM_PROMPT - System prompt function
getContextChatTools - Tool definitions using Zod schemas
ContextChatContext - TypeScript type for the context
import { z } from "zod" ;
import { tool } from "ai" ;
my_custom_tool : tool ( {
description : "What this tool does" ,
inputSchema : z . object ( {
param : z . string ( ) . describe ( "Parameter description" ) ,
} ) ,
execute : async ( { param } ) => {
// Tool logic here
return { result : "data" } ;
} ,
} ) ,
Route
Purpose
/admin/ai
Overview + Stats
/admin/ai/generations
All AI Generations table
/admin/ai/chats
All Chats table
/admin/ai/chats/:id
Chat Detail (Read-Only)
Total Generations
Total Cost
Average Cost per Object
Average Time per Object
Breakdown by Object Type
Breakdown by Model
1. User types message in ChatbotWidget
2. Widget calls API route with chatId + messages
3. API route calls createChatStreamResponse()
4. StreamService:
- Ensures chat exists in DB
- Saves user message
- Loads conversation history
- Creates GeneratedObject (pending)
- Calls streamText() with context tools
5. Tool Execution Loop:
- AI requests tool call
- Execute tool
- Return result to AI
6. AI streams response chunks
7. StreamService sends SSE to client
8. Widget displays streaming text
9. StreamService saves assistant message
10. Updates GeneratedObject (success + metrics)
import { ChatbotWidget } from "~/modules/chatbot/components/chatbot-widget" ;
< ChatbotWidget
context = "tenant" // "tenant" | "admin" | "marketing"
chatId = { chatId } // Optional: existing chat
initialMessages = { [ ] } // Optional: preload messages
readOnly = { false } // Optional: disable input
/>
Create tools-{context}.server.ts in app/modules/chatbot/lib/
Export CONTEXT_SYSTEM_PROMPT, getContextChatTools, ContextChatContext
Create API route at app/routes/api/ai.chat.{context}.ts
Add context config to chatbot-config.ts
Create chat routes at app/routes/{path}/chat/
The tenant chat automatically connects to the MCP server at /mcp when available. MCP tools extend the chatbot's capabilities with additional data access.
See MCP Server documentation for available tools.