-
Notifications
You must be signed in to change notification settings - Fork 20
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
Move all examples to a single Django project #77
Changes from 1 commit
bf8a887
848d66f
d80905d
a58108a
02938cf
178580f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,6 @@ | |
from typing import Any, ClassVar, Sequence, cast | ||
|
||
from django.http import HttpRequest | ||
from django.views import View | ||
|
||
from langchain.agents import AgentExecutor | ||
from langchain.agents.format_scratchpad.tools import ( | ||
|
@@ -223,7 +222,7 @@ def get_history_aware_retriever(self) -> Runnable[dict, RetrieverOutput]: | |
def as_chain(self, thread_id: int | None) -> Runnable[dict, dict]: | ||
# Based on: | ||
# - https://python.langchain.com/v0.2/docs/how_to/qa_chat_history_how_to/ | ||
# - https://python.langchain.com/v0.2/docs/how_to/migrate_agent/#memory | ||
# - https://python.langchain.com/v0.2/docs/how_to/migrate_agent/ | ||
# TODO: use langgraph instead? | ||
llm = self.get_llm() | ||
tools = self.get_tools() | ||
|
@@ -312,18 +311,43 @@ def register_assistant(cls: type[AIAssistant]): | |
return cls | ||
|
||
|
||
def _get_assistant_cls( | ||
assistant_id: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
): | ||
if assistant_id not in ASSISTANT_CLS_REGISTRY: | ||
raise AIAssistantNotDefinedError(f"Assistant with id={assistant_id} not found") | ||
assistant_cls = ASSISTANT_CLS_REGISTRY[assistant_id] | ||
if not can_run_assistant( | ||
assistant_cls=assistant_cls, | ||
user=user, | ||
request=request, | ||
): | ||
raise AIUserNotAllowedError("User is not allowed to use this assistant") | ||
return assistant_cls | ||
|
||
|
||
def get_single_assistant_info( | ||
assistant_id: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
): | ||
assistant_cls = _get_assistant_cls(assistant_id, user, request) | ||
|
||
return { | ||
"id": assistant_id, | ||
"name": assistant_cls.name, | ||
} | ||
|
||
|
||
def get_assistants_info( | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
return [ | ||
{ | ||
"id": assistant_id, | ||
"name": assistant_cls.name, | ||
} | ||
for assistant_id, assistant_cls in ASSISTANT_CLS_REGISTRY.items() | ||
if can_run_assistant(assistant_cls=assistant_cls, user=user, request=request, view=view) | ||
_get_assistant_cls(assistant_id=assistant_id, user=user, request=request) | ||
for assistant_id in ASSISTANT_CLS_REGISTRY.keys() | ||
] | ||
|
||
|
||
|
@@ -333,23 +357,14 @@ def create_message( | |
user: Any, | ||
content: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
if not can_create_message(thread=thread, user=user, request=request, view=view): | ||
assistant_cls = _get_assistant_cls(assistant_id, user, request) | ||
|
||
if not can_create_message(thread=thread, user=user, request=request): | ||
raise AIUserNotAllowedError("User is not allowed to create messages in this thread") | ||
if assistant_id not in ASSISTANT_CLS_REGISTRY: | ||
raise AIAssistantNotDefinedError(f"Assistant with id={assistant_id} not found") | ||
assistant_cls = ASSISTANT_CLS_REGISTRY[assistant_id] | ||
if not can_run_assistant( | ||
assistant_cls=assistant_cls, | ||
user=user, | ||
request=request, | ||
view=view, | ||
): | ||
raise AIUserNotAllowedError("User is not allowed to use this assistant") | ||
|
||
# TODO: Check if we can separate the message creation from the chain invoke | ||
assistant = assistant_cls(user=user, request=request, view=view) | ||
assistant = assistant_cls(user=user, request=request) | ||
assistant_message = assistant.invoke( | ||
{"input": content}, | ||
thread_id=thread.id, | ||
|
@@ -361,19 +376,25 @@ def create_thread( | |
name: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
if not can_create_thread(user=user, request=request, view=view): | ||
if not can_create_thread(user=user, request=request): | ||
raise AIUserNotAllowedError("User is not allowed to create threads") | ||
|
||
thread = Thread.objects.create(name=name, created_by=user) | ||
return thread | ||
|
||
|
||
def get_single_thread( | ||
thread_id: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
): | ||
return Thread.objects.filter(created_by=user).get(id=thread_id) | ||
|
||
|
||
def get_threads( | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
return list(Thread.objects.filter(created_by=user)) | ||
|
||
|
@@ -382,9 +403,8 @@ def delete_thread( | |
thread: Thread, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
if not can_delete_thread(thread=thread, user=user, request=request, view=view): | ||
if not can_delete_thread(thread=thread, user=user, request=request): | ||
raise AIUserNotAllowedError("User is not allowed to delete this thread") | ||
|
||
return thread.delete() | ||
|
@@ -394,7 +414,6 @@ def get_thread_messages( | |
thread_id: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
) -> list[BaseMessage]: | ||
# TODO: have more permissions for threads? View thread permission? | ||
thread = Thread.objects.get(id=thread_id) | ||
|
@@ -409,7 +428,6 @@ def create_thread_message_as_user( | |
content: str, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
# TODO: have more permissions for threads? View thread permission? | ||
thread = Thread.objects.get(id=thread_id) | ||
|
@@ -423,9 +441,8 @@ def delete_message( | |
message: Message, | ||
user: Any, | ||
request: HttpRequest | None = None, | ||
view: View | None = None, | ||
): | ||
if not can_delete_message(message=message, user=user, request=request, view=view): | ||
if not can_delete_message(message=message, user=user, request=request): | ||
raise AIUserNotAllowedError("User is not allowed to delete this message") | ||
|
||
return DjangoChatMessageHistory(thread_id=message.thread_id).remove_messages([message.id]) | ||
return DjangoChatMessageHistory(thread_id=message.thread_id).remove_messages([str(message.id)]) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type error. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,73 @@ | ||
import "@mantine/core/styles.css"; | ||
|
||
import { createTheme, MantineProvider } from "@mantine/core"; | ||
import { Chat } from "@/Chat"; | ||
import { Container, createTheme, MantineProvider } from "@mantine/core"; | ||
import { Chat } from "@/components"; | ||
import { createBrowserRouter, Link, RouterProvider } from "react-router-dom"; | ||
import { configAIAssistant } from "django-ai-assistant-client"; | ||
import React from "react"; | ||
fjsj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const theme = createTheme({}); | ||
|
||
// Relates to path("ai-assistant/", include("django_ai_assistant.urls")) | ||
// which can be found at example/demo/urls.py) | ||
configAIAssistant({ baseURL: "ai-assistant" }); | ||
|
||
const ExampleIndex = () => { | ||
return ( | ||
<Container> | ||
<h1>Examples</h1> | ||
<ul> | ||
<li> | ||
<Link to="/weather-chat">Weather Chat</Link> | ||
</li> | ||
<li> | ||
<Link to="/movies-chat">Movie Recommendation Chat</Link> | ||
</li> | ||
<li> | ||
<Link to="/rag-chat">Django Docs RAG Chat</Link> | ||
</li> | ||
<li> | ||
<Link to="/htmx">HTMX demo (no React)</Link> | ||
</li> | ||
</ul> | ||
</Container> | ||
); | ||
}; | ||
fjsj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const Redirect = ({ to }: { to: string }) => { | ||
window.location.href = to; | ||
return null; | ||
}; | ||
|
||
const router = createBrowserRouter([ | ||
{ | ||
path: "/", | ||
element: <ExampleIndex />, | ||
}, | ||
{ | ||
path: "/weather-chat", | ||
element: <Chat assistantId="weather_assistant" />, | ||
}, | ||
{ | ||
path: "/movies-chat", | ||
element: <Chat assistantId="movie_recommendation_assistant" />, | ||
}, | ||
{ | ||
path: "/rag-chat", | ||
element: <Chat assistantId="django_docs_assistant" />, | ||
}, | ||
{ | ||
path: "/htmx", | ||
element: <Redirect to="/htmx/" />, | ||
}, | ||
]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please review. |
||
|
||
const App = () => { | ||
return ( | ||
<MantineProvider theme={theme}> | ||
<Chat /> | ||
<React.StrictMode> | ||
<RouterProvider router={router} /> | ||
</React.StrictMode> | ||
</MantineProvider> | ||
); | ||
}; | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,7 @@ | |
.chat { | ||
height: 100%; | ||
} | ||
|
||
.mdMessage p { | ||
margin: 0; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks better! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll use that in another task to show the assistant proper name in the frontend: #78