Developer Documentation
🤖 llms.txtv1.1.6

AI Chat for Your Website

One line of code. No backend. Custom tools.

index.html
<script 
  src="https://okidoki.chat/embed/okidoki.js"
  data-app-id="YOUR_APP_ID">
</script>

Installation

1. Get Your App ID

Create a free account and get your App ID from the dashboard.

Create Account

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

timeout

Max time in ms. Default: 60s, Max: 10min

lockGroup

Same group = no concurrent

parallel

true = 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)`);
});
OptionTypeDefaultDescription
searchKnowledgeBasebooleanfalseEnable RAG search
searchQuerystringpromptCustom search query
searchSourcestring'all''website' | 'documents' | 'all'
searchLimitnumber3Max results (1-5)

Relevance Scores

  • 0.85+High confidence
  • 0.70-0.85Good match
  • 0.55-0.70Partial match
  • <0.55Use 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