mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-05 12:13:55 +00:00
The backend import package is now docsgpt, the name it will carry on PyPI; application was far too generic to install into anyone's site-packages. git mv plus a mechanical rewrite of every import, dotted string and path reference: 734 Python files, the compose files, Dockerfile, workflows, docs, setup scripts, devcontainer, k8s manifests, vscode config, pytest and coverage config, .gitignore. Behaviour is unchanged. Kept for one release: - A top-level application package whose meta-path finder resolves application.x.y to the already-imported docsgpt.x.y object, so old imports and entry points (celery -A application.app.celery, uvicorn application.asgi:asgi_app) keep working with a FutureWarning. - Celery registers every application.* task name as an alias of its docsgpt.* task on start-up, so messages queued by the previous release still run. The redbeat key prefix moves to redbeat:docsgpt:v2: so schedule entries the previous release wrote are left unread instead of firing twice. The backend image builds from the repository root (docker build -f docsgpt/Dockerfile .) so it can ship the alias package; a root .dockerignore allow-lists docsgpt/ and application/ and keeps caches, local data, .env files, the sample index files and the Dockerfile out. Compose and the image workflows point at the new context.
137 lines
4.9 KiB
Python
137 lines
4.9 KiB
Python
from docsgpt.agents.tools.base import Tool
|
|
from docsgpt.security.safe_url import UnsafeUserUrlError, pinned_request
|
|
|
|
class NtfyTool(Tool):
|
|
"""
|
|
Ntfy Tool
|
|
A tool for sending notifications to ntfy topics on a specified server.
|
|
"""
|
|
|
|
def __init__(self, config):
|
|
"""
|
|
Initialize the NtfyTool with configuration.
|
|
|
|
Args:
|
|
config (dict): Configuration dictionary containing the access token.
|
|
"""
|
|
self.config = config
|
|
self.token = config.get("token", "")
|
|
|
|
def execute_action(self, action_name, **kwargs):
|
|
"""
|
|
Execute the specified action with given parameters.
|
|
|
|
Args:
|
|
action_name (str): Name of the action to execute.
|
|
**kwargs: Parameters for the action, including server_url.
|
|
|
|
Returns:
|
|
dict: Result of the action with status code and message.
|
|
|
|
Raises:
|
|
ValueError: If the action name is unknown.
|
|
"""
|
|
actions = {
|
|
"ntfy_send_message": self._send_message,
|
|
}
|
|
if action_name in actions:
|
|
return actions[action_name](**kwargs)
|
|
else:
|
|
raise ValueError(f"Unknown action: {action_name}")
|
|
|
|
def _send_message(self, server_url, message, topic, title=None, priority=None):
|
|
"""
|
|
Send a message to an ntfy topic on the specified server.
|
|
|
|
Args:
|
|
server_url (str): Base URL of the ntfy server (e.g., https://ntfy.sh).
|
|
message (str): The message text to send.
|
|
topic (str): The topic to send the message to.
|
|
title (str, optional): Title of the notification.
|
|
priority (int, optional): Priority of the notification (1-5).
|
|
|
|
Returns:
|
|
dict: Response with status code and a confirmation message.
|
|
|
|
Raises:
|
|
ValueError: If priority is not an integer between 1 and 5.
|
|
"""
|
|
url = f"{server_url.rstrip('/')}/{topic}"
|
|
headers = {}
|
|
if title:
|
|
headers["X-Title"] = title
|
|
if priority:
|
|
try:
|
|
priority = int(priority)
|
|
except (ValueError, TypeError):
|
|
raise ValueError("Priority must be convertible to an integer")
|
|
if priority < 1 or priority > 5:
|
|
raise ValueError("Priority must be an integer between 1 and 5")
|
|
headers["X-Priority"] = str(priority)
|
|
if self.token:
|
|
headers["Authorization"] = f"Basic {self.token}"
|
|
data = message.encode("utf-8")
|
|
try:
|
|
response = pinned_request(
|
|
"POST", url, data=data, headers=headers, timeout=100,
|
|
)
|
|
except UnsafeUserUrlError as e:
|
|
return {"status_code": None, "message": f"URL validation error: {e}"}
|
|
return {"status_code": response.status_code, "message": "Message sent"}
|
|
|
|
def get_actions_metadata(self):
|
|
"""
|
|
Provide metadata about available actions.
|
|
|
|
Returns:
|
|
list: List of dictionaries describing each action.
|
|
"""
|
|
return [
|
|
{
|
|
"name": "ntfy_send_message",
|
|
"description": (
|
|
"Send a push notification to an ntfy topic on the "
|
|
"configured server. Provide the message text; title and "
|
|
"priority (1-5) are optional."
|
|
),
|
|
"parameters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"server_url": {
|
|
"type": "string",
|
|
"description": "Base URL of the ntfy server",
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Text to send in the notification",
|
|
},
|
|
"topic": {
|
|
"type": "string",
|
|
"description": "Topic to send the notification to",
|
|
},
|
|
"title": {
|
|
"type": "string",
|
|
"description": "Title of the notification (optional)",
|
|
},
|
|
"priority": {
|
|
"type": "integer",
|
|
"description": "Priority of the notification (1-5, optional)",
|
|
},
|
|
},
|
|
"required": ["server_url", "message", "topic"],
|
|
"additionalProperties": False,
|
|
},
|
|
},
|
|
]
|
|
|
|
def get_config_requirements(self):
|
|
return {
|
|
"token": {
|
|
"type": "string",
|
|
"label": "Access Token",
|
|
"description": "Ntfy access token for authentication",
|
|
"required": True,
|
|
"secret": True,
|
|
"order": 1,
|
|
},
|
|
} |