AI Chat for Your Website
One line of code. No backend. Custom tools.
<script
src="https://okidoki.chat/embed/okidoki.js"
data-app-id="YOUR_APP_ID">
</script>Installation
2. Add the Script
Paste this code before the closing </body> tag in your HTML.
<script
src="https://okidoki.chat/embed/okidoki.js"
data-app-id="YOUR_APP_ID">
</script>Works Everywhere
Compatible with React, Next.js, Vue, WordPress, Shopify, Webflow, static HTML, and more.
Custom Tools
Let the AI interact with your app. Define functions that the assistant can call.
Basic Example
// Register a custom tool
OkidokiWidget.registerTools([{
name: 'add_to_cart',
description: 'Add a product to the shopping cart',
input: {
productId: 'The product ID to add',
quantity: 'Number of items (optional, default: 1)'
},
handler: async ({ productId, quantity = 1 }) => {
const result = await myStore.addToCart(productId, quantity);
return {
success: true,
cartCount: result.totalItems,
message: `Added ${quantity} item(s) to cart`
};
}
}]);Execution Control
timeoutMax time in ms. Default: 60s, Max: 10min
lockGroupSame group = no concurrent
paralleltrue = can always run
// Long-running tool with timeout
OkidokiWidget.registerTools([{
name: 'translate_document',
description: 'Translate the entire document to another language',
timeout: 300000, // 5 minutes (default: 60s, max: 10min)
lockGroup: 'document_write', // Prevents concurrent document writes
input: {
targetLanguage: 'Target language code (e.g., "es", "fr")'
},
handler: async ({ targetLanguage }) => {
OkidokiWidget.setToolNotification('Translating document...');
await translateDocument(targetLanguage);
OkidokiWidget.setToolNotification(null);
return { success: true };
}
}]);
// Read-only tool that can run anytime
OkidokiWidget.registerTools([{
name: 'get_document_stats',
description: 'Get word count and page count',
parallel: true, // Never blocks, never blocked
handler: async () => {
return { wordCount: 1500, pageCount: 5 };
}
}]);💡 Tips
- • Write descriptions as if explaining to a smart assistant
- • Use parallel: true for read-only tools
- • Return concise data - the AI will phrase it naturally
Programmatic AI API
Call the LLM directly from your tools for structured responses.
OkidokiWidget.ask()
Send prompts to the AI and receive structured responses using schemas.
// AI-powered structured responses
const { array, object, string, number } = OkidokiWidget.helpers;
const result = await OkidokiWidget.ask({
prompt: 'Find all dates in this document that need updating',
context: documentContent, // Up to ~400k characters
temperature: 0.2, // Lower = more deterministic
output: {
updates: array(
object({
original: string('The original date text'),
suggested: string('The updated date'),
reason: string('Why this needs updating')
}),
'List of date updates needed'
)
}
});
if (result.success) {
console.log(result.result.updates);
// [{ original: "January 2024", suggested: "January 2025", reason: "..." }]
}Knowledge Base Search (RAG)
Search your crawled website and uploaded documents before answering. Results include relevance scores and source attribution.
// Search your knowledge base before answering
const answer = await OkidokiWidget.ask({
prompt: 'What are your pricing plans?',
searchKnowledgeBase: true
});
console.log(answer.result); // "Our plans start at $29/month..."
console.log(answer.sources); // Source documents used
// [{ title: "Pricing", relevance: 0.91, type: "website", snippet: "..." }]
// Advanced: Custom search query and source filtering
const result = await OkidokiWidget.ask({
prompt: 'Does this contract align with our terms?',
context: contractText,
searchKnowledgeBase: true,
searchQuery: 'standard contract terms policies', // Custom search
searchSource: 'documents', // 'website' | 'documents' | 'all'
searchLimit: 5 // Max results (1-5, default: 3)
});
// Use relevance scores to show source attribution
result.sources?.forEach(source => {
const confidence = source.relevance >= 0.85 ? 'high'
: source.relevance >= 0.70 ? 'medium' : 'low';
console.log(`${source.title} (${confidence} confidence)`);
});| Option | Type | Default | Description |
|---|---|---|---|
| searchKnowledgeBase | boolean | false | Enable RAG search |
| searchQuery | string | prompt | Custom search query |
| searchSource | string | 'all' | 'website' | 'documents' | 'all' |
| searchLimit | number | 3 | Max results (1-5) |
Relevance Scores
- 0.85+ — High confidence
- 0.70-0.85 — Good match
- 0.55-0.70 — Partial match
- <0.55 — Use with caution
Schema Helpers
Helpers for defining schemas simply.
// Schema helpers for structured outputs
const { string, number, boolean, array, object, enum_ } = OkidokiWidget.helpers;
// Simple types
const schema = {
title: string('Document title'),
pageCount: number('Number of pages'),
isPublished: boolean('Whether published')
};
// Enum constraints
const priority = enum_(['low', 'medium', 'high'], 'Task priority');
// Nested objects
const metadata = object({
author: string('Author name'),
created: string('Creation date ISO format')
}, 'Document metadata');
// Arrays
const tags = array(string('Tag name'), 'List of tags');
const items = array(
object({
id: string('Item ID'),
name: string('Item name'),
price: number('Price in cents')
}),
'Shopping cart items'
);Method Reference
All methods available on window.OkidokiWidget
Use Cases
Inspiration for what you can build
E-commerce
Cart, orders, recommendations
Booking
Appointments & availability
Documentation
Search & guided help
SaaS
Onboarding & feature discovery
Ready to get started?
Create your free account and get your App ID in seconds
Create Free Account🤖 Building with AI tools like Cursor? See llms.txt