feat(tools): add read_article tool for fetching full article content
Adds read_article tool definition and execute_tool handler. Uses _fetch_full_article (trafilatura) from rss.py, caps tool output at 40K chars to keep context window manageable. Always registered (not gated on SearXNG). Tests cover success, failure, truncation, empty URL, and history builder replay. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -880,6 +880,28 @@ _IMAGE_TOOLS = [
|
||||
]
|
||||
|
||||
|
||||
_URL_TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "read_article",
|
||||
"description": (
|
||||
"Fetch and read the full text of a web page or article from a URL. "
|
||||
"Use when the user shares a URL and wants you to read it, "
|
||||
"or to get the full content of a linked page. "
|
||||
"Do NOT use search_web for URLs — use this tool instead."
|
||||
),
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"url": {"type": "string", "description": "The URL to fetch and read"}
|
||||
},
|
||||
"required": ["url"],
|
||||
},
|
||||
},
|
||||
}
|
||||
]
|
||||
|
||||
_RAG_TOOLS = [
|
||||
{
|
||||
"type": "function",
|
||||
@@ -1032,6 +1054,7 @@ _ENTITY_TOOLS = [
|
||||
async def get_tools_for_user(user_id: int) -> list[dict]:
|
||||
"""Build the tool list for a user based on their configured integrations."""
|
||||
tools = list(_CORE_TOOLS)
|
||||
tools.extend(_URL_TOOLS)
|
||||
tools.extend(_RAG_TOOLS)
|
||||
tools.extend(_ENTITY_TOOLS)
|
||||
if await is_caldav_configured(user_id):
|
||||
@@ -1768,6 +1791,24 @@ async def execute_tool(
|
||||
"data": {"project": proj.title, "count": len(summary), "milestones": summary},
|
||||
}
|
||||
|
||||
elif tool_name == "read_article":
|
||||
from fabledassistant.services.rss import _fetch_full_article
|
||||
url = arguments.get("url", "").strip()
|
||||
if not url:
|
||||
return {"success": False, "error": "No URL provided"}
|
||||
content = await _fetch_full_article(url)
|
||||
if not content:
|
||||
return {"success": False, "error": f"Could not fetch article content from {url}"}
|
||||
_TOOL_CONTENT_CAP = 40_000
|
||||
truncated = len(content) > _TOOL_CONTENT_CAP
|
||||
return {
|
||||
"success": True,
|
||||
"type": "article_content",
|
||||
"url": url,
|
||||
"content": content[:_TOOL_CONTENT_CAP],
|
||||
"truncated": truncated,
|
||||
}
|
||||
|
||||
elif tool_name == "search_web":
|
||||
from fabledassistant.services.research import _search_searxng
|
||||
query = arguments.get("query", "")
|
||||
|
||||
Reference in New Issue
Block a user