All files / server/prompts step2-complete-prompt.ts

100% Statements 3/3
100% Branches 0/0
100% Functions 1/1
100% Lines 3/3

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102                                              51x                                                                                                                                             9x   9x          
/**
 * Step 2: Complete Query with Actual Dimension Values
 *
 * This prompt is used in the second stage of the multi-stage AI query generation flow.
 * It receives actual dimension values fetched from the database (with security context)
 * and uses them to generate the final query.
 *
 * This ensures filter values match actual data in the database, preventing
 * hallucinated or incorrect filter values.
 *
 * @see https://github.com/cliftonc/drizzle-cube/blob/main/src/server/prompts/step2-complete-prompt.ts
 */
 
import type { DimensionValues } from './types.js'
 
/**
 * System prompt for Step 2: Generate final query with actual dimension values.
 *
 * Placeholders:
 * - {CUBE_SCHEMA} - JSON-formatted cube schema
 * - {USER_PROMPT} - User's natural language query
 * - {DIMENSION_VALUES} - JSON object of dimension names to their actual values
 */
export const STEP2_SYSTEM_PROMPT = `Complete the data query using actual dimension values from the database.
 
ORIGINAL USER REQUEST: {USER_PROMPT}
 
CUBE SCHEMA:
{CUBE_SCHEMA}
 
AVAILABLE DIMENSION VALUES (from the actual database):
{DIMENSION_VALUES}
 
Complete the query using ONLY the values listed above for any dimension filters.
Do NOT invent or guess filter values - use exactly what's available.
Match user intent to the closest available values (e.g., if user says "opened" but only "created" exists, use "created").
 
RESPONSE FORMAT (same as single-step):
{
  "query": { /* Cube.js query OR funnel query with actual filter values */ },
  "chartType": "line"|"bar"|"area"|"pie"|"scatter"|"bubble"|"table"|"funnel",
  "chartConfig": {
    "xAxis": string[],
    "yAxis": string[],
    "series": string[],
    "sizeField": string,
    "colorField": string
  }
}
 
FUNNEL QUERY STRUCTURE (if queryType was "funnel"):
{
  "funnel": {
    "bindingKey": "PREvents.prNumber",
    "timeDimension": "PREvents.timestamp",
    "steps": [
      {
        "name": "Created",
        "filter": [
          { "member": "PREvents.eventType", "operator": "equals", "values": ["created"] },
          { "member": "PREvents.timestamp", "operator": "inDateRange", "values": ["last 6 months"] }
        ]
      },
      {
        "name": "Merged",
        "filter": { "member": "PREvents.eventType", "operator": "equals", "values": ["merged"] }
      }
    ],
    "includeTimeMetrics": true
  }
}
 
CRITICAL FILTER FORMAT RULES:
- filter MUST be a flat array of filter objects: [{ member, operator, values }, ...]
- filter MUST NOT be nested arrays: NOT [[{ member, operator, values }]]
- For a single filter, use object format: { "member": "...", "operator": "...", "values": [...] }
- For multiple filters on step 0, use flat array: [{ filter1 }, { filter2 }] (NOT [[filter1, filter2]])
- The time filter (inDateRange) goes ONLY on step 0's filter, not on other steps.
 
Return ONLY valid JSON - no explanations or markdown:`
 
/**
 * Build the Step 2 prompt with actual dimension values from the database
 *
 * @param cubeSchema - JSON-formatted cube schema
 * @param userPrompt - User's natural language query
 * @param dimensionValues - Actual dimension values fetched from database
 * @returns Complete prompt ready to send to AI
 */
export function buildStep2Prompt(
  cubeSchema: string,
  userPrompt: string,
  dimensionValues: DimensionValues
): string {
  const valuesJson = JSON.stringify(dimensionValues, null, 2)
 
  return STEP2_SYSTEM_PROMPT
    .replace('{CUBE_SCHEMA}', cubeSchema)
    .replace('{USER_PROMPT}', userPrompt)
    .replace('{DIMENSION_VALUES}', valuesJson)
}