> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brainstormer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Prompt Configuration

> Unified prompt configuration system: data model, three-tier resolution, versioning, modes, streaming, and dynamic variables.

## Overview

The Prompt Configuration System is a unified, versioned system for all LLM prompts used by agents -- system prompts, welcome messages, KB context injection templates, and additional prompt types -- managed through a single governed system.

**Key features:**

* **Prompt type registry** enforcing what types exist and how they behave
* **Per-agent prompt overrides** with `fixed` (static text) or `generated` (LLM-driven) modes
* **System defaults** used when no agent-level override exists
* **Dynamic variables** (`{{variable_name}}`) injected at runtime
* **Semantic versioning** (major.minor) with changelog on all configs
* **Streaming configuration** at agent and request level

## Data Model

### prompt\_type\_registry

Governs all valid prompt types. No prompt config can reference a type not in this table (FK constraint).

| Column            | Type            | Description                                        |
| ----------------- | --------------- | -------------------------------------------------- |
| `key`             | VARCHAR(100) PK | Machine identifier (immutable after creation)      |
| `label`           | VARCHAR(255)    | Human-readable name                                |
| `description`     | TEXT            | Purpose and usage guidance                         |
| `category`        | VARCHAR(50)     | Grouping: `chat`, `rag`, `engagement`, `tools`     |
| `supported_modes` | TEXT\[]         | Valid modes: `['fixed']`, `['generated']`, or both |
| `default_mode`    | VARCHAR(20)     | Mode when not explicitly specified                 |
| `required`        | BOOLEAN         | Whether every agent must have this configured      |
| `deprecated_at`   | TIMESTAMP       | Non-null means deprecated                          |

**Initial registry entries:**

| Key                    | Category | Modes                | Required |
| ---------------------- | -------- | -------------------- | -------- |
| `system`               | `chat`   | `fixed`, `generated` | true     |
| `welcome`              | `chat`   | `fixed`, `generated` | false    |
| `kb_context_injection` | `rag`    | `fixed`              | false    |
| `creator_analysis`     | `chat`   | `generated`          | false    |

### bot\_prompt\_configs

Per-agent prompt overrides. One row per prompt type per agent. UNIQUE on `(bot_id, prompt_type)`.

| Column                           | Type                                 | Description                                |
| -------------------------------- | ------------------------------------ | ------------------------------------------ |
| `id`                             | UUID PK                              |                                            |
| `bot_id`                         | UUID FK                              |                                            |
| `prompt_type`                    | VARCHAR FK -> prompt\_type\_registry |                                            |
| `mode`                           | VARCHAR(20)                          | `fixed` or `generated`                     |
| `content`                        | TEXT                                 | Literal text (mode=fixed, required)        |
| `prompt`                         | TEXT                                 | LLM instruction (mode=generated, required) |
| `enabled`                        | BOOLEAN                              | Toggle without deleting config             |
| `metadata`                       | JSONB                                | Extensible config                          |
| `version_major`, `version_minor` | INTEGER                              | Semantic version                           |

### system\_prompt\_defaults

Platform-wide defaults. One row per prompt type. Used when no bot-level override exists.

### conversation\_variables

Per-conversation resolved dynamic variables.

| Column                | Description                                      |
| --------------------- | ------------------------------------------------ |
| `conversation_id`     | PK + FK -> conversations                         |
| `initial_variables`   | Variables set at conversation start (immutable)  |
| `variables`           | Current merged state                             |
| `sensitive_variables` | Server-set variables (encrypted, never returned) |

## Three-Tier Resolution Flow

```mermaid theme={null}
graph TD
    A["Need prompt for (bot_id, prompt_type)"] --> B{bot_prompt_configs<br/>exists AND enabled?}
    B -->|Yes| C[Use bot-level config]
    B -->|No| D{system_prompt_defaults<br/>exists?}
    D -->|Yes| E[Use system default]
    D -->|No| F[Use hardcoded fallback constant]
    C & E & F --> G[Resolve dynamic variables]
    G --> H{Mode?}
    H -->|fixed| I[Return rendered content]
    H -->|generated| J[Send rendered prompt to LLM]
    J --> K[Return LLM output]
```

This three-tier fallback ensures the system always works even if config data is missing.

## Welcome Message Flow

