feat: implement re-authentication flow for Linear and Notion HITL connectors and improve their HITL flow and error states

- Added re-authentication endpoints for Linear and Notion connectors to handle expired authentication.
- Enhanced error handling in issue creation, deletion, and update tools to return appropriate authentication error messages.
- Updated UI components to display authentication status and guide users on re-authentication steps.
- Improved account health checks to ensure valid tokens are used for operations.
This commit is contained in:
Anish Sarkar 2026-03-18 14:10:11 +05:30
parent 5fb33b7cff
commit df872e261e
18 changed files with 724 additions and 155 deletions

View file

@ -84,6 +84,15 @@ def create_create_linear_issue_tool(
logger.error(f"Failed to fetch creation context: {context['error']}")
return {"status": "error", "message": context["error"]}
workspaces = context.get("workspaces", [])
if workspaces and all(w.get("auth_expired") for w in workspaces):
logger.warning("All Linear accounts have expired authentication")
return {
"status": "auth_error",
"message": "All connected Linear accounts need re-authentication. Please re-authenticate in your connector settings.",
"connector_type": "linear",
}
logger.info(f"Requesting approval for creating Linear issue: '{title}'")
approval = interrupt(
{

View file

@ -91,6 +91,14 @@ def create_delete_linear_issue_tool(
if "error" in context:
error_msg = context["error"]
if context.get("auth_expired"):
logger.warning(f"Auth expired for delete context: {error_msg}")
return {
"status": "auth_error",
"message": error_msg,
"connector_id": context.get("connector_id"),
"connector_type": "linear",
}
if "not found" in error_msg.lower():
logger.warning(f"Issue not found: {error_msg}")
return {"status": "not_found", "message": error_msg}

View file

@ -103,6 +103,14 @@ def create_update_linear_issue_tool(
if "error" in context:
error_msg = context["error"]
if context.get("auth_expired"):
logger.warning(f"Auth expired for update context: {error_msg}")
return {
"status": "auth_error",
"message": error_msg,
"connector_id": context.get("connector_id"),
"connector_type": "linear",
}
if "not found" in error_msg.lower():
logger.warning(f"Issue not found: {error_msg}")
return {"status": "not_found", "message": error_msg}

View file

@ -89,6 +89,15 @@ def create_create_notion_page_tool(
"message": context["error"],
}
accounts = context.get("accounts", [])
if accounts and all(a.get("auth_expired") for a in accounts):
logger.warning("All Notion accounts have expired authentication")
return {
"status": "auth_error",
"message": "All connected Notion accounts need re-authentication. Please re-authenticate in your connector settings.",
"connector_type": "notion",
}
logger.info(f"Requesting approval for creating Notion page: '{title}'")
approval = interrupt(
{

View file

@ -262,6 +262,16 @@ def create_delete_notion_page_tool(
raise
logger.error(f"Error deleting Notion page: {e}", exc_info=True)
error_str = str(e).lower()
if isinstance(e, NotionAPIError) and (
"401" in error_str or "unauthorized" in error_str
):
return {
"status": "auth_error",
"message": str(e),
"connector_id": connector_id_from_context if "connector_id_from_context" in dir() else None,
"connector_type": "notion",
}
if isinstance(e, ValueError | NotionAPIError):
message = str(e)
else:

View file

@ -264,6 +264,16 @@ def create_update_notion_page_tool(
raise
logger.error(f"Error updating Notion page: {e}", exc_info=True)
error_str = str(e).lower()
if isinstance(e, NotionAPIError) and (
"401" in error_str or "unauthorized" in error_str
):
return {
"status": "auth_error",
"message": str(e),
"connector_id": connector_id_from_context if "connector_id_from_context" in dir() else None,
"connector_type": "notion",
}
if isinstance(e, ValueError | NotionAPIError):
message = str(e)
else: