mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-07-02 22:01:05 +02:00
add notion tools for create/update/delete pages
This commit is contained in:
parent
c492505876
commit
8649ca7ac0
6 changed files with 368 additions and 42 deletions
|
|
@ -1,38 +0,0 @@
|
||||||
import hashlib
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from langchain_core.tools import tool
|
|
||||||
|
|
||||||
|
|
||||||
def create_create_notion_page_tool():
|
|
||||||
@tool
|
|
||||||
async def create_notion_page(
|
|
||||||
title: str,
|
|
||||||
content: str,
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
"""Create a new page in Notion with the given title and content.
|
|
||||||
|
|
||||||
Use this tool when the user asks you to create, save, or publish
|
|
||||||
something to Notion. The page will be created in the user's
|
|
||||||
configured Notion workspace.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
title: The title of the Notion page.
|
|
||||||
content: The markdown content for the page body.
|
|
||||||
"""
|
|
||||||
# Generate a unique page ID based on title for testing
|
|
||||||
# This helps verify if edited args were used
|
|
||||||
page_hash = hashlib.md5(title.encode()).hexdigest()[:8]
|
|
||||||
|
|
||||||
# Return detailed response showing what was actually received
|
|
||||||
return {
|
|
||||||
"status": "success",
|
|
||||||
"page_id": f"stub-page-{page_hash}",
|
|
||||||
"title": title,
|
|
||||||
"content_preview": content[:100] + "..." if len(content) > 100 else content,
|
|
||||||
"content_length": len(content),
|
|
||||||
"url": f"https://www.notion.so/stub-page-{page_hash}",
|
|
||||||
"message": f"✅ Created Notion page '{title}' with {len(content)} characters",
|
|
||||||
}
|
|
||||||
|
|
||||||
return create_notion_page
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
"""Notion tools for creating, updating, and deleting pages."""
|
||||||
|
|
||||||
|
from .create_page import create_create_notion_page_tool
|
||||||
|
from .delete_page import create_delete_notion_page_tool
|
||||||
|
from .update_page import create_update_notion_page_tool
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"create_create_notion_page_tool",
|
||||||
|
"create_update_notion_page_tool",
|
||||||
|
"create_delete_notion_page_tool",
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,110 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from langchain_core.tools import tool
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.connectors.notion_history import NotionHistoryConnector
|
||||||
|
|
||||||
|
|
||||||
|
def create_create_notion_page_tool(
|
||||||
|
db_session: AsyncSession | None = None,
|
||||||
|
search_space_id: int | None = None,
|
||||||
|
connector_id: int | None = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Factory function to create the create_notion_page tool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_session: Database session for accessing Notion connector
|
||||||
|
search_space_id: Search space ID to find the Notion connector
|
||||||
|
connector_id: Optional specific connector ID (if known)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Configured create_notion_page tool
|
||||||
|
"""
|
||||||
|
|
||||||
|
@tool
|
||||||
|
async def create_notion_page(
|
||||||
|
title: str,
|
||||||
|
content: str,
|
||||||
|
parent_page_id: str | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Create a new page in Notion with the given title and content.
|
||||||
|
|
||||||
|
Use this tool when the user asks you to create, save, or publish
|
||||||
|
something to Notion. The page will be created in the user's
|
||||||
|
configured Notion workspace.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
title: The title of the Notion page.
|
||||||
|
content: The markdown content for the page body (supports headings, lists, paragraphs).
|
||||||
|
parent_page_id: Optional parent page ID to create as a subpage.
|
||||||
|
If not provided, will ask for one.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary with:
|
||||||
|
- status: "success" or "error"
|
||||||
|
- page_id: Created page ID
|
||||||
|
- url: URL to the created page
|
||||||
|
- title: Page title
|
||||||
|
- message: Success or error message
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "Create a Notion page titled 'Meeting Notes' with content 'Discussed project timeline'"
|
||||||
|
- "Save this to Notion with title 'Research Summary'"
|
||||||
|
"""
|
||||||
|
if db_session is None or search_space_id is None:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "Notion tool not properly configured. Please contact support.",
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get connector ID if not provided
|
||||||
|
if connector_id is None:
|
||||||
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||||
|
|
||||||
|
result = await db_session.execute(
|
||||||
|
select(SearchSourceConnector).filter(
|
||||||
|
SearchSourceConnector.search_space_id == search_space_id,
|
||||||
|
SearchSourceConnector.connector_type
|
||||||
|
== SearchSourceConnectorType.NOTION_CONNECTOR,
|
||||||
|
SearchSourceConnector.is_enabled == True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
connector = result.scalars().first()
|
||||||
|
|
||||||
|
if not connector:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "No Notion connector found. Please connect Notion in your workspace settings.",
|
||||||
|
}
|
||||||
|
|
||||||
|
connector_id = connector.id
|
||||||
|
|
||||||
|
# Create connector instance
|
||||||
|
notion_connector = NotionHistoryConnector(
|
||||||
|
session=db_session,
|
||||||
|
connector_id=connector_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create the page
|
||||||
|
result = await notion_connector.create_page(
|
||||||
|
title=title, content=content, parent_page_id=parent_page_id
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": str(e),
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": f"Unexpected error creating Notion page: {str(e)}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return create_notion_page
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from langchain_core.tools import tool
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.connectors.notion_history import NotionHistoryConnector
|
||||||
|
|
||||||
|
|
||||||
|
def create_delete_notion_page_tool(
|
||||||
|
db_session: AsyncSession | None = None,
|
||||||
|
search_space_id: int | None = None,
|
||||||
|
connector_id: int | None = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Factory function to create the delete_notion_page tool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_session: Database session for accessing Notion connector
|
||||||
|
search_space_id: Search space ID to find the Notion connector
|
||||||
|
connector_id: Optional specific connector ID (if known)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Configured delete_notion_page tool
|
||||||
|
"""
|
||||||
|
|
||||||
|
@tool
|
||||||
|
async def delete_notion_page(
|
||||||
|
page_id: str,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Delete (archive) a Notion page.
|
||||||
|
|
||||||
|
Use this tool when the user asks you to delete, remove, or archive
|
||||||
|
a Notion page. Note that Notion doesn't permanently delete pages,
|
||||||
|
it archives them (they can be restored from trash).
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page_id: The ID of the Notion page to delete (required).
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary with:
|
||||||
|
- status: "success" or "error"
|
||||||
|
- page_id: Deleted page ID
|
||||||
|
- message: Success or error message
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "Delete the Notion page abc123"
|
||||||
|
- "Remove the page xyz789 from Notion"
|
||||||
|
- "Archive this Notion page: abc123"
|
||||||
|
"""
|
||||||
|
if db_session is None or search_space_id is None:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "Notion tool not properly configured. Please contact support.",
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get connector ID if not provided
|
||||||
|
if connector_id is None:
|
||||||
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||||
|
|
||||||
|
result = await db_session.execute(
|
||||||
|
select(SearchSourceConnector).filter(
|
||||||
|
SearchSourceConnector.search_space_id == search_space_id,
|
||||||
|
SearchSourceConnector.connector_type
|
||||||
|
== SearchSourceConnectorType.NOTION_CONNECTOR,
|
||||||
|
SearchSourceConnector.is_enabled == True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
connector = result.scalars().first()
|
||||||
|
|
||||||
|
if not connector:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "No Notion connector found. Please connect Notion in your workspace settings.",
|
||||||
|
}
|
||||||
|
|
||||||
|
connector_id = connector.id
|
||||||
|
|
||||||
|
# Create connector instance
|
||||||
|
notion_connector = NotionHistoryConnector(
|
||||||
|
session=db_session,
|
||||||
|
connector_id=connector_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Delete the page
|
||||||
|
result = await notion_connector.delete_page(page_id=page_id)
|
||||||
|
return result
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": str(e),
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": f"Unexpected error deleting Notion page: {str(e)}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return delete_notion_page
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from langchain_core.tools import tool
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
|
from app.connectors.notion_history import NotionHistoryConnector
|
||||||
|
|
||||||
|
|
||||||
|
def create_update_notion_page_tool(
|
||||||
|
db_session: AsyncSession | None = None,
|
||||||
|
search_space_id: int | None = None,
|
||||||
|
connector_id: int | None = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Factory function to create the update_notion_page tool.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
db_session: Database session for accessing Notion connector
|
||||||
|
search_space_id: Search space ID to find the Notion connector
|
||||||
|
connector_id: Optional specific connector ID (if known)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Configured update_notion_page tool
|
||||||
|
"""
|
||||||
|
|
||||||
|
@tool
|
||||||
|
async def update_notion_page(
|
||||||
|
page_id: str,
|
||||||
|
title: str | None = None,
|
||||||
|
content: str | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Update an existing Notion page's title and/or content.
|
||||||
|
|
||||||
|
Use this tool when the user asks you to modify, edit, or update
|
||||||
|
a Notion page. At least one of title or content must be provided.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
page_id: The ID of the Notion page to update (required).
|
||||||
|
title: New title for the page (optional).
|
||||||
|
content: New markdown content for the page body (optional).
|
||||||
|
If provided, replaces all existing content.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Dictionary with:
|
||||||
|
- status: "success" or "error"
|
||||||
|
- page_id: Updated page ID
|
||||||
|
- url: URL to the updated page
|
||||||
|
- title: Current page title
|
||||||
|
- message: Success or error message
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
- "Update the Notion page abc123 with title 'Updated Meeting Notes'"
|
||||||
|
- "Change the content of page xyz789 to 'New content here'"
|
||||||
|
- "Update page abc123 with new title 'Final Report' and content '# Summary...'"
|
||||||
|
"""
|
||||||
|
if db_session is None or search_space_id is None:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "Notion tool not properly configured. Please contact support.",
|
||||||
|
}
|
||||||
|
|
||||||
|
if not title and not content:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "At least one of 'title' or 'content' must be provided to update the page.",
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Get connector ID if not provided
|
||||||
|
if connector_id is None:
|
||||||
|
from sqlalchemy.future import select
|
||||||
|
|
||||||
|
from app.db import SearchSourceConnector, SearchSourceConnectorType
|
||||||
|
|
||||||
|
result = await db_session.execute(
|
||||||
|
select(SearchSourceConnector).filter(
|
||||||
|
SearchSourceConnector.search_space_id == search_space_id,
|
||||||
|
SearchSourceConnector.connector_type
|
||||||
|
== SearchSourceConnectorType.NOTION_CONNECTOR,
|
||||||
|
SearchSourceConnector.is_enabled == True,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
connector = result.scalars().first()
|
||||||
|
|
||||||
|
if not connector:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": "No Notion connector found. Please connect Notion in your workspace settings.",
|
||||||
|
}
|
||||||
|
|
||||||
|
connector_id = connector.id
|
||||||
|
|
||||||
|
# Create connector instance
|
||||||
|
notion_connector = NotionHistoryConnector(
|
||||||
|
session=db_session,
|
||||||
|
connector_id=connector_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Update the page
|
||||||
|
result = await notion_connector.update_page(
|
||||||
|
page_id=page_id, title=title, content=content
|
||||||
|
)
|
||||||
|
return result
|
||||||
|
|
||||||
|
except ValueError as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": str(e),
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return {
|
||||||
|
"status": "error",
|
||||||
|
"message": f"Unexpected error updating Notion page: {str(e)}",
|
||||||
|
}
|
||||||
|
|
||||||
|
return update_notion_page
|
||||||
|
|
@ -45,12 +45,16 @@ from langchain_core.tools import BaseTool
|
||||||
|
|
||||||
from app.db import ChatVisibility
|
from app.db import ChatVisibility
|
||||||
|
|
||||||
from .create_notion_page import create_create_notion_page_tool
|
|
||||||
from .display_image import create_display_image_tool
|
from .display_image import create_display_image_tool
|
||||||
from .generate_image import create_generate_image_tool
|
from .generate_image import create_generate_image_tool
|
||||||
from .knowledge_base import create_search_knowledge_base_tool
|
from .knowledge_base import create_search_knowledge_base_tool
|
||||||
from .link_preview import create_link_preview_tool
|
from .link_preview import create_link_preview_tool
|
||||||
from .mcp_tool import load_mcp_tools
|
from .mcp_tool import load_mcp_tools
|
||||||
|
from .notion import (
|
||||||
|
create_create_notion_page_tool,
|
||||||
|
create_delete_notion_page_tool,
|
||||||
|
create_update_notion_page_tool,
|
||||||
|
)
|
||||||
from .podcast import create_generate_podcast_tool
|
from .podcast import create_generate_podcast_tool
|
||||||
from .scrape_webpage import create_scrape_webpage_tool
|
from .scrape_webpage import create_scrape_webpage_tool
|
||||||
from .search_surfsense_docs import create_search_surfsense_docs_tool
|
from .search_surfsense_docs import create_search_surfsense_docs_tool
|
||||||
|
|
@ -201,13 +205,34 @@ BUILTIN_TOOLS: list[ToolDefinition] = [
|
||||||
requires=["user_id", "search_space_id", "db_session", "thread_visibility"],
|
requires=["user_id", "search_space_id", "db_session", "thread_visibility"],
|
||||||
),
|
),
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# ADD YOUR CUSTOM TOOLS BELOW
|
# NOTION TOOLS - create, update, delete pages
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
ToolDefinition(
|
ToolDefinition(
|
||||||
name="create_notion_page",
|
name="create_notion_page",
|
||||||
description="Create a new page in the user's Notion workspace",
|
description="Create a new page in the user's Notion workspace",
|
||||||
factory=lambda deps: create_create_notion_page_tool(),
|
factory=lambda deps: create_create_notion_page_tool(
|
||||||
requires=[],
|
db_session=deps["db_session"],
|
||||||
|
search_space_id=deps["search_space_id"],
|
||||||
|
),
|
||||||
|
requires=["db_session", "search_space_id"],
|
||||||
|
),
|
||||||
|
ToolDefinition(
|
||||||
|
name="update_notion_page",
|
||||||
|
description="Update an existing Notion page's title or content",
|
||||||
|
factory=lambda deps: create_update_notion_page_tool(
|
||||||
|
db_session=deps["db_session"],
|
||||||
|
search_space_id=deps["search_space_id"],
|
||||||
|
),
|
||||||
|
requires=["db_session", "search_space_id"],
|
||||||
|
),
|
||||||
|
ToolDefinition(
|
||||||
|
name="delete_notion_page",
|
||||||
|
description="Delete (archive) a Notion page",
|
||||||
|
factory=lambda deps: create_delete_notion_page_tool(
|
||||||
|
db_session=deps["db_session"],
|
||||||
|
search_space_id=deps["search_space_id"],
|
||||||
|
),
|
||||||
|
requires=["db_session", "search_space_id"],
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue