Global Search
How to integrate your Butler with The Butler's global search system. Register your Butler as searchable, handle search queries, and return results with likelihood scores so users can find and access your Butler's functionality from anywhere.
Overview
The Butler provides a global search interface that searches across all Butlers and data categories. When users issue commands or search queries, The Butler queries all installed Butlers to determine which ones are most likely to handle the request. Your Butler can participate in this search system by implementing the search hook.
Search Registration
To participate in global search, your Butler must declare search capability and implement the search hook.
Manifest Declaration
{
"hooks": {
"onSearch": true
}
}Implement Search Hook
Implement the onSearch hook to handle search queries:
// Register search handler
window.lifeButler.onSearch(async (query, context) => {
// Analyze query to determine if your Butler can handle it
const likelihood = calculateLikelihood(query);
if (likelihood > 0.3) {
return {
likelihood: likelihood,
title: 'My Butler Result',
subtitle: 'Description of what this result does',
icon: '/butler-icon.png',
action: {
type: 'navigate',
path: '/butlers/my-butler',
params: { searchQuery: query }
},
metadata: {
category: 'finance',
keywords: ['expense', 'transaction']
}
};
}
return null; // Don't return result if likelihood is too low
});Likelihood Scoring
Each Butler returns a likelihood score (0.0 to 1.0) indicating confidence in handling the query. The platform aggregates scores and presents top matches sorted by likelihood.
Scoring Strategies
- Keyword matching: Check if query contains keywords related to your Butler's functionality
- AI classification: Use AI to classify the intent of the query
- Entity recognition: Detect entities (dates, amounts, categories) that your Butler handles
- Context awareness: Consider user's current context and recent activity
Example Scoring
function calculateLikelihood(query) {
const lowerQuery = query.toLowerCase();
let score = 0.0;
// High confidence keywords
if (lowerQuery.includes('expense') || lowerQuery.includes('spend')) {
score += 0.6;
}
// Medium confidence keywords
if (lowerQuery.includes('transaction') || lowerQuery.includes('payment')) {
score += 0.3;
}
// Amount detection
if (/\$\d+/.test(query)) {
score += 0.2;
}
return Math.min(score, 1.0);
}Search Result Structure
Return a structured search result object with all necessary information for display and navigation.
interface SearchResult {
likelihood: number; // 0.0 to 1.0
title: string; // Display title
subtitle?: string; // Optional description
icon?: string; // Butler icon or custom icon
action: SearchAction; // What happens when selected
metadata?: { // Additional context
category?: string;
keywords?: string[];
[key: string]: any;
};
}
type SearchAction =
| { type: 'navigate'; path: string; params?: Record<string, any> }
| { type: 'quickAction'; actionId: string; params?: Record<string, any> }
| { type: 'showSheet'; sheetType: 'decision' | 'input'; config: any };Requirements
- Declare search capability: Set
hooks.onSearch: truein your manifest. - Implement onSearch hook: Handle search queries and return results with likelihood scores.
- Return accurate likelihood: Use appropriate scoring strategies to determine if your Butler can handle the query.
- Provide complete results: Include title, subtitle, icon, and action for each search result.
- Handle edge cases: Return
nullif your Butler cannot handle the query (don't return low-likelihood results).