Skip to main content
A task management assistant built with LlamaIndex that demonstrates the ReAct agent pattern with custom function tools. Uses Nebius AI for intelligent task analysis and time calculations.

Features

  • ReAct agent pattern with LlamaIndex
  • Custom function tools for task management
  • Duration analysis and productivity tracking
  • Task estimation capabilities
  • Easy-to-extend architecture

Prerequisites

Installation

1

Clone the repository

git clone https://github.com/Arindam200/awesome-ai-apps.git
cd starter_ai_agents/llamaindex_starter
2

Install dependencies

pip install -r requirements.txt
3

Configure environment

Create a .env file and add your Nebius API key:
NEBIUS_API_KEY=your_api_key_here

Implementation

Custom Function Tools

Create function tools for task management:
main.py
from llama_index.core.tools import FunctionTool
from datetime import datetime

def calculate_task_duration(start_time: str, end_time: str) -> str:
    """Calculate the duration between two times in HH:MM format"""
    try:
        start = datetime.strptime(start_time, "%H:%M")
        end = datetime.strptime(end_time, "%H:%M")
        duration = end - start
        hours = duration.seconds // 3600
        minutes = (duration.seconds % 3600) // 60
        return f"{hours} hours and {minutes} minutes"
    except ValueError:
        return "Invalid time format. Please use HH:MM format."

def estimate_task_completion(tasks: int, time_per_task: int) -> str:
    """Estimate total time needed to complete a number of tasks"""
    total_minutes = tasks * time_per_task
    hours = total_minutes // 60
    minutes = total_minutes % 60
    return f"{hours} hours and {minutes} minutes"

def calculate_productivity(tasks_completed: int, total_time: int) -> str:
    """Calculate tasks completed per hour
    Args:
        tasks_completed: Number of tasks completed
        total_time: Total time in minutes
    Returns:
        String showing tasks per hour
    """
    if total_time <= 0:
        return "Cannot calculate productivity with zero or negative time"
    if tasks_completed < 0:
        return "Cannot calculate productivity with negative tasks"
    
    # Convert total_time to hours for the calculation
    hours = total_time / 60
    tasks_per_hour = tasks_completed / hours
    return f"{tasks_per_hour:.2f} tasks per hour"

# Create tools
duration_tool = FunctionTool.from_defaults(fn=calculate_task_duration)
estimate_tool = FunctionTool.from_defaults(fn=estimate_task_completion)
productivity_tool = FunctionTool.from_defaults(fn=calculate_productivity)

ReAct Agent Setup

main.py
from llama_index.core.agent import ReActAgent
from llama_index.llms.nebius import NebiusLLM
from dotenv import load_dotenv
import os

load_dotenv()

# Create the agent
agent = ReActAgent.from_tools(
    [duration_tool, estimate_tool, productivity_tool],
    llm=NebiusLLM(
        model="Qwen/Qwen3-235B-A22B",
        api_key=os.getenv("NEBIUS_API_KEY")
    ),
    verbose=True,
)

Usage Example

main.py
print("\nTask Management Assistant")
print("------------------------")

response = agent.chat(
    "If I worked from 09:00 to 17:00 and completed 8 tasks, what was my productivity rate?"
)
print("\nResponse:", response)

Usage

Run the agent:
python main.py

Example Queries

Try these queries with your task management assistant:
  • “If I worked from 09:00 to 17:00 and completed 8 tasks, what was my productivity rate?”
  • “How long will it take to complete 3 tasks that each take 45 minutes?”
  • “Calculate the duration between 09:00 and 17:00”
  • “I need to complete 10 tasks, each taking 30 minutes. How long will it take?”

Technical Details

ReAct Pattern

The agent uses LlamaIndex’s ReAct (Reasoning and Acting) pattern:
  1. Reason: Analyze the user’s query
  2. Act: Select and execute appropriate tools
  3. Observe: Process tool results
  4. Repeat: Continue until task is complete

LlamaIndex

Agent framework with ReAct pattern

Nebius AI

Qwen/Qwen3-235B-A22B model

Function Tools

Custom task management functions

Python datetime

Time calculations and formatting

Extending the Agent

Add New Tools

Create additional function tools:
def prioritize_tasks(tasks: list, deadline: str) -> str:
    """Prioritize tasks based on deadline and complexity"""
    # Your implementation
    return prioritized_list

priority_tool = FunctionTool.from_defaults(fn=prioritize_tasks)

agent = ReActAgent.from_tools(
    [duration_tool, estimate_tool, productivity_tool, priority_tool],
    llm=NebiusLLM(model="Qwen/Qwen3-235B-A22B", api_key=os.getenv("NEBIUS_API_KEY")),
    verbose=True,
)

Customize LLM Settings

llm = NebiusLLM(
    model="Qwen/Qwen3-235B-A22B",
    api_key=os.getenv("NEBIUS_API_KEY"),
    temperature=0.7,
    max_tokens=1000,
)

Add Structured Output

from pydantic import BaseModel

class TaskAnalysis(BaseModel):
    total_duration: str
    productivity_rate: float
    recommendations: list[str]

# Use structured output in your agent

Architecture

Best Practices

  • Keep tools focused on single responsibilities
  • Provide clear docstrings for tool functions
  • Include input validation and error handling
  • Return structured, parseable results
  • Use verbose mode during development
  • Choose appropriate models for your use case
  • Set reasonable temperature and token limits
  • Test with various query types
  • Validate input formats in tool functions
  • Provide helpful error messages
  • Handle edge cases (zero values, negative numbers)
  • Log errors for debugging

Next Steps

RAG with LlamaIndex

Build retrieval-augmented generation apps

Multi-Agent Systems

Create complex agent workflows

Build docs developers (and LLMs) love