diff --git a/apiserver/plane/api/urls.py b/apiserver/plane/api/urls.py index 8848c2822..8c91fefa9 100644 --- a/apiserver/plane/api/urls.py +++ b/apiserver/plane/api/urls.py @@ -128,6 +128,9 @@ from plane.api.views import ( ImportServiceEndpoint, UpdateServiceImportStatusEndpoint, ## End importer + # Gpt + GPTIntegrationEndpoint, + ## End Gpt ) @@ -1144,4 +1147,11 @@ urlpatterns = [ name="importer", ), ## End Importer + # Gpt + path( + "workspaces//projects//ai-assistant/", + GPTIntegrationEndpoint.as_view(), + name="importer", + ), + ## End Gpt ] diff --git a/apiserver/plane/api/views/__init__.py b/apiserver/plane/api/views/__init__.py index 25c76f380..a14e9236a 100644 --- a/apiserver/plane/api/views/__init__.py +++ b/apiserver/plane/api/views/__init__.py @@ -121,3 +121,6 @@ from .page import ( MyPagesEndpoint, CreatedbyOtherPagesEndpoint, ) + + +from .gpt import GPTIntegrationEndpoint diff --git a/apiserver/plane/api/views/gpt.py b/apiserver/plane/api/views/gpt.py new file mode 100644 index 000000000..6c7b11157 --- /dev/null +++ b/apiserver/plane/api/views/gpt.py @@ -0,0 +1,54 @@ +# Third party imports +from rest_framework.response import Response +from rest_framework import status +import openai +from sentry_sdk import capture_exception + +# Django imports +from django.conf import settings + +# Module imports +from .base import BaseAPIView +from plane.api.permissions import ProjectEntityPermission + + +class GPTIntegrationEndpoint(BaseAPIView): + permission_classes = [ + ProjectEntityPermission, + ] + + def post(self, request, slug, project_id): + try: + if not settings.OPENAI_API_KEY or not settings.GPT_ENGINE: + return Response( + {"error": "OpenAI API key and engine is required"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + prompt = request.data.get("prompt", False) + task = request.data.get("task", False) + + if not prompt or not task: + return Response( + {"error": "Task and prompt are required"}, + status=status.HTTP_400_BAD_REQUEST, + ) + + final_text = task + prompt + + openai.api_key = settings.OPENAI_API_KEY + response = openai.Completion.create( + engine=settings.GPT_ENGINE, + prompt=final_text, + temperature=0.7, + max_tokens=1024, + ) + + text = response.choices[0].text.strip() + return Response({"response": text}, status=status.HTTP_200_OK) + except Exception as e: + capture_exception(e) + return Response( + {"error": "Something went wrong please try again later"}, + status=status.HTTP_400_BAD_REQUEST, + ) diff --git a/apiserver/plane/settings/local.py b/apiserver/plane/settings/local.py index f8839bdb4..6cb9ebcc5 100644 --- a/apiserver/plane/settings/local.py +++ b/apiserver/plane/settings/local.py @@ -81,3 +81,5 @@ PROXY_BASE_URL = os.environ.get("PROXY_BASE_URL", False) ANALYTICS_SECRET_KEY = os.environ.get("ANALYTICS_SECRET_KEY", False) ANALYTICS_BASE_API = os.environ.get("ANALYTICS_BASE_API", False) +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", False) +GPT_ENGINE = os.environ.get("GPT_ENGINE", "text-davinci-003") diff --git a/apiserver/plane/settings/production.py b/apiserver/plane/settings/production.py index 31b5bba89..87d59c049 100644 --- a/apiserver/plane/settings/production.py +++ b/apiserver/plane/settings/production.py @@ -229,3 +229,5 @@ PROXY_BASE_URL = os.environ.get("PROXY_BASE_URL", False) ANALYTICS_SECRET_KEY = os.environ.get("ANALYTICS_SECRET_KEY", False) ANALYTICS_BASE_API = os.environ.get("ANALYTICS_BASE_API", False) +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", False) +GPT_ENGINE = os.environ.get("GPT_ENGINE", "text-davinci-003") diff --git a/apiserver/plane/settings/staging.py b/apiserver/plane/settings/staging.py index 55c50bc6e..48a9702b9 100644 --- a/apiserver/plane/settings/staging.py +++ b/apiserver/plane/settings/staging.py @@ -190,3 +190,5 @@ PROXY_BASE_URL = os.environ.get("PROXY_BASE_URL", False) ANALYTICS_SECRET_KEY = os.environ.get("ANALYTICS_SECRET_KEY", False) ANALYTICS_BASE_API = os.environ.get("ANALYTICS_BASE_API", False) +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY", False) +GPT_ENGINE = os.environ.get("GPT_ENGINE", "text-davinci-003") diff --git a/apiserver/requirements/base.txt b/apiserver/requirements/base.txt index ffe11a234..3c881bb3c 100644 --- a/apiserver/requirements/base.txt +++ b/apiserver/requirements/base.txt @@ -26,4 +26,5 @@ google-api-python-client==2.75.0 django-rq==2.6.0 django-redis==5.2.0 uvicorn==0.20.0 -channels==4.0.0 \ No newline at end of file +channels==4.0.0 +openai==0.27.2 \ No newline at end of file