Metadata-Version: 2.1
Name: ai_function_helper
Version: 0.2.6
Summary: A helper for creating AI-powered functions using OpenAI's API
Home-page: https://github.com/Clad3815/ai-function-helper-python
Author: Clad3815
Author-email: clad3815@gmail.com
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Requires-Python: >=3.7
Description-Content-Type: text/markdown
Requires-Dist: openai
Requires-Dist: pydantic
Requires-Dist: jsonschema
Requires-Dist: colorama
Requires-Dist: json_repair

# AI Function Helper

[![PyPI version](https://badge.fury.io/py/ai-function-helper.svg)](https://badge.fury.io/py/ai-function-helper)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Versions](https://img.shields.io/pypi/pyversions/ai-function-helper.svg)](https://pypi.org/project/ai-function-helper/)

**Streamline your AI-powered Python functions with ease!**

[Key Features](#key-features) • [Installation](#installation) • [Quick Start](#quick-start) • [Documentation](#documentation) • [Contributing](#contributing)

---

## 📚 Table of Contents

- [AI Function Helper](#ai-function-helper)
  - [📚 Table of Contents](#-table-of-contents)
  - [🌟 Key Features](#-key-features)
  - [🚀 Installation](#-installation)
  - [🏁 Quick Start](#-quick-start)
  - [🧠 Core Concepts](#-core-concepts)
  - [🔧 Advanced Usage](#-advanced-usage)
    - [Customizing AI Function Behavior](#customizing-ai-function-behavior)
    - [Function Formats](#function-formats)
    - [Synchronous vs Asynchronous Usage](#synchronous-vs-asynchronous-usage)
    - [Batch Processing](#batch-processing)
    - [Complex Data Structures](#complex-data-structures)
  - [🐞 Error Handling and Debugging](#-error-handling-and-debugging)
  - [📘 Examples](#-examples)
    - [Simple Text Generation](#simple-text-generation)
    - [Interactive Quiz Bot](#interactive-quiz-bot)
    - [Data Analysis Assistant](#data-analysis-assistant)
    - [Detailed Content Generation with Specific Instructions](#detailed-content-generation-with-specific-instructions)
    - [Complex Example: AI-Powered Travel Planner](#complex-example-ai-powered-travel-planner)
  - [🤝 Contributing](#-contributing)
  - [📄 License](#-license)

## 🌟 Key Features

- **Seamless OpenAI Integration**: Easy setup with various AI models (GPT-3.5, GPT-4, etc.)
- **Flexible Function Decorators**: Customize AI-powered tasks with ease
- **Synchronous and Asynchronous Support**: Use AI functions in both sync and async contexts
- **Batch Processing**: Efficiently handle multiple inputs in a single API call
- **Robust Error Handling**: Automatic retries and comprehensive error management
- **Type Safety**: Pydantic models for JSON parsing and validation
- **Debugging Capabilities**: Detailed logging of API interactions
- **Function Calling**: Support for OpenAI's function calling feature
- **Multiple Return Formats**: Flexible output handling (JSON, string, raw response)
- **Image Input Support**: Process and analyze images within your AI functions

## 🚀 Installation

Install AI Function Helper using pip:

```bash
pip install ai-function-helper
```

## 🏁 Quick Start

Get up and running with AI Function Helper in just a few lines of code:

```python
from ai_function_helper import AIFunctionHelper

# Initialize AI Function Helper
ai_helper = AIFunctionHelper("your-api-key")

# Create an AI-powered function
@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=200)
def generate_short_story(theme: str) -> str:
    """
    Generate a short story based on a given theme.
    """

# Use the function
story = generate_short_story(theme="A day in the life of a time traveler")
print(story)
```

## 🧠 Core Concepts

AI Function Helper is built around several key concepts:

1. **AIFunctionHelper Class**: The main entry point for creating AI-powered functions.
2. **AI Function Decorator**: Transforms regular Python functions into AI-powered ones, supporting both sync and async usage.
3. **Pydantic Models**: Ensures type safety and easy validation of AI-generated responses.
4. **Error Handling**: Built-in mechanisms for handling API errors and retrying failed calls.
5. **Debugging**: Comprehensive logging options for troubleshooting and optimization.

## 🔧 Advanced Usage

### Customizing AI Function Behavior

Fine-tune your AI functions with various parameters:

```python
@ai_helper.ai_function(
    model="gpt-4o",
    max_tokens=500,
    temperature=0.7,
    top_p=0.9,
    frequency_penalty=0.1,
    presence_penalty=0.1,
    timeout=60,
    max_retries=3,
    show_debug=True,
    debug_level=2
)
def advanced_function(input_data: str) -> ComplexResponseModel:
    """
    An advanced AI-powered function with custom settings.
    """
```

### Function Formats

AI Function Helper supports multiple function formats:

1. **Using `ai_result` Parameter**:
   ```python
   def func(ai_result: ResponseModel, input: str) -> ResponseModel:
   ```

2. **Direct Pydantic Model Return**:
   ```python
   def func(input: str) -> ResponseModel:
   ```

3. **String Output**:
   ```python
   def func(input: str) -> str:
   ```

4. **Unspecified Return Type** (The output will be a `str` by default)
   ```python
   def func(input: str):
   ```

### Synchronous vs Asynchronous Usage

AI Function Helper supports both synchronous and asynchronous usage:

```python
# Synchronous
@ai_helper.ai_function(model="gpt-3.5-turbo")
def sync_function(input: str) -> str:
    """A synchronous AI-powered function."""

# Asynchronous
@ai_helper.ai_function(model="gpt-3.5-turbo")
async def async_function(input: str) -> str:
    """An asynchronous AI-powered function."""
```

### Batch Processing

Efficiently process multiple inputs in a single API call:

```python
@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=1500)
async def batch_process(inputs: List[str]) -> List[str]:
    """Process multiple inputs in a single API call."""
```

### Complex Data Structures

Handle complex input and output data structures using Pydantic models:

```python
from pydantic import BaseModel, Field
from typing import List

class ComplexInput(BaseModel):
    text: str
    category: str
    tags: List[str]

class ComplexOutput(BaseModel):
    summary: str
    sentiment: float
    keywords: List[str]

@ai_helper.ai_function(model="gpt-4o")
async def process_complex_data(data: ComplexInput) -> ComplexOutput:
    """Process complex structured data."""
```

## 🐞 Error Handling and Debugging

Enable detailed logging and set retry attempts:

```python
@ai_helper.ai_function(max_retries=3, show_debug=True, debug_level=2)
def debug_example(input_data: str) -> ResponseModel:
    """
    This function will display detailed debug information and retry up to 3 times on failure.
    """
```

## 📘 Examples

In the following examples, the text between the triple quotes (`"""`) in each function serves as the prompt for the AI. This docstring provides context and instructions to guide the AI's response.

### Simple Text Generation

Create a simple haiku generator:

```python
@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=100)
def generate_haiku(theme: str) -> str:
    """
    Generate a haiku based on the given theme.
    The haiku should follow the 5-7-5 syllable structure and capture the essence of the theme.
    """

haiku = generate_haiku(theme="autumn leaves")
print(haiku)

# Possible output:
# Crisp autumn leaves fall
# Dancing on the chilly breeze
# Nature's gold blanket
```

### Interactive Quiz Bot

Create an interactive quiz bot with batch processing:

```python
from pydantic import BaseModel, Field
from typing import List

class QuizQuestion(BaseModel):
    question: str
    correct_answer: str

class QuizResult(BaseModel):
    score: int
    total_questions: int
    evaluations: List[dict]

@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=1500)
async def generate_quiz(topic: str, num_questions: int) -> List[QuizQuestion]:
    """
    Generate a quiz on the given topic with the specified number of questions.
    Each question should be challenging but appropriate for a general audience.
    Provide a clear and concise correct answer for each question.
    """

@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=1500)
async def evaluate_quiz(questions: List[QuizQuestion], user_answers: List[str]) -> QuizResult:
    """
    Evaluate the user's answers for the quiz.
    Compare each user answer to the correct answer, accounting for minor variations in wording.
    Provide a brief explanation for each evaluation, highlighting why the answer is correct or incorrect.
    Calculate the final score based on the number of correct answers.
    """

# Usage
async def run_quiz():
    questions = await generate_quiz("Python programming", 3)
    user_answers = []
    for q in questions:
        print(q.question)
        user_answers.append(input("Your answer: "))
    result = await evaluate_quiz(questions, user_answers)
    print(f"Score: {result.score}/{result.total_questions}")
    for eval in result.evaluations:
        print(f"Q: {eval['question']}")
        print(f"Your answer: {eval['user_answer']}")
        print(f"Correct: {eval['is_correct']}")
        print(f"Explanation: {eval['explanation']}")

asyncio.run(run_quiz())

# Possible output:
# Q: What is a Python decorator?
# Your answer: A function that modifies another function
# Correct: True
# Explanation: Your answer captures the essence of a Python decorator. More precisely, a decorator is a callable that takes a function as an input and returns a modified version of that function.

# Q: Explain the difference between a list and a tuple in Python.
# Your answer: Lists are mutable, tuples are immutable
# Correct: True
# Explanation: Excellent! Your answer succinctly captures the key difference. Lists can be modified after creation, while tuples cannot be changed once they are created.

# Q: What is the purpose of the 'self' parameter in Python class methods?
# Your answer: It refers to the instance of the class
# Correct: True
# Explanation: Great answer! The 'self' parameter is indeed used to refer to the instance of the class, allowing access to the attributes and methods of that instance within the class definition.

# Score: 3/3
```

### Data Analysis Assistant

Create a data analysis assistant that can process complex data structures:

```python
from pydantic import BaseModel, Field
from typing import List, Dict

class DataPoint(BaseModel):
    timestamp: str
    value: float
    category: str

class AnalysisResult(BaseModel):
    summary: str
    trend: str
    anomalies: List[Dict[str, any]]

@ai_helper.ai_function(model="gpt-4o", max_tokens=1000)
async def analyze_data(data: List[DataPoint]) -> AnalysisResult:
    """
    Analyze the given series of data points and provide insights.
    Your analysis should include:
    1. A brief summary of the overall data trends.
    2. Identification of the primary trend (increasing, decreasing, or stable).
    3. Detection of any anomalies or outliers in the data.
    Use statistical reasoning to support your analysis.
    """

# Usage
async def main():
    data = [
        DataPoint(timestamp="2023-01-01", value=100, category="A"),
        DataPoint(timestamp="2023-01-02", value=110, category="B"),
        DataPoint(timestamp="2023-01-03", value=105, category="A"),
        DataPoint(timestamp="2023-01-04", value=200, category="B"),
        DataPoint(timestamp="2023-01-05", value=115, category="A"),
    ]
    result = await analyze_data(data)
    print(f"Summary: {result.summary}")
    print(f"Trend: {result.trend}")
    print("Anomalies:")
    for anomaly in result.anomalies:
        print(f"  - {anomaly}")

asyncio.run(main())

# Possible output:
# Summary: The data shows fluctuating values across 5 data points, alternating between categories A and B. There's a general upward trend with one significant spike.
# Trend: Increasing
# Anomalies:
#   - {'timestamp': '2023-01-04', 'value': 200, 'category': 'B', 'reason': 'Unusually high value compared to the overall trend'}
```

### Detailed Content Generation with Specific Instructions

This example demonstrates how to use a detailed prompt to guide the AI in generating specific content:

```python
from pydantic import BaseModel, Field
from typing import List

class BlogPost(BaseModel):
    title: str
    introduction: str
    main_points: List[str]
    conclusion: str

@ai_helper.ai_function(model="gpt-4o", max_tokens=4000, temperature=0.7)
async def generate_blog_post(topic: str, target_audience: str) -> BlogPost:
    """
    Generate a structured blog post on the given topic for the specified target audience.
    
    Follow these guidelines:
    1. Title: Create an engaging, SEO-friendly title that accurately reflects the content.
    2. Introduction: Write a compelling introduction that hooks the reader and outlines the post's purpose.
    3. Main Points: Develop 3-5 key points that explore different aspects of the topic. Each point should be concise yet informative.
    4. Conclusion: Summarize the main ideas and provide a call-to-action or thought-provoking final statement.
    
    Style Guidelines:
    - Tone: Maintain a conversational yet professional tone throughout the post.
    - Language: Use clear, jargon-free language appropriate for the target audience.
    - Engagement: Incorporate rhetorical questions or relatable examples to keep the reader engaged.
    - Length: Aim for a total length of about 600-800 words.
    
    Remember to tailor the content specifically to the target audience's interests and level of expertise.
    """

# Usage
async def main():
    blog_post = await generate_blog_post(
        topic="The Impact of Artificial Intelligence on Modern Healthcare",
        target_audience="Healthcare professionals with basic tech knowledge"
    )
    print(f"Title: {blog_post.title}\n")
    print(f"Introduction:\n{blog_post.introduction}\n")
    print("Main Points:")
    for i, point in enumerate(blog_post.main_points, 1):
        print(f"{i}. {point}")
    print(f"\nConclusion:\n{blog_post.conclusion}")

asyncio.run(main())

# Possible output:
# Title: Revolutionizing Patient Care: How AI is Transforming Modern Healthcare
#
# Introduction:
# In recent years, the healthcare industry has witnessed a seismic shift with the integration of Artificial Intelligence (AI). As healthcare professionals, we find ourselves at the crossroads of tradition and innovation. But what does this AI revolution mean for our daily practice and, more importantly, for patient outcomes? This blog post delves into the transformative impact of AI on modern healthcare, exploring both its promising advantages and the challenges we need to navigate.
#
# Main Points:
# 1. Enhanced Diagnostic Accuracy: AI algorithms are now capable of analyzing medical images with remarkable precision, often surpassing human capabilities in detecting subtle abnormalities in X-rays, MRIs, and CT scans.
# 2. Personalized Treatment Plans: By processing vast amounts of patient data, AI can help tailor treatment plans to individual patients, considering factors like genetic makeup, lifestyle, and previous medical history.
# 3. Streamlined Administrative Tasks: AI-powered systems are reducing the bureaucratic burden on healthcare professionals by automating tasks like scheduling, billing, and maintaining electronic health records, allowing more time for patient care.
# 4. Real-time Patient Monitoring: AI-enabled devices can continuously monitor patients' vital signs and alert healthcare providers to potential issues before they become critical, especially beneficial in intensive care settings.
# 5. Drug Discovery and Development: AI is accelerating the process of drug discovery and development by predicting how different compounds will interact with target proteins, potentially bringing life-saving medications to market faster.
#
# Conclusion:
# The integration of AI in healthcare is not just a technological upgrade; it's a paradigm shift in how we approach patient care. While AI offers unprecedented opportunities to improve diagnostic accuracy, treatment efficacy, and operational efficiency, it's crucial to remember that it's a tool to augment, not replace, human expertise. As healthcare professionals, our challenge lies in embracing these innovations while ensuring they align with ethical standards and prioritize patient well-being. The future of healthcare is here, and it's a future where human compassion and machine intelligence work hand in hand to provide the best possible care for our patients. How will you incorporate AI into your practice to enhance patient outcomes?
```

In each of these examples, the docstring (text between `"""`) serves as a prompt that guides the AI in generating the desired output. By providing clear instructions and context in the docstring, you can control the AI's response and ensure it aligns with your specific requirements.

### Complex Example: AI-Powered Travel Planner

This example demonstrates how to use AI Function Helper to create a comprehensive travel planning application. It showcases the library's ability to handle complex, multi-step processes and generate large amounts of structured content.

```python
from typing import List, Dict
from pydantic import BaseModel, Field
from ai_function_helper import AIFunctionHelper

# Initialize AI Function Helper
ai_helper = AIFunctionHelper("your-api-key")

# Define data models
class Destination(BaseModel):
    city: str = Field(..., description="Name of the city")
    country: str = Field(..., description="Name of the country")
    days: int = Field(..., description="Number of days to spend in this destination")

class Activity(BaseModel):
    name: str = Field(..., description="Name of the activity")
    description: str = Field(..., description="Brief description of the activity")
    duration: float = Field(..., description="Estimated duration of the activity in hours")

class DailyPlan(BaseModel):
    day: int = Field(..., description="Day number of the trip")
    activities: List[Activity] = Field(..., description="List of activities for the day")

class CulturalInfo(BaseModel):
    language: str = Field(..., description="Main language spoken")
    customs: List[str] = Field(..., description="Important customs to be aware of")
    cuisine: List[str] = Field(..., description="Notable local dishes")

class SafetyTips(BaseModel):
    health: List[str] = Field(..., description="Health-related tips")
    security: List[str] = Field(..., description="Security-related tips")

class ExpenseCategory(BaseModel):
    category: str = Field(..., description="Category of expense")
    amount: float = Field(..., description="Amount in USD")
    details: List[str] = Field(..., description="Detailed breakdown or examples of expenses")

class DestinationBudget(BaseModel):
    destination: str = Field(..., description="Name of the destination (City, Country)")
    daily_estimate: float = Field(..., description="Estimated daily expenses in USD")
    expenses: List[ExpenseCategory] = Field(..., description="Breakdown of expenses by category")
    local_currency: str = Field(..., description="Local currency code")
    exchange_rate: float = Field(..., description="Exchange rate to USD")

class DetailedBudget(BaseModel):
    total_estimate: float = Field(..., description="Estimated total trip expenses in USD")
    average_daily_estimate: float = Field(..., description="Average estimated daily expenses in USD")
    destination_budgets: List[DestinationBudget] = Field(..., description="Detailed budget for each destination")
    budget_tips: List[str] = Field(..., description="Money-saving tips and budget considerations")
    unexpected_expenses: List[str] = Field(..., description="Potential unexpected expenses to consider")

class TravelPlan(BaseModel):
    destinations: List[Destination] = Field(..., description="List of destinations in the trip")
    daily_plans: List[DailyPlan] = Field(..., description="Detailed plan for each day of the trip")
    cultural_info: Dict[str, CulturalInfo] = Field(..., description="Cultural information for each country")
    safety_tips: Dict[str, SafetyTips] = Field(..., description="Safety tips for each country")
    budget: DetailedBudget = Field(..., description="Detailed budget estimation for the entire trip")

# AI-powered functions
@ai_helper.ai_function(model="gpt-4o", max_tokens=1000)
async def suggest_destinations(preferences: str, duration: int) -> List[Destination]:
    """
    Suggest a list of destinations based on the user's preferences and trip duration.
    Consider factors such as the user's interests, preferred activities, and the time available for the trip.
    Ensure that the suggested destinations are diverse and can be reasonably visited within the given duration.
    """

@ai_helper.ai_function(model="gpt-4o", max_tokens=1500)
async def plan_activities(destination: Destination, preferences: str) -> List[DailyPlan]:
    """
    Create a detailed plan of activities for each day in a specific destination.
    Take into account the user's preferences, the destination's attractions, and local events or experiences.
    Ensure a balance between different types of activities (e.g., cultural, outdoor, culinary) based on the user's interests.
    """

@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=500)
async def get_cultural_info(country: str) -> CulturalInfo:
    """
    Retrieve relevant cultural information about a specific country.
    Include details about the main language(s) spoken, important customs or etiquette,
    and notable aspects of the local cuisine that travelers should be aware of.
    """

@ai_helper.ai_function(model="gpt-3.5-turbo", max_tokens=500)
async def get_safety_tips(country: str) -> SafetyTips:
    """
    Provide important safety tips and health information for travelers visiting a specific country.
    Include advice on health precautions, recommended vaccinations, common safety concerns,
    and any current travel advisories or warnings for the country.
    """

@ai_helper.ai_function(model="gpt-4o", max_tokens=2000)
async def estimate_detailed_budget(destinations: List[Destination], preferences: str) -> DetailedBudget:
    """
    Estimate a detailed budget for the entire trip based on the selected destinations and user preferences.
    
    For each destination, provide:
    1. Daily estimate in USD
    2. Breakdown of expenses by category (accommodation, food, transportation, activities, miscellaneous)
    3. Local currency and exchange rate
    
    Also include:
    - Total trip estimate
    - Average daily estimate across all destinations
    - Budget-saving tips specific to the destinations and travel style
    - Potential unexpected expenses to consider
    
    Consider factors such as:
    - Accommodation costs based on preferences (budget, mid-range, luxury)
    - Food expenses (mix of local cuisine, street food, and restaurants)
    - Local transportation costs
    - Entrance fees for attractions and activities
    - Shopping and souvenirs
    - Any specific expenses related to the user's preferences or destination-specific activities
    
    Ensure the budget is realistic and aligns with the local cost of living in each destination.
    """

# Main function to create a travel plan
async def create_travel_plan(preferences: str, duration: int) -> TravelPlan:
    destinations = await suggest_destinations(preferences, duration)
    
    daily_plans = []
    cultural_info = {}
    safety_tips = {}
    for dest in destinations:
        daily_plans.extend(await plan_activities(dest, preferences))
        cultural_info[dest.country] = await get_cultural_info(dest.country)
        safety_tips[dest.country] = await get_safety_tips(dest.country)
    
    budget = await estimate_detailed_budget(destinations, preferences)
    
    return TravelPlan(
        destinations=destinations,
        daily_plans=daily_plans,
        cultural_info=cultural_info,
        safety_tips=safety_tips,
        budget=budget
    )

# Usage
import asyncio

async def main():
    travel_plan = await create_travel_plan(
        preferences="I love history, local cuisine, and outdoor activities. I prefer off-the-beaten-path destinations and mid-range accommodations.",
        duration=10
    )
    print(travel_plan.model_dump_json(indent=2))

asyncio.run(main())
```

This example demonstrates several key features of AI Function Helper:

1. **Complex Data Structures**: Using Pydantic models to define structured data for destinations, activities, cultural information, and a detailed budget.
2. **Multiple AI Function Calls**: The travel plan is created through a series of AI function calls, each handling a specific aspect of the planning process.
3. **Chaining AI Outputs**: The output of one AI function (e.g., `suggest_destinations`) is used as input for subsequent functions (e.g., `plan_activities`).
4. **Flexible Model Selection**: Different models (GPT-4, GPT-3.5-turbo) are used for various tasks based on their complexity.
5. **Large Content Generation**: The combined output of all AI functions results in a comprehensive travel plan with detailed information.
6. **Detailed Budget Estimation**: The `estimate_detailed_budget` function showcases the ability to generate complex, structured financial data.

Example Output (truncated for brevity):

```json
{
  "destinations": [
    {
      "city": "Matera",
      "country": "Italy",
      "days": 3
    },
    {
      "city": "Mostar",
      "country": "Bosnia and Herzegovina",
      "days": 2
    },
    {
      "city": "Ohrid",
      "country": "North Macedonia",
      "days": 3
    },
    {
      "city": "Plovdiv",
      "country": "Bulgaria",
      "days": 2
    }
  ],
  "daily_plans": [
    {
      "day": 1,
      "activities": [
        {
          "name": "Sassi di Matera Tour",
          "description": "Explore the ancient cave dwellings and rock churches of Sassi di Matera.",
          "duration": 3.5
        },
        {
          "name": "Traditional Lucanian Lunch",
          "description": "Enjoy local specialties like orecchiette pasta and lamb dishes at a family-run trattoria.",
          "duration": 1.5
        },
        {
          "name": "Palombaro Lungo Underground Cistern Visit",
          "description": "Discover Matera's underground water system and its historical significance.",
          "duration": 1.0
        },
        {
          "name": "Sunset at Belvedere di Murgia Timone",
          "description": "Hike to a panoramic viewpoint for a breathtaking sunset over Matera's landscape.",
          "duration": 2.0
        }
      ]
    }
  ],
  "cultural_info": {
    "Italy": {
      "language": "Italian",
      "customs": [
        "Greet with 'Buongiorno' (Good day) or 'Buonasera' (Good evening)",
        "Expect shops to close for a few hours in the afternoon for 'riposo'",
        "Tipping is not mandatory but appreciated for good service"
      ],
      "cuisine": [
        "Pasta dishes like orecchiette and cavatelli",
        "Crusco peppers",
        "Podolico cheese",
        "Lucanian sausage"
      ]
    }
  },
  "safety_tips": {
    "Italy": {
      "health": [
        "Tap water is safe to drink in most areas",
        "Healthcare is of high quality, but travel insurance is recommended",
        "Pharmacies are widely available for minor health issues"
      ],
      "security": [
        "Be aware of pickpocketing in tourist areas",
        "Keep valuables secure and be cautious in crowded places",
        "Emergency number for police, ambulance, and fire is 112"
      ]
    }
  },
  "budget": {
    "total_estimate": 3450.0,
    "average_daily_estimate": 115.0,
    "destination_budgets": [
      {
        "destination": "Matera, Italy",
        "daily_estimate": 130.0,
        "expenses": [
          {
            "category": "Accommodation",
            "amount": 60.0,
            "details": ["Mid-range hotel in Sassi area", "Unique cave hotel experience"]
          },
          {
            "category": "Food",
            "amount": 35.0,
            "details": ["Breakfast at hotel", "Light lunch at local trattoria", "Dinner with local specialties"]
          },
          {
            "category": "Transportation",
            "amount": 10.0,
            "details": ["Walking in old town", "Occasional bus or taxi"]
          },
          {
            "category": "Activities",
            "amount": 20.0,
            "details": ["Sassi di Matera guided tour", "Entrance to rock churches", "Rupestrian museum"]
          },
          {
            "category": "Miscellaneous",
            "amount": 5.0,
            "details": ["Souvenirs", "Gelato", "Unexpected expenses"]
          }
        ],
        "local_currency": "EUR",
        "exchange_rate": 1.18
      }
    ],
    "budget_tips": [
      "Stay in guesthouses or B&Bs in Matera for a more authentic and often cheaper experience",
      "Use local transportation in Mostar instead of taxis to save money",
      "Take advantage of free walking tours available in Ohrid and Plovdiv",
      "Buy a multi-day transport pass in larger cities to save on transportation costs",
      "Eat at local markets and try street food for affordable and authentic culinary experiences"
    ],
    "unexpected_expenses": [
      "Visa fees for non-EU citizens entering Bosnia and Herzegovina",
      "Potential ferry or boat tour costs in Ohrid",
      "Emergency medical expenses (travel insurance recommended)",
      "Currency exchange fees and ATM withdrawal charges",
      "Overweight luggage fees when traveling between destinations"
    ]
  }
}
```

This complex example showcases how AI Function Helper can be used to create sophisticated applications that generate large amounts of structured content through multiple AI function calls. The travel planner demonstrates the library's ability to handle complex data structures, chain multiple AI outputs, and produce detailed, coherent results that would be challenging to generate in a single AI call.

## 🤝 Contributing

We welcome contributions to AI Function Helper! Here's how you can help:

1. Fork the repository
2. Create a new branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Commit your changes (`git commit -m 'Add some amazing feature'`)
5. Push to the branch (`git push origin feature/amazing-feature`)
6. Open a Pull Request

Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
