office365 toolkit bug fixes (#13618)

Several bug fixes:
- emails: instead of `bcc` the `cc` is used.
- errors in the truncation descriptions
- no truncation of the `message_search`
Several updates:
- generalized UTC format 
- truncation limit can be changed now in _call()
This commit is contained in:
Leonid Ganeline 2023-11-28 08:49:24 -08:00 committed by GitHub
parent 60309341bd
commit 7929b26017
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 20 deletions

View File

@ -60,7 +60,7 @@ class O365CreateDraftMessage(O365BaseTool):
if cc is not None: if cc is not None:
message.cc.add(cc) message.cc.add(cc)
if bcc is not None: if bcc is not None:
message.bcc.add(cc) message.bcc.add(bcc)
message.save_draft() message.save_draft()

View File

@ -11,13 +11,13 @@ from langchain_core.pydantic_v1 import BaseModel, Extra, Field
from langchain.callbacks.manager import CallbackManagerForToolRun from langchain.callbacks.manager import CallbackManagerForToolRun
from langchain.tools.office365.base import O365BaseTool from langchain.tools.office365.base import O365BaseTool
from langchain.tools.office365.utils import clean_body from langchain.tools.office365.utils import UTC_FORMAT, clean_body
class SearchEventsInput(BaseModel): class SearchEventsInput(BaseModel):
"""Input for SearchEmails Tool.""" """Input for SearchEmails Tool.
"""From https://learn.microsoft.com/en-us/graph/search-query-parameter""" From https://learn.microsoft.com/en-us/graph/search-query-parameter"""
start_datetime: str = Field( start_datetime: str = Field(
description=( description=(
@ -47,7 +47,7 @@ class SearchEventsInput(BaseModel):
default=True, default=True,
description=( description=(
"Whether the event's body is truncated to meet token number limits. Set to " "Whether the event's body is truncated to meet token number limits. Set to "
"False for searches that will retrieve very few results, otherwise, set to " "False for searches that will retrieve small events, otherwise, set to "
"True." "True."
), ),
) )
@ -82,16 +82,15 @@ class O365SearchEvents(O365BaseTool):
max_results: int = 10, max_results: int = 10,
truncate: bool = True, truncate: bool = True,
run_manager: Optional[CallbackManagerForToolRun] = None, run_manager: Optional[CallbackManagerForToolRun] = None,
truncate_limit: int = 150,
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
TRUNCATE_LIMIT = 150
# Get calendar object # Get calendar object
schedule = self.account.schedule() schedule = self.account.schedule()
calendar = schedule.get_default_calendar() calendar = schedule.get_default_calendar()
# Process the date range parameters # Process the date range parameters
start_datetime_query = dt.strptime(start_datetime, "%Y-%m-%dT%H:%M:%S%z") start_datetime_query = dt.strptime(start_datetime, UTC_FORMAT)
end_datetime_query = dt.strptime(end_datetime, "%Y-%m-%dT%H:%M:%S%z") end_datetime_query = dt.strptime(end_datetime, UTC_FORMAT)
# Run the query # Run the query
q = calendar.new_query("start").greater_equal(start_datetime_query) q = calendar.new_query("start").greater_equal(start_datetime_query)
@ -107,7 +106,7 @@ class O365SearchEvents(O365BaseTool):
output_event["subject"] = event.subject output_event["subject"] = event.subject
if truncate: if truncate:
output_event["body"] = clean_body(event.body)[:TRUNCATE_LIMIT] output_event["body"] = clean_body(event.body)[:truncate_limit]
else: else:
output_event["body"] = clean_body(event.body) output_event["body"] = clean_body(event.body)
@ -115,14 +114,14 @@ class O365SearchEvents(O365BaseTool):
time_zone = start_datetime_query.tzinfo time_zone = start_datetime_query.tzinfo
# Assign the datetimes in the search time zone # Assign the datetimes in the search time zone
output_event["start_datetime"] = event.start.astimezone(time_zone).strftime( output_event["start_datetime"] = event.start.astimezone(time_zone).strftime(
"%Y-%m-%dT%H:%M:%S%z" UTC_FORMAT
) )
output_event["end_datetime"] = event.end.astimezone(time_zone).strftime( output_event["end_datetime"] = event.end.astimezone(time_zone).strftime(
"%Y-%m-%dT%H:%M:%S%z" UTC_FORMAT
) )
output_event["modified_date"] = event.modified.astimezone( output_event["modified_date"] = event.modified.astimezone(
time_zone time_zone
).strftime("%Y-%m-%dT%H:%M:%S%z") ).strftime(UTC_FORMAT)
output_events.append(output_event) output_events.append(output_event)

View File

@ -10,7 +10,7 @@ from langchain_core.pydantic_v1 import BaseModel, Extra, Field
from langchain.callbacks.manager import CallbackManagerForToolRun from langchain.callbacks.manager import CallbackManagerForToolRun
from langchain.tools.office365.base import O365BaseTool from langchain.tools.office365.base import O365BaseTool
from langchain.tools.office365.utils import clean_body from langchain.tools.office365.utils import UTC_FORMAT, clean_body
class SearchEmailsInput(BaseModel): class SearchEmailsInput(BaseModel):
@ -46,7 +46,7 @@ class SearchEmailsInput(BaseModel):
default=True, default=True,
description=( description=(
"Whether the email body is truncated to meet token number limits. Set to " "Whether the email body is truncated to meet token number limits. Set to "
"False for searches that will retrieve very few results, otherwise, set to " "False for searches that will retrieve small messages, otherwise, set to "
"True" "True"
), ),
) )
@ -78,6 +78,7 @@ class O365SearchEmails(O365BaseTool):
max_results: int = 10, max_results: int = 10,
truncate: bool = True, truncate: bool = True,
run_manager: Optional[CallbackManagerForToolRun] = None, run_manager: Optional[CallbackManagerForToolRun] = None,
truncate_limit: int = 150,
) -> List[Dict[str, Any]]: ) -> List[Dict[str, Any]]:
# Get mailbox object # Get mailbox object
mailbox = self.account.mailbox() mailbox = self.account.mailbox()
@ -97,13 +98,13 @@ class O365SearchEmails(O365BaseTool):
output_message["from"] = message.sender output_message["from"] = message.sender
if truncate: if truncate:
output_message["body"] = message.body_preview output_message["body"] = message.body_preview[:truncate_limit]
else: else:
output_message["body"] = clean_body(message.body) output_message["body"] = clean_body(message.body)
output_message["subject"] = message.subject output_message["subject"] = message.subject
output_message["date"] = message.modified.strftime("%Y-%m-%dT%H:%M:%S%z") output_message["date"] = message.modified.strftime(UTC_FORMAT)
output_message["to"] = [] output_message["to"] = []
for recipient in message.to._recipients: for recipient in message.to._recipients:

