Glow Architecture

Architecture and design of the Glow AI chat system

Architecture Overview

Glow follows a layered architecture with clear separation between client UI, server logic, and database access:

┌─────────────────────────────────────────────────────────────┐
│   API Layer (Next.js Route Handlers)                        │
│   apps/zooly-app/app/api/glow-chat-client/                  │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│   @zooly/glow-server                                        │
│   packages/glow-server/src/                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│   @zooly/glow-client                                        │
│   packages/glow-client/src/                                 │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│   @zooly/db (access layer)                                 │
│   packages/db/src/access/glow/                              │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│   Database (Drizzle ORM)                                    │
│   packages/db/src/glow/                                     │
└─────────────────────────────────────────────────────────────┘

Database Schema

Location: packages/db/src/glow/

Core Tables

TablePurpose
glow_settingsFlow configuration: slug, name, prompt, Mermaid chart, nodes metadata, tool list
glow_chatChat sessions: messages, currentNodeId, glowCurrentSlug, userId, clientMsgState
glow_toolAPI tool definitions: name, urlApi, fields, customHeaders
glow_chat_msgs_dataPer-message metadata (glowSlug, etc.)
glow_settings_chat_msgsDefault chat messages per flow
tool_callTool call logs for context building
cached_answer_stateCached answer parts for streaming
question_cacheQuestion-answer pairs with embeddings for cache lookup
glow_settings_embeddingFlow-level embeddings
glow_tool_embeddingTool-level embeddings
chat_token_usageToken usage logging

Key Relationships

  • glow_chat.glowCurrentSlugglow_settings.slug
  • glow_chat.cacheStateIdcached_answer_state.id
  • glow_chat.mockStateId → mock LLM state (testing)
  • nodesMetadata in glow_settings references tools by name; tools are resolved from glow_tool or built-in UI tools

Server Components

Location: packages/glow-server/src/

Request Flow

FunctionPurpose
handleGlowChatStreamEntry point for streaming; validates session, updates user/location, delegates to cache/core
handleGlowChatWithCacheWraps core; checks question cache when enabled, creates cache state on hit
handleGlowChatCoreMain LLM flow: builds prompts, resolves tools, calls streamText, handles steps
getGlowChatDataLoads glowChat + glowSettings by glowChatId
getOrCreateGlowChatCreates new chat or returns existing by chatId; used for generate/embed flows

Prompt Building

FunctionPurpose
getGlowChatSystemPromptFlow-level prompt: flow name, description, Mermaid chart, user data, tool usage rules
getGlowChatInstructionsSystemPromptNode-level: current node id, system instructions, available tools, moveToNodeId rules

Tool Resolution

FunctionPurpose
getCurrentNodeToolsResolves tools for current node from nodesMetadata + glow_tool table
getToolsListReturns all tools for a flow
executeApiToolCalls external API for API tools (POST to urlApi)
toolsBaseBase tool definitions including moveToNodeId, changeChatContext, returnToContext

Context & State

FunctionPurpose
changeChatContextSwitches chat to new flow by slug; updates glowCurrentSlug, currentNodeId
returnToContextReturns to previous flow
buildContextStackBuilds context from tool call logs for multi-turn tool handling
prepareStepHandlerRuns before each step; handles moveToNodeId, changeChatContext, etc.
onStepFinishHandlerRuns after each step; persists tool results, updates state
defaultOnFinishFinal handler: saves messages, clears cache state, logs usage

Caching

  • questionCacheService (@zooly/db) - Finds similar questions by embedding, returns cached answer
  • createCachedAnswerState - Creates streamable cache state for a cached answer
  • cacheStreamingLLM - AI SDK–compatible "model" that streams from cached parts
  • CACHE_CONFIG.SIMILARITY_THRESHOLD - Minimum similarity for cache hit

Client Components

Location: packages/glow-client/src/

Core Components

ComponentPurpose
GlowChatClientMain chat container; wraps GlowAIProvider, message queue, input form
GlowAIProviderContext: chatAI, glowChat, sendMsgOnBehalfOfUser, resetToMessage, etc.
useGlowChatCustom hook wrapping useChat; handles API URL, glowChatId, message persistence
GlowChatMessageQueueRenders message list with assistant/user parts
GlowChatInputFormInput area with send, attachments

UI Tools (tool-registry.tsx)

Tools are registered by name and render based on tool call type:

  • Media: askUserToUploadImage, askUserToCaptureImage, displayImage, downloadImage, playVideo, playAudio, etc.
  • Choices: askUserToChooseOptionWithBtns, askUserToMultiChooseFromListOfBtns
  • Memory: getFromMemory, saveToMemory
  • Other: askUserToRate, login, slideOut, downloadFile

Each tool has an "invocation" component (when AI calls it) and a "result" component (when user responds).

Context Providers

  • GlowAIProvider - Chat state, actions, glowChat metadata
  • GlowChatMsgPartProvider - Current message/part for nested tool components
  • GlowCommunicationProvider - Cross-component communication (e.g., sendToGlow)

API Endpoints

The consuming app (e.g., zooly-app) implements routes that delegate to glow-server:

RoutePurpose
POST /api/glow-chat-clientStream chat completion (handleGlowChatStream)
POST /api/glow-chat-client/reset-to-messageReset chat to a specific message
POST /api/glow-chat-client/reset-tool-callReset a tool call
POST /api/glow-chat-client/client-msg-state/saveSave clientMsgState
POST /api/glow-chat-client/message-data/get-public-dataGet public message data

Exact route paths may vary by app; the client uses a configurable url (e.g., /api/glow-chat-client).

Dependencies

glow-server

  • ai - AI SDK (streamText, convertToModelMessages, etc.)
  • @zooly/db - Database access, cache, embeddings
  • @zooly/types - GlowChat, GlowSettings, GlowTool, etc.
  • @zooly/util - extractQuestionFromMessage
  • @zooly/llm-mock - Mock LLM for testing
  • next, next-auth - Request/session handling

glow-client

  • @ai-sdk/react - useChat
  • ai - AI SDK types
  • @zooly/client - Shared client utilities
  • @zooly/util - Shared utilities
  • react, next, next-intl, zustand - UI and state

Types

Location: packages/types/src/types/glow/

TypePurpose
GlowSettingsFlow config (slug, glowName, glowPrompt, nodesMetadata, etc.)
GlowChatChat session (id, messages, currentNodeId, glowCurrentSlug, etc.)
GlowToolAPI tool (name, urlApi, fields, customHeaders)
GlowToolMinimalMinimal tool for node metadata (name, description, fields)
NodeMetadataNode config (id, label, fields, tools)
NodeMetadataDictMap of node id → NodeMetadata
CachedAnswerPartCached answer part (type, text, etc.)
ExtendedUIMessageUI message with tool parts