""" STEW Tool Registry — Full Capability Set Every tool the agent can call, with OpenAI function-calling definitions. """ import json import datetime import requests from config import Config # ════════════════════════════════════════════════════════════════════════════════ # TOOL DEFINITIONS (OpenAI function-calling schema) # ════════════════════════════════════════════════════════════════════════════════ TOOL_DEFINITIONS = [ # ── Utility ──────────────────────────────────────────────────────────── {"type":"function","function":{"name":"get_current_datetime","description":"Returns current UTC date/time.","parameters":{"type":"object","properties":{},"required":[]}}}, # ── Web Research ──────────────────────────────────────────────────────── {"type":"function","function":{"name":"web_search","description":"Search the web for information.","parameters":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}}}, {"type":"function","function":{"name":"browser_fetch","description":"Fetch visible text content of any URL.","parameters":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}, # ── Notion ────────────────────────────────────────────────────────────── {"type":"function","function":{"name":"notion_list_pages","description":"List recent Notion pages.","parameters":{"type":"object","properties":{},"required":[]}}}, {"type":"function","function":{"name":"notion_create_page","description":"Create a Notion page.","parameters":{"type":"object","properties":{"title":{"type":"string"},"content":{"type":"string"}},"required":["title","content"]}}}, # ── Slack ──────────────────────────────────────────────────────────────── {"type":"function","function":{"name":"slack_send_message","description":"Send a Slack message.","parameters":{"type":"object","properties":{"channel":{"type":"string"},"text":{"type":"string"}},"required":["channel","text"]}}}, {"type":"function","function":{"name":"slack_list_channels","description":"List Slack channels.","parameters":{"type":"object","properties":{},"required":[]}}}, # ── Gmail ──────────────────────────────────────────────────────────────── {"type":"function","function":{"name":"gmail_send_email","description":"Send an email via Gmail.","parameters":{"type":"object","properties":{"to":{"type":"string"},"subject":{"type":"string"},"body":{"type":"string"}},"required":["to","subject","body"]}}}, {"type":"function","function":{"name":"gmail_list_inbox","description":"List Gmail inbox emails.","parameters":{"type":"object","properties":{"max_results":{"type":"integer","default":5}},"required":[]}}}, # ── Google Calendar ────────────────────────────────────────────────────── {"type":"function","function":{"name":"calendar_list_events","description":"List upcoming Google Calendar events.","parameters":{"type":"object","properties":{"max_results":{"type":"integer","default":10}},"required":[]}}}, {"type":"function","function":{"name":"calendar_create_event","description":"Create a Google Calendar event.","parameters":{"type":"object","properties":{"title":{"type":"string"},"start":{"type":"string","description":"ISO 8601"},"end":{"type":"string","description":"ISO 8601"},"description":{"type":"string"}},"required":["title","start","end"]}}}, # ── Google Drive ───────────────────────────────────────────────────────── {"type":"function","function":{"name":"drive_list_files","description":"List recent Google Drive files.","parameters":{"type":"object","properties":{},"required":[]}}}, {"type":"function","function":{"name":"drive_search_files","description":"Search files in Google Drive.","parameters":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}}}, # ── Vector Memory ──────────────────────────────────────────────────────── {"type":"function","function":{"name":"memory_store","description":"Save information to long-term vector memory.","parameters":{"type":"object","properties":{"text":{"type":"string"}},"required":["text"]}}}, {"type":"function","function":{"name":"memory_search","description":"Search long-term vector memory semantically.","parameters":{"type":"object","properties":{"query":{"type":"string"}},"required":["query"]}}}, # ── Multi-Agent ────────────────────────────────────────────────────────── {"type":"function","function":{"name":"run_multi_agent","description":"Delegate complex task to specialist sub-agents (researcher, coder, planner, analyst, writer, reviewer).","parameters":{"type":"object","properties":{"task":{"type":"string"},"pipeline":{"type":"array","items":{"type":"string"},"description":"Optional ordered agent roles"}},"required":["task"]}}}, ] # ════════════════════════════════════════════════════════════════════════════════ # IMPLEMENTATIONS # ════════════════════════════════════════════════════════════════════════════════ def get_current_datetime(**_) -> str: return datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S UTC") def web_search(query: str, **_) -> str: try: r = requests.get("https://api.duckduckgo.com/", params={"q": query, "format": "json", "no_html": 1, "skip_disambig": 1}, timeout=8) data = r.json() abstract = data.get("AbstractText", "") related = [t.get("Text", "") for t in data.get("RelatedTopics", [])[:4]] return f"Summary: {abstract}\n\nRelated: {'; '.join(related)}" if abstract else (f"Related: {'; '.join(related)}" if related else "No results.") except Exception as e: return f"Search error: {e}" def browser_fetch(url: str, **_) -> str: try: from integrations.browser import get_browser return get_browser().fetch_sync(url) except Exception as e: return f"Browser error: {e}" def notion_list_pages(**_) -> str: from integrations.notion import NotionIntegration return NotionIntegration().list_pages() def notion_create_page(title: str, content: str, **_) -> str: from integrations.notion import NotionIntegration return NotionIntegration().create_page(title, content) def slack_send_message(channel: str, text: str, **_) -> str: from integrations.slack import SlackIntegration return SlackIntegration().send_message(channel, text) def slack_list_channels(**_) -> str: from integrations.slack import SlackIntegration return SlackIntegration().list_channels() def gmail_send_email(to: str, subject: str, body: str, **_) -> str: from integrations.gmail import GmailIntegration return GmailIntegration().send_email(to, subject, body) def gmail_list_inbox(max_results: int = 5, **_) -> str: from integrations.gmail import GmailIntegration return GmailIntegration().list_inbox(max_results) def calendar_list_events(max_results: int = 10, **_) -> str: from integrations.google_calendar import GoogleCalendarIntegration return GoogleCalendarIntegration().list_events(max_results) def calendar_create_event(title: str, start: str, end: str, description: str = "", **_) -> str: from integrations.google_calendar import GoogleCalendarIntegration return GoogleCalendarIntegration().create_event(title, start, end, description) def drive_list_files(**_) -> str: from integrations.google_drive import GoogleDriveIntegration return GoogleDriveIntegration().list_files() def drive_search_files(query: str, **_) -> str: from integrations.google_drive import GoogleDriveIntegration return GoogleDriveIntegration().search_files(query) def memory_store(text: str, **_) -> str: from vector_memory import get_vector_memory return get_vector_memory().store(text) def memory_search(query: str, **_) -> str: from vector_memory import get_vector_memory return get_vector_memory().search(query) def run_multi_agent(task: str, pipeline: list | None = None, **_) -> str: from multiagent import MultiAgentCoordinator c = MultiAgentCoordinator() return c.run_pipeline(task, pipeline) if pipeline else c.smart_route(task) # ── Dispatcher ───────────────────────────────────────────────────────────────── TOOL_MAP = { "get_current_datetime": get_current_datetime, "web_search": web_search, "browser_fetch": browser_fetch, "notion_list_pages": notion_list_pages, "notion_create_page": notion_create_page, "slack_send_message": slack_send_message, "slack_list_channels": slack_list_channels, "gmail_send_email": gmail_send_email, "gmail_list_inbox": gmail_list_inbox, "calendar_list_events": calendar_list_events, "calendar_create_event": calendar_create_event, "drive_list_files": drive_list_files, "drive_search_files": drive_search_files, "memory_store": memory_store, "memory_search": memory_search, "run_multi_agent": run_multi_agent, } def execute_tool(name: str, arguments) -> str: fn = TOOL_MAP.get(name) if not fn: return f"Unknown tool: {name}" try: args = json.loads(arguments) if isinstance(arguments, str) else arguments return str(fn(**args)) except Exception as e: return f"Tool '{name}' error: {e}"