mirror of
https://github.com/arc53/DocsGPT.git
synced 2026-05-22 13:25:08 +00:00
* feat: postgres tests * feat: mongo cutoff * feat: mongo cutoff * feat: adjust docs and compose files * fix: mini code mongo removals * fix: tests and k8s mongo stuff * feat: test fixes * fix: ruff * fix: vale * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix: mini suggestions * vale lint fix 2 * fix: codeql columns thing * fix: test mongo * fix: tests coverage * feat: better tests 4 * feat: more tests * feat: decent coverage * fix: ruff fixes * fix: remove mongo mock * feat: enhance workflow engine and API routes; add document retrieval and source handling * feat: e2e tests * fix: mcp, mongo and more * fix: mini codeql warning * fix: agent chunk view * fix: mini issues * fix: more pg fixes * feat: postgres prep on start * feat: qa tests * fix: mini improvements * fix: tests --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Siddhant Rai <siddhant.rai.5686@gmail.com>
121 lines
4.6 KiB
Python
121 lines
4.6 KiB
Python
"""Agent management webhook handlers."""
|
|
|
|
import secrets
|
|
|
|
from flask import current_app, jsonify, make_response, request
|
|
from flask_restx import Namespace, Resource
|
|
|
|
from application.api import api
|
|
from application.api.user.base import require_agent
|
|
from application.api.user.tasks import process_agent_webhook
|
|
from application.core.settings import settings
|
|
from application.storage.db.repositories.agents import AgentsRepository
|
|
from application.storage.db.session import db_readonly, db_session
|
|
|
|
|
|
agents_webhooks_ns = Namespace(
|
|
"agents", description="Agent management operations", path="/api"
|
|
)
|
|
|
|
|
|
@agents_webhooks_ns.route("/agent_webhook")
|
|
class AgentWebhook(Resource):
|
|
@api.doc(
|
|
params={"id": "ID of the agent"},
|
|
description="Generate webhook URL for the agent",
|
|
)
|
|
def get(self):
|
|
decoded_token = request.decoded_token
|
|
if not decoded_token:
|
|
return make_response(jsonify({"success": False}), 401)
|
|
user = decoded_token.get("sub")
|
|
agent_id = request.args.get("id")
|
|
if not agent_id:
|
|
return make_response(
|
|
jsonify({"success": False, "message": "ID is required"}), 400
|
|
)
|
|
try:
|
|
with db_readonly() as conn:
|
|
agent = AgentsRepository(conn).get_any(agent_id, user)
|
|
if not agent:
|
|
return make_response(
|
|
jsonify({"success": False, "message": "Agent not found"}), 404
|
|
)
|
|
webhook_token = agent.get("incoming_webhook_token")
|
|
if not webhook_token:
|
|
webhook_token = secrets.token_urlsafe(32)
|
|
with db_session() as conn:
|
|
AgentsRepository(conn).update(
|
|
str(agent["id"]), user,
|
|
{"incoming_webhook_token": webhook_token},
|
|
)
|
|
base_url = settings.API_URL.rstrip("/")
|
|
full_webhook_url = f"{base_url}/api/webhooks/agents/{webhook_token}"
|
|
except Exception as err:
|
|
current_app.logger.error(
|
|
f"Error generating webhook URL: {err}", exc_info=True
|
|
)
|
|
return make_response(
|
|
jsonify({"success": False, "message": "Error generating webhook URL"}),
|
|
400,
|
|
)
|
|
return make_response(
|
|
jsonify({"success": True, "webhook_url": full_webhook_url}), 200
|
|
)
|
|
|
|
|
|
@agents_webhooks_ns.route("/webhooks/agents/<string:webhook_token>")
|
|
class AgentWebhookListener(Resource):
|
|
method_decorators = [require_agent]
|
|
|
|
def _enqueue_webhook_task(self, agent_id_str, payload, source_method):
|
|
if not payload:
|
|
current_app.logger.warning(
|
|
f"Webhook ({source_method}) received for agent {agent_id_str} with empty payload."
|
|
)
|
|
current_app.logger.info(
|
|
f"Incoming {source_method} webhook for agent {agent_id_str}. Enqueuing task with payload: {payload}"
|
|
)
|
|
|
|
try:
|
|
task = process_agent_webhook.delay(
|
|
agent_id=agent_id_str,
|
|
payload=payload,
|
|
)
|
|
current_app.logger.info(
|
|
f"Task {task.id} enqueued for agent {agent_id_str} ({source_method})."
|
|
)
|
|
return make_response(jsonify({"success": True, "task_id": task.id}), 200)
|
|
except Exception as err:
|
|
current_app.logger.error(
|
|
f"Error enqueuing webhook task ({source_method}) for agent {agent_id_str}: {err}",
|
|
exc_info=True,
|
|
)
|
|
return make_response(
|
|
jsonify({"success": False, "message": "Error processing webhook"}), 500
|
|
)
|
|
|
|
@api.doc(
|
|
description="Webhook listener for agent events (POST). Expects JSON payload, which is used to trigger processing.",
|
|
)
|
|
def post(self, webhook_token, agent, agent_id_str):
|
|
payload = request.get_json()
|
|
if payload is None:
|
|
return make_response(
|
|
jsonify(
|
|
{
|
|
"success": False,
|
|
"message": "Invalid or missing JSON data in request body",
|
|
}
|
|
),
|
|
400,
|
|
)
|
|
return self._enqueue_webhook_task(agent_id_str, payload, source_method="POST")
|
|
|
|
@api.doc(
|
|
description="Webhook listener for agent events (GET). Uses URL query parameters as payload to trigger processing.",
|
|
)
|
|
def get(self, webhook_token, agent, agent_id_str):
|
|
payload = request.args.to_dict(flat=True)
|
|
return self._enqueue_webhook_task(agent_id_str, payload, source_method="GET")
|