File size: 5,546 Bytes
1d32142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
"""Web search tool for searching charity organization information using OpenAI."""

import os
from pprint import pprint
from typing import Dict, Any, Optional
from openai import OpenAI
from langchain_core.tools import tool


# Simple in-memory cache to avoid duplicate searches within a session
_search_cache: Dict[str, str] = {}


def get_openai_client():
    """Get OpenAI client instance."""
    return OpenAI()


def clear_search_cache():
    """Clear the search cache. Call this at the start of a new conversation."""
    global _search_cache
    _search_cache.clear()
    print("๐Ÿ—‘๏ธ Search cache cleared")


def openai_web_search(query: str, use_cache: bool = True) -> str:
    """Perform web search using OpenAI's web_search tool.

    Args:
        query: The search query
        use_cache: Whether to use cached results if available

    Returns:
        Search results as text
    """
    # Check cache first
    cache_key = query.lower().strip()
    if use_cache and cache_key in _search_cache:
        print("\n" + "=" * 50)
        print("๐Ÿ“ฆ RETURNING CACHED SEARCH RESULT")
        print("=" * 50)
        pprint({"query": query, "cached": True})
        print("=" * 50 + "\n")
        return _search_cache[cache_key]

    print("\n" + "=" * 50)
    print("๐Ÿ” OPENAI WEB SEARCH CALLED")
    print("=" * 50)
    pprint({"query": query})
    print("=" * 50 + "\n")

    client = get_openai_client()

    try:
        response = client.responses.create(
            model="gpt-5",
            tools=[{"type": "web_search"}],
            input=query
        )
        print("\n" + "-" * 50)
        print("โœ… SEARCH RESULTS RECEIVED")
        print("-" * 50)
        pprint({"output_length": len(response.output_text)})
        print("-" * 50 + "\n")

        # Cache the result
        _search_cache[cache_key] = response.output_text

        return response.output_text
    except Exception as e:
        print(f"\nโŒ SEARCH FAILED: {str(e)}\n")
        return f"Search failed: {str(e)}"


@tool
def search_charity_comprehensive(charity_name: str) -> str:
    """Search the web for comprehensive information about a charity organization.

    This tool performs a SINGLE optimized search to find ALL relevant information
    about a charity including:
    - Mission and programs
    - Charity ratings (Charity Navigator, GuideStar, BBB)
    - Financial transparency and accountability
    - Recent news and impact reports
    - Contact information and ways to donate

    Use this as your PRIMARY tool - it combines general info and ratings in one search.

    Args:
        charity_name: The name of the charity organization to research.
                     Example: "Red Cross" or "Doctors Without Borders"

    Returns:
        Comprehensive search results about the charity including ratings and programs.
    """
    print("\n๐Ÿ“‹ TOOL CALLED: search_charity_comprehensive")
    pprint({"charity_name": charity_name})

    # Build a comprehensive query that covers all aspects in ONE search
    comprehensive_query = (
        f"{charity_name} charity nonprofit organization "
        f"mission programs impact "
        f"Charity Navigator rating GuideStar "
        f"financial transparency accountability review"
    )

    try:
        results = openai_web_search(comprehensive_query)
        return results
    except Exception as e:
        return f"Search failed: {str(e)}. Please try again with a different query."


@tool
def search_charity_info(query: str) -> str:
    """Search the web for information about a charity organization.

    NOTE: Prefer using search_charity_comprehensive for most queries as it
    combines general info and ratings in a single search.

    Use this tool only when you need to search for something very specific
    that isn't covered by comprehensive search.

    Args:
        query: The search query about the charity organization.
               Example: "Red Cross disaster relief programs 2024"

    Returns:
        Search results containing relevant information about the charity.
    """
    print("\n๐Ÿ“‹ TOOL CALLED: search_charity_info")
    pprint({"input_query": query})

    # Enhance query for charity-specific searches
    enhanced_query = f"{query} charity nonprofit organization"

    try:
        results = openai_web_search(enhanced_query)
        return results
    except Exception as e:
        return f"Search failed: {str(e)}. Please try again with a different query."


@tool
def search_charity_ratings(charity_name: str) -> str:
    """Search for charity ratings and reviews from watchdog organizations.

    NOTE: Prefer using search_charity_comprehensive as it already includes
    rating information. Use this only if you specifically need MORE detailed
    rating information after the comprehensive search.

    Args:
        charity_name: The name of the charity to look up ratings for.

    Returns:
        Information about the charity's ratings and accountability.
    """
    print("\nโญ TOOL CALLED: search_charity_ratings")
    pprint({"charity_name": charity_name})

    query = f"{charity_name} charity rating Charity Navigator GuideStar review"

    try:
        results = openai_web_search(query)
        return results
    except Exception as e:
        return f"Rating search failed: {str(e)}. Please try again."


# List of all available tools for the charity search agent
# Put comprehensive search FIRST so the LLM prefers it
CHARITY_SEARCH_TOOLS = [search_charity_comprehensive, search_charity_info, search_charity_ratings]