Skip to content

Commit

Permalink
fixes conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
amandasavluchinske committed Jun 19, 2024
2 parents f4fd99b + 84aabec commit 47068ce
Show file tree
Hide file tree
Showing 20 changed files with 1,151 additions and 144 deletions.
1 change: 1 addition & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ indent_size = 2

[*.md]
trim_trailing_whitespace = false
indent_size = 4

[Makefile]
indent_style = tab
18 changes: 16 additions & 2 deletions django_ai_assistant/api/views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import List

from django.http import Http404
from django.shortcuts import get_object_or_404

from langchain_core.messages import message_to_dict
from ninja import NinjaAPI
from ninja.operation import Operation
from ninja.security import django_auth

from django_ai_assistant import package_name, version
from django_ai_assistant.api.schemas import (
Expand All @@ -26,7 +28,14 @@ def get_openapi_operation_id(self, operation: Operation) -> str:
return (package_name + "_" + name).replace(".", "_")


api = API(title=package_name, version=version, urls_namespace="django_ai_assistant")
api = API(
title=package_name,
version=version,
urls_namespace="django_ai_assistant",
# Add auth to all endpoints
auth=django_auth,
csrf=True,
)


@api.exception_handler(AIUserNotAllowedError)
Expand Down Expand Up @@ -63,7 +72,12 @@ def create_thread(request, payload: ThreadSchemaIn):

@api.get("threads/{thread_id}/", response=ThreadSchema, url_name="thread_detail_update_delete")
def get_thread(request, thread_id: str):
thread = use_cases.get_single_thread(thread_id=thread_id, user=request.user, request=request)
try:
thread = use_cases.get_single_thread(
thread_id=thread_id, user=request.user, request=request
)
except Thread.DoesNotExist:
raise Http404("No %s matches the given query." % Thread._meta.object_name) from None
return thread


Expand Down
11 changes: 11 additions & 0 deletions django_ai_assistant/helpers/assistants.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,9 @@ def get_contextualize_prompt(self) -> ChatPromptTemplate:
return ChatPromptTemplate.from_messages(
[
("system", contextualize_q_system_prompt),
# TODO: make history key confirgurable?
MessagesPlaceholder("history"),
# TODO: make input key confirgurable?
("human", "{input}"),
]
)
Expand Down Expand Up @@ -284,6 +286,15 @@ def invoke(self, *args, thread_id: int | None, **kwargs):
chain = self.as_chain(thread_id)
return chain.invoke(*args, **kwargs)

def run(self, message, thread_id: int | None, **kwargs):
return self.invoke(
{
"input": message,
},
thread_id=thread_id,
**kwargs,
)["output"]

def run_as_tool(self, message: str, **kwargs):
chain = self.as_chain(thread_id=None)
output = chain.invoke({"input": message}, **kwargs)
Expand Down
8 changes: 7 additions & 1 deletion django_ai_assistant/helpers/use_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
can_delete_message,
can_delete_thread,
can_run_assistant,
can_view_thread,
)


Expand Down Expand Up @@ -98,7 +99,12 @@ def get_single_thread(
user: Any,
request: HttpRequest | None = None,
):
return Thread.objects.filter(created_by=user).get(id=thread_id)
thread = Thread.objects.get(id=thread_id)

if not can_view_thread(thread=thread, user=user, request=request):
raise AIUserNotAllowedError("User is not allowed to view this thread")

return thread


def get_threads(
Expand Down
14 changes: 14 additions & 0 deletions django_ai_assistant/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ def can_create_thread(
)


def can_view_thread(
thread: Thread,
user: Any,
request: HttpRequest | None = None,
**kwargs,
) -> bool:
return app_settings.call_fn(
"CAN_VIEW_THREAD_FN",
**_get_default_kwargs(user, request),
thread=thread,
**kwargs,
)


def can_update_thread(
thread: Thread,
user: Any,
Expand Down
32 changes: 32 additions & 0 deletions docs/get-started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Get started

## Prerequisites

- Python: <a href="https://pypi.org/project/django-ai-assistant" target="_blank"><img src="https://img.shields.io/pypi/pyversions/django-ai-assistant.svg?color=%2334D058" alt="Supported Python versions"></a>
- Django: <a href="https://pypi.org/project/django-ai-assistant" target="_blank"><img src="https://img.shields.io/pypi/frameworkversions/django/django-ai-assistant.svg" alt="Supported Django versions"></a>

## How to install

Install Django AI Assistant package:

```bash
pip install django-ai-assistant
```

Add Django AI Assistant to your Django project's `INSTALLED_APPS`:

```python title="myproject/settings.py"
INSTALLED_APPS = [
...
'django_ai_assistant',
...
]
```

Run the migrations:

```bash
python manage.py migrate
```

Learn how to use the package in the [Tutorial](tutorial.md) section.
24 changes: 24 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Django AI Assistant

Implement powerful AI Assistants using Django.
Combine the power of Large Language Models with Django's productivity.

Regardless of the feasibility of AGI, AI assistants are (already!) a new paradigm for computation.
AI agents and assistants allow devs to easily build applications with smart decision logic
that would otherwise be too expensive to build and maintain.

The latest LLMs from major AI providers have a "killer feature" called Tool Calling,
which enables AI models to call provided methods from Django's side, and essentially
do anything a Django view can, such as accessing DBs, checking permissions, sending emails,
downloading and uploading media files, etc.

While users commonly interact with LLMs via conversations, AI Assistants can do a lot with any kind of string input, including JSON.
Your application's end users won't even realize that a LLM is doing the heavy-lifting behind the scenes!
Some ideas for innovative AI assistants:

- A movie recommender chatbot that helps users manage their movie backlogs
- An autofill button for certain forms of your application
- Personalized email reminders that consider users' written preferences and the application's recent notifications
- A real-time audio guide for tourists that recommends attractions given the user's current location

We have an open-source example with some of those applications, but it's best to start with the [Get Started](get-started.md) guide.
Loading

0 comments on commit 47068ce

Please sign in to comment.