Danvas
Danvas
DashboardSupportWelcome

👤 USER DOCS

User Guides

Getting Started

Getting StartedDashboard & OnboardingApp Settings

Tutorials

Tutorial: Setting Up Shift Tasks & ClosersTutorial: Managing Incidents in the InboxTutorial: Tracking Compliance & Sync StatusTutorial: Operational Workflows with the AI AssistantTutorial: Building & Deploying Custom Checklists

Daily Operations (Staff)

Shift Workspace & TasksService Day SetupDaily Line-UpStaff Service Day ReportsForms

Communication & Chat

Messages & AnnouncementsUnified Operations InboxAI Assistant

Manager & Admin Guides

Daily Line-Up SetupStaff SchedulingManaging LocationsNPS and Guest FeedbackCouponsContacts and Guest HistoryManager CloseoutsDaily Line-Up & ComplianceAnalyticsIncident ReportingWhistleblower Concerns & FeedbackAdmin Tools

⚙️ DEVELOPER DOCS

Getting Started

Getting StartedDevelopmentDeployment Guide

Architecture

Architecture OverviewExplanation: AI Integration & Tenant SecurityExplanation: Dynamic Forms Engine DesignExplanation: Compliance Ledger DesignExplanation: Live Sync & Data FreshnessData FlowArchitecture Decision Records

Core Domain

Core DomainDatabase ReferenceLocations DomainAuth & RBACScheduling DomainReports DomainIncidents DomainUnified Operations InboxLive Sync Data FreshnessToast Sync PipelineNotifications DomainCoupons and Guest NPSAudit Log & Compliance ArchitectureDesign Audit FindingsAI Chat IntegrationAnalytics & Tips Integration

Frontend

Frontend ArchitectureFormsLoading SkeletonsComponentsPWA & Offline ShellScreenshots

API Reference

API Reference

Endpoints

POS Sales APIOptimization Data APISchedule Shifts APIEmployee Export APIReports APIIncidents APIAI Chat APIPush Notifications APIWebhooks APICron API

Contributing

ContributingCode Examples

Security

Security & Compliance

Release Notes

What's New

AI Chat Integration

Technical details of the Vercel AI Gateway integration, AI tool schemas, and dashboard AI chat

This page provides technical details for the AI Assistant integration, including model registry configuration, prompt system architecture, telemetry tracking, and message persistence.

Model Configuration

The AI model configuration is centralized in packages/ai/lib/models.ts. General language calls use Vercel AI Gateway; general selects DeepSeek V4.1 Flash and fast selects GLM 5.3 Flash. The Luna curator uses GPT-6 Luna. Additional registry slots and image/speech factories do not demonstrate an active product feature. Embeddings (voyageai/voyage-4) and reranking (voyageai/rerank-3) use the separate OpenRouter boundary (OPENROUTER_API_KEY). The maintained workload routing reference distinguishes agents, workflows, bounded generators, retrieval, external voice inference and forecasting.

import "server-only";
import { createGateway } from "@ai-sdk/gateway";
// Abridged: getGateway() wraps createGateway() for lazy key resolution
// (packages/ai/lib/models.ts holds the full registry).

export const MODEL_REGISTRY: Record<string, ModelDefinition> = {
  general: {
    key: "general",
    modelId: "deepseek/deepseek-v4.1-flash",
    displayName: "DeepSeek V4.1 Flash",
    provider: "DeepSeek",
    maxOutputTokens: 4096,
    supportsTools: true,
  },
};

Environment variable required:

  • AI_GATEWAY_API_KEY — API key for Vercel AI Gateway access; the shared factory resolves it lazily and rejects a missing key before constructing the provider.

AI Route Handler

The assistant route handler lives at apps/app/src/app/api/assistant/chat/route.ts and streams through the Vercel AI SDK message pipeline via @repo/ai; canonical execution runs through the Mastra runtime (apps/api/lib/assistant/mastra.ts), enabled by default. Agent instructions live with the runtime: tier and knowledge rules in apps/api/lib/assistant/mastra.ts, and per-mode and draft-purpose guidance in apps/api/lib/assistant/mode-instructions.ts, selected from the conversation's persisted mode and the forwarded draft purpose.

In Actions mode, managers also get three drafting tools from apps/api/lib/assistant/operational-draft-tools.ts:

  • draftShiftHandoff builds a handoff from the focused location's logged incidents and shift task records.
  • draftGuestRecovery triages a guest concern and drafts a reply with contact details redacted and no unauthorized compensation.
  • draftTrainingMaterial drafts a lesson or quiz from verified company SOPs only.

Each tool takes identity, location, and evidence from the server, and Ask Danvas renders the result with the matching artifact card for review. None of them sends or assigns anything.

System Prompt Architecture

The system prompt injects:

  1. User Identity & Role: Role (admin / manager / member), teamId, and effective location scope. An admin with no explicit location assignments has team-wide location scope; other callers receive their authorized location IDs.
  2. Assistant Mode:
    • general: Operational, SOP, and policy navigation.
    • actions: Draft-first assistance for announcements, handover notes, and incident summaries.
    • data: Metric definitions and explanation of data contracts.
  3. UI Context: Current page surface (surface: "ask" or specific dashboard view) and active locationSlug / locationId.

Message Persistence Schema

Dashboard chat threads, messages, and telemetry are stored in PostgreSQL (packages/database/src/schema/chat.ts):

export const chatThreads = pgTable("chat_threads", {
  id: text("id").primaryKey(),
  teamId: text("team_id").notNull(),
  userId: text("user_id").notNull(),
  title: text("title"),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

export const chatMessages = pgTable("chat_messages", {
  id: text("id").primaryKey(),
  threadId: text("thread_id").notNull().references(() => chatThreads.id),
  role: text("role", { enum: ["user", "assistant", "system"] }).notNull(),
  parts: jsonb("parts").notNull(),
  createdAt: timestamp("created_at").notNull().defaultNow(),
});

export const chatGenerations = pgTable("chat_generations", {
  id: text("id").primaryKey(),
  messageId: text("message_id").references(() => chatMessages.id),
  modelId: text("model_id").notNull(),
  promptTokens: integer("prompt_tokens"),
  completionTokens: integer("completion_tokens"),
  estimatedCost: numeric("estimated_cost", { precision: 10, scale: 6 }),
  createdAt: timestamp("created_at").notNull().defaultNow(),
});

Related

AI Assistant User Guide

Auth & RBAC

Database Schemas

Design Audit Findings

Summary of design audit findings and remediation status

Analytics & Tips Integration

Tip marts, performance facts, cron writers, and read surfaces for Intelligence → Analytics

On this page

Model ConfigurationAI Route HandlerSystem Prompt ArchitectureMessage Persistence SchemaRelated