Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic docs with tutorial #96

Merged
merged 12 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
8 changes: 7 additions & 1 deletion django_ai_assistant/api/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
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
Expand Down Expand Up @@ -63,7 +64,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,
Copy link
Member Author

@fjsj fjsj Jun 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This permission was on examples, but not being used. Added now.

)


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