2026-05-06 21:35:57 +05:30
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
from collections.abc import AsyncIterator
|
|
|
|
|
from typing import Any, Self
|
|
|
|
|
|
|
|
|
|
from langchain_core.callbacks import (
|
|
|
|
|
AsyncCallbackManagerForLLMRun,
|
|
|
|
|
CallbackManagerForLLMRun,
|
|
|
|
|
)
|
|
|
|
|
from langchain_core.language_models import BaseChatModel
|
|
|
|
|
from langchain_core.messages import AIMessage, AIMessageChunk, BaseMessage
|
|
|
|
|
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult
|
|
|
|
|
|
|
|
|
|
DRIVE_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_DRIVE_001"
|
2026-05-07 02:52:14 +05:30
|
|
|
GMAIL_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_GMAIL_001"
|
2026-05-07 03:16:02 +05:30
|
|
|
GMAIL_CANARY_SUBJECT = "E2E Canary Email"
|
|
|
|
|
GMAIL_CANARY_MESSAGE_ID = "fake-msg-canary-001"
|
2026-05-07 03:41:47 +05:30
|
|
|
CALENDAR_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_CALENDAR_001"
|
|
|
|
|
CALENDAR_CANARY_SUMMARY = "E2E Canary Calendar Event"
|
2026-05-08 03:48:35 +05:30
|
|
|
ONEDRIVE_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_ONEDRIVE_001"
|
|
|
|
|
ONEDRIVE_CANARY_FILE = "e2e-onedrive-canary.txt"
|
2026-05-08 12:28:26 +05:30
|
|
|
DROPBOX_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_DROPBOX_001"
|
|
|
|
|
DROPBOX_CANARY_FILE = "e2e-dropbox-canary.txt"
|
2026-05-07 22:22:01 +05:30
|
|
|
NOTION_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_NOTION_001"
|
|
|
|
|
NOTION_CANARY_TITLE = "E2E Canary Notion Page"
|
2026-05-08 01:09:49 +05:30
|
|
|
CONFLUENCE_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_CONFLUENCE_001"
|
|
|
|
|
CONFLUENCE_CANARY_TITLE = "E2E Canary Confluence Page"
|
2026-05-07 23:15:37 +05:30
|
|
|
LINEAR_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_LINEAR_001"
|
|
|
|
|
LINEAR_CANARY_TITLE = "E2E Canary Linear Issue"
|
2026-05-08 00:15:18 +05:30
|
|
|
JIRA_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_JIRA_001"
|
|
|
|
|
JIRA_CANARY_SUMMARY = "E2E Canary Jira Issue"
|
|
|
|
|
JIRA_CANARY_KEY = "E2E-101"
|
2026-05-08 03:08:36 +05:30
|
|
|
SLACK_CANARY_TOKEN = "SURFSENSE_E2E_CANARY_TOKEN_SLACK_001"
|
|
|
|
|
SLACK_CANARY_CHANNEL = "slack-e2e-canary"
|
2026-05-06 21:35:57 +05:30
|
|
|
NO_RELEVANT_CONTENT_SENTINEL = "No relevant indexed content found."
|
|
|
|
|
NO_RELEVANT_CONTENT_QUERY = "E2E_NO_RELEVANT_CONTENT_SMOKE"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _content_to_text(content: Any) -> str:
|
|
|
|
|
if isinstance(content, str):
|
|
|
|
|
return content
|
|
|
|
|
if isinstance(content, list):
|
|
|
|
|
return " ".join(_content_to_text(item) for item in content)
|
|
|
|
|
if isinstance(content, dict):
|
|
|
|
|
text = content.get("text") or content.get("content")
|
|
|
|
|
if isinstance(text, str):
|
|
|
|
|
return text
|
|
|
|
|
return json.dumps(content, sort_keys=True)
|
|
|
|
|
if content is None:
|
|
|
|
|
return ""
|
|
|
|
|
return str(content)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _messages_to_text(messages: list[BaseMessage]) -> str:
|
|
|
|
|
return "\n".join(_content_to_text(message.content) for message in messages)
|
|
|
|
|
|
|
|
|
|
|
2026-05-07 02:52:14 +05:30
|
|
|
def _contains_any(text: str, needles: tuple[str, ...]) -> bool:
|
|
|
|
|
lowered = text.lower()
|
|
|
|
|
return any(needle.lower() in lowered for needle in needles)
|
|
|
|
|
|
|
|
|
|
|
2026-05-07 03:16:02 +05:30
|
|
|
def _latest_tool_message(messages: list[BaseMessage]) -> BaseMessage | None:
|
2026-05-07 22:22:01 +05:30
|
|
|
return next(
|
|
|
|
|
(message for message in reversed(messages) if message.type == "tool"), None
|
|
|
|
|
)
|
2026-05-07 03:16:02 +05:30
|
|
|
|
|
|
|
|
|
2026-05-06 21:35:57 +05:30
|
|
|
class FakeChatLLM(BaseChatModel):
|
|
|
|
|
@property
|
|
|
|
|
def _llm_type(self) -> str:
|
|
|
|
|
return "e2e-fake-chat"
|
|
|
|
|
|
|
|
|
|
def bind_tools(self, tools: Any, **kwargs: Any) -> Self:
|
|
|
|
|
return self
|
|
|
|
|
|
|
|
|
|
def _response_for(self, messages: list[BaseMessage]) -> str:
|
|
|
|
|
latest_human = next(
|
|
|
|
|
(
|
|
|
|
|
_content_to_text(message.content)
|
|
|
|
|
for message in reversed(messages)
|
|
|
|
|
if message.type == "human"
|
|
|
|
|
),
|
|
|
|
|
"",
|
|
|
|
|
)
|
|
|
|
|
if NO_RELEVANT_CONTENT_QUERY in latest_human:
|
|
|
|
|
return NO_RELEVANT_CONTENT_SENTINEL
|
|
|
|
|
|
|
|
|
|
prompt_text = _messages_to_text(messages)
|
2026-05-07 03:16:02 +05:30
|
|
|
latest_tool = _latest_tool_message(messages)
|
|
|
|
|
latest_tool_name = getattr(latest_tool, "name", None)
|
|
|
|
|
latest_tool_text = _content_to_text(latest_tool.content) if latest_tool else ""
|
|
|
|
|
|
2026-05-07 22:22:01 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "read_gmail_email"
|
|
|
|
|
and GMAIL_CANARY_TOKEN in latest_tool_text
|
|
|
|
|
):
|
2026-05-07 03:16:02 +05:30
|
|
|
return f"Gmail live tool content found: {GMAIL_CANARY_TOKEN}"
|
2026-05-07 22:22:01 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "search_gmail"
|
|
|
|
|
and GMAIL_CANARY_MESSAGE_ID in latest_tool_text
|
|
|
|
|
):
|
2026-05-07 03:16:02 +05:30
|
|
|
return "Reading the matching Gmail message next."
|
2026-05-07 03:41:47 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "search_calendar_events"
|
|
|
|
|
and CALENDAR_CANARY_TOKEN in latest_tool_text
|
|
|
|
|
):
|
|
|
|
|
return f"Calendar live tool content found: {CALENDAR_CANARY_TOKEN}"
|
2026-05-07 23:15:37 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "list_issues"
|
|
|
|
|
and LINEAR_CANARY_TOKEN in latest_tool_text
|
|
|
|
|
):
|
|
|
|
|
return f"Linear live tool content found: {LINEAR_CANARY_TOKEN}"
|
2026-05-08 00:15:18 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "searchJiraIssuesUsingJql"
|
|
|
|
|
and JIRA_CANARY_TOKEN in latest_tool_text
|
|
|
|
|
):
|
|
|
|
|
return f"Jira live tool content found: {JIRA_CANARY_TOKEN}"
|
2026-05-08 03:08:36 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "slack_search_channels"
|
|
|
|
|
and SLACK_CANARY_TOKEN in latest_tool_text
|
|
|
|
|
):
|
|
|
|
|
return f"Slack live tool content found: {SLACK_CANARY_TOKEN}"
|
2026-05-07 03:16:02 +05:30
|
|
|
|
2026-05-07 02:52:14 +05:30
|
|
|
wants_gmail = _contains_any(
|
|
|
|
|
latest_human,
|
2026-05-07 03:16:02 +05:30
|
|
|
("gmail", "email", "message", GMAIL_CANARY_SUBJECT),
|
2026-05-07 02:52:14 +05:30
|
|
|
)
|
2026-05-07 03:41:47 +05:30
|
|
|
wants_calendar = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("calendar", "event", "meeting", CALENDAR_CANARY_SUMMARY),
|
|
|
|
|
)
|
2026-05-07 02:52:14 +05:30
|
|
|
wants_drive = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("drive", "file", "e2e-canary.txt"),
|
|
|
|
|
)
|
2026-05-08 03:48:35 +05:30
|
|
|
wants_onedrive = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("onedrive", ONEDRIVE_CANARY_FILE, ONEDRIVE_CANARY_TOKEN),
|
|
|
|
|
)
|
2026-05-08 12:28:26 +05:30
|
|
|
wants_dropbox = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("dropbox", DROPBOX_CANARY_FILE, DROPBOX_CANARY_TOKEN),
|
|
|
|
|
)
|
2026-05-07 22:22:01 +05:30
|
|
|
wants_notion = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("notion", "page", NOTION_CANARY_TITLE),
|
|
|
|
|
)
|
2026-05-08 01:09:49 +05:30
|
|
|
wants_confluence = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("confluence", CONFLUENCE_CANARY_TITLE),
|
|
|
|
|
)
|
2026-05-07 23:15:37 +05:30
|
|
|
wants_linear = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("linear", "issue", LINEAR_CANARY_TITLE),
|
|
|
|
|
)
|
2026-05-08 00:15:18 +05:30
|
|
|
wants_jira = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
(
|
|
|
|
|
"jira",
|
|
|
|
|
"atlassian",
|
|
|
|
|
JIRA_CANARY_SUMMARY,
|
|
|
|
|
JIRA_CANARY_KEY,
|
|
|
|
|
"surfsense-e2e.atlassian.net",
|
|
|
|
|
"fake-jira-cloud-001",
|
|
|
|
|
),
|
|
|
|
|
)
|
2026-05-08 03:08:36 +05:30
|
|
|
wants_slack = _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("slack", SLACK_CANARY_TOKEN),
|
|
|
|
|
)
|
2026-05-07 02:52:14 +05:30
|
|
|
has_gmail_evidence = (
|
2026-05-07 03:16:02 +05:30
|
|
|
GMAIL_CANARY_SUBJECT in prompt_text
|
|
|
|
|
or GMAIL_CANARY_MESSAGE_ID in prompt_text
|
2026-05-07 02:52:14 +05:30
|
|
|
or GMAIL_CANARY_TOKEN in prompt_text
|
|
|
|
|
)
|
2026-05-07 03:41:47 +05:30
|
|
|
has_calendar_evidence = (
|
2026-05-07 22:22:01 +05:30
|
|
|
CALENDAR_CANARY_SUMMARY in prompt_text
|
|
|
|
|
or CALENDAR_CANARY_TOKEN in prompt_text
|
2026-05-07 03:41:47 +05:30
|
|
|
)
|
2026-05-07 02:52:14 +05:30
|
|
|
has_drive_evidence = (
|
|
|
|
|
"e2e-canary.txt" in prompt_text
|
2026-05-06 21:35:57 +05:30
|
|
|
or "fake-file-canary" in prompt_text
|
|
|
|
|
or DRIVE_CANARY_TOKEN in prompt_text
|
2026-05-07 02:52:14 +05:30
|
|
|
)
|
2026-05-08 03:48:35 +05:30
|
|
|
has_onedrive_evidence = (
|
|
|
|
|
ONEDRIVE_CANARY_FILE in prompt_text
|
|
|
|
|
or "fake-onedrive-canary" in prompt_text
|
|
|
|
|
or ONEDRIVE_CANARY_TOKEN in prompt_text
|
|
|
|
|
)
|
2026-05-08 12:28:26 +05:30
|
|
|
has_dropbox_evidence = (
|
|
|
|
|
DROPBOX_CANARY_FILE in prompt_text
|
|
|
|
|
or "id:fake-dropbox-canary" in prompt_text
|
|
|
|
|
or DROPBOX_CANARY_TOKEN in prompt_text
|
|
|
|
|
)
|
2026-05-07 22:22:01 +05:30
|
|
|
has_notion_evidence = (
|
|
|
|
|
NOTION_CANARY_TITLE in prompt_text or NOTION_CANARY_TOKEN in prompt_text
|
|
|
|
|
)
|
2026-05-08 01:09:49 +05:30
|
|
|
has_confluence_evidence = (
|
|
|
|
|
CONFLUENCE_CANARY_TITLE in prompt_text
|
|
|
|
|
or CONFLUENCE_CANARY_TOKEN in prompt_text
|
|
|
|
|
or "fake-confluence-page-canary-001" in prompt_text
|
|
|
|
|
or "fake-confluence-space-001" in prompt_text
|
|
|
|
|
)
|
2026-05-07 23:15:37 +05:30
|
|
|
has_linear_evidence = (
|
|
|
|
|
LINEAR_CANARY_TITLE in prompt_text
|
|
|
|
|
or LINEAR_CANARY_TOKEN in prompt_text
|
|
|
|
|
or "fake-linear-issue-canary-001" in prompt_text
|
2026-05-08 00:15:18 +05:30
|
|
|
)
|
|
|
|
|
has_jira_evidence = (
|
|
|
|
|
JIRA_CANARY_SUMMARY in prompt_text
|
|
|
|
|
or JIRA_CANARY_TOKEN in prompt_text
|
|
|
|
|
or JIRA_CANARY_KEY in prompt_text
|
|
|
|
|
or "fake-jira-issue-canary-001" in prompt_text
|
|
|
|
|
or "fake-jira-cloud-001" in prompt_text
|
|
|
|
|
or "surfsense-e2e.atlassian.net" in prompt_text
|
2026-05-07 23:15:37 +05:30
|
|
|
)
|
2026-05-08 03:08:36 +05:30
|
|
|
has_slack_evidence = (
|
|
|
|
|
SLACK_CANARY_CHANNEL in prompt_text
|
|
|
|
|
or SLACK_CANARY_TOKEN in prompt_text
|
|
|
|
|
or "C_FAKE_SLACK_CANARY" in prompt_text
|
|
|
|
|
or "T_FAKE_SLACK_TEAM" in prompt_text
|
|
|
|
|
)
|
2026-05-07 02:52:14 +05:30
|
|
|
|
2026-05-08 03:08:36 +05:30
|
|
|
if wants_slack and has_slack_evidence:
|
|
|
|
|
return f"Slack content found: {SLACK_CANARY_TOKEN}"
|
2026-05-08 00:15:18 +05:30
|
|
|
if wants_jira and has_jira_evidence:
|
|
|
|
|
return f"Jira content found: {JIRA_CANARY_TOKEN}"
|
2026-05-07 23:15:37 +05:30
|
|
|
if wants_linear and has_linear_evidence:
|
|
|
|
|
return f"Linear content found: {LINEAR_CANARY_TOKEN}"
|
2026-05-08 01:09:49 +05:30
|
|
|
if wants_confluence and has_confluence_evidence:
|
|
|
|
|
return f"Confluence content found: {CONFLUENCE_CANARY_TOKEN}"
|
2026-05-07 22:22:01 +05:30
|
|
|
if wants_notion and has_notion_evidence:
|
|
|
|
|
return f"Notion content found: {NOTION_CANARY_TOKEN}"
|
2026-05-07 03:41:47 +05:30
|
|
|
if wants_calendar and has_calendar_evidence:
|
|
|
|
|
return f"Calendar content found: {CALENDAR_CANARY_TOKEN}"
|
2026-05-07 02:52:14 +05:30
|
|
|
if wants_gmail and has_gmail_evidence:
|
|
|
|
|
return f"Gmail content found: {GMAIL_CANARY_TOKEN}"
|
2026-05-08 03:48:35 +05:30
|
|
|
if wants_onedrive and has_onedrive_evidence:
|
|
|
|
|
return f"OneDrive content found: {ONEDRIVE_CANARY_TOKEN}"
|
2026-05-08 12:28:26 +05:30
|
|
|
if wants_dropbox and has_dropbox_evidence:
|
|
|
|
|
return f"Dropbox content found: {DROPBOX_CANARY_TOKEN}"
|
2026-05-07 02:52:14 +05:30
|
|
|
if wants_drive and has_drive_evidence:
|
|
|
|
|
return f"Drive content found: {DRIVE_CANARY_TOKEN}"
|
2026-05-07 22:22:01 +05:30
|
|
|
if (
|
|
|
|
|
has_notion_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_jira_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
and not has_linear_evidence
|
2026-05-07 22:22:01 +05:30
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-07 22:22:01 +05:30
|
|
|
):
|
|
|
|
|
return f"Notion content found: {NOTION_CANARY_TOKEN}"
|
2026-05-08 01:09:49 +05:30
|
|
|
if (
|
|
|
|
|
has_confluence_evidence
|
|
|
|
|
and not has_jira_evidence
|
|
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
):
|
|
|
|
|
return f"Confluence content found: {CONFLUENCE_CANARY_TOKEN}"
|
2026-05-08 00:15:18 +05:30
|
|
|
if (
|
|
|
|
|
has_jira_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
):
|
|
|
|
|
return f"Jira content found: {JIRA_CANARY_TOKEN}"
|
2026-05-07 23:15:37 +05:30
|
|
|
if (
|
|
|
|
|
has_linear_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_jira_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
):
|
|
|
|
|
return f"Linear content found: {LINEAR_CANARY_TOKEN}"
|
2026-05-07 22:22:01 +05:30
|
|
|
if (
|
|
|
|
|
has_calendar_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_jira_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
and not has_linear_evidence
|
2026-05-07 22:22:01 +05:30
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-07 22:22:01 +05:30
|
|
|
):
|
2026-05-07 03:41:47 +05:30
|
|
|
return f"Calendar content found: {CALENDAR_CANARY_TOKEN}"
|
2026-05-07 23:15:37 +05:30
|
|
|
if (
|
|
|
|
|
has_gmail_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_jira_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
):
|
2026-05-07 02:52:14 +05:30
|
|
|
return f"Gmail content found: {GMAIL_CANARY_TOKEN}"
|
2026-05-08 03:48:35 +05:30
|
|
|
if (
|
|
|
|
|
has_onedrive_evidence
|
|
|
|
|
and not has_confluence_evidence
|
|
|
|
|
and not has_jira_evidence
|
|
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_slack_evidence
|
|
|
|
|
):
|
|
|
|
|
return f"OneDrive content found: {ONEDRIVE_CANARY_TOKEN}"
|
2026-05-08 12:28:26 +05:30
|
|
|
if (
|
|
|
|
|
has_dropbox_evidence
|
|
|
|
|
and not has_confluence_evidence
|
|
|
|
|
and not has_jira_evidence
|
|
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
|
|
|
|
and not has_onedrive_evidence
|
|
|
|
|
and not has_slack_evidence
|
|
|
|
|
):
|
|
|
|
|
return f"Dropbox content found: {DROPBOX_CANARY_TOKEN}"
|
2026-05-07 23:15:37 +05:30
|
|
|
if (
|
|
|
|
|
has_drive_evidence
|
2026-05-08 01:09:49 +05:30
|
|
|
and not has_confluence_evidence
|
2026-05-08 00:15:18 +05:30
|
|
|
and not has_jira_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_gmail_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
and not has_slack_evidence
|
2026-05-07 23:15:37 +05:30
|
|
|
):
|
2026-05-06 21:35:57 +05:30
|
|
|
return f"Drive content found: {DRIVE_CANARY_TOKEN}"
|
2026-05-08 03:08:36 +05:30
|
|
|
if (
|
|
|
|
|
has_slack_evidence
|
|
|
|
|
and not has_confluence_evidence
|
|
|
|
|
and not has_jira_evidence
|
|
|
|
|
and not has_linear_evidence
|
|
|
|
|
and not has_notion_evidence
|
|
|
|
|
and not has_calendar_evidence
|
|
|
|
|
and not has_gmail_evidence
|
|
|
|
|
and not has_drive_evidence
|
2026-05-08 03:48:35 +05:30
|
|
|
and not has_onedrive_evidence
|
2026-05-08 12:28:26 +05:30
|
|
|
and not has_dropbox_evidence
|
2026-05-08 03:08:36 +05:30
|
|
|
):
|
|
|
|
|
return f"Slack content found: {SLACK_CANARY_TOKEN}"
|
2026-05-06 21:35:57 +05:30
|
|
|
return NO_RELEVANT_CONTENT_SENTINEL
|
|
|
|
|
|
2026-05-07 03:16:02 +05:30
|
|
|
def _tool_call_message_for(self, messages: list[BaseMessage]) -> AIMessage | None:
|
|
|
|
|
latest_human = next(
|
|
|
|
|
(
|
|
|
|
|
_content_to_text(message.content)
|
|
|
|
|
for message in reversed(messages)
|
|
|
|
|
if message.type == "human"
|
|
|
|
|
),
|
|
|
|
|
"",
|
|
|
|
|
)
|
|
|
|
|
latest_tool = _latest_tool_message(messages)
|
|
|
|
|
latest_tool_name = getattr(latest_tool, "name", None)
|
|
|
|
|
latest_tool_text = _content_to_text(latest_tool.content) if latest_tool else ""
|
|
|
|
|
|
2026-05-07 22:22:01 +05:30
|
|
|
if (
|
|
|
|
|
latest_tool_name == "search_gmail"
|
|
|
|
|
and GMAIL_CANARY_MESSAGE_ID in latest_tool_text
|
|
|
|
|
):
|
2026-05-07 03:16:02 +05:30
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "read_gmail_email",
|
|
|
|
|
"args": {"message_id": GMAIL_CANARY_MESSAGE_ID},
|
|
|
|
|
"id": "call_e2e_read_gmail",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if latest_tool is None and _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("gmail", "email", "message", GMAIL_CANARY_SUBJECT),
|
|
|
|
|
):
|
|
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "search_gmail",
|
|
|
|
|
"args": {
|
|
|
|
|
"query": f"subject:{GMAIL_CANARY_SUBJECT}",
|
|
|
|
|
"max_results": 5,
|
|
|
|
|
},
|
|
|
|
|
"id": "call_e2e_search_gmail",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-07 03:41:47 +05:30
|
|
|
if latest_tool is None and _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("calendar", "event", "meeting", CALENDAR_CANARY_SUMMARY),
|
|
|
|
|
):
|
|
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "search_calendar_events",
|
|
|
|
|
"args": {
|
|
|
|
|
"start_date": "2026-05-07",
|
|
|
|
|
"end_date": "2026-05-21",
|
|
|
|
|
"max_results": 10,
|
|
|
|
|
},
|
|
|
|
|
"id": "call_e2e_search_calendar_events",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-08 00:15:18 +05:30
|
|
|
if latest_tool is None and _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
(
|
|
|
|
|
"jira",
|
|
|
|
|
"atlassian",
|
|
|
|
|
JIRA_CANARY_SUMMARY,
|
|
|
|
|
JIRA_CANARY_KEY,
|
|
|
|
|
"surfsense-e2e.atlassian.net",
|
|
|
|
|
"fake-jira-cloud-001",
|
|
|
|
|
),
|
|
|
|
|
):
|
|
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "searchJiraIssuesUsingJql",
|
|
|
|
|
"args": {
|
|
|
|
|
"jql": f'summary ~ "{JIRA_CANARY_SUMMARY}"',
|
|
|
|
|
"maxResults": 5,
|
|
|
|
|
},
|
|
|
|
|
"id": "call_e2e_search_jira_issues",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-07 23:15:37 +05:30
|
|
|
if latest_tool is None and _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("linear", "issue", LINEAR_CANARY_TITLE),
|
|
|
|
|
):
|
|
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "list_issues",
|
|
|
|
|
"args": {"query": LINEAR_CANARY_TITLE, "limit": 5},
|
|
|
|
|
"id": "call_e2e_list_linear_issues",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-08 03:08:36 +05:30
|
|
|
if latest_tool is None and _contains_any(
|
|
|
|
|
latest_human,
|
|
|
|
|
("slack", SLACK_CANARY_TOKEN),
|
|
|
|
|
):
|
|
|
|
|
return AIMessage(
|
|
|
|
|
content="",
|
|
|
|
|
tool_calls=[
|
|
|
|
|
{
|
|
|
|
|
"name": "slack_search_channels",
|
|
|
|
|
"args": {"query": SLACK_CANARY_CHANNEL, "limit": 5},
|
|
|
|
|
"id": "call_e2e_search_slack_channels",
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
|
2026-05-07 03:16:02 +05:30
|
|
|
return None
|
|
|
|
|
|
2026-05-06 21:35:57 +05:30
|
|
|
def _generate(
|
|
|
|
|
self,
|
|
|
|
|
messages: list[BaseMessage],
|
|
|
|
|
stop: list[str] | None = None,
|
|
|
|
|
run_manager: CallbackManagerForLLMRun | None = None,
|
|
|
|
|
**kwargs: Any,
|
|
|
|
|
) -> ChatResult:
|
|
|
|
|
del stop, run_manager, kwargs
|
2026-05-07 03:16:02 +05:30
|
|
|
message = self._tool_call_message_for(messages) or AIMessage(
|
|
|
|
|
content=self._response_for(messages), tool_calls=[]
|
|
|
|
|
)
|
2026-05-06 21:35:57 +05:30
|
|
|
return ChatResult(generations=[ChatGeneration(message=message)])
|
|
|
|
|
|
|
|
|
|
async def _astream(
|
|
|
|
|
self,
|
|
|
|
|
messages: list[BaseMessage],
|
|
|
|
|
stop: list[str] | None = None,
|
|
|
|
|
run_manager: AsyncCallbackManagerForLLMRun | None = None,
|
|
|
|
|
**kwargs: Any,
|
|
|
|
|
) -> AsyncIterator[ChatGenerationChunk]:
|
|
|
|
|
del stop, run_manager, kwargs
|
2026-05-07 03:16:02 +05:30
|
|
|
tool_call_message = self._tool_call_message_for(messages)
|
|
|
|
|
if tool_call_message:
|
|
|
|
|
for tool_call in tool_call_message.tool_calls:
|
|
|
|
|
yield ChatGenerationChunk(
|
|
|
|
|
message=AIMessageChunk(
|
|
|
|
|
content="",
|
|
|
|
|
tool_call_chunks=[
|
|
|
|
|
{
|
|
|
|
|
"name": tool_call["name"],
|
|
|
|
|
"args": json.dumps(tool_call["args"]),
|
|
|
|
|
"id": tool_call["id"],
|
|
|
|
|
"index": 0,
|
|
|
|
|
}
|
|
|
|
|
],
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
return
|
|
|
|
|
|
2026-05-06 21:35:57 +05:30
|
|
|
yield ChatGenerationChunk(
|
|
|
|
|
message=AIMessageChunk(content=self._response_for(messages))
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2026-05-07 22:22:01 +05:30
|
|
|
def fake_create_chat_litellm_from_agent_config(
|
|
|
|
|
*args: Any, **kwargs: Any
|
|
|
|
|
) -> FakeChatLLM:
|
2026-05-06 21:35:57 +05:30
|
|
|
del args, kwargs
|
|
|
|
|
return FakeChatLLM()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def fake_create_chat_litellm_from_config(*args: Any, **kwargs: Any) -> FakeChatLLM:
|
|
|
|
|
del args, kwargs
|
|
|
|
|
return FakeChatLLM()
|