Skip to content

Agentic Assistant

Multi-step task execution with autonomous tool use and conversation memory.

Features

  • Agentic Mode - Autonomous multi-step tool execution
  • Built-in Tools - Calculator, web search, weather, notes, tasks
  • Conversation Memory - Persistent history across sessions
  • Streaming Responses - Real-time output as the agent works
  • Execution Limits - Configurable max tool rounds
  • Error Recovery - Graceful handling of tool failures

Quick Start

bash
export OPENAI_API_KEY=your_key
npm run recipe:agentic-assistant

How It Works

This recipe creates an autonomous AI assistant that can execute multi-step tasks using tools, with persistent memory across sessions.

Key capabilities:

  • Automatically selects and chains tools to complete tasks
  • Remembers context from previous conversations
  • Limits execution rounds to prevent runaway loops

Flow:

  1. User submits a request
  2. Agent analyzes what tools (if any) are needed
  3. Executes tools in sequence, processing results
  4. Loops until task is complete or max rounds reached
  5. Returns final response with results

Available Tools

ToolDescription
calculatorPerform mathematical calculations
web_searchSearch the web for information
get_weatherGet current weather for a location
create_noteSave a note for later reference
list_notesView all saved notes
create_taskCreate a new todo task
list_tasksView all tasks with status
complete_taskMark a task as completed

Example Session

You: What's 15% of 847 and create a note about it?

🔧 calculator("847 * 15 / 100")
→ = 127.05
🔧 create_note("15% of 847 Calculation")
→ Note saved with ID: k3m9x2p1

Assistant: 15% of 847 is 127.05. I have saved this calculation as a note
for your reference. You can view it anytime with the "notes" command.

Code Walkthrough

Creating the Agent

typescript
/**
 * Agentic Assistant Library
 *
 * Exported functions for the Agentic Assistant recipe.
 * Snippet markers allow VitePress to extract code for documentation.
 */

import * as fs from 'fs';
import { ChatClient, ToolRegistry, FileStorage, ChatError } from '../../../src';

// [start:config]
export const STORAGE_DIR = './.agent-memory';
export const CONVERSATION_ID = 'agent-session';
export const NOTES_FILE = `${STORAGE_DIR}/notes.json`;
export const TASKS_FILE = `${STORAGE_DIR}/tasks.json`;
export const MAX_TOOL_ROUNDS = 10;
export const MODEL = 'gpt-4o-mini';
// [end:config]

// [start:colors]
export const colors = {
  reset: '\x1b[0m',
  dim: '\x1b[2m',
  bold: '\x1b[1m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  green: '\x1b[32m',
  cyan: '\x1b[36m',
  magenta: '\x1b[35m',
  blue: '\x1b[34m',
  gray: '\x1b[90m'
};
// [end:colors]

// [start:types]
export interface Note {
  id: string;
  title: string;
  content: string;
  createdAt: string;
}

export interface Task {
  id: string;
  title: string;
  completed: boolean;
  createdAt: string;
}

export interface SearchResult {
  title: string;
  snippet: string;
  url: string;
}
// [end:types]

export function generateId(): string {
  return Math.random().toString(36).substring(2, 10);
}

export function log(
  level: 'info' | 'tool' | 'result' | 'error' | 'success',
  message: string
): void {
  const prefix = {
    info: `${colors.cyan}ℹ${colors.reset}`,
    tool: `${colors.magenta}🔧${colors.reset}`,
    result: `${colors.blue}→${colors.reset}`,
    error: `${colors.red}✗${colors.reset}`,
    success: `${colors.green}✓${colors.reset}`
  };
  console.log(`${prefix[level]} ${message}`);
}

// [start:persistence]
export function ensureStorageDir(): void {
  if (!fs.existsSync(STORAGE_DIR)) {
    fs.mkdirSync(STORAGE_DIR, { recursive: true });
  }
}

export function loadNotes(): Note[] {
  try {
    if (fs.existsSync(NOTES_FILE)) {
      return JSON.parse(fs.readFileSync(NOTES_FILE, 'utf-8'));
    }
  } catch (error) {
    if (error instanceof Error && !error.message.includes('ENOENT')) {
      console.error('Failed to load notes:', error.message);
    }
  }
  return [];
}

export function saveNotes(notes: Note[]): void {
  ensureStorageDir();
  fs.writeFileSync(NOTES_FILE, JSON.stringify(notes, null, 2));
}

export function loadTasks(): Task[] {
  try {
    if (fs.existsSync(TASKS_FILE)) {
      return JSON.parse(fs.readFileSync(TASKS_FILE, 'utf-8'));
    }
  } catch (error) {
    if (error instanceof Error && !error.message.includes('ENOENT')) {
      console.error('Failed to load tasks:', error.message);
    }
  }
  return [];
}

export function saveTasks(tasks: Task[]): void {
  ensureStorageDir();
  fs.writeFileSync(TASKS_FILE, JSON.stringify(tasks, null, 2));
}
// [end:persistence]

// [start:create-tools]
export function createToolRegistry(): ToolRegistry {
  const registry = new ToolRegistry();

  // Calculator tool
  // NOTE: Uses eval() for demo simplicity. For production, use 'mathjs' or 'expr-eval'.
  registry.registerTool(
    'calculator',
    async (args: { expression: string }) => {
      log('tool', `calculator("${args.expression}")`);
      try {
        const sanitized = args.expression.replace(/[^0-9+\-*/().%\s]/g, '');
        const result = eval(sanitized);
        log('result', `= ${result}`);
        return { result, expression: args.expression };
      } catch {
        return { error: 'Invalid mathematical expression' };
      }
    },
    {
      description: 'Perform mathematical calculations. Supports +, -, *, /, %, and parentheses.',
      parameters: {
        type: 'object',
        properties: {
          expression: {
            type: 'string',
            description: 'Mathematical expression to evaluate (e.g., "15 * 847 / 100")'
          }
        },
        required: ['expression']
      }
    }
  );

  // Web search tool (simulated)
  registry.registerTool(
    'web_search',
    async (args: { query: string }) => {
      log('tool', `web_search("${args.query}")`);
      const results: SearchResult[] = [];
      const query = args.query.toLowerCase();

      if (query.includes('ai') || query.includes('artificial intelligence')) {
        results.push(
          {
            title: 'Latest AI Developments in 2026',
            snippet: 'Major breakthroughs in multimodal AI systems and reasoning capabilities...',
            url: 'https://example.com/ai-news'
          },
          {
            title: 'AI in Enterprise: Adoption Trends',
            snippet: 'Enterprise AI adoption reaches 78% as companies integrate automation...',
            url: 'https://example.com/enterprise-ai'
          }
        );
      } else {
        results.push({
          title: `Search results for: ${args.query}`,
          snippet: `Found relevant information about "${args.query}". Simulated result.`,
          url: 'https://example.com/search'
        });
      }

      log('result', `Found ${results.length} results`);
      return { results, query: args.query };
    },
    {
      description: 'Search the web for information on any topic.',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string', description: 'Search query' }
        },
        required: ['query']
      }
    }
  );

  // Weather tool (simulated)
  registry.registerTool(
    'get_weather',
    async (args: { location: string }) => {
      log('tool', `get_weather("${args.location}")`);
      const weatherData: Record<
        string,
        { temperature: number; condition: string; humidity: number }
      > = {
        tokyo: { temperature: 22, condition: 'Partly Cloudy', humidity: 65 },
        'new york': { temperature: 18, condition: 'Sunny', humidity: 45 },
        london: { temperature: 12, condition: 'Rainy', humidity: 80 }
      };

      const location = args.location.toLowerCase();
      const weather = weatherData[location] || {
        temperature: 20,
        condition: 'Clear',
        humidity: 50
      };

      log('result', `${weather.temperature}°C, ${weather.condition}`);
      return {
        location: args.location,
        temperature: weather.temperature,
        temperatureUnit: 'Celsius',
        condition: weather.condition,
        humidity: weather.humidity
      };
    },
    {
      description: 'Get current weather information for a location.',
      parameters: {
        type: 'object',
        properties: {
          location: { type: 'string', description: 'City name (e.g., "Tokyo", "New York")' }
        },
        required: ['location']
      }
    }
  );

  // Note tools
  registry.registerTool(
    'create_note',
    async (args: { title: string; content: string }) => {
      log('tool', `create_note("${args.title}")`);
      const notes = loadNotes();
      const note: Note = {
        id: generateId(),
        title: args.title,
        content: args.content,
        createdAt: new Date().toISOString()
      };
      notes.push(note);
      saveNotes(notes);
      log('result', `Note saved with ID: ${note.id}`);
      return { success: true, note };
    },
    {
      description: 'Create and save a note for later reference.',
      parameters: {
        type: 'object',
        properties: {
          title: { type: 'string', description: 'Note title' },
          content: { type: 'string', description: 'Note content' }
        },
        required: ['title', 'content']
      }
    }
  );

  registry.registerTool(
    'list_notes',
    async () => {
      log('tool', 'list_notes()');
      const notes = loadNotes();
      log('result', `Found ${notes.length} notes`);
      return { notes, count: notes.length };
    },
    { description: 'List all saved notes.' }
  );

  // Task tools
  registry.registerTool(
    'create_task',
    async (args: { title: string }) => {
      log('tool', `create_task("${args.title}")`);
      const tasks = loadTasks();
      const task: Task = {
        id: generateId(),
        title: args.title,
        completed: false,
        createdAt: new Date().toISOString()
      };
      tasks.push(task);
      saveTasks(tasks);
      log('result', `Task created with ID: ${task.id}`);
      return { success: true, task };
    },
    {
      description: 'Create a new todo task.',
      parameters: {
        type: 'object',
        properties: {
          title: { type: 'string', description: 'Task description' }
        },
        required: ['title']
      }
    }
  );

  registry.registerTool(
    'list_tasks',
    async () => {
      log('tool', 'list_tasks()');
      const tasks = loadTasks();
      const pending = tasks.filter((t) => !t.completed);
      const completed = tasks.filter((t) => t.completed);
      log('result', `${pending.length} pending, ${completed.length} completed`);
      return { tasks, pending: pending.length, completed: completed.length };
    },
    { description: 'List all tasks with their status.' }
  );

  registry.registerTool(
    'complete_task',
    async (args: { taskId: string }) => {
      log('tool', `complete_task("${args.taskId}")`);
      const tasks = loadTasks();
      const task = tasks.find((t) => t.id === args.taskId);

      if (!task) {
        log('result', 'Task not found');
        return { success: false, error: 'Task not found' };
      }

      task.completed = true;
      saveTasks(tasks);
      log('result', `Task "${task.title}" marked complete`);
      return { success: true, task };
    },
    {
      description: 'Mark a task as completed.',
      parameters: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'ID of the task to complete' }
        },
        required: ['taskId']
      }
    }
  );

  return registry;
}
// [end:create-tools]

// [start:create-client]
export function createAgentClient(apiKey: string): ChatClient {
  const storage = new FileStorage(STORAGE_DIR);
  const tools = createToolRegistry();

  return new ChatClient({
    provider: 'openai',
    model: MODEL,
    apiKey,
    storage,
    conversationId: CONVERSATION_ID,
    tools,
    agenticMode: true,
    maxToolRounds: MAX_TOOL_ROUNDS,
    systemPrompt: `You are a helpful AI assistant with access to various tools.
You can perform calculations, search the web, check weather, and manage notes and tasks.
When a user asks you to do something, use the appropriate tools to help them.
For multi-step tasks, break them down and use tools as needed.
Always explain what you're doing and provide helpful responses.
Be concise but thorough.`
  });
}
// [end:create-client]

// [start:streaming]
export async function streamResponse(
  client: ChatClient,
  message: string,
  onChunk: (content: string) => void
): Promise<void> {
  for await (const chunk of client.stream(message)) {
    onChunk(chunk.content);
  }
}
// [end:streaming]

// [start:error-handling]
export function handleError(error: unknown): string {
  if (error instanceof ChatError) {
    return `Error: ${error.message}`;
  } else if (error instanceof Error) {
    return `Error: ${error.message}`;
  } else {
    return 'An unexpected error occurred';
  }
}
// [end:error-handling]

export function printBanner(): void {
  console.log(`
${colors.cyan}╭─────────────────────────────────────────────╮
│  ${colors.reset}${colors.bold}Agentic Assistant${colors.reset}${colors.cyan}                          │
│  ${colors.dim}Multi-step task execution with tools${colors.reset}${colors.cyan}       │
│  ${colors.dim}Type 'exit' to quit, 'help' for commands${colors.reset}${colors.cyan}   │
╰─────────────────────────────────────────────╯${colors.reset}
`);
}

export function printHelp(): void {
  console.log(`
${colors.yellow}Commands:${colors.reset}
  ${colors.bold}exit${colors.reset}     - Quit the assistant
  ${colors.bold}clear${colors.reset}    - Clear conversation history
  ${colors.bold}notes${colors.reset}    - View all saved notes
  ${colors.bold}tasks${colors.reset}    - View all tasks
  ${colors.bold}help${colors.reset}     - Show this help message

${colors.yellow}Available Tools:${colors.reset}
  ${colors.cyan}calculator${colors.reset}    - Perform mathematical calculations
  ${colors.cyan}web_search${colors.reset}    - Search the web for information
  ${colors.cyan}get_weather${colors.reset}   - Get current weather for a location
  ${colors.cyan}create_note${colors.reset}   - Save a note for later
  ${colors.cyan}list_notes${colors.reset}    - View all saved notes
  ${colors.cyan}create_task${colors.reset}   - Create a todo task
  ${colors.cyan}list_tasks${colors.reset}    - View all tasks
  ${colors.cyan}complete_task${colors.reset} - Mark a task as complete
`);
}

Registering Tools

typescript
/**
 * Agentic Assistant Library
 *
 * Exported functions for the Agentic Assistant recipe.
 * Snippet markers allow VitePress to extract code for documentation.
 */

import * as fs from 'fs';
import { ChatClient, ToolRegistry, FileStorage, ChatError } from '../../../src';

// [start:config]
export const STORAGE_DIR = './.agent-memory';
export const CONVERSATION_ID = 'agent-session';
export const NOTES_FILE = `${STORAGE_DIR}/notes.json`;
export const TASKS_FILE = `${STORAGE_DIR}/tasks.json`;
export const MAX_TOOL_ROUNDS = 10;
export const MODEL = 'gpt-4o-mini';
// [end:config]

// [start:colors]
export const colors = {
  reset: '\x1b[0m',
  dim: '\x1b[2m',
  bold: '\x1b[1m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  green: '\x1b[32m',
  cyan: '\x1b[36m',
  magenta: '\x1b[35m',
  blue: '\x1b[34m',
  gray: '\x1b[90m'
};
// [end:colors]

// [start:types]
export interface Note {
  id: string;
  title: string;
  content: string;
  createdAt: string;
}

export interface Task {
  id: string;
  title: string;
  completed: boolean;
  createdAt: string;
}

export interface SearchResult {
  title: string;
  snippet: string;
  url: string;
}
// [end:types]

export function generateId(): string {
  return Math.random().toString(36).substring(2, 10);
}

export function log(
  level: 'info' | 'tool' | 'result' | 'error' | 'success',
  message: string
): void {
  const prefix = {
    info: `${colors.cyan}ℹ${colors.reset}`,
    tool: `${colors.magenta}🔧${colors.reset}`,
    result: `${colors.blue}→${colors.reset}`,
    error: `${colors.red}✗${colors.reset}`,
    success: `${colors.green}✓${colors.reset}`
  };
  console.log(`${prefix[level]} ${message}`);
}

// [start:persistence]
export function ensureStorageDir(): void {
  if (!fs.existsSync(STORAGE_DIR)) {
    fs.mkdirSync(STORAGE_DIR, { recursive: true });
  }
}

export function loadNotes(): Note[] {
  try {
    if (fs.existsSync(NOTES_FILE)) {
      return JSON.parse(fs.readFileSync(NOTES_FILE, 'utf-8'));
    }
  } catch (error) {
    if (error instanceof Error && !error.message.includes('ENOENT')) {
      console.error('Failed to load notes:', error.message);
    }
  }
  return [];
}

export function saveNotes(notes: Note[]): void {
  ensureStorageDir();
  fs.writeFileSync(NOTES_FILE, JSON.stringify(notes, null, 2));
}

export function loadTasks(): Task[] {
  try {
    if (fs.existsSync(TASKS_FILE)) {
      return JSON.parse(fs.readFileSync(TASKS_FILE, 'utf-8'));
    }
  } catch (error) {
    if (error instanceof Error && !error.message.includes('ENOENT')) {
      console.error('Failed to load tasks:', error.message);
    }
  }
  return [];
}

export function saveTasks(tasks: Task[]): void {
  ensureStorageDir();
  fs.writeFileSync(TASKS_FILE, JSON.stringify(tasks, null, 2));
}
// [end:persistence]

// [start:create-tools]
export function createToolRegistry(): ToolRegistry {
  const registry = new ToolRegistry();

  // Calculator tool
  // NOTE: Uses eval() for demo simplicity. For production, use 'mathjs' or 'expr-eval'.
  registry.registerTool(
    'calculator',
    async (args: { expression: string }) => {
      log('tool', `calculator("${args.expression}")`);
      try {
        const sanitized = args.expression.replace(/[^0-9+\-*/().%\s]/g, '');
        const result = eval(sanitized);
        log('result', `= ${result}`);
        return { result, expression: args.expression };
      } catch {
        return { error: 'Invalid mathematical expression' };
      }
    },
    {
      description: 'Perform mathematical calculations. Supports +, -, *, /, %, and parentheses.',
      parameters: {
        type: 'object',
        properties: {
          expression: {
            type: 'string',
            description: 'Mathematical expression to evaluate (e.g., "15 * 847 / 100")'
          }
        },
        required: ['expression']
      }
    }
  );

  // Web search tool (simulated)
  registry.registerTool(
    'web_search',
    async (args: { query: string }) => {
      log('tool', `web_search("${args.query}")`);
      const results: SearchResult[] = [];
      const query = args.query.toLowerCase();

      if (query.includes('ai') || query.includes('artificial intelligence')) {
        results.push(
          {
            title: 'Latest AI Developments in 2026',
            snippet: 'Major breakthroughs in multimodal AI systems and reasoning capabilities...',
            url: 'https://example.com/ai-news'
          },
          {
            title: 'AI in Enterprise: Adoption Trends',
            snippet: 'Enterprise AI adoption reaches 78% as companies integrate automation...',
            url: 'https://example.com/enterprise-ai'
          }
        );
      } else {
        results.push({
          title: `Search results for: ${args.query}`,
          snippet: `Found relevant information about "${args.query}". Simulated result.`,
          url: 'https://example.com/search'
        });
      }

      log('result', `Found ${results.length} results`);
      return { results, query: args.query };
    },
    {
      description: 'Search the web for information on any topic.',
      parameters: {
        type: 'object',
        properties: {
          query: { type: 'string', description: 'Search query' }
        },
        required: ['query']
      }
    }
  );

  // Weather tool (simulated)
  registry.registerTool(
    'get_weather',
    async (args: { location: string }) => {
      log('tool', `get_weather("${args.location}")`);
      const weatherData: Record<
        string,
        { temperature: number; condition: string; humidity: number }
      > = {
        tokyo: { temperature: 22, condition: 'Partly Cloudy', humidity: 65 },
        'new york': { temperature: 18, condition: 'Sunny', humidity: 45 },
        london: { temperature: 12, condition: 'Rainy', humidity: 80 }
      };

      const location = args.location.toLowerCase();
      const weather = weatherData[location] || {
        temperature: 20,
        condition: 'Clear',
        humidity: 50
      };

      log('result', `${weather.temperature}°C, ${weather.condition}`);
      return {
        location: args.location,
        temperature: weather.temperature,
        temperatureUnit: 'Celsius',
        condition: weather.condition,
        humidity: weather.humidity
      };
    },
    {
      description: 'Get current weather information for a location.',
      parameters: {
        type: 'object',
        properties: {
          location: { type: 'string', description: 'City name (e.g., "Tokyo", "New York")' }
        },
        required: ['location']
      }
    }
  );

  // Note tools
  registry.registerTool(
    'create_note',
    async (args: { title: string; content: string }) => {
      log('tool', `create_note("${args.title}")`);
      const notes = loadNotes();
      const note: Note = {
        id: generateId(),
        title: args.title,
        content: args.content,
        createdAt: new Date().toISOString()
      };
      notes.push(note);
      saveNotes(notes);
      log('result', `Note saved with ID: ${note.id}`);
      return { success: true, note };
    },
    {
      description: 'Create and save a note for later reference.',
      parameters: {
        type: 'object',
        properties: {
          title: { type: 'string', description: 'Note title' },
          content: { type: 'string', description: 'Note content' }
        },
        required: ['title', 'content']
      }
    }
  );

  registry.registerTool(
    'list_notes',
    async () => {
      log('tool', 'list_notes()');
      const notes = loadNotes();
      log('result', `Found ${notes.length} notes`);
      return { notes, count: notes.length };
    },
    { description: 'List all saved notes.' }
  );

  // Task tools
  registry.registerTool(
    'create_task',
    async (args: { title: string }) => {
      log('tool', `create_task("${args.title}")`);
      const tasks = loadTasks();
      const task: Task = {
        id: generateId(),
        title: args.title,
        completed: false,
        createdAt: new Date().toISOString()
      };
      tasks.push(task);
      saveTasks(tasks);
      log('result', `Task created with ID: ${task.id}`);
      return { success: true, task };
    },
    {
      description: 'Create a new todo task.',
      parameters: {
        type: 'object',
        properties: {
          title: { type: 'string', description: 'Task description' }
        },
        required: ['title']
      }
    }
  );

  registry.registerTool(
    'list_tasks',
    async () => {
      log('tool', 'list_tasks()');
      const tasks = loadTasks();
      const pending = tasks.filter((t) => !t.completed);
      const completed = tasks.filter((t) => t.completed);
      log('result', `${pending.length} pending, ${completed.length} completed`);
      return { tasks, pending: pending.length, completed: completed.length };
    },
    { description: 'List all tasks with their status.' }
  );

  registry.registerTool(
    'complete_task',
    async (args: { taskId: string }) => {
      log('tool', `complete_task("${args.taskId}")`);
      const tasks = loadTasks();
      const task = tasks.find((t) => t.id === args.taskId);

      if (!task) {
        log('result', 'Task not found');
        return { success: false, error: 'Task not found' };
      }

      task.completed = true;
      saveTasks(tasks);
      log('result', `Task "${task.title}" marked complete`);
      return { success: true, task };
    },
    {
      description: 'Mark a task as completed.',
      parameters: {
        type: 'object',
        properties: {
          taskId: { type: 'string', description: 'ID of the task to complete' }
        },
        required: ['taskId']
      }
    }
  );

  return registry;
}
// [end:create-tools]

// [start:create-client]
export function createAgentClient(apiKey: string): ChatClient {
  const storage = new FileStorage(STORAGE_DIR);
  const tools = createToolRegistry();

  return new ChatClient({
    provider: 'openai',
    model: MODEL,
    apiKey,
    storage,
    conversationId: CONVERSATION_ID,
    tools,
    agenticMode: true,
    maxToolRounds: MAX_TOOL_ROUNDS,
    systemPrompt: `You are a helpful AI assistant with access to various tools.
You can perform calculations, search the web, check weather, and manage notes and tasks.
When a user asks you to do something, use the appropriate tools to help them.
For multi-step tasks, break them down and use tools as needed.
Always explain what you're doing and provide helpful responses.
Be concise but thorough.`
  });
}
// [end:create-client]

// [start:streaming]
export async function streamResponse(
  client: ChatClient,
  message: string,
  onChunk: (content: string) => void
): Promise<void> {
  for await (const chunk of client.stream(message)) {
    onChunk(chunk.content);
  }
}
// [end:streaming]

// [start:error-handling]
export function handleError(error: unknown): string {
  if (error instanceof ChatError) {
    return `Error: ${error.message}`;
  } else if (error instanceof Error) {
    return `Error: ${error.message}`;
  } else {
    return 'An unexpected error occurred';
  }
}
// [end:error-handling]

export function printBanner(): void {
  console.log(`
${colors.cyan}╭─────────────────────────────────────────────╮
│  ${colors.reset}${colors.bold}Agentic Assistant${colors.reset}${colors.cyan}                          │
│  ${colors.dim}Multi-step task execution with tools${colors.reset}${colors.cyan}       │
│  ${colors.dim}Type 'exit' to quit, 'help' for commands${colors.reset}${colors.cyan}   │
╰─────────────────────────────────────────────╯${colors.reset}
`);
}

export function printHelp(): void {
  console.log(`
${colors.yellow}Commands:${colors.reset}
  ${colors.bold}exit${colors.reset}     - Quit the assistant
  ${colors.bold}clear${colors.reset}    - Clear conversation history
  ${colors.bold}notes${colors.reset}    - View all saved notes
  ${colors.bold}tasks${colors.reset}    - View all tasks
  ${colors.bold}help${colors.reset}     - Show this help message

${colors.yellow}Available Tools:${colors.reset}
  ${colors.cyan}calculator${colors.reset}    - Perform mathematical calculations
  ${colors.cyan}web_search${colors.reset}    - Search the web for information
  ${colors.cyan}get_weather${colors.reset}   - Get current weather for a location
  ${colors.cyan}create_note${colors.reset}   - Save a note for later
  ${colors.cyan}list_notes${colors.reset}    - View all saved notes
  ${colors.cyan}create_task${colors.reset}   - Create a todo task
  ${colors.cyan}list_tasks${colors.reset}    - View all tasks
  ${colors.cyan}complete_task${colors.reset} - Mark a task as complete
`);
}

Commands

CommandDescription
exitQuit the assistant
clearClear conversation history
notesView all saved notes
tasksView all tasks
helpShow help message

Configuration

OptionDefaultDescription
agenticModetrueEnable autonomous tool execution
maxToolRounds10Maximum tool execution rounds
storageFileStoragePersistence for conversation history
conversationIdagent-sessionID for conversation persistence

Environment Variables

VariableRequiredDescription
OPENAI_API_KEYYesOpenAI API key (GPT-4 recommended)

Use Cases

Personal Assistant

Manage notes, tasks, and calculations in natural conversation.

Research Helper

Search for information and save relevant findings.

Task Automation

Chain multiple tools together for complex workflows.

Full Source

View on GitHub

Released under the MIT License.