Files

1 line
137 KiB
JSON
Raw Permalink Normal View History

2025-09-13 12:46:39 -04:00
[{"id":"followup_and_scheduled_tasks_controller","user_id":"b0dbb398-2e9d-406c-af2f-2843a5a83848","name":"Followup and Scheduled Tasks Controller","content":"# all comments are lowercase\nimport os, json, httpx\nfrom typing import Optional, Dict, Any, List\nfrom pydantic import BaseModel, Field\n\n\nclass Tools:\n class Valves(BaseModel):\n API_BASE_URL: str = Field(\n default=\"http://ollama-scheduler:12253\", description=\"the scheduler api url\"\n )\n\n def __init__(self):\n # open webui populates valves for tools ig, so just keep local handle\n self.valves = self.Valves()\n\n # ---------- helpers ----------\n\n @staticmethod\n def _ensure_user_id(__user__: Optional[dict]) -> str:\n uid = (__user__ or {}).get(\"id\")\n if not uid:\n raise ValueError(\"error: no user context available\")\n return str(uid)\n\n @staticmethod\n def _derive_context(\n context: Optional[str], __messages__: Optional[List[dict]]\n ) -> str:\n if context:\n return context\n if __messages__:\n for m in reversed(__messages__):\n if m.get(\"role\") == \"user\":\n return str(m.get(\"content\", \"\"))[:4000] # keep it sane\n return \"\"\n\n @staticmethod\n def _collect_file_urls(__files__: Optional[List[dict]]) -> List[str]:\n urls: List[str] = []\n if __files__:\n for f in __files__:\n u = f.get(\"url\")\n if u:\n urls.append(str(u))\n return urls\n\n def _headers(self, user_id: str) -> Dict[str, str]:\n # every call is scoped to the caller via this header\n return {\"content-type\": \"application/json\", \"x-user-id\": user_id}\n\n # ---------- core calls to your scheduler api ----------\n\n async def list_workflow_templates(self) -> str:\n async with httpx.AsyncClient(timeout=30) as client:\n r = await client.get(f\"{self.valves.API_BASE_URL}/api/workflowtemplates\")\n r.raise_for_status()\n return r.text\n\n async def list_schedules(self, __user__: Optional[dict] = None) -> str:\n user_id = self._ensure_user_id(__user__)\n async with httpx.AsyncClient(timeout=30) as client:\n r = await client.get(\n f\"{self.valves.API_BASE_URL}/api/schedules\",\n headers=self._headers(user_id),\n )\n r.raise_for_status()\n return r.text\n\n async def delete_schedule(self, name: str, __user__: Optional[dict] = None) -> str:\n user_id = self._ensure_user_id(__user__)\n async with httpx.AsyncClient(timeout=30) as client:\n r = await client.delete(\n f\"{self.valves.API_BASE_URL}/schedules/{httpx.QueryParams({'n': name})['n']}\",\n headers=self._headers(user_id),\n )\n # the api returns 204 on success\n if r.status_code not in (200, 202, 204):\n r.raise_for_status()\n return json.dumps({\"ok\": r.status_code in (200, 202, 204)})\n\n async def schedule_job(\n self,\n # schedule identity / timing\n name: str,\n when_iso: Optional[str] = None,\n when_cron: Optional[str] = None,\n tz: str = \"America/New_York\",\n one_shot: bool = False,\n # argo template wiring\n template_name: str = \"\",\n cluster_scope: bool = False,\n entrypoint: Optional[str] = None,\n # content to pass through\n query: Optional[str] = None,\n context: Optional[str] = None,\n extra_parameters: Optional[Dict[str, Any]] = None,\n __user__: Optional[dict] = None,\n __files__: Optional[list] = None,\n __messages__: Optional[list] = None,\n ) -> str:\n user_id = self._ensure_user_id(__user__)\n ctx = self._derive_context(context, __messages__)\n file_urls = self._collect_file_urls(__files__)\n\n params: Dict[str, A