<Tabs>
  <Tab title="Fixed Mode">
    ```
    POST /bots/:id/conversations
      -> Create conversation record
      -> Resolve + store variables
      -> Resolve welcome config (bot -> system default -> no-op)
      -> Render content with variables
      -> Return welcome message (no loading state needed)
      -> Save as first assistant message
    ```

    **Cost:** None (no LLM call).
  </Tab>

  <Tab title="Generated Mode">
    ```
    POST /bots/:id/conversations
      -> Create conversation record
      -> Resolve + store variables
      -> Resolve welcome config
      -> Render prompt template with variables
      -> Call LLM with rendered prompt + system prompt as context
      -> If streaming: stream response
      -> Return generated welcome message
      -> Save as first assistant message
    ```

    **Cost:** Calls `record_external_cost_event()` with operation `welcome_message_generation`.
  </Tab>

  <Tab title="No Welcome">
    If `welcome` prompt type has `enabled=false` at bot level, or no config/default exists, the conversation starts empty.
  </Tab>
</Tabs>

## Versioning System

### Version Numbering

* **Major.Minor** format (e.g., `1.0`, `1.3`, `2.0`)
* **Minor bump:** Content edits, wording changes, variable adjustments
* **Major bump:** Mode changes, structural changes, breaking variable contract changes

### Version Bump Logic

```
On update:
1. Compare new state with current
2. If mode changed -> major bump (1.3 -> 2.0)
3. If only content/prompt/metadata changed -> minor bump (1.3 -> 1.4)
4. Snapshot current state into *_versions table with changelog
5. Update current record with new version numbers
```

### Rollback

Restoring a previous version creates a **new** version entry with changelog "Rolled back to vX.Y". History is never rewritten.

## Streaming Configuration

### Effective Behavior

```
effective_streaming = bot.streaming_enabled AND request.stream === true
```

| Channel                         | Sends `stream`                     |
| ------------------------------- | ---------------------------------- |
| Web widget / landing page       | `true`                             |
| Telegram / WhatsApp / Instagram | `false` (full response, then send) |
| Direct API caller               | Caller's choice                    |

* `bots.streaming_enabled` (BOOLEAN, default: true) -- agent-level toggle
* `stream` param on `POST /bots/:id/chat` (default: false) -- client declares capability

## Adding New Prompt Types

New prompt types require a DB migration with these fields:

1. `key` -- unique, immutable machine identifier
2. `label` -- human-readable name
3. `description` -- clear explanation of purpose
4. `category` -- one of `chat`, `rag`, `engagement`, `tools`
5. `supported_modes` -- which modes are valid
6. `default_mode` -- must be in `supported_modes`

<Warning>
  **Deprecation before deletion:** Set `deprecated_at` to warn before removing. Cannot delete a type with existing bot configs or system defaults referencing it.
</Warning>

## API Endpoints

### Bot Service -- Prompt Config

| Method | Path                                      | Description             |
| ------ | ----------------------------------------- | ----------------------- |
| GET    | `/bots/:id/prompt-configs`                | List all prompt configs |
| GET    | `/bots/:id/prompt-configs/:type`          | Get specific config     |
| PUT    | `/bots/:id/prompt-configs/:type`          | Create or update        |
| DELETE | `/bots/:id/prompt-configs/:type`          | Remove override         |
| GET    | `/bots/:id/prompt-configs/:type/versions` | Version history         |
| POST   | `/bots/:id/prompt-configs/:type/rollback` | Rollback to version     |

### Auth Service -- Superadmin

| Method  | Path                                    | Description       |
| ------- | --------------------------------------- | ----------------- |
| GET     | `/admin/prompt-types`                   | List registry     |
| POST    | `/admin/prompt-types`                   | Register new type |
| PUT     | `/admin/prompt-types/:key`              | Update metadata   |
| POST    | `/admin/prompt-types/:key/deprecate`    | Deprecate type    |
| GET/PUT | `/admin/prompt-defaults/:type`          | System defaults   |
| GET     | `/admin/prompt-defaults/:type/versions` | Version history   |
| POST    | `/admin/prompt-defaults/:type/rollback` | Rollback          |

## Security

* **Sensitive variables:** Stored encrypted via `packages/shared/src/crypto.ts`. Never returned in client-facing responses.
* **Signed context tokens:** JWT with expiry; validated server-side on every use.
* **Prompt injection:** Variables should be wrapped in quotes or XML tags in LLM prompts.
* **Access control:** Bot prompt configs scoped to bot owner's org (existing RBAC). Registry/defaults endpoints require superadmin.
