AI Tools
Last updated: August 3, 2023
AugmentOS provides a powerful way for TPAs to extend Mira AI's capabilities through custom tools. These tools allow Mira to take actions within your TPA, such as creating content, fetching data, or controlling features - all through natural language conversations with users.
// Example of handling a tool call in your TPA
protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {
if (toolCall.toolId === "add_todo") {
const todoItem = toolCall.toolParameters.todo_item as string;
const dueDate = toolCall.toolParameters.due_date as string | undefined;
// Add the todo item to your storage
const newTodo = await this.todoService.addTodo(toolCall.userId, todoItem, dueDate);
return `✅ Added: "${todoItem}"${dueDate ? ` due ${dueDate}` : ''}`;
}
return undefined;
}
What Are TPA Tools?
TPA tools are functions that your application exposes to Mira AI. When a user asks Mira to perform an action that matches one of your tools, Mira will:
- Identify the relevant tool
- Extract necessary parameters from the user's request
- Call your TPA with these parameters
- Return your response to the user
This creates a seamless experience where users interact with your TPA through natural conversations with Mira.
Tool calls don't happen in the context of a session, and your app does not need to be running to respond to a tool call. Your app should respond with a text string that Mira's AI will use to formulate a response.
For detailed reference on the interfaces involved, see Tool Types.
Defining Your Tools
Tools are defined in a tpa_config.json
file placed in your TPA's public directory. This file describes your tools, their parameters, and phrases that might trigger them.
Basic Structure
{
"name": "My TPA",
"description": "My awesome TPA description",
"version": "1.0.0",
"tools": [
{
"id": "tool_id",
"description": "What this tool does",
"activationPhrases": ["add something", "create new", "make a"],
"parameters": {
"param_name": {
"type": "string",
"description": "What this parameter does",
"required": true
}
}
}
]
}
Tool Properties
Each tool definition requires:
id
: Unique identifier for the tool (string)description
: Human-readable description of what the tool does (string)activationPhrases
: Optional array of phrases that might trigger this tool (array of strings, optional)parameters
: Optional map of parameters the tool accepts (object, optional)
For the full interface definition, see ToolSchema.
Parameter Properties
Each parameter definition requires:
type
: Data type of the parameter -"string"
,"number"
, or"boolean"
description
: Human-readable description of the parameterrequired
: Whether the parameter is required (boolean, default: false)enum
: Optional array of allowed values for string parameters (optional)
For the full interface definition, see ToolParameterSchema.
Implementing Tool Handling
1. Override onToolCall
In your TPA server, override the onToolCall
method to handle incoming tool calls:
import { TpaServer, ToolCall } from '@augmentos/sdk';
export class MyTpaServer extends TpaServer {
protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {
console.log(`Tool called: ${toolCall.toolId}`);
console.log(`User: ${toolCall.userId}`);
console.log(`Parameters: ${JSON.stringify(toolCall.toolParameters)}`);
// Handle specific tools based on toolId
switch (toolCall.toolId) {
case 'my_tool':
return this.handleMyTool(toolCall);
case 'another_tool':
return this.handleAnotherTool(toolCall);
default:
return undefined;
}
}
private async handleMyTool(toolCall: ToolCall): Promise<string> {
// Implement your tool-specific logic here
// ...
return "Tool result message";
}
}
2. The ToolCall Interface
The ToolCall
object contains:
interface ToolCall {
/** ID of the tool being called */
toolId: string;
/** Parameter values extracted by Mira */
toolParameters: Record<string, string | number | boolean>;
/** When the tool call was made */
timestamp: Date;
/** ID of the user who triggered the tool */
userId: string;
}
See the full definition at ToolCall.
3. Return Values
Your onToolCall
method should return:
- A string - Displayed to the user as Mira's response
- undefined - If the tool can't handle the request (Mira will inform the user)
Common Tool Patterns
CRUD Operations
{
"tools": [
{
"id": "create_item",
"description": "Create a new item",
"parameters": {
"name": {
"type": "string",
"description": "Name of the item",
"required": true
},
"category": {
"type": "string",
"description": "Category of the item",
"enum": ["Category1", "Category2", "Category3"]
}
}
},
{
"id": "get_items",
"description": "Get a list of items",
"parameters": {
"limit": {
"type": "number",
"description": "Maximum number of items to return"
},
"category": {
"type": "string",
"description": "Filter by category"
}
}
},
{
"id": "update_item",
"description": "Update an existing item",
"parameters": {
"id": {
"type": "string",
"description": "ID of the item to update",
"required": true
},
"name": {
"type": "string",
"description": "New name for the item"
},
"category": {
"type": "string",
"description": "New category for the item"
}
}
},
{
"id": "delete_item",
"description": "Delete an item",
"parameters": {
"id": {
"type": "string",
"description": "ID of the item to delete",
"required": true
}
}
}
]
}
Todo List Example
{
"tools": [
{
"id": "add_todo",
"description": "Add a new to-do item",
"activationPhrases": ["add a reminder", "create a todo", "remind me to"],
"parameters": {
"todo_item": {
"type": "string",
"description": "The to-do item text",
"required": true
},
"due_date": {
"type": "string",
"description": "Due date in ISO format (YYYY-MM-DD)"
}
}
},
{
"id": "get_todos",
"description": "Get all to-do items",
"activationPhrases": ["show my todos", "list my reminders"],
"parameters": {
"include_completed": {
"type": "boolean",
"description": "Whether to include completed items"
}
}
},
{
"id": "mark_todo_complete",
"description": "Mark a to-do item as complete",
"parameters": {
"todo_id": {
"type": "string",
"description": "ID of the to-do item",
"required": true
}
}
}
]
}
Implementation Example
Here's how to implement a complete todo list TPA with Mira integration:
import { TpaServer, ToolCall } from '@augmentos/sdk';
// Simple in-memory todo storage
const todos = new Map<string, Map<string, Todo>>();
interface Todo {
id: string;
text: string;
completed: boolean;
dueDate?: string;
createdAt: Date;
}
export class TodoTpaServer extends TpaServer {
protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {
const { toolId, userId, toolParameters } = toolCall;
// Initialize user's todo list if it doesn't exist
if (!todos.has(userId)) {
todos.set(userId, new Map<string, Todo>());
}
// Get user's todo list
const userTodos = todos.get(userId)!;
// Handle different tool calls
switch (toolId) {
case 'add_todo': {
const todoText = toolParameters.todo_item as string;
const dueDate = toolParameters.due_date as string | undefined;
// Create a new todo
const id = Date.now().toString();
const newTodo: Todo = {
id,
text: todoText,
completed: false,
dueDate,
createdAt: new Date()
};
// Save it
userTodos.set(id, newTodo);
return `✅ Added to your list: "${todoText}"${dueDate ? ` due ${dueDate}` : ''}`;
}
case 'get_todos': {
const includeCompleted = toolParameters.include_completed as boolean || false;
// Filter todos
const filteredTodos = Array.from(userTodos.values())
.filter(todo => includeCompleted || !todo.completed)
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
if (filteredTodos.length === 0) {
return "You don't have any todos yet.";
}
// Format response
const todoList = filteredTodos.map(todo =>
`- ${todo.completed ? '✓' : '○'} ${todo.text}${todo.dueDate ? ` (due ${todo.dueDate})` : ''}`
).join('\n');
return `Your todo list:\n${todoList}`;
}
case 'mark_todo_complete': {
const todoId = toolParameters.todo_id as string;
const todo = userTodos.get(todoId);
if (!todo) {
return "I couldn't find that todo item.";
}
// Update todo
todo.completed = true;
userTodos.set(todoId, todo);
return `✓ Marked "${todo.text}" as complete.`;
}
case 'mark_todo_incomplete': {
const todoId = toolParameters.todo_id as string;
const todo = userTodos.get(todoId);
if (!todo) {
return "I couldn't find that todo item.";
}
// Update todo
todo.completed = false;
userTodos.set(todoId, todo);
return `○ Marked "${todo.text}" as incomplete.`;
}
case 'delete_todo': {
const todoId = toolParameters.todo_id as string;
const todo = userTodos.get(todoId);
if (!todo) {
return "I couldn't find that todo item.";
}
// Delete todo
userTodos.delete(todoId);
return `🗑️ Deleted "${todo.text}" from your list.`;
}
default:
return undefined;
}
}
}
Tool Call Lifecycle
- Tool Call Detection: Mira AI identifies a tool call based on the tool's activation phrases
- Parameter Extraction: Mira extracts parameters from the user's request
- Tool Call Execution: Mira calls the
/tool
endpoint of your TPA server with the extracted parameters. You don't need to handle this manually, the SDK handles this for you. - Your TPA Handles the Tool Call: Your overridden
onToolCall
method is called with the tool call details. You can handle the tool call logic here. - Your TPA Responds: Your app responds with a text string that Mira's AI will use to formulate a response.
- Mira Responds to the User: Mira uses your response to formulate a response to the user, or call other tools as needed. Your response is not necessarily the final response to the user, it is just information the AI uses to formulate a response.
Related Documentation
- Tool Types Reference - Detailed type definitions for tools
- TPA Server - onToolCall - API reference for the onToolCall method
- Getting Started with TPAs - Complete guide to building a TPA