From 4123060f53489ff0e6bbb52d34c997099e9d0918 Mon Sep 17 00:00:00 2001 From: Mustafa Esoofally Date: Wed, 29 Apr 2026 13:30:15 -0400 Subject: [PATCH 1/2] feat: add Gmail and Calendar context providers Wire up GmailContextProvider and CalendarContextProvider to Scout's context registry. Both auto-enable when OAuth or SA credentials are set. - Gmail requires SA+delegated_user or OAuth - Calendar requires SA (delegation optional) or OAuth - Both use read-only mode by default --- scout/contexts.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/scout/contexts.py b/scout/contexts.py index f7db9db..1b2e3c7 100644 --- a/scout/contexts.py +++ b/scout/contexts.py @@ -13,8 +13,10 @@ from os import getenv from pathlib import Path +from agno.context.calendar import CalendarContextProvider from agno.context.database import DatabaseContextProvider from agno.context.gdrive import GDriveContextProvider +from agno.context.gmail import GmailContextProvider from agno.context.mcp import MCPContextProvider from agno.context.provider import ContextProvider from agno.context.slack import SlackContextProvider @@ -67,7 +69,12 @@ def create_context_providers() -> list[ContextProvider]: _create_knowledge_wiki(), _create_voice_wiki(), ] - for factory in (_create_slack_provider, _create_gdrive_provider): + for factory in ( + _create_slack_provider, + _create_gdrive_provider, + _create_gmail_provider, + _create_calendar_provider, + ): try: provider = factory() except Exception as exc: @@ -248,6 +255,32 @@ def _create_gdrive_provider() -> GDriveContextProvider | None: return GDriveContextProvider(model=default_model()) +def _create_gmail_provider() -> GmailContextProvider | None: + """Gmail context — OAuth or service account with delegation. + + For OAuth: set GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_PROJECT_ID. + For SA: set GOOGLE_SERVICE_ACCOUNT_FILE and GOOGLE_DELEGATED_USER. + """ + has_oauth = getenv("GOOGLE_CLIENT_ID") and getenv("GOOGLE_CLIENT_SECRET") + has_sa = getenv("GOOGLE_SERVICE_ACCOUNT_FILE") and getenv("GOOGLE_DELEGATED_USER") + if not (has_oauth or has_sa): + return None + return GmailContextProvider(model=default_model(), read=True, write=False) + + +def _create_calendar_provider() -> CalendarContextProvider | None: + """Calendar context — OAuth or service account (delegation optional). + + For OAuth: set GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_PROJECT_ID. + For SA: set GOOGLE_SERVICE_ACCOUNT_FILE (GOOGLE_DELEGATED_USER optional). + """ + has_oauth = getenv("GOOGLE_CLIENT_ID") and getenv("GOOGLE_CLIENT_SECRET") + has_sa = getenv("GOOGLE_SERVICE_ACCOUNT_FILE") + if not (has_oauth or has_sa): + return None + return CalendarContextProvider(model=default_model(), read=True, write=False) + + def _create_mcp_providers() -> list[MCPContextProvider]: """Registered MCP servers. From efbca3f7f305f0a4cd410a40384a52c26afcc168 Mon Sep 17 00:00:00 2001 From: Mustafa Esoofally Date: Wed, 29 Apr 2026 13:40:31 -0400 Subject: [PATCH 2/2] feat: enable write for Gmail and Calendar providers --- scout/contexts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scout/contexts.py b/scout/contexts.py index 1b2e3c7..17da9f2 100644 --- a/scout/contexts.py +++ b/scout/contexts.py @@ -265,7 +265,7 @@ def _create_gmail_provider() -> GmailContextProvider | None: has_sa = getenv("GOOGLE_SERVICE_ACCOUNT_FILE") and getenv("GOOGLE_DELEGATED_USER") if not (has_oauth or has_sa): return None - return GmailContextProvider(model=default_model(), read=True, write=False) + return GmailContextProvider(model=default_model(), read=True, write=True) def _create_calendar_provider() -> CalendarContextProvider | None: @@ -278,7 +278,7 @@ def _create_calendar_provider() -> CalendarContextProvider | None: has_sa = getenv("GOOGLE_SERVICE_ACCOUNT_FILE") if not (has_oauth or has_sa): return None - return CalendarContextProvider(model=default_model(), read=True, write=False) + return CalendarContextProvider(model=default_model(), read=True, write=True) def _create_mcp_providers() -> list[MCPContextProvider]: