dhisana 0.0.1.dev28__tar.gz → 0.0.1.dev29__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 (85) hide show
  1. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/PKG-INFO +1 -1
  2. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/setup.py +1 -1
  3. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/google_workspace_tools.py +59 -67
  4. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/PKG-INFO +1 -1
  5. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/README.md +0 -0
  6. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/pyproject.toml +0 -0
  7. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/setup.cfg +0 -0
  8. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/__init__.py +0 -0
  9. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/cli/__init__.py +0 -0
  10. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/cli/cli.py +0 -0
  11. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/cli/datasets.py +0 -0
  12. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/cli/models.py +0 -0
  13. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/cli/predictions.py +0 -0
  14. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/schemas/__init__.py +0 -0
  15. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/schemas/common.py +0 -0
  16. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/schemas/sales.py +0 -0
  17. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/ui/__init__.py +0 -0
  18. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/ui/components.py +0 -0
  19. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/__init__.py +0 -0
  20. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/agent_task.py +0 -0
  21. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/agent_tools.py +0 -0
  22. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/apollo_tools.py +0 -0
  23. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/assistant_tool_tag.py +0 -0
  24. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/built_with_api_tools.py +0 -0
  25. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/cache_output_tools.py +0 -0
  26. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/check_email_validity_tools.py +0 -0
  27. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/check_for_intent_signal.py +0 -0
  28. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/check_linkedin_url_validity.py +0 -0
  29. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/clay_tools.py +0 -0
  30. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/company_utils.py +0 -0
  31. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/compose_cadence.py +0 -0
  32. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/compose_salesnav_query.py +0 -0
  33. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/compose_search_query.py +0 -0
  34. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/compose_three_step_workflow.py +0 -0
  35. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/compose_workflow.py +0 -0
  36. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/composite_tools.py +0 -0
  37. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/create_list_from_sales_navigator.py +0 -0
  38. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/create_smart_list.py +0 -0
  39. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/dataframe_tools.py +0 -0
  40. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/domain_parser.py +0 -0
  41. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/enrich_lead_information.py +0 -0
  42. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/extract_email_content_for_llm.py +0 -0
  43. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/g2_tools.py +0 -0
  44. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_content.py +0 -0
  45. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_email.py +0 -0
  46. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_email_response.py +0 -0
  47. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_flow.py +0 -0
  48. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_linkedin_connect_message.py +0 -0
  49. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_linkedin_response_message.py +0 -0
  50. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/generate_structured_output_internal.py +0 -0
  51. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/google_custom_search.py +0 -0
  52. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/hubspot_clearbit.py +0 -0
  53. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/hubspot_crm_tools.py +0 -0
  54. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/instantly_tools.py +0 -0
  55. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/linkedin_crawler.py +0 -0
  56. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/lusha_tools.py +0 -0
  57. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openai_assistant_and_file_utils.py +0 -0
  58. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openai_helpers.py +0 -0
  59. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openapi_spec_to_tools.py +0 -0
  60. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openapi_tool/__init__.py +0 -0
  61. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openapi_tool/api_models.py +0 -0
  62. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openapi_tool/convert_openai_spec_to_tool.py +0 -0
  63. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/openapi_tool/openapi_tool.py +0 -0
  64. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/proxy_curl_tools.py +0 -0
  65. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/python_function_to_tools.py +0 -0
  66. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/research_lead.py +0 -0
  67. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/sales_navigator_crawler.py +0 -0
  68. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/salesforce_crm_tools.py +0 -0
  69. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/sendgrid_tools.py +0 -0
  70. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/serpapi_search_tools.py +0 -0
  71. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/trasform_json.py +0 -0
  72. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/web_download_parse_tools.py +0 -0
  73. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/workflow_code_model.py +0 -0
  74. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/utils/zoominfo_tools.py +0 -0
  75. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/workflow/__init__.py +0 -0
  76. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/workflow/agent.py +0 -0
  77. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/workflow/flow.py +0 -0
  78. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/workflow/task.py +0 -0
  79. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana/workflow/test.py +0 -0
  80. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/SOURCES.txt +0 -0
  81. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/dependency_links.txt +0 -0
  82. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/entry_points.txt +0 -0
  83. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/requires.txt +0 -0
  84. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/src/dhisana.egg-info/top_level.txt +0 -0
  85. {dhisana-0.0.1.dev28 → dhisana-0.0.1.dev29}/tests/test_agent_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dhisana
3
- Version: 0.0.1.dev28
3
+ Version: 0.0.1.dev29
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-dev28',
5
+ version='0.0.1-dev29',
6
6
  description='A Python SDK for Dhisana AI Platform',
7
7
  author='Admin',
8
8
  author_email='contact@dhisana.ai',
@@ -15,6 +15,7 @@ from googleapiclient.discovery import build
15
15
  from googleapiclient.http import MediaIoBaseDownload, MediaFileUpload
16
16
  from google.auth.transport.requests import Request
17
17
  from googleapiclient.errors import HttpError
18
+ from pydantic import BaseModel
18
19
 
19
20
  from dhisana.utils.assistant_tool_tag import assistant_tool
20
21
 
@@ -332,12 +333,16 @@ async def list_files_in_drive_folder_by_name(
332
333
  # GMAIL EMAIL OPERATIONS
333
334
  ################################################################################
334
335
 
336
+ class SendEmailContext(BaseModel):
337
+ recipient: str
338
+ subject: str
339
+ body: str
340
+ sender_name: str
341
+ sender_email: str
342
+
335
343
  @assistant_tool
336
344
  async def send_email_using_service_account_async(
337
- recipient: str,
338
- subject: str,
339
- body: str,
340
- sender_email: str,
345
+ send_email_context: SendEmailContext,
341
346
  tool_config: Optional[List[Dict]] = None
342
347
  ) -> str:
343
348
  """
@@ -345,36 +350,27 @@ async def send_email_using_service_account_async(
345
350
  The service account must have domain-wide delegation to impersonate the sender_email.
346
351
 
347
352
  Args:
348
- recipient (str): The email address of the recipient.
349
- subject (str): The subject of the email.
350
- body (str): The body text of the email.
351
- sender_email (str): The address to impersonate for sending.
352
- tool_config (Optional[List[Dict]]): Tool configuration for credentials.
353
+ send_email_context (SendEmailContext): The context with recipient, subject, body, sender_name, and sender_email.
354
+ tool_config (Optional[List[Dict]]): Tool configuration for credentials (if any).
353
355
 
354
356
  Returns:
355
357
  str: The ID of the sent message.
356
-
357
- Raises:
358
- httpx.HTTPError, Google-related errors for any issues with the API.
359
358
  """
360
- if not sender_email:
359
+ if not send_email_context.sender_email:
361
360
  raise ValueError("sender_email is required to impersonate for sending.")
362
361
 
363
362
  SCOPES = ['https://mail.google.com/']
364
- credentials = get_google_credentials(sender_email, SCOPES, tool_config)
363
+ credentials = get_google_credentials(send_email_context.sender_email, SCOPES, tool_config)
365
364
  access_token = credentials.token
366
365
 
367
366
  gmail_api_url = 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send'
368
367
 
369
- # Create the email message
370
- message = MIMEText(body)
371
- message['to'] = recipient
372
- message['from'] = sender_email
373
- message['subject'] = subject
368
+ message = MIMEText(send_email_context.body)
369
+ message['to'] = send_email_context.recipient
370
+ message['from'] = f"{send_email_context.sender_name} <{send_email_context.sender_email}>"
371
+ message['subject'] = send_email_context.subject
374
372
 
375
- # Encode the message in base64url format
376
373
  raw_message = base64.urlsafe_b64encode(message.as_bytes()).decode()
377
-
378
374
  payload = {'raw': raw_message}
379
375
  headers = {
380
376
  'Authorization': f'Bearer {access_token}',
@@ -389,13 +385,16 @@ async def send_email_using_service_account_async(
389
385
  return sent_message.get('id', 'No ID returned')
390
386
 
391
387
 
388
+ class QueryEmailContext(BaseModel):
389
+ start_time: str
390
+ end_time: str
391
+ sender_email: str
392
+ unread_only: bool = True
393
+ labels: Optional[List[str]] = None
394
+
392
395
  @assistant_tool
393
396
  async def list_emails_in_time_range_async(
394
- start_time: str,
395
- end_time: str,
396
- sender_email: str,
397
- unread_only: bool = True,
398
- labels: Optional[List[str]] = None,
397
+ context: QueryEmailContext,
399
398
  tool_config: Optional[List[Dict]] = None
400
399
  ) -> List[Dict[str, Any]]:
401
400
  """
@@ -403,43 +402,36 @@ async def list_emails_in_time_range_async(
403
402
  The service account must have domain-wide delegation to impersonate the sender_email.
404
403
 
405
404
  Args:
406
- start_time (str): The start time in RFC 3339 format (e.g., '2021-01-01T00:00:00Z').
407
- end_time (str): The end time in RFC 3339 format (e.g., '2021-01-31T23:59:59Z').
408
- sender_email (str): The mailbox email to impersonate.
409
- unread_only (bool): If True, only return unread emails.
410
- labels (Optional[List[str]]): Optional list of Gmail labels to filter.
405
+ context (QueryEmailContext): The query context with start_time, end_time, sender_email, unread_only, and labels.
411
406
  tool_config (Optional[List[Dict]]): Tool configuration for credentials.
412
407
 
413
408
  Returns:
414
409
  List[Dict[str, Any]]: A list of email message details.
415
-
416
- Raises:
417
- httpx.HTTPError, Google-related errors for any issues with the API.
418
410
  """
419
- if labels is None:
420
- labels = []
411
+ if context.labels is None:
412
+ context.labels = []
421
413
 
422
- if not sender_email:
414
+ if not context.sender_email:
423
415
  raise ValueError("sender_email is required to impersonate for listing emails.")
424
416
 
425
417
  SCOPES = ['https://mail.google.com/']
426
- credentials = get_google_credentials(sender_email, SCOPES, tool_config)
418
+ credentials = get_google_credentials(context.sender_email, SCOPES, tool_config)
427
419
  access_token = credentials.token
428
420
 
429
421
  gmail_api_url = 'https://gmail.googleapis.com/gmail/v1/users/me/messages'
430
422
 
431
423
  # Convert RFC 3339 times to Unix epoch timestamps
432
- start_dt = datetime.datetime.fromisoformat(start_time.replace('Z', '+00:00'))
433
- end_dt = datetime.datetime.fromisoformat(end_time.replace('Z', '+00:00'))
424
+ start_dt = datetime.datetime.fromisoformat(context.start_time.replace('Z', '+00:00'))
425
+ end_dt = datetime.datetime.fromisoformat(context.end_time.replace('Z', '+00:00'))
434
426
  start_timestamp = int(start_dt.timestamp())
435
427
  end_timestamp = int(end_dt.timestamp())
436
428
 
437
429
  # Build the search query
438
430
  query = f'after:{start_timestamp} before:{end_timestamp}'
439
- if unread_only:
431
+ if context.unread_only:
440
432
  query += ' is:unread'
441
- if labels:
442
- label_query = ' '.join([f'label:{lbl}' for lbl in labels])
433
+ if context.labels:
434
+ label_query = ' '.join([f'label:{lbl}' for lbl in context.labels])
443
435
  query += f' {label_query}'
444
436
 
445
437
  headers = {'Authorization': f'Bearer {access_token}'}
@@ -458,7 +450,6 @@ async def list_emails_in_time_range_async(
458
450
  message_response.raise_for_status()
459
451
  message_data = message_response.json()
460
452
 
461
- # Extract relevant info
462
453
  headers_list = message_data['payload']['headers']
463
454
  email_details.append({
464
455
  "mailbox_email_id": message_data['id'],
@@ -639,13 +630,17 @@ async def get_email_details_async(
639
630
  return message_details
640
631
 
641
632
 
633
+ class ReplyEmailContext(BaseModel):
634
+ message_id: str
635
+ reply_body: str
636
+ sender_email: str
637
+ sender_name: str
638
+ mark_as_read: str = "True"
639
+ add_labels: Optional[List[str]] = None
640
+
642
641
  @assistant_tool
643
642
  async def reply_to_email_async(
644
- message_id: str,
645
- reply_body: str,
646
- sender_email: str,
647
- mark_as_read: str = "True",
648
- add_labels: Optional[List[str]] = None,
643
+ reply_email_context: ReplyEmailContext,
649
644
  tool_config: Optional[List[Dict]] = None
650
645
  ) -> Dict[str, Any]:
651
646
  """
@@ -653,35 +648,32 @@ async def reply_to_email_async(
653
648
  The service account must have domain-wide delegation to impersonate the sender_email.
654
649
 
655
650
  Args:
656
- message_id (str): The ID of the email message to reply to.
657
- reply_body (str): The body text of the reply email.
658
- sender_email (str): The mailbox email to impersonate for domain-wide delegation.
659
- mark_as_read (str): If "True", mark the email thread as read after replying.
660
- add_labels (List[str]): Optional list of labels to add to the email thread.
651
+ context (ReplyEmailContext): The context with message_id, reply_body, sender_email, sender_name,
652
+ mark_as_read, and add_labels.
661
653
  tool_config (Optional[List[Dict]]): Tool configuration for credentials.
662
654
 
663
655
  Returns:
664
656
  Dict[str, Any]: A dictionary containing the details of the sent message.
665
657
  """
666
- if add_labels is None:
667
- add_labels = []
658
+ if reply_email_context.add_labels is None:
659
+ reply_email_context.add_labels = []
668
660
 
669
- if not sender_email:
661
+ if not reply_email_context.sender_email:
670
662
  raise ValueError("sender_email is required to impersonate for replying to an email.")
671
663
 
672
664
  SCOPES = ['https://mail.google.com/']
673
- credentials = get_google_credentials(sender_email, SCOPES, tool_config)
665
+ credentials = get_google_credentials(reply_email_context.sender_email, SCOPES, tool_config)
674
666
  access_token = credentials.token
675
667
 
676
- # 1. Retrieve original message
677
668
  gmail_api_base_url = 'https://gmail.googleapis.com/gmail/v1/users/me'
678
- get_message_url = f'{gmail_api_base_url}/messages/{message_id}'
669
+ get_message_url = f'{gmail_api_base_url}/messages/{reply_email_context.message_id}'
679
670
  headers = {
680
671
  'Authorization': f'Bearer {access_token}',
681
672
  'Content-Type': 'application/json'
682
673
  }
683
674
  params = {'format': 'full'}
684
675
 
676
+ # 1. Retrieve original message
685
677
  async with httpx.AsyncClient() as client:
686
678
  response = await client.get(get_message_url, headers=headers, params=params)
687
679
  response.raise_for_status()
@@ -701,11 +693,11 @@ async def reply_to_email_async(
701
693
  message_id_header = headers_dict.get('Message-ID', '')
702
694
 
703
695
  # 3. Create the reply email message
704
- msg = MIMEText(reply_body)
696
+ msg = MIMEText(reply_email_context.reply_body)
705
697
  msg['To'] = to_addresses
706
698
  if cc_addresses:
707
699
  msg['Cc'] = cc_addresses
708
- msg['From'] = sender_email
700
+ msg['From'] = f"{reply_email_context.sender_name} <{reply_email_context.sender_email}>"
709
701
  msg['Subject'] = subject
710
702
  msg['In-Reply-To'] = message_id_header
711
703
  msg['References'] = message_id_header
@@ -724,7 +716,7 @@ async def reply_to_email_async(
724
716
  sent_message = response.json()
725
717
 
726
718
  # 5. (Optional) Mark the thread as read
727
- if mark_as_read.lower() == "true":
719
+ if reply_email_context.mark_as_read.lower() == "true":
728
720
  modify_thread_url = f'{gmail_api_base_url}/threads/{thread_id}/modify'
729
721
  modify_payload = {'removeLabelIds': ['UNREAD']}
730
722
  async with httpx.AsyncClient() as client:
@@ -732,9 +724,9 @@ async def reply_to_email_async(
732
724
  response.raise_for_status()
733
725
 
734
726
  # 6. (Optional) Add labels
735
- if add_labels:
727
+ if reply_email_context.add_labels:
736
728
  modify_thread_url = f'{gmail_api_base_url}/threads/{thread_id}/modify'
737
- modify_payload = {'addLabelIds': add_labels}
729
+ modify_payload = {'addLabelIds': reply_email_context.add_labels}
738
730
  async with httpx.AsyncClient() as client:
739
731
  response = await client.post(modify_thread_url, headers=headers, json=modify_payload)
740
732
  response.raise_for_status()
@@ -744,9 +736,9 @@ async def reply_to_email_async(
744
736
  "mailbox_email_id": sent_message['id'],
745
737
  "message_id": sent_message['threadId'],
746
738
  "email_subject": subject,
747
- "email_sender": sender_email,
739
+ "email_sender": reply_email_context.sender_email,
748
740
  "email_recipients": [to_addresses] + ([cc_addresses] if cc_addresses else []),
749
- "read_email_status": 'READ' if mark_as_read.lower() == "true" else 'UNREAD',
741
+ "read_email_status": 'READ' if reply_email_context.mark_as_read.lower() == "true" else 'UNREAD',
750
742
  "email_labels": sent_message.get('labelIds', [])
751
743
  }
752
744
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: dhisana
3
- Version: 0.0.1.dev28
3
+ Version: 0.0.1.dev29
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