Skip to main content

Overview

Port: 4002 The Bot Service handles agent CRUD operations, AI chat via OpenRouter/LangChain, RAG context retrieval from linked knowledge bases, prompt configuration, conversation management, and credit billing.

Endpoints

Agent CRUD

Chat

Prompt Configuration

Variables and Context Tokens

Models and Files

Knowledge Base Readiness Gate

All paths that make an agent publicly or organizationally “live” verify KB readiness before proceeding:
  • POST /bots with isDraft: false
  • PUT /bots/:id when setting isDraft: false
  • POST /bots/:id/publish
  • POST /bots/:id/approve
  • POST /bots/:botId/distribution/publish
The GET /bots/:id/indexing-status endpoint proxies GET /knowledge/agents/:id/indexing-status and returns: If the knowledge service is unreachable, the check is fail-closed and publishing is blocked.

Chat Flow Pipeline

The core chat endpoint (POST /bots/:id/chat) follows this pipeline:

Provider Error Handling

Provider-level failures are mapped to user-friendly messages before reaching the UI. The mapping is centralized in services/bot/src/utils/error-utils.ts via mapProviderError(). The raw provider error message — including any API key URLs — is sanitized by sanitizeProviderMessage() before logging. Streaming chat emits error events as data: { "type": "error", "message": "...", "code": "..." }. Non-streaming chat returns { "error": "...", "code": "..." } when a provider-level failure occurs. Public widget chat and chat-core headless consumers receive the same codes.

Welcome Message Flow

When a conversation is created (POST /bots/:id/conversations):
1

Create Conversation

Create conversation record in database.
2

Resolve Variables

Merge variables from context_token, request body, and agent defaults.
3

Resolve Welcome Config

Welcome is read from bots.widget_config.welcome (web-widget-scoped), not via prompt-resolution. If absent or disabled, the conversation returns with no welcome message.
4

Render and Generate

  • If no config or enabled=false: return conversation with no welcome message.
  • If mode='fixed': render content with variables, return directly.
  • If mode='generated': render prompt template, call LLM, optionally stream response.
5

Save and Return

Save welcome message as first assistant message. Return { conversationId, welcomeMessage }.
Fixed mode has no cost. Generated mode calls record_external_cost_event() with operation welcome_message_generation.

Prompt Resolution Flow

All prompts resolve via the same three-tier chain:

RAG Quality Controls

Core Services

Database Tables

External Integrations

Critical Patterns

Use request.user.organizationId / request.user.id from JWT middleware. NEVER read raw headers.
Every chat MUST call record_external_cost_event() with provider, operation, cost, orgId, userId. Generated-mode welcome messages also bill.
On bot update, knowledgeBaseIds array replaces all links in kb_agent_links. If frontend sends [], all links are deleted.
checkResourceAccess() before all bot operations.
KB retrieval failures do not block chat — response continues without context.
NEVER read bots.system_prompt directly in new code. Always go through prompt-resolution.service.ts.
NEVER return conversation_variables.sensitive_variables in any API response.
Check bot.streaming_enabled AND request.stream === true before streaming any response.