View File

@ -11,6 +11,7 @@ from langchain_core.pydantic_v1 import BaseModel, Field
from langchain.callbacks.manager import CallbackManagerForToolRun from langchain.callbacks.manager import CallbackManagerForToolRun
from langchain.tools.office365.base import O365BaseTool from langchain.tools.office365.base import O365BaseTool
from langchain.tools.office365.utils import UTC_FORMAT
class SendEventSchema(BaseModel): class SendEventSchema(BaseModel):
@ -72,8 +73,8 @@ class O365SendEvent(O365BaseTool):
event.body = body event.body = body
event.subject = subject event.subject = subject
event.start = dt.strptime(start_datetime, "%Y-%m-%dT%H:%M:%S%z") event.start = dt.strptime(start_datetime, UTC_FORMAT)
event.end = dt.strptime(end_datetime, "%Y-%m-%dT%H:%M:%S%z") event.end = dt.strptime(end_datetime, UTC_FORMAT)
for attendee in attendees: for attendee in attendees:
event.attendees.add(attendee) event.attendees.add(attendee)

View File

@ -60,7 +60,7 @@ class O365SendMessage(O365BaseTool):
if cc is not None: if cc is not None:
message.cc.add(cc) message.cc.add(cc)
if bcc is not None: if bcc is not None:
message.bcc.add(cc) message.bcc.add(bcc)
message.send() message.send()

View File

@ -72,3 +72,7 @@ def authenticate() -> Account:
return account return account
else: else:
return account return account
UTC_FORMAT = "%Y-%m-%dT%H:%M:%S%z"
"""UTC format for datetime objects."""