GessoAI
GessoAI is an intelligent component generation system that enables users to create UI components through natural language prompts. The system leverages AI/LLM capabilities to understand user intent and automatically generate appropriate React components with proper data structures.
System Architecture
The GessoAI system follows a clear data flow from user input to rendered components:
User Prompt → PromptBar → AI/LLM → JSON Response → ComponentFactory → Plugins → UI Components
Core Components
- PromptBar Component - Captures user input and sends it to the AI service
- AI Service - Processes prompts using LLM with structured schemas
- ComponentFactory - Orchestrates the conversion of AI responses to React components
- Plugins - Handle the actual component rendering logic
- Schemas - Guide the AI in generating appropriate JSON structures
How It Works
1. User Interaction
Users interact with GessoAI through the PromptBar component, typically found in pages like /ai
. They can request components using natural language:
- "Can you create an faq page. Include a title, an intro, paragraph and use accordions for each FAQ"
- "Show me a group of product cards"
- "Show me a page of content with multiple levels of headings"
2. AI Processing
The AI service receives the prompt along with predefined schemas that describe available components. These schemas act as a "vocabulary" that helps the LLM understand:
- What components are available
- What data structure each component expects
- When to use specific components
- How to configure component properties
3. JSON Generation
Based on the schemas and user prompt, the AI generates a structured JSON response containing:
- Component type (e.g., "Accordion", "ProductCard")
- Component data (titles, content, images, etc.)
- Configuration options (styling, behavior, standalone mode)
4. Component Rendering
The ComponentFactory receives the JSON response and:
- Validates the component type
- Looks up the appropriate plugin
- Passes the data to the plugin for rendering
- Applies any special modes (like standalone)
Schemas
Schemas are TypeScript definitions that describe components to the AI. They serve as the contract between the AI and the component system.
Schema Structure
Each schema typically includes:
- Description - What the component does and when to use it
- Properties - Required and optional data fields
- Examples - Sample data structures
- Usage Guidelines - When and how to apply the component
### Schema Guidelines
- **Be Descriptive** - Help the AI understand when and how to use components
- **Provide Context** - Explain the purpose and best use cases
## Plugins
Plugins are the bridge between AI-generated JSON and actual React components. They handle the rendering logic and any special processing needed.
### Plugin Structure
Each plugin is a function that:
1. Receives component data from the AI response
2. Processes and validates the data
3. Renders the appropriate React component
4. Applies any special modes or configurations
## Standalone Mode
Standalone mode is a special rendering mode that visually separates AI-generated components from surrounding content by applying padding.
### Standalone Property Format
The `standalone` property can be either:
- **Boolean**: When `standalone` is set to `true`, padding is applied to all sides of the component for full visual separation.
- **Object**: When `standalone` is an object, you can configure padding for individual sides:
- `paddingTop` (boolean)
- `paddingBottom` (boolean)
- `paddingLeft` (boolean)
- `paddingRight` (boolean)
**Example:**
```typescript
standalone: true // Applies padding to all sides
standalone: {
paddingTop: true,
paddingBottom: false,
paddingLeft: false,
paddingRight: true,
} // Applies padding only to top and right sides
Using standalone
as a boolean is a shortcut for uniform padding, while the object format allows for granular control over which sides receive padding.
Supported Components
All AI components support standalone mode:
- Typography
- Card
- Accordion
- ProductCard
- AIWhy
- AIFollowUp
- Sources
- Section
- Grid
- FootnoteMarker
- Container
When to Use Standalone Mode
The AI decides to use standalone mode based on context clues in the user prompt:
- User requests a "standalone" or "isolated" component
- Component is meant to be a focal point or demo
- Content suggests the component should be visually distinct
- User is testing or showcasing a specific component
- Mixed content scenarios: When rendering different component types together (e.g., typography with product cards)
Implementation
Standalone mode is implemented using wrapWithStandaloneMode which is a helper function that wraps components.
Schema Documentation
Schemas should document the standalone property:
standalone: {
type: "boolean | { paddingTop?: boolean; paddingBottom?: boolean; paddingLeft?: boolean; paddingRight?: boolean }",
description: "Controls visual separation of the component. Use true for uniform padding, or an object to specify which sides should have padding."
}
File Locations
AI Schemas
packages/providers/ai/src/schemas/
├── Accordion.ts
├── ProductCard.ts
├── Sources.ts
└── ... other schemas
Component Factory Plugins
packages/ui/design-system/src/plugins/ComponentFactory/
├── ComponentFactoryPlugins.tsx # Main plugin definitions
├── ComponentFactory.tsx # Core orchestration logic
Integration Points
packages/ui/next/src/client/AIPage/ # Main AI interface
packages/ui/design-system/src/components/AI/GessoAI/ # Core AI components
Development Workflow
Adding a New Component
-
Create the Schema
A schema consists of three main parts: the content type definition, usage details, and the exported schema string.
// packages/providers/ai/src/schemas/YourComponent.ts
// 1. Define the data structure the AI should generate
const yourComponentContentType = {
id: 'uuidv4',
type: 'yourComponent', // Must match the plugin key
title: 'Title here',
description: 'Description here',
// ... other properties your component needs
standalone: 'Optional boolean, set to true for standalone display'
};
// 2. Provide detailed usage guidance for the AI
const yourComponentContentUsageDetails = `
Use the yourComponent format when:
- Specific condition 1 (e.g., presenting structured data)
- Specific condition 2 (e.g., content has clear hierarchy)
- Specific condition 3 (e.g., actionable items are needed)
Set standalone: true when:
- Component needs visual separation from other content
- Content should stand out as important
- Mixing with other component types
Set standalone: false when:
- Multiple related components should be grouped
- Part of a cohesive series or list
`;
// 3. Export the complete schema for the AI service
export const YourComponentContentSchema =
`\n\n <YourComponentFormat> \n\n` +
`<Schema> ${JSON.stringify(yourComponentContentType)} </Schema>` +
`\n\n` +
`<UsageDetails> ${yourComponentContentUsageDetails} </UsageDetails>` +
`\n\n </YourComponentFormat> \n\n`;// Usage details guide the AI on when and how to use this component const cardContentUsageDetails = ` Use the card format when:
- Presenting a specific entity with title and supporting details
- Content benefits from visual elements or hierarchy
- Information includes actionable links
- Representing items like products, events, articles `;
-
Add the Plugin
// In ComponentFactoryPlugins.tsx
{
type: 'YourComponent',
plugin: ({ data, standalone }: AIComponentProps) => {
const content = <YourComponent {...data} />;
return standalone ? wrapWithStandaloneMode(content) : content;
}
} -
Update Response Structure
- Add to relevant page configurations (AIPage, ProductPage, etc.)
- Include in schema exports and AI service configurations