mirror of https://github.com/buster-so/buster.git
fix prompts of dashboard and metric tools
This commit is contained in:
parent
5d2631b848
commit
0f0a5ed7d1
|
@ -2,7 +2,7 @@ Creates dashboard configuration files with YAML content following the dashboard
|
|||
|
||||
## COMPLETE DASHBOARD YAML SCHEMA
|
||||
|
||||
# DASHBOARD CONFIGURATION - YML STRUCTURE
|
||||
`# DASHBOARD CONFIGURATION - YML STRUCTURE
|
||||
# ----------------------------------------
|
||||
# Required fields:
|
||||
#
|
||||
|
@ -32,5 +32,96 @@ Creates dashboard configuration files with YAML content following the dashboard
|
|||
# 8. String values generally should NOT use quotes unless they contain special characters (like :, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `) or start/end with whitespace.
|
||||
# 9. If a string contains special characters or needs to preserve leading/trailing whitespace, enclose it in double quotes (`"`). Example: `name: "Sales & Marketing Dashboard"`
|
||||
# 10. Avoid special characters in names and descriptions where possible, but if needed, use quotes as described in rule 9. UUIDs should NEVER be quoted.
|
||||
# ----------------------------------------
|
||||
|
||||
type: object
|
||||
name: Dashboard Configuration Schema
|
||||
description: Specifies the structure and constraints of a dashboard config file.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description: The title of the dashboard (e.g. Sales & Marketing Dashboard) - do NOT use quotes
|
||||
description:
|
||||
type: string
|
||||
description: A description of the dashboard, its metrics, and its purpose
|
||||
rows:
|
||||
type: array
|
||||
description: Array of row objects, each containing metric items
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
description: This is just an integer representing the row number 1 -> n
|
||||
items:
|
||||
type: array
|
||||
description: Array of metrics to display in this row (max 4 items)
|
||||
maxItems: 4
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: UUIDv4 identifier of an existing metric
|
||||
required:
|
||||
- id
|
||||
column_sizes:
|
||||
type: array
|
||||
description: Required array of column sizes (must sum to exactly 12)
|
||||
items:
|
||||
type: integer
|
||||
minimum: 3
|
||||
maximum: 12
|
||||
required:
|
||||
- id
|
||||
- items
|
||||
- column_sizes
|
||||
required:
|
||||
- name
|
||||
- description
|
||||
- rows`
|
||||
|
||||
**Key Requirements:**
|
||||
- `name`: Dashboard title (no underscores, descriptive name)
|
||||
- `description`: Natural language explanation of the dashboard's purpose and contents
|
||||
- `rows`: Array of row objects, each with unique ID, items (metric UUIDs), and column_sizes
|
||||
- Each row must have 1-4 items maximum
|
||||
- `column_sizes` must sum to exactly 12 and each size must be >= 3
|
||||
- All metric IDs must be valid UUIDs of existing metrics
|
||||
- Row IDs must be unique integers (typically 1, 2, 3, etc.)
|
||||
|
||||
**Dashboard Layout Rules:**
|
||||
- Grid system: Each row spans 12 columns total
|
||||
- Column sizes: [12] = full width, [6,6] = two halves, [4,4,4] = three thirds, [3,3,3,3] = four quarters
|
||||
- Common layouts: [12], [6,6], [4,8], [3,9], [4,4,4], [3,3,6], [3,3,3,3]
|
||||
- Each metric item gets the corresponding column size in the same position
|
||||
|
||||
**Example Structure:**
|
||||
```yaml
|
||||
name: Sales Performance Dashboard
|
||||
description: Comprehensive overview of sales metrics including revenue, conversions, and geographic performance
|
||||
rows:
|
||||
- id: 1
|
||||
items:
|
||||
- id: 550e8400-e29b-41d4-a716-446655440001
|
||||
column_sizes:
|
||||
- 12
|
||||
- id: 2
|
||||
items:
|
||||
- id: 550e8400-e29b-41d4-a716-446655440002
|
||||
- id: 550e8400-e29b-41d4-a716-446655440003
|
||||
column_sizes:
|
||||
- 6
|
||||
- 6
|
||||
- id: 3
|
||||
items:
|
||||
- id: 550e8400-e29b-41d4-a716-446655440004
|
||||
- id: 550e8400-e29b-41d4-a716-446655440005
|
||||
- id: 550e8400-e29b-41d4-a716-446655440006
|
||||
column_sizes:
|
||||
- 4
|
||||
- 4
|
||||
- 4
|
||||
```
|
||||
|
||||
**CRITICAL:** Follow the schema exactly - all metric IDs must reference existing metrics, column sizes must sum to 12, and row IDs must be unique. The tool will validate all metric references against the database.
|
|
@ -0,0 +1,41 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import dashboardToolDescription from './dashboard-tool-description.txt';
|
||||
import { getDashboardToolDescription } from './get-dashboard-tool-description';
|
||||
|
||||
describe('getDashboardToolDescription', () => {
|
||||
it('should return the dashboard tool description from the .txt file', () => {
|
||||
const description = getDashboardToolDescription();
|
||||
|
||||
// Verify it returns a non-empty string
|
||||
expect(typeof description).toBe('string');
|
||||
expect(description.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify it contains the expected content from the actual .txt file
|
||||
expect(description).toContain('Creates dashboard configuration files');
|
||||
expect(description).toContain('COMPLETE DASHBOARD YAML SCHEMA');
|
||||
expect(description).toContain('DASHBOARD CONFIGURATION - YML STRUCTURE');
|
||||
});
|
||||
|
||||
it('should have no template variables in the .txt file', () => {
|
||||
const content = dashboardToolDescription;
|
||||
|
||||
// Find any template variables in the file
|
||||
const templateVariablePattern = /\{\{([^}]+)\}\}/g;
|
||||
const foundVariables = new Set<string>();
|
||||
|
||||
const matches = Array.from(content.matchAll(templateVariablePattern));
|
||||
for (const match of matches) {
|
||||
if (match[1]) {
|
||||
foundVariables.add(match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Should have no template variables since this tool just returns the raw content
|
||||
expect(foundVariables.size).toBe(0);
|
||||
|
||||
// If any variables are found, list them for debugging
|
||||
if (foundVariables.size > 0) {
|
||||
console.error('Found unexpected template variables:', Array.from(foundVariables));
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,13 +1,5 @@
|
|||
import dashboardToolDescription from './dashboard-tool-description.txt';
|
||||
|
||||
/**
|
||||
* Template parameters for the dashboard tool prompt
|
||||
*/
|
||||
export interface DashboardToolTemplateParams {
|
||||
dataSourceSyntax: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the template function for use in dashboard tool
|
||||
*/
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import dashboardToolDescription from './dashboard-tool-description.txt';
|
||||
import { getDashboardToolDescription } from './get-dashboard-tool-description';
|
||||
|
||||
describe('Dashboard Tool Prompt Instructions', () => {
|
||||
it('should validate template file has no template variables', () => {
|
||||
const content = dashboardToolDescription;
|
||||
|
||||
// Find any template variables in the file
|
||||
const templateVariablePattern = /\{\{([^}]+)\}\}/g;
|
||||
const foundVariables = new Set<string>();
|
||||
|
||||
const matches = Array.from(content.matchAll(templateVariablePattern));
|
||||
for (const match of matches) {
|
||||
if (match[1] && match[1] !== 'variable') {
|
||||
foundVariables.add(match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Should have no template variables since this tool just fetches the raw content
|
||||
expect(foundVariables.size).toBe(0);
|
||||
expect(content.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should load the dashboard tool description correctly', () => {
|
||||
const result = getDashboardToolDescription();
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe('string');
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
|
||||
// Should return the raw content from the text file
|
||||
expect(result).toBe(dashboardToolDescription);
|
||||
});
|
||||
|
||||
it('should contain expected sections from the dashboard description', () => {
|
||||
const result = getDashboardToolDescription();
|
||||
|
||||
// Check for key sections that should be in the dashboard description
|
||||
expect(result).toContain('Creates dashboard configuration files');
|
||||
expect(result).toContain('COMPLETE DASHBOARD YAML SCHEMA');
|
||||
expect(result).toContain('DASHBOARD CONFIGURATION - YML STRUCTURE');
|
||||
expect(result).toContain('Required fields:');
|
||||
expect(result).toContain('Rules:');
|
||||
});
|
||||
});
|
|
@ -1,78 +1,46 @@
|
|||
import { describe, expect, it } from 'vitest';
|
||||
import { getMetricToolDescriptionPrompt } from './get-metric-tool-description';
|
||||
import { getMetricToolDescription } from './get-metric-tool-description';
|
||||
import metricToolDescription from './metric-tool-description.txt';
|
||||
|
||||
describe('Metric Tool Description Instructions', () => {
|
||||
it('should validate template file contains expected variables', () => {
|
||||
describe('getMetricToolDescription', () => {
|
||||
it('should return the metric tool description from the .txt file', () => {
|
||||
const description = getMetricToolDescription();
|
||||
|
||||
// Verify it returns a non-empty string
|
||||
expect(typeof description).toBe('string');
|
||||
expect(description.length).toBeGreaterThan(0);
|
||||
|
||||
// Verify it contains the expected content from the actual .txt file
|
||||
expect(description).toContain('Creates metric configuration files with YAML content');
|
||||
expect(description).toContain('COMPLETE METRIC YAML SCHEMA SPECIFICATION');
|
||||
expect(description).toContain('selectedChartType');
|
||||
expect(description).toContain('columnLabelFormats');
|
||||
|
||||
// Verify it has the full schema documentation
|
||||
expect(description).toContain('# METRIC CONFIGURATION - YML STRUCTURE');
|
||||
expect(description).toContain('bar, line, scatter, pie, combo, metric, table');
|
||||
});
|
||||
|
||||
it('should have no template variables in the .txt file', () => {
|
||||
const content = metricToolDescription;
|
||||
|
||||
// Expected template variables
|
||||
const expectedVariables = ['sql_dialect_guidance', 'date'];
|
||||
|
||||
// Find all template variables in the file
|
||||
// Find any template variables in the file
|
||||
const templateVariablePattern = /\{\{([^}]+)\}\}/g;
|
||||
const foundVariables = new Set<string>();
|
||||
|
||||
const matches = Array.from(content.matchAll(templateVariablePattern));
|
||||
for (const match of matches) {
|
||||
if (match[1] && match[1] !== 'variable') {
|
||||
if (match[1]) {
|
||||
foundVariables.add(match[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Convert to arrays for easier comparison
|
||||
const foundVariablesArray = Array.from(foundVariables).sort();
|
||||
const expectedVariablesArray = expectedVariables.sort();
|
||||
// Should have no template variables since this tool just returns the raw content
|
||||
expect(foundVariables.size).toBe(0);
|
||||
|
||||
// Check that we have exactly the expected variables
|
||||
expect(foundVariablesArray).toEqual(expectedVariablesArray);
|
||||
|
||||
// Also verify each expected variable exists
|
||||
for (const variable of expectedVariables) {
|
||||
expect(content).toMatch(new RegExp(`\\{\\{${variable}\\}\\}`));
|
||||
// If any variables are found, list them for debugging
|
||||
if (foundVariables.size > 0) {
|
||||
console.error('Found unexpected template variables:', Array.from(foundVariables));
|
||||
}
|
||||
|
||||
// Ensure no unexpected variables exist
|
||||
expect(foundVariables.size).toBe(expectedVariables.length);
|
||||
});
|
||||
|
||||
it('should load and process the prompt template correctly', () => {
|
||||
const sqlDialectGuidance = 'Test SQL guidance for PostgreSQL';
|
||||
const result = getMetricToolDescriptionPrompt(sqlDialectGuidance);
|
||||
|
||||
expect(result).toBeDefined();
|
||||
expect(typeof result).toBe('string');
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
|
||||
// Should contain the SQL guidance we provided
|
||||
expect(result).toContain(sqlDialectGuidance);
|
||||
|
||||
// Should not contain any unreplaced template variables
|
||||
expect(result).not.toMatch(/\{\{sql_dialect_guidance\}\}/);
|
||||
expect(result).not.toMatch(/\{\{date\}\}/);
|
||||
|
||||
// Should contain the current date in YYYY-MM-DD format
|
||||
const currentDate = new Date().toISOString().split('T')[0];
|
||||
expect(result).toContain(currentDate);
|
||||
});
|
||||
|
||||
it('should contain expected sections from the prompt template', () => {
|
||||
const result = getMetricToolDescriptionPrompt('Test guidance');
|
||||
|
||||
// Check for key sections that should be in the prompt
|
||||
// Note: These expectations may need to be adjusted based on the actual content
|
||||
// of the metric-tool-description.txt file
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
// Additional specific content checks can be added based on the prompt template structure
|
||||
});
|
||||
|
||||
it('should throw an error for empty SQL dialect guidance', () => {
|
||||
expect(() => {
|
||||
getMetricToolDescriptionPrompt('');
|
||||
}).toThrow('SQL dialect guidance is required');
|
||||
|
||||
expect(() => {
|
||||
getMetricToolDescriptionPrompt(' '); // whitespace only
|
||||
}).toThrow('SQL dialect guidance is required');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,40 +1,8 @@
|
|||
import metricToolDescription from './metric-tool-description.txt';
|
||||
|
||||
/**
|
||||
* Template parameters for the metric tool description prompt
|
||||
*/
|
||||
export interface MetricToolTemplateParams {
|
||||
dataSourceSyntax: string;
|
||||
date: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the metric tool description prompt template and replaces variables
|
||||
*/
|
||||
function loadAndProcessPrompt(sqlDialectGuidance: string): string {
|
||||
if (!sqlDialectGuidance.trim()) {
|
||||
throw new Error('SQL dialect guidance is required');
|
||||
}
|
||||
|
||||
// Replace template variables
|
||||
const currentDate = new Date().toISOString().split('T')[0] ?? '';
|
||||
const processedContent = metricToolDescription
|
||||
.replace(/\{\{sql_dialect_guidance\}\}/g, sqlDialectGuidance)
|
||||
.replace(/\{\{date\}\}/g, currentDate);
|
||||
|
||||
return processedContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export the template function for use in metric tool
|
||||
*/
|
||||
export const getMetricToolDescription = (): string => {
|
||||
return metricToolDescription;
|
||||
};
|
||||
|
||||
/**
|
||||
* Export the template function with parameters for use in metric tool
|
||||
*/
|
||||
export const getMetricToolDescriptionPrompt = (sqlDialectGuidance: string): string => {
|
||||
return loadAndProcessPrompt(sqlDialectGuidance);
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue