Tool Handler Logic
Understanding the flexibility and capabilities of DAIN tool handlers
Tool Handler Overview
The handler function in a DAIN tool is where you implement your core business logic. It receives the parsed input parameters and authenticated agent information, allowing you to perform any operations needed to fulfill the tool's purpose.
import { DainResponse, CardUIBuilder } from "@dainprotocol/utils";
handler: async (inputs: InputType, agentInfo: AgentInfo) => {
// Your custom logic here
return new DainResponse({
text: string, // Message for the AI agent
data: OutputType, // Structured data matching output schema
ui?: UIComponent // Optional UI built with UIBuilders
});
}
Authentication and Identity
Every tool handler receives an agentInfo
parameter that provides authenticated identity information:
interface AgentInfo {
id: string; // Unique identifier linked to DAIN ID
// ... other agent properties
}
The id
is uniquely tied to either:
- A human user's DAIN ID smart account (id.dain.org)
- An AI agent's unique identifier
You can use this ID to:
- Authenticate users against your own systems
- Maintain user-specific state or preferences
- Track usage and implement rate limiting
- Link actions to specific DAIN identities
Handler Capabilities
Inside your handler, you can implement any logic your tool requires:
import { DainResponse, CardUIBuilder, AlertUIBuilder } from "@dainprotocol/utils";
handler: async ({ query }, agentInfo) => {
try {
// Database operations
const userPreferences = await db.getUserPreferences(agentInfo.id);
// External API calls
const apiResponse = await axios.get('https://api.example.com/data');
// Custom business logic
const processedData = await processData(apiResponse.data);
// Authentication with external services
const userToken = await getUserAuthToken(agentInfo.id);
// File operations
const fileContent = await fs.readFile('template.json');
// Machine learning models
const prediction = await mlModel.predict(query);
const cardUI = new CardUIBuilder()
.title("Results")
.content(`Processed data for user ${agentInfo.id}`)
.build();
return new DainResponse({
text: `Processed request for user ${agentInfo.id}`,
data: processedData,
ui: cardUI
});
} catch (error) {
console.error(`Error processing request for ${agentInfo.id}:`, error);
const errorUI = new AlertUIBuilder()
.variant("error")
.title("Error")
.message("Unable to complete request")
.build();
return new DainResponse({
text: `Error occurred: ${error.message}. Consider suggesting an alternative approach.`,
data: { error: error.message },
ui: errorUI
});
}
}
Error Handling
import { DainResponse, AlertUIBuilder, CardUIBuilder } from "@dainprotocol/utils";
handler: async (inputs, agentInfo) => {
try {
const results = await processData(inputs);
const successUI = new CardUIBuilder()
.title("Success")
.content("Operation completed successfully")
.variant("default")
.build();
return new DainResponse({
text: "Successfully processed the request",
data: results,
ui: successUI
});
} catch (error) {
console.error(`Error processing request for ${agentInfo.id}:`, error);
const errorUI = new AlertUIBuilder()
.variant("error")
.title("Operation Failed")
.message(error.message)
.icon(true)
.build();
return new DainResponse({
text: `Error occurred: ${error.message}. Consider suggesting an alternative approach.`,
data: { error: error.message },
ui: errorUI
});
}
}
Example with Multiple UI Components
import {
DainResponse,
CardUIBuilder,
TableUIBuilder,
ChartUIBuilder
} from "@dainprotocol/utils";
handler: async (inputs, agentInfo) => {
const data = await fetchAnalytics(agentInfo.id);
const chartUI = new ChartUIBuilder()
.type("line")
.title("Usage Trends")
.chartData(data.trends)
.dataKeys({ x: "date", y: "value" })
.build();
const tableUI = new TableUIBuilder()
.addColumns([
{ key: "metric", header: "Metric" },
{ key: "value", header: "Value" }
])
.rows(data.metrics)
.build();
const cardUI = new CardUIBuilder()
.title("Analytics Dashboard")
.addChild(chartUI)
.addChild(tableUI)
.build();
return new DainResponse({
text: "Generated analytics dashboard",
data: data,
ui: cardUI
});
}
Type Safety
interface AnalyticsData {
trends: Array<{
date: string;
value: number;
}>;
metrics: Array<{
metric: string;
value: number;
}>;
}
interface HandlerResponse {
text: string;
data: AnalyticsData;
ui?: UIComponent;
}
handler: async (inputs, agentInfo): Promise<HandlerResponse> => {
// Implementation
}