brainsqueeze commited on
Commit
d0f7444
·
verified ·
1 Parent(s): cc3ef97

Delete ask_candid/tools/recommendation.py

Browse files
Files changed (1) hide show
  1. ask_candid/tools/recommendation.py +0 -238
ask_candid/tools/recommendation.py DELETED
@@ -1,238 +0,0 @@
1
- import os
2
-
3
- from openai import OpenAI
4
- from langchain_core.prompts import ChatPromptTemplate
5
- import requests
6
-
7
- from ask_candid.agents.schema import AgentState, Context
8
- from ask_candid.base.api_base import BaseAPI
9
-
10
- class AutocodingAPI(BaseAPI):
11
- def __init__(self):
12
- super().__init__(
13
- url=os.getenv("AUTOCODING_API_URL"),
14
- headers={
15
- 'x-api-key': os.getenv("AUTOCODING_API_KEY"),
16
- 'Content-Type': 'application/json'
17
- }
18
- )
19
-
20
- def __call__(self, text: str, taxonomy: str = 'pcs-v3'):
21
- params = {
22
- 'text': text,
23
- 'taxonomy': taxonomy
24
- }
25
- return self.get(**params)
26
-
27
- class GeoAPI(BaseAPI):
28
- def __init__(self):
29
- super().__init__(
30
- url=os.getenv("GEO_API_URL"),
31
- headers={
32
- 'x-api-key': os.getenv("GEO_API_KEY"),
33
- 'Content-Type': 'application/json'
34
- }
35
- )
36
-
37
- def __call__(self, text: str):
38
- payload = {
39
- 'text': text
40
- }
41
- return self.post(payload=payload)
42
-
43
- class EntitiesAPI(BaseAPI):
44
- def __init__(self):
45
- super().__init__(
46
- url=f'{os.getenv("DOCUMENT_API_URL")}/entities',
47
- headers={
48
- 'x-api-key': os.getenv("DOCUMENT_API_KEY"),
49
- 'Content-Type': 'application/json'
50
- }
51
- )
52
-
53
- def __call__(self, text: str):
54
- payload = {
55
- 'text': text
56
- }
57
- return self.post(payload=payload)
58
-
59
-
60
-
61
- class FunderRecommendationAPI(BaseAPI):
62
- def __init__(self):
63
- super().__init__(
64
- url=os.getenv("FUNDER_REC_API_URL"),
65
- headers={"x-api-key": os.getenv("FUNDER_REC_API_KEY")}
66
- )
67
-
68
- def __call__(self, subjects, populations, geos):
69
- params = {
70
- "subjects": subjects,
71
- "populations": populations,
72
- "geos": geos
73
- }
74
- return self.get(**params)
75
-
76
- class RFPRecommendationAPI(BaseAPI):
77
- def __init__(self):
78
- super().__init__(
79
- url= f'{os.getenv("FUNDER_REC_API_URL")}/rfp',
80
- headers={"x-api-key": os.getenv("FUNDER_REC_API_KEY")}
81
- )
82
-
83
- def __call__(self, org_id, subjects, populations, geos):
84
- params = {
85
- "candid_entity_id": org_id,
86
- "subjects": subjects,
87
- "populations": populations,
88
- "geos": geos
89
- }
90
- return self.get(**params)
91
-
92
-
93
-
94
-
95
- def detect_intent_with_llm(state: AgentState, llm) -> AgentState:
96
- """Detect query intent (which type of recommendation) and update the state using the specified LLM."""
97
- print("running detect intent")
98
-
99
- query = state["messages"][-1].content
100
-
101
- prompt_template = ChatPromptTemplate.from_messages(
102
- [
103
- ("system", """
104
- Please classify the following query by stating ONLY the category name: 'none', 'funder', or 'rfp'.
105
- Please answer WITHOUT any reasoning.
106
- - 'none': The query does not ask for any recommendations.
107
- - 'funder': The query asks for recommendations about funders, such as foundations or donors.
108
- - 'rfp': The query asks for recommendations about specific Requests for Proposals (RFPs).
109
-
110
- Consider:
111
- - If the query seeks broad, long-term funding sources or organizations, classify as 'funder'.
112
- - If the query seeks specific, time-bound funding opportunities with a deadline, classify as 'rfp'.
113
- - If the query does not seek any recommendations, classify as 'none'.
114
-
115
- Query: """),
116
- ("human", f"{query}")
117
- ]
118
- )
119
-
120
- chain = prompt_template | llm
121
- response = chain.invoke({"query": query})
122
-
123
- intent = response.content.strip().lower()
124
- state["intent"] = intent.strip("'").strip('"') # Remove extra quotes if necessary
125
- print(state["intent"])
126
- return state
127
-
128
-
129
- def determine_context(state: AgentState) -> AgentState:
130
- print("running context")
131
- query = state["messages"][-1].content
132
-
133
- autocoding_api = AutocodingAPI()
134
- entities_api = EntitiesAPI()
135
-
136
- subject_codes, population_codes, geo_ids = [], [], []
137
-
138
- try:
139
- autocoding_response = autocoding_api(text=query)
140
- returned_pcs = autocoding_response.get("data", {})
141
- population_codes = [item['full_code'] for item in returned_pcs.get("population", [])]
142
- subject_codes = [item['full_code'] for item in returned_pcs.get("subject", [])]
143
- except Exception as e:
144
- print(f"Failed to retrieve autocoding data: {e}")
145
-
146
- try:
147
- geo_response = entities_api(text=query)
148
- entities = geo_response.get('entities', [])
149
- geo_ids = [match['geonames_id'] for entity in entities if entity['type'] == 'geo' and 'match' in entity
150
- for match in entity['match'] if 'geonames_id' in match]
151
- except Exception as e:
152
- print(f"Failed to retrieve geographic data: {e}")
153
-
154
- state["context"] = Context(
155
- subject=subject_codes,
156
- population=population_codes,
157
- geography=geo_ids
158
- )
159
- return state
160
-
161
-
162
-
163
- def format_recommendations(intent, data):
164
- if 'recommendations' not in data:
165
- return "No recommendations available."
166
-
167
- recommendations = data['recommendations']
168
- if not recommendations:
169
- return "No recommendations found."
170
-
171
- recommendation_texts = []
172
- if intent == "funder":
173
- for rec in recommendations:
174
- main_sort_name = rec['funder_data']['main_sort_name']
175
- profile_url = f"https://app.candid.org/profile/{rec['funder_id']}"
176
- recommendation_texts.append(f"{main_sort_name} - Profile: {profile_url}")
177
- elif intent == "rfp":
178
- for rec in recommendations:
179
- title = rec.get('title', 'N/A')
180
- funder_name = rec.get('funder_name', 'N/A')
181
- amount = rec.get('amount', 'Not specified')
182
- description = rec.get('description', 'No description available')
183
- deadline = rec.get('deadline', 'No deadline provided')
184
- application_url = rec.get('application_url', 'No URL available')
185
- text = (f"Title: {title}\n"
186
- f"Funder: {funder_name}\n"
187
- f"Amount: {amount}\n"
188
- f"Description: {description}\n"
189
- f"Deadline: {deadline}\n"
190
- f"Application URL: {application_url}\n")
191
- recommendation_texts.append(text)
192
- else:
193
- return "Only funder recommendation or RFP recommendation are supported."
194
-
195
- return "\n".join(recommendation_texts)
196
-
197
-
198
-
199
- def make_recommendation(state: AgentState) -> AgentState:
200
- print("running recommendation")
201
- org_id = "6908122" # Example organization ID (Candid)
202
- funder_or_rfp = state["intent"]
203
-
204
- contexts = state["context"]
205
- subject_codes = ",".join(contexts.get("subject", []))
206
- population_codes = ",".join(contexts.get("population", []))
207
- geo_ids = ",".join([str(geo) for geo in contexts.get("geography", [])])
208
-
209
- recommendation_display_text = ""
210
-
211
- try:
212
- if funder_or_rfp == "funder":
213
- funder_api = FunderRecommendationAPI()
214
- recommendations = funder_api(subject_codes, population_codes, geo_ids)
215
- elif funder_or_rfp == "rfp":
216
- rfp_api = RFPRecommendationAPI()
217
- recommendations = rfp_api(org_id, subject_codes, population_codes, geo_ids)
218
- else:
219
- recommendation_display_text = "Unknown intent. Intent 'funder' or 'rfp' expected."
220
- state["recommendation"] = recommendation_display_text
221
- return state
222
-
223
- if recommendations:
224
- recommendation_display_text = format_recommendations(funder_or_rfp, recommendations)
225
- else:
226
- recommendation_display_text = "No recommendations were found for your query. Please try refining your search criteria."
227
-
228
- except requests.exceptions.HTTPError as e:
229
- # Handle HTTP errors raised by raise_for_status()
230
- print(f"HTTP error occurred: {e.response.status_code} - {e.response.reason}")
231
- recommendation_display_text = "HTTP error occurred, please report this to datascience@candid.org"
232
- except Exception as e:
233
- # Catch-all for any other exceptions that are not HTTP errors
234
- print(f"An unexpected error occurred: {str(e)}")
235
- recommendation_display_text = "Unexpected error occurred, please report this to datascience@candid.org"
236
-
237
- state["recommendation"] = recommendation_display_text
238
- return state