ai-site-pilot 0.4.5 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -1,121 +1,122 @@
1
1
  # AI Instructions for ai-site-pilot
2
2
 
3
- This file provides instructions for AI coding assistants (Claude, GPT, Copilot, etc.) on how to integrate ai-site-pilot into projects.
3
+ This file helps AI coding assistants (Claude, GPT, Copilot) integrate ai-site-pilot into projects.
4
4
 
5
5
  ## What is ai-site-pilot?
6
6
 
7
- A drop-in AI chat widget that can **control and navigate websites**. It's not just a chatbot - the AI can execute tools to filter content, open modals, navigate sections, and more.
7
+ A drop-in AI chat widget that can **control and navigate websites**. The AI can execute tools to filter content, open modals, navigate sections, and more.
8
8
 
9
- ## ⚠️ IMPORTANT: How the AI Learns Your Site
9
+ **Key features:**
10
+ - Works with any AI model via OpenRouter (Gemini, GPT-4, Claude, Llama)
11
+ - Free tier available (Gemini 2.0 Flash)
12
+ - Auto-generates system prompts from site content
13
+ - Streaming responses with tool execution
10
14
 
11
- The package provides chat UI and streaming. **The AI doesn't automatically know your site structure.** You must:
15
+ ## Quick Setup (Recommended)
12
16
 
13
- 1. **Tell it what exists** - In the system prompt, list your sections, data, categories
14
- 2. **Define tools** - Create tools that match your site's DOM and state
15
- 3. **Write handlers** - Client-side code that executes the actual actions
17
+ ### 1. Install
16
18
 
17
- ### Example: Teaching the AI About Your Site
18
-
19
- ```typescript
20
- // In your API route - this is the MOST IMPORTANT part
21
- const SYSTEM_PROMPT = `You are an AI assistant for MyStore.
22
-
23
- ## SITE STRUCTURE
24
- The page has these sections (use navigate_to_section tool):
25
- - hero: Top of page with tagline
26
- - products: Product grid (id="products")
27
- - about: About us section (id="about")
28
- - contact: Contact form (id="contact")
29
-
30
- ## AVAILABLE DATA
31
- Products on this site:
32
- - Electronics: laptops, phones, tablets
33
- - Clothing: shirts, pants, shoes
34
- - Home: furniture, decor, kitchen
35
-
36
- Categories for filtering: electronics, clothing, home, all
37
-
38
- ## YOUR TOOLS
39
- - navigate_to_section: Scroll to a section by ID
40
- - filter_products: Filter the product grid by category
41
- - open_product_modal: Show details for a specific product (use product slug)
42
- - open_contact: Open the contact modal
43
-
44
- ## BEHAVIOR
45
- - When users ask about products, use filter_products to show relevant category
46
- - When users want details, use open_product_modal
47
- - When users want to buy/contact, use open_contact
48
- - Always be helpful and proactively use tools to show relevant content`;
19
+ ```bash
20
+ npm install ai-site-pilot
49
21
  ```
50
22
 
51
- The system prompt teaches the AI:
52
- - What sections exist and their IDs
53
- - What data/content is available
54
- - What tools it can use and when
55
- - How to behave (proactively use tools)
56
-
57
- ## Quick Setup (Copy-Paste Ready)
23
+ ### 2. Configure Tailwind (Required)
58
24
 
59
- ### 1. Install the package
25
+ Add to `tailwind.config.js`:
60
26
 
61
- ```bash
62
- npm install ai-site-pilot
27
+ ```js
28
+ module.exports = {
29
+ content: [
30
+ './app/**/*.{js,ts,jsx,tsx}',
31
+ './components/**/*.{js,ts,jsx,tsx}',
32
+ './node_modules/ai-site-pilot/dist/**/*.{js,mjs}', // Required!
33
+ ],
34
+ }
63
35
  ```
64
36
 
65
- ### 2. Create the API route
37
+ ### 3. Create API Route with `siteContent`
66
38
 
67
- Create `app/api/chat/route.ts` (Next.js App Router):
39
+ The easiest way - just pass your site's data and the prompt is auto-generated:
68
40
 
69
41
  ```typescript
70
- import { streamText } from 'ai';
71
- import { google } from '@ai-sdk/google';
72
- // Or use any Vercel AI SDK provider:
73
- // import { openai } from '@ai-sdk/openai';
74
- // import { anthropic } from '@ai-sdk/anthropic';
75
-
76
- const SYSTEM_PROMPT = `You are a helpful AI assistant for this website. You can help users navigate and find information.
77
-
78
- ## YOUR CAPABILITIES
79
- You have access to tools that control the website:
80
- - navigate_to_section: Scroll to different sections
81
- - open_modal: Open detail modals
82
- - filter_content: Filter displayed content
83
- - search: Search the site
84
-
85
- Use these tools proactively when relevant to the user's request.`;
86
-
87
- export async function POST(req: Request) {
88
- const { messages } = await req.json();
89
-
90
- const result = streamText({
91
- model: google('gemini-2.0-flash'),
92
- system: SYSTEM_PROMPT,
93
- messages,
94
- tools: {
95
- // Define your site-specific tools here
96
- navigate_to_section: {
97
- description: 'Scroll to a section of the page',
98
- parameters: {
99
- type: 'object',
100
- properties: {
101
- section: { type: 'string', enum: ['hero', 'features', 'pricing', 'contact'] }
102
- },
103
- required: ['section']
104
- }
42
+ // app/api/chat/route.ts
43
+ import { createHandler } from 'ai-site-pilot/api';
44
+ import { defineTool } from 'ai-site-pilot/tools';
45
+
46
+ // Define tools the AI can use
47
+ const navigateTool = defineTool({
48
+ name: 'navigate_to_section',
49
+ description: 'Scroll to a section of the page',
50
+ parameters: {
51
+ type: 'object',
52
+ properties: {
53
+ section: {
54
+ type: 'string',
55
+ description: 'Section ID to navigate to',
56
+ enum: ['hero', 'services', 'about', 'contact'],
105
57
  },
106
- // Add more tools as needed
107
58
  },
108
- });
59
+ required: ['section'],
60
+ },
61
+ });
109
62
 
110
- return result.toDataStreamResponse();
111
- }
63
+ const showServiceTool = defineTool({
64
+ name: 'show_service',
65
+ description: 'Show details about a specific service',
66
+ parameters: {
67
+ type: 'object',
68
+ properties: {
69
+ serviceId: {
70
+ type: 'string',
71
+ description: 'The service ID',
72
+ },
73
+ },
74
+ required: ['serviceId'],
75
+ },
76
+ });
77
+
78
+ // Create handler with site content - prompt is auto-generated!
79
+ export const POST = createHandler({
80
+ model: 'google/gemini-2.0-flash-exp:free', // Free!
81
+ siteContent: {
82
+ name: 'Acme Dance Studio',
83
+ type: 'dance studio',
84
+ description: 'Premier dance education for all ages',
85
+ personality: 'warm, encouraging, and helpful',
86
+ pages: ['home', 'classes', 'teachers', 'schedule', 'contact'],
87
+ items: [
88
+ // Classes
89
+ { id: 'ballet', name: 'Ballet', category: 'class', description: 'Classical ballet for ages 3-adult', price: '$80/month' },
90
+ { id: 'jazz', name: 'Jazz', category: 'class', description: 'High-energy jazz for ages 6+', price: '$75/month' },
91
+ { id: 'hip-hop', name: 'Hip Hop', category: 'class', description: 'Street dance styles for ages 8+', price: '$70/month' },
92
+ // Teachers
93
+ { id: 'sarah', name: 'Sarah Johnson', category: 'teacher', description: 'Owner, 15 years experience, specializes in ballet' },
94
+ { id: 'mike', name: 'Mike Chen', category: 'teacher', description: 'Hip hop and jazz instructor, 8 years experience' },
95
+ ],
96
+ faqs: [
97
+ { question: 'What should I wear?', answer: 'Leotard and ballet slippers for ballet, athletic wear for jazz and hip hop.' },
98
+ { question: 'Do you offer trial classes?', answer: 'Yes! First class is free for new students.' },
99
+ ],
100
+ contact: {
101
+ email: 'info@acmedance.com',
102
+ phone: '555-123-4567',
103
+ address: '123 Dance Street, NYC',
104
+ hours: 'Mon-Sat 9am-8pm',
105
+ },
106
+ },
107
+ tools: [navigateTool, showServiceTool],
108
+ });
112
109
  ```
113
110
 
114
- ### 3. Add the chat widget
111
+ **The AI now automatically knows:**
112
+ - All your classes, teachers, pricing
113
+ - FAQs and contact info
114
+ - What tools to use and when
115
115
 
116
- In your layout or page component:
116
+ ### 4. Add the Chat Widget
117
117
 
118
118
  ```tsx
119
+ // components/ChatWidget.tsx
119
120
  'use client';
120
121
 
121
122
  import { SitePilot } from 'ai-site-pilot';
@@ -123,15 +124,18 @@ import 'ai-site-pilot/styles.css';
123
124
 
124
125
  export function ChatWidget() {
125
126
  const handleToolCall = (name: string, args: Record<string, unknown>) => {
126
- // Handle tool execution - this runs on the client
127
127
  switch (name) {
128
128
  case 'navigate_to_section':
129
- document.getElementById(args.section as string)?.scrollIntoView({ behavior: 'smooth' });
129
+ document.getElementById(args.section as string)?.scrollIntoView({
130
+ behavior: 'smooth',
131
+ });
130
132
  break;
131
- case 'open_modal':
132
- // Your modal logic
133
+ case 'show_service':
134
+ // Dispatch event for your page to handle
135
+ window.dispatchEvent(new CustomEvent('show-service', {
136
+ detail: { serviceId: args.serviceId },
137
+ }));
133
138
  break;
134
- // Handle other tools
135
139
  }
136
140
  };
137
141
 
@@ -140,347 +144,237 @@ export function ChatWidget() {
140
144
  apiEndpoint="/api/chat"
141
145
  onToolCall={handleToolCall}
142
146
  suggestions={[
143
- { text: 'Show me features', icon: '' },
144
- { text: 'How does pricing work?', icon: '💰' },
145
- { text: 'Contact sales', icon: '📞' },
147
+ { text: 'What classes do you offer?', icon: '💃' },
148
+ { text: 'Meet the teachers', icon: '👩‍🏫' },
149
+ { text: 'Contact us', icon: '📞' },
146
150
  ]}
147
- welcomeMessage="Hi! I can help you explore this site. What would you like to know?"
148
- theme={{
149
- accentColor: '#3b82f6', // Your brand color
150
- backgroundColor: '#0f172a', // Dark background
151
- // See full theme options below
152
- }}
151
+ theme={{ accent: 'pink' }} // or accentColor: '#ec4899'
152
+ welcomeMessage="Hi! I'm your dance studio assistant. How can I help you today?"
153
153
  />
154
154
  );
155
155
  }
156
156
  ```
157
157
 
158
- ## Theme Customization
158
+ ### 5. Environment Variable
159
159
 
160
- All colors accept any CSS color value (hex, rgb, hsl, etc.):
161
-
162
- ```tsx
163
- <SitePilot
164
- theme={{
165
- // Position
166
- position: 'bottom-right', // 'bottom-left', 'top-right', 'top-left'
167
- borderRadius: 24, // pixels
168
-
169
- // Colors
170
- accentColor: '#f59e0b', // Primary accent (buttons, highlights)
171
- accentColorDark: '#d97706', // Gradient end color
172
- backgroundColor: '#0F0720', // Panel background
173
- textColor: '#ffffff', // Primary text
174
- textMutedColor: '#a1a1aa', // Secondary text
175
- borderColor: 'rgba(255,255,255,0.1)',
176
-
177
- // Message bubbles
178
- userMessageBg: 'linear-gradient(135deg, #f59e0b, #d97706)',
179
- assistantMessageBg: 'rgba(255,255,255,0.05)',
180
- }}
181
- />
160
+ ```bash
161
+ # .env.local
162
+ OPENROUTER_API_KEY=sk-or-...
182
163
  ```
183
164
 
184
- ## Feature Toggles
185
-
186
- ```tsx
187
- <SitePilot
188
- features={{
189
- speech: true, // Voice input (microphone)
190
- tts: true, // Text-to-speech for responses
191
- fullscreen: true, // Fullscreen toggle button
192
- suggestions: true, // Show suggestion chips
193
- }}
194
- />
195
- ```
165
+ Get a free key at [openrouter.ai](https://openrouter.ai) - Gemini 2.0 Flash is free!
196
166
 
197
- ## Tool System
167
+ ## Alternative: Manual System Prompt
198
168
 
199
- Define tools that the AI can call to control your site:
169
+ If you need full control, use `systemPrompt` instead of `siteContent`:
200
170
 
201
171
  ```typescript
202
- // Using the defineTool helper (optional, for type safety)
203
- import { defineTool } from 'ai-site-pilot/tools';
204
-
205
- const filterProductsTool = defineTool({
206
- name: 'filter_products',
207
- description: 'Filter products by category',
208
- parameters: {
209
- type: 'object',
210
- properties: {
211
- category: {
212
- type: 'string',
213
- description: 'Product category',
214
- enum: ['electronics', 'clothing', 'home', 'all']
215
- }
216
- },
217
- required: ['category']
218
- }
172
+ export const POST = createHandler({
173
+ model: 'google/gemini-2.0-flash-exp:free',
174
+ systemPrompt: `You are an assistant for Acme Dance Studio.
175
+
176
+ ## Classes
177
+ - Ballet: Ages 3-adult, $80/month
178
+ - Jazz: Ages 6+, $75/month
179
+ - Hip Hop: Ages 8+, $70/month
180
+
181
+ ## Tools
182
+ - navigate_to_section: Scroll to a section (hero, classes, teachers, contact)
183
+ - show_service: Show details about a class
184
+
185
+ When users ask about classes, provide specific details.
186
+ Use tools proactively to show relevant content.`,
187
+ tools: [navigateTool, showServiceTool],
219
188
  });
220
189
  ```
221
190
 
222
- ## Environment Variables
223
-
224
- For the API route, you'll need your AI provider's API key:
191
+ ## SiteContent Schema
225
192
 
226
- ```env
227
- # For Google Gemini
228
- GOOGLE_GENERATIVE_AI_API_KEY=your-key-here
229
-
230
- # Or for OpenAI
231
- OPENAI_API_KEY=your-key-here
193
+ ```typescript
194
+ interface SiteContent {
195
+ name: string; // Business name
196
+ type?: string; // Business type (e.g., 'dance studio')
197
+ description?: string; // Brief description
198
+ personality?: string; // AI personality (e.g., 'warm and helpful')
199
+ pages?: string[]; // Available navigation pages
200
+ items?: SiteContentItem[]; // Products, services, team, etc.
201
+ faqs?: Array<{ question: string; answer: string }>;
202
+ contact?: {
203
+ email?: string;
204
+ phone?: string;
205
+ address?: string;
206
+ hours?: string;
207
+ };
208
+ additionalContext?: string; // Extra info for the prompt
209
+ }
232
210
 
233
- # Or for Anthropic
234
- ANTHROPIC_API_KEY=your-key-here
211
+ interface SiteContentItem {
212
+ id: string; // Unique identifier
213
+ name: string; // Display name
214
+ category?: string; // Category (e.g., 'class', 'teacher', 'product')
215
+ description?: string; // Description
216
+ [key: string]: unknown; // Any extra fields (price, duration, etc.)
217
+ }
235
218
  ```
236
219
 
237
- ## Complete Real-World Example
238
-
239
- Here's a full implementation for a portfolio site showing all three parts:
220
+ ## Theme Presets
240
221
 
241
- ### Part 1: System Prompt (teaches the AI what exists)
222
+ Use preset names for easy theming:
242
223
 
243
- ```typescript
244
- // app/api/chat/route.ts
245
- const PROJECTS = `
246
- Available projects (use open_project_modal with these IDs):
247
- - acme-dashboard: Acme Dashboard (SaaS, Live) - Analytics platform
248
- - mobile-app: FitTrack (Mobile, Live) - Fitness tracking app
249
- - ecommerce: ShopFlow (E-commerce, In Progress) - Online store template
250
- - api-service: DataSync API (Backend, Live) - Data synchronization service
251
-
252
- Categories: All, SaaS, Mobile, E-commerce, Backend
253
- Statuses: Live, In Progress, Concept
254
- `;
255
-
256
- const SYSTEM_PROMPT = `You are a portfolio assistant for Jane Developer.
257
-
258
- ## SITE SECTIONS
259
- - hero: Landing section with intro (id="hero")
260
- - projects: Project showcase grid (id="projects")
261
- - about: About section (id="about")
262
- - contact: Contact form (id="contact")
263
-
264
- ## PROJECT DATA
265
- ${PROJECTS}
266
-
267
- ## YOUR TOOLS
268
- - navigate_to_section: Scroll to hero, projects, about, or contact
269
- - filter_by_category: Filter projects (SaaS, Mobile, E-commerce, Backend, All)
270
- - filter_by_status: Filter by status (Live, In Progress, Concept)
271
- - open_project_modal: Open project details (use project ID like "acme-dashboard")
272
- - highlight_project: Pulse animation on a project card
273
- - open_contact: Open contact/hire modal
274
-
275
- ## WHEN TO USE TOOLS
276
- - "Show me your work" → navigate_to_section("projects")
277
- - "Any mobile apps?" → filter_by_category("Mobile")
278
- - "What's live?" → filter_by_status("Live")
279
- - "Tell me about Acme" → open_project_modal("acme-dashboard")
280
- - "I want to hire you" → open_contact()
281
-
282
- Be conversational but proactively use tools to make the site interactive.`;
224
+ ```tsx
225
+ <SitePilot theme={{ accent: 'pink' }} /> // Hot pink
226
+ <SitePilot theme={{ accent: 'amber' }} /> // Default orange/amber
227
+ <SitePilot theme={{ accent: 'blue' }} /> // Primary blue
228
+ <SitePilot theme={{ accent: 'green' }} /> // Emerald green
229
+ <SitePilot theme={{ accent: 'purple' }} /> // Violet purple
230
+ <SitePilot theme={{ accent: 'cyan' }} /> // Teal cyan
283
231
  ```
284
232
 
285
- ### Part 2: Tool Definitions (what the AI can call)
286
-
287
- ```typescript
288
- // app/api/chat/route.ts (continued)
289
- export async function POST(req: Request) {
290
- const { messages } = await req.json();
291
-
292
- const result = streamText({
293
- model: google('gemini-2.0-flash'),
294
- system: SYSTEM_PROMPT,
295
- messages,
296
- tools: {
297
- navigate_to_section: {
298
- description: 'Scroll to a page section',
299
- parameters: {
300
- type: 'object',
301
- properties: {
302
- section: { type: 'string', enum: ['hero', 'projects', 'about', 'contact'] }
303
- },
304
- required: ['section']
305
- }
306
- },
307
- filter_by_category: {
308
- description: 'Filter projects by category',
309
- parameters: {
310
- type: 'object',
311
- properties: {
312
- category: { type: 'string', enum: ['All', 'SaaS', 'Mobile', 'E-commerce', 'Backend'] }
313
- },
314
- required: ['category']
315
- }
316
- },
317
- open_project_modal: {
318
- description: 'Open project detail modal',
319
- parameters: {
320
- type: 'object',
321
- properties: {
322
- projectId: { type: 'string', description: 'Project ID like acme-dashboard' }
323
- },
324
- required: ['projectId']
325
- }
326
- },
327
- open_contact: {
328
- description: 'Open the contact/hire modal',
329
- parameters: { type: 'object', properties: {}, required: [] }
330
- }
331
- },
332
- });
233
+ Or use a custom hex color:
333
234
 
334
- return result.toDataStreamResponse();
335
- }
235
+ ```tsx
236
+ <SitePilot theme={{ accentColor: '#8b5cf6' }} />
336
237
  ```
337
238
 
338
- ### Part 3: Client Handler (executes the actions)
239
+ ## Tool-Only Response Handling
240
+
241
+ When the AI uses tools without text, customize the fallback message:
339
242
 
340
243
  ```tsx
341
- // components/ChatWidget.tsx
342
- 'use client';
244
+ import { SitePilot, createFallbackMessageGenerator } from 'ai-site-pilot';
343
245
 
344
- import { SitePilot } from 'ai-site-pilot';
345
- import 'ai-site-pilot/styles.css';
246
+ const generateFallback = createFallbackMessageGenerator({
247
+ navigate_to_section: (args) => `Scrolled to **${args.section}**.`,
248
+ show_service: (args) => `Showing details for **${args.serviceId}**.`,
249
+ filter_products: (args) => `Filtered to **${args.category}** products.`,
250
+ });
346
251
 
347
- export function ChatWidget() {
348
- const handleToolCall = (name: string, args: Record<string, unknown>) => {
349
- switch (name) {
350
- case 'navigate_to_section':
351
- document.getElementById(args.section as string)?.scrollIntoView({
352
- behavior: 'smooth'
353
- });
354
- break;
252
+ <SitePilot
253
+ apiEndpoint="/api/chat"
254
+ generateFallbackMessage={generateFallback}
255
+ />
256
+ ```
355
257
 
356
- case 'filter_by_category':
357
- // Dispatch custom event for your page to handle
358
- window.dispatchEvent(new CustomEvent('filter-projects', {
359
- detail: { category: args.category }
360
- }));
361
- break;
258
+ ## Full Props Reference
362
259
 
363
- case 'open_project_modal':
364
- window.dispatchEvent(new CustomEvent('open-project', {
365
- detail: { projectId: args.projectId }
366
- }));
367
- break;
260
+ ```typescript
261
+ interface SitePilotProps {
262
+ // Required
263
+ apiEndpoint: string;
368
264
 
369
- case 'open_contact':
370
- window.dispatchEvent(new CustomEvent('open-contact'));
371
- break;
372
- }
265
+ // Tool handling
266
+ onToolCall?: (name: string, args: Record<string, unknown>) => void;
267
+ generateFallbackMessage?: (toolName: string, args: Record<string, unknown>) => string;
268
+
269
+ // UI customization
270
+ suggestions?: Array<{ text: string; icon?: string }>;
271
+ welcomeMessage?: string;
272
+ placeholder?: string;
273
+ defaultOpen?: boolean;
274
+ position?: 'bottom-right' | 'bottom-left';
275
+
276
+ // Theme
277
+ theme?: {
278
+ accent?: 'amber' | 'pink' | 'blue' | 'green' | 'purple' | 'red' | 'cyan' | 'orange';
279
+ accentColor?: string; // Hex color (overrides accent)
280
+ backgroundColor?: string;
281
+ radius?: number;
373
282
  };
374
283
 
375
- return (
376
- <SitePilot
377
- apiEndpoint="/api/chat"
378
- onToolCall={handleToolCall}
379
- suggestions={[
380
- { text: "Show me your work", icon: "💼" },
381
- { text: "What's live?", icon: "🚀" },
382
- { text: "I want to hire you", icon: "💡" },
383
- ]}
384
- theme={{
385
- accentColor: '#8b5cf6',
386
- backgroundColor: '#0f0f23',
387
- }}
388
- />
389
- );
284
+ // Features
285
+ features?: {
286
+ speech?: boolean; // Voice input
287
+ tts?: boolean; // Text-to-speech
288
+ fullscreen?: boolean; // Fullscreen toggle
289
+ };
390
290
  }
391
291
  ```
392
292
 
393
- ### Part 4: Page Listens for Events
293
+ ## Common Patterns
294
+
295
+ ### E-commerce Site
394
296
 
395
- ```tsx
396
- // app/page.tsx or components/HomePage.tsx
397
- 'use client';
297
+ ```typescript
298
+ siteContent: {
299
+ name: 'MyStore',
300
+ type: 'online store',
301
+ items: [
302
+ { id: 'laptop-1', name: 'MacBook Pro', category: 'product', price: '$1999', inStock: true },
303
+ { id: 'phone-1', name: 'iPhone 15', category: 'product', price: '$999', inStock: true },
304
+ ],
305
+ pages: ['home', 'products', 'cart', 'checkout'],
306
+ }
398
307
 
399
- import { useEffect, useState } from 'react';
308
+ // Tools: search_products, filter_by_category, add_to_cart, open_product
309
+ ```
400
310
 
401
- export function HomePage() {
402
- const [filter, setFilter] = useState('All');
403
- const [selectedProject, setSelectedProject] = useState(null);
404
- const [showContact, setShowContact] = useState(false);
311
+ ### Portfolio Site
405
312
 
406
- useEffect(() => {
407
- const handleFilter = (e: CustomEvent) => setFilter(e.detail.category);
408
- const handleProject = (e: CustomEvent) => setSelectedProject(e.detail.projectId);
409
- const handleContact = () => setShowContact(true);
313
+ ```typescript
314
+ siteContent: {
315
+ name: 'Jane Developer',
316
+ type: 'portfolio',
317
+ items: [
318
+ { id: 'project-1', name: 'Acme Dashboard', category: 'project', status: 'Live', tech: 'React, Node' },
319
+ { id: 'project-2', name: 'FitTrack App', category: 'project', status: 'Live', tech: 'React Native' },
320
+ ],
321
+ pages: ['hero', 'projects', 'about', 'contact'],
322
+ }
410
323
 
411
- window.addEventListener('filter-projects', handleFilter as EventListener);
412
- window.addEventListener('open-project', handleProject as EventListener);
413
- window.addEventListener('open-contact', handleContact);
324
+ // Tools: filter_projects, open_project_modal, navigate_to_section, open_contact
325
+ ```
414
326
 
415
- return () => {
416
- window.removeEventListener('filter-projects', handleFilter as EventListener);
417
- window.removeEventListener('open-project', handleProject as EventListener);
418
- window.removeEventListener('open-contact', handleContact);
419
- };
420
- }, []);
327
+ ### SaaS Landing Page
421
328
 
422
- // Your page components use filter, selectedProject, showContact state...
329
+ ```typescript
330
+ siteContent: {
331
+ name: 'CloudSync',
332
+ type: 'SaaS platform',
333
+ description: 'Real-time data synchronization for teams',
334
+ items: [
335
+ { id: 'starter', name: 'Starter Plan', category: 'pricing', price: '$9/mo', features: '5 users, 10GB' },
336
+ { id: 'pro', name: 'Pro Plan', category: 'pricing', price: '$29/mo', features: '25 users, 100GB' },
337
+ ],
338
+ faqs: [
339
+ { question: 'Is there a free trial?', answer: 'Yes, 14-day free trial on all plans.' },
340
+ ],
423
341
  }
342
+
343
+ // Tools: navigate_to_section, show_pricing, open_signup, open_demo
424
344
  ```
425
345
 
426
- ## Common Patterns
346
+ ## Troubleshooting
427
347
 
428
- ### E-commerce Site
429
- ```tsx
430
- const tools = {
431
- search_products: { /* search inventory */ },
432
- filter_by_category: { /* filter product grid */ },
433
- add_to_cart: { /* add item to cart */ },
434
- open_product: { /* show product details */ },
435
- };
348
+ ### Button only shows icon, no "Ask AI" text
349
+ Your Tailwind config isn't scanning the package:
350
+ ```js
351
+ content: ['./node_modules/ai-site-pilot/dist/**/*.{js,mjs}']
436
352
  ```
437
353
 
438
- ### Documentation Site
354
+ ### Theme colors not working
355
+ Use component props, not CSS variables:
439
356
  ```tsx
440
- const tools = {
441
- search_docs: { /* search documentation */ },
442
- navigate_to_page: { /* go to specific doc page */ },
443
- show_code_example: { /* display code snippet */ },
444
- };
445
- ```
357
+ // Good
358
+ <SitePilot theme={{ accent: 'pink' }} />
446
359
 
447
- ### Portfolio Site
448
- ```tsx
449
- const tools = {
450
- filter_projects: { /* filter by category/status */ },
451
- open_project_modal: { /* show project details */ },
452
- navigate_to_section: { /* scroll to section */ },
453
- open_contact: { /* open contact form */ },
454
- };
360
+ // Bad - don't set CSS vars directly
455
361
  ```
456
362
 
457
- ## Troubleshooting
458
-
459
- **Chat not appearing?**
460
- - Make sure you imported the CSS: `import 'ai-site-pilot/styles.css'`
461
- - Check that the component is rendered (use React DevTools)
363
+ ### AI gives generic responses
364
+ Use `siteContent` to provide actual data about your site. The AI only knows what you tell it.
462
365
 
463
- **Tools not executing?**
464
- - Verify `onToolCall` is passed to SitePilot
465
- - Check browser console for the tool calls
466
- - Make sure tool names match between API and client
366
+ ### Tools not executing
367
+ 1. Check `onToolCall` is passed to SitePilot
368
+ 2. Verify tool names match between API and client handler
369
+ 3. Check browser console for errors
467
370
 
468
- **Styling issues?**
469
- - CSS variables can be overridden in your global CSS
470
- - The component uses `z-index: 200` - adjust if needed
371
+ ## Available Models
471
372
 
472
- ## Full Props Reference
373
+ | Model | ID | Notes |
374
+ |-------|-----|-------|
375
+ | Gemini 2.0 Flash | `google/gemini-2.0-flash-exp:free` | **Free!** Default |
376
+ | GPT-4o | `openai/gpt-4o` | Best overall |
377
+ | Claude 3.5 Sonnet | `anthropic/claude-3.5-sonnet` | Best for coding |
378
+ | Llama 3.1 70B | `meta-llama/llama-3.1-70b-instruct` | Open source |
473
379
 
474
- ```typescript
475
- interface SitePilotProps {
476
- apiEndpoint: string; // Required: Your chat API endpoint
477
- theme?: SitePilotTheme; // Theme customization
478
- suggestions?: Suggestion[]; // Suggestion chips
479
- features?: SitePilotFeatures; // Feature toggles
480
- onToolCall?: (name: string, args: Record<string, unknown>) => void;
481
- defaultOpen?: boolean; // Start with chat open
482
- placeholder?: string; // Input placeholder
483
- welcomeMessage?: string; // Initial greeting
484
- className?: string; // Additional CSS class
485
- }
486
- ```
380
+ See all models at [openrouter.ai/models](https://openrouter.ai/models)