dhisana 0.0.1.dev101__tar.gz → 0.0.1.dev102__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/PKG-INFO +1 -1
  2. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/setup.py +1 -1
  3. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/apollo_tools.py +11 -1
  4. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/check_email_validity_tools.py +17 -1
  5. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/research_lead.py +32 -7
  6. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/PKG-INFO +1 -1
  7. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/README.md +0 -0
  8. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/pyproject.toml +0 -0
  9. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/setup.cfg +0 -0
  10. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/__init__.py +0 -0
  11. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/cli/__init__.py +0 -0
  12. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/cli/cli.py +0 -0
  13. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/cli/datasets.py +0 -0
  14. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/cli/models.py +0 -0
  15. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/cli/predictions.py +0 -0
  16. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/schemas/__init__.py +0 -0
  17. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/schemas/common.py +0 -0
  18. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/schemas/sales.py +0 -0
  19. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/ui/__init__.py +0 -0
  20. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/ui/components.py +0 -0
  21. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/__init__.py +0 -0
  22. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/add_mapping.py +0 -0
  23. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/agent_tools.py +0 -0
  24. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/assistant_tool_tag.py +0 -0
  25. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/built_with_api_tools.py +0 -0
  26. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/cache_output_tools.py +0 -0
  27. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/cache_output_tools_local.py +0 -0
  28. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/check_for_intent_signal.py +0 -0
  29. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/check_linkedin_url_validity.py +0 -0
  30. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/clay_tools.py +0 -0
  31. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/clean_properties.py +0 -0
  32. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/company_utils.py +0 -0
  33. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/compose_salesnav_query.py +0 -0
  34. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/compose_search_query.py +0 -0
  35. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/compose_three_step_workflow.py +0 -0
  36. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/composite_tools.py +0 -0
  37. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/dataframe_tools.py +0 -0
  38. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/domain_parser.py +0 -0
  39. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/email_parse_helpers.py +0 -0
  40. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/enrich_lead_information.py +0 -0
  41. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/extract_email_content_for_llm.py +0 -0
  42. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/field_validators.py +0 -0
  43. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/g2_tools.py +0 -0
  44. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_content.py +0 -0
  45. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_email.py +0 -0
  46. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_email_response.py +0 -0
  47. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_flow.py +0 -0
  48. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_leads_salesnav.py +0 -0
  49. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_linkedin_connect_message.py +0 -0
  50. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_linkedin_response_message.py +0 -0
  51. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/generate_structured_output_internal.py +0 -0
  52. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/google_custom_search.py +0 -0
  53. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/google_workspace_tools.py +0 -0
  54. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/hubspot_clearbit.py +0 -0
  55. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/hubspot_crm_tools.py +0 -0
  56. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/instantly_tools.py +0 -0
  57. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/linkedin_crawler.py +0 -0
  58. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/lusha_tools.py +0 -0
  59. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openai_assistant_and_file_utils.py +0 -0
  60. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openai_helpers.py +0 -0
  61. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openapi_spec_to_tools.py +0 -0
  62. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openapi_tool/__init__.py +0 -0
  63. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openapi_tool/api_models.py +0 -0
  64. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openapi_tool/convert_openai_spec_to_tool.py +0 -0
  65. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/openapi_tool/openapi_tool.py +0 -0
  66. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/parse_linkedin_messages_txt.py +0 -0
  67. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/proxy_curl_tools.py +0 -0
  68. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/python_function_to_tools.py +0 -0
  69. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/sales_navigator_crawler.py +0 -0
  70. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/salesforce_crm_tools.py +0 -0
  71. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/sendgrid_tools.py +0 -0
  72. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/serpapi_search_tools.py +0 -0
  73. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/test_connect.py +0 -0
  74. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/trasform_json.py +0 -0
  75. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/web_download_parse_tools.py +0 -0
  76. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/workflow_code_model.py +0 -0
  77. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/utils/zoominfo_tools.py +0 -0
  78. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/workflow/__init__.py +0 -0
  79. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/workflow/agent.py +0 -0
  80. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/workflow/flow.py +0 -0
  81. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/workflow/task.py +0 -0
  82. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana/workflow/test.py +0 -0
  83. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/SOURCES.txt +0 -0
  84. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/dependency_links.txt +0 -0
  85. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/entry_points.txt +0 -0
  86. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/requires.txt +0 -0
  87. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/src/dhisana.egg-info/top_level.txt +0 -0
  88. {dhisana-0.0.1.dev101 → dhisana-0.0.1.dev102}/tests/test_agent_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev101
3
+ Version: 0.0.1.dev102
4
4
  Summary: A Python SDK for Dhisana AI Platform
5
5
  Home-page: https://github.com/dhisana-ai/dhisana-python-sdk
6
6
  Author: Admin
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='dhisana',
5
- version='0.0.1-dev101',
5
+ version='0.0.1-dev102',
6
6
  description='A Python SDK for Dhisana AI Platform',
7
7
  author='Admin',
8
8
  author_email='contact@dhisana.ai',
@@ -192,6 +192,16 @@ async def lookup_person_in_apollo_by_name(
192
192
  "per_page": 10
193
193
  }
194
194
 
195
+ # Build a cache key that includes full_name and company_name (if provided)
196
+ # so that results are correctly cached and retrieved.
197
+ key_item = f"lookup_person_in_apollo_by_name_{full_name}_{company_name or ''}".lower()
198
+
199
+ # Attempt to retrieve a cached response first
200
+ cached_response = retrieve_output("lookup_person_in_apollo_by_name", key_item)
201
+ if cached_response is not None:
202
+ logger.info(f"Cache hit for user: {full_name}, company: {company_name or ''}")
203
+ return cached_response
204
+
195
205
  url = 'https://api.apollo.io/api/v1/mixed_people/search'
196
206
  logger.debug(f"Making request to Apollo with payload: {data}")
197
207
 
@@ -202,6 +212,7 @@ async def lookup_person_in_apollo_by_name(
202
212
  if response.status == 200:
203
213
  result = await response.json()
204
214
  logger.info("Successfully looked up person by name on Apollo.")
215
+ cache_output("lookup_person_in_apollo_by_name", key_item, result)
205
216
  return result
206
217
  elif response.status == 429:
207
218
  msg = "Rate limit exceeded"
@@ -222,7 +233,6 @@ async def lookup_person_in_apollo_by_name(
222
233
  logger.exception("Exception occurred while looking up person by name.")
223
234
  return {'error': str(e)}
224
235
 
225
-
226
236
  @assistant_tool
227
237
  @backoff.on_exception(
228
238
  backoff.expo,
@@ -220,6 +220,18 @@ async def check_email_validity_with_hunter(
220
220
  "confidence": "low",
221
221
  "is_valid": False
222
222
  }
223
+
224
+ cache_key = f"{email_id}"
225
+ cached_response = retrieve_output("hunter_validate", cache_key)
226
+ if cached_response is not None:
227
+ logger.info("Cache hit for Hunter validate.")
228
+ if not cached_response:
229
+ return {
230
+ "email": email_id,
231
+ "confidence": "low",
232
+ "is_valid": False
233
+ }
234
+ return json.loads(cached_response[0])
223
235
 
224
236
  HUNTER_API_KEY = get_hunter_access_token(tool_config)
225
237
  if not HUNTER_API_KEY:
@@ -241,11 +253,14 @@ async def check_email_validity_with_hunter(
241
253
  if response.status != 200:
242
254
  content = await safe_read_json_or_text(response)
243
255
  logger.warning(f"[Hunter] Non-200 status: {response.status} => {content}")
244
- return {
256
+
257
+ final_response = {
245
258
  "email": email_id,
246
259
  "confidence": "low",
247
260
  "is_valid": False
248
261
  }
262
+ cache_output("hunter_validate", cache_key, [json.dumps(final_response)])
263
+ return final_response
249
264
 
250
265
  result = await response.json()
251
266
  except Exception as ex:
@@ -266,6 +281,7 @@ async def check_email_validity_with_hunter(
266
281
  "confidence": confidence,
267
282
  "is_valid": is_valid
268
283
  }
284
+ cache_output("hunter_validate", cache_key, [json.dumps(final_response)])
269
285
  logger.info("Exiting check_email_validity_with_hunter.")
270
286
  return final_response
271
287
 
@@ -8,6 +8,23 @@ def clean_nul_bytes(s: str) -> str:
8
8
  s = s.replace('```markdown', '')
9
9
  return s.replace('\x00', '')
10
10
 
11
+ def _remove_excluded_fields(data: Dict) -> Dict:
12
+ """
13
+ Return a copy of `data` that excludes keys named 'id'
14
+ or that end in '_by', '_id', '_to', or '_at'.
15
+ """
16
+ excluded_keys = {"id"}
17
+ excluded_endings = ["_by", "_id", "_to", "_at", "_status", "research_summary"]
18
+
19
+ cleaned = {}
20
+ for k, v in data.items():
21
+ if k in excluded_keys:
22
+ continue
23
+ if any(k.endswith(suffix) for suffix in excluded_endings):
24
+ continue
25
+ cleaned[k] = v
26
+ return cleaned
27
+
11
28
  class LeadResearchInformation(BaseModel):
12
29
  research_summary: str
13
30
 
@@ -20,7 +37,13 @@ async def research_lead_with_full_info_ai(
20
37
  """
21
38
  Research on lead provided given input. Provide Detailed Summary.
22
39
  """
40
+ # Clean user properties (e.g. remove newlines, sanitize strings, etc.)
23
41
  user_properties = cleanup_email_context(user_properties)
42
+
43
+ # Remove excluded fields from user_properties
44
+ user_properties = _remove_excluded_fields(user_properties)
45
+
46
+ # Optionally remove any known keys that should not appear (e.g. 'date_extracted')
24
47
  user_properties.pop("date_extracted", None)
25
48
 
26
49
  instructions = f"""
@@ -69,7 +92,7 @@ async def research_lead_with_full_info_ai(
69
92
  response.research_summary = clean_nul_bytes(response.research_summary)
70
93
  return response.model_dump()
71
94
  else:
72
- {"research_summary", ""}
95
+ return {"research_summary": ""}
73
96
 
74
97
  # --------------------------------------------
75
98
  # COMPANY-RELATED MODELS & FUNCTION (FIXED)
@@ -94,9 +117,12 @@ async def research_company_with_full_info_ai(
94
117
  Returns:
95
118
  dict: The JSON response containing the detailed research summary of the company.
96
119
  """
120
+ # Clean company properties (e.g. remove newlines, sanitize strings, etc.)
97
121
  company_properties = cleanup_email_context(company_properties)
98
122
 
99
- # Build the LLM instructions for the company research
123
+ # Remove excluded fields from company_properties
124
+ company_properties = _remove_excluded_fields(company_properties)
125
+
100
126
  instructions = f"""
101
127
  Please read the following company information and instructions, then produce a detailed summary of the company in the specified format.
102
128
  ---
@@ -130,11 +156,10 @@ async def research_company_with_full_info_ai(
130
156
  "research_summary": "Detailed summary about the company. The summary should be neatly formatted in GitHub-Flavored Markdown, and include all the key information from the listed sections."
131
157
  }}
132
158
  """
133
-
134
159
  response, status = await get_structured_output_internal(
135
- instructions,
136
- CompanyResearchInformation,
137
- model="gpt-4o",
160
+ instructions,
161
+ CompanyResearchInformation,
162
+ model="gpt-4o",
138
163
  use_web_search=True,
139
164
  tool_config=tool_config
140
165
  )
@@ -142,4 +167,4 @@ async def research_company_with_full_info_ai(
142
167
  response.research_summary = clean_nul_bytes(response.research_summary)
143
168
  return response.model_dump()
144
169
  else:
145
- return {"research_summary", ""}
170
+ return {"research_summary": ""}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dhisana
3
- Version: 0.0.1.dev101
3
+ Version: 0.0.1.dev102
4
4
  Summary: A Python SDK for Dhisana AI Platform
5
5
  Home-page: https://github.com/dhisana-ai/dhisana-python-sdk
6
6
  Author: Admin
File without changes
File without changes