diff --git a/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/system_prompt.md b/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/system_prompt.md
index 0289f40e2..60bcff29c 100644
--- a/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/system_prompt.md
+++ b/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/system_prompt.md
@@ -8,6 +8,7 @@ Pull evidence from the live web with the web.* capability verbs and answer the d
- `web_discover` — search the web for a query; returns ranked hits (url, title, snippet, provider).
- `web_scrape` — fetch specific URLs; returns clean page content and metadata per URL.
+- `start_watch` — (only when running inside a chat) keep re-asking a question on a schedule in this chat, so the user gets refreshed answers without asking again. Takes the self-contained question, a cron cadence, and an IANA timezone.
@@ -15,6 +16,7 @@ Pull evidence from the live web with the web.* capability verbs and answer the d
- If it does not, call `web_discover` first, pick the most relevant hits, then `web_scrape` those URLs to read them.
- Batch URLs into a single `web_scrape` call when reading several pages (up to its limit) instead of many one-URL calls.
- For "what changed" / monitoring requests, compare the freshly scraped values against the prior values already present in this conversation's earlier tool results, and report the concrete deltas (added, removed, changed old -> new). Do not claim a change you cannot point to.
+- When the user asks to keep watching / track something on a recurring basis (e.g. "check this daily", "tell me weekly what changed"), first answer now, then call `start_watch` with the self-contained question and the cadence (cron + timezone). Ask for the cadence or timezone only if the user did not imply one.
diff --git a/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/tools/index.py b/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/tools/index.py
index f0b088dc1..98f704755 100644
--- a/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/tools/index.py
+++ b/surfsense_backend/app/agents/chat/multi_agent_chat/subagents/builtins/intelligence_agent/tools/index.py
@@ -11,6 +11,10 @@ from app.capabilities.access.agent import build_capability_tools
from app.capabilities.web.discover.definition import WEB_DISCOVER
from app.capabilities.web.scrape.definition import WEB_SCRAPE
+from .refresh_watch import create_refresh_watch_tool
+from .start_watch import create_start_watch_tool
+from .stop_watch import create_stop_watch_tool
+
NAME = "intelligence_agent"
RULESET = Ruleset(origin=NAME, rules=[])
@@ -22,7 +26,23 @@ def load_tools(
*, dependencies: dict[str, Any] | None = None, **kwargs: Any
) -> list[BaseTool]:
d = {**(dependencies or {}), **kwargs}
- return build_capability_tools(
+ tools: list[BaseTool] = build_capability_tools(
workspace_id=d.get("workspace_id"),
capabilities=_CI_VERBS,
)
+
+ # Watch tools bind a recurring automation to the current chat, so they are
+ # only offered when we have a chat to bind to and auth to manage it.
+ thread_id = d.get("thread_id")
+ auth_context = d.get("auth_context")
+ if thread_id is not None and auth_context is not None:
+ binding = {
+ "workspace_id": d.get("workspace_id"),
+ "thread_id": thread_id,
+ "auth_context": auth_context,
+ }
+ tools.append(create_start_watch_tool(**binding))
+ tools.append(create_stop_watch_tool(**binding))
+ tools.append(create_refresh_watch_tool(**binding))
+
+ return tools