-
Notifications
You must be signed in to change notification settings - Fork 2
fix: Use timezone.utc instead of UTC #6
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
base: main
Are you sure you want to change the base?
Changes from all commits
9ca4ff6
c9facce
6127f02
9a5504c
07ce918
7e3fc4f
e985ce0
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 |
|---|---|---|
|
|
@@ -11,11 +11,16 @@ | |
|
|
||
| class BaseAdapter: | ||
|
|
||
| async def call_copilot(self, name, args={}, default=None): | ||
| return_value = default | ||
| if cl.context.session.client_type == "copilot": | ||
| return_value = await cl.CopilotFunction(name=name, args=args).acall() | ||
| return return_value | ||
| async def call_copilot(self, name: str, fallback = None, **kwargs): | ||
| if cl.context.session.client_type != "copilot": | ||
| return fallback | ||
|
|
||
| try: | ||
| result = await cl.CopilotFunction(name=name, args=kwargs).acall() | ||
| except Exception: | ||
| return fallback | ||
|
|
||
| return fallback if result is None else result | ||
|
|
||
| async def on_chat_start(self): | ||
| pass | ||
|
|
@@ -62,13 +67,15 @@ async def on_chat_start(self): | |
| cl.user_session.set("project_id", project_id) | ||
|
|
||
| # get lang_code from the copilot and store it in the session | ||
| lang_code = await self.call_copilot("getLangCode", default="en") | ||
| lang_code = await self.call_copilot("getLangCode", fallback="en") | ||
| cl.user_session.set("lang_code", lang_code) | ||
|
|
||
| # check if we have a history, yet | ||
| if store.has_history(user.identifier, project_id): | ||
| content = getattr(config, f"CONTINUATION_{lang_code.upper()}", "") | ||
| await cl.Message(content=content).send() | ||
| history = store.get_history(user.identifier, project_id) | ||
|
Member
Author
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. I've added here the chat history to the messages below this continuation message. Added it as a feature here but would make sense right? |
||
| await self.send_history(history, user) | ||
| else: | ||
| # if the history is empty, display the confirmation message | ||
| content = getattr(config, f"CONFIRMATION_{lang_code.upper()}", "") | ||
|
|
@@ -93,7 +100,8 @@ async def on_user_message(self, message): | |
| user = cl.user_session.get("user") | ||
|
|
||
| # get the full project from the copilot | ||
| project = await self.call_copilot("getProject", default={}) | ||
| project = await self.call_copilot("getProject") | ||
| project = project if isinstance(project, dict) else {} | ||
| project_id = project.get("id") | ||
|
|
||
| # get the history from the store | ||
|
|
@@ -141,6 +149,19 @@ async def on_user_message(self, message): | |
|
|
||
| return response_message | ||
|
|
||
| async def send_history(self, history, user): | ||
| assistant_name = getattr(config, "ASSISTANT_NAME", "Assistant") | ||
|
|
||
| for message in history: | ||
| if isinstance(message, HumanMessage): | ||
| author = user.display_name or "You" | ||
| elif isinstance(message, AIMessage): | ||
| author = assistant_name | ||
| else: | ||
| continue | ||
|
|
||
| await cl.Message(content=message.content, author=author).send() | ||
|
|
||
| async def on_system_message(self, message): | ||
| try: | ||
| action = message.metadata.get("action") | ||
|
|
@@ -153,7 +174,7 @@ async def on_system_message(self, message): | |
| store.reset_history(user.identifier, project_id) | ||
|
|
||
| async def on_transfer(self, action): | ||
| await self.call_copilot("handleTransfer", args=action.payload) | ||
| await self.call_copilot("handleTransfer", **action.payload) | ||
|
|
||
| async def on_contact(self, action): | ||
| # get user and project_id from the session | ||
|
|
@@ -163,9 +184,7 @@ async def on_contact(self, action): | |
| # get the history from the store | ||
| history = store.get_history(user.identifier, project_id) | ||
|
|
||
| await self.call_copilot("openContactModal", args={ | ||
| "history": messages_to_dicts(history) | ||
| }) | ||
| await self.call_copilot("openContactModal", history=messages_to_dicts(history)) | ||
|
|
||
|
|
||
| class OpenAILangChainAdapter(LangChainAdapter): | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,15 @@ function truncate(string, maxLength = 32) { | |
| return string.length > maxLength ? string.slice(0, maxLength) + '…' : string; | ||
| } | ||
|
|
||
| const getCookie = (name) => { | ||
| return document.cookie | ||
| .split(';') | ||
| .map((cookie) => cookie.trim()) | ||
| .filter((cookie) => cookie.startsWith(`${name}=`)) | ||
| .map((cookie) => decodeURIComponent(cookie.split('=')[1])) | ||
| .shift() | ||
| } | ||
|
|
||
| const getLangCode = async (args) => { | ||
| return language | ||
| } | ||
|
|
@@ -142,22 +151,34 @@ const openContactModal = async (args) => { | |
|
|
||
| const submitButton = contactModal.querySelector('#chatbot-contact-submit') | ||
|
|
||
| $(submitButton).click(async () => { | ||
| const payload = { | ||
| subject: subjectInput.value, | ||
| message: messageInput.value | ||
| } | ||
| $(submitButton).off('click').on('click', async () => { | ||
|
Member
Author
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. the submit button for send email was hanging(didn't do anything) for me at some point. |
||
| submitButton.disabled = true | ||
|
|
||
| await fetch(url, { | ||
| method: 'POST', | ||
| body: JSON.stringify(payload), | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-CSRFToken': Cookies.get('csrftoken') | ||
| try { | ||
| const payload = { | ||
| subject: subjectInput.value, | ||
| message: messageInput.value | ||
| } | ||
|
|
||
| const response = await fetch(url, { | ||
| method: 'POST', | ||
| body: JSON.stringify(payload), | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-CSRFToken': getCookie('csrftoken') | ||
| } | ||
| }) | ||
|
|
||
| if (!response.ok) { | ||
| throw new Error(`Failed to send contact email (${response.status})`) | ||
| } | ||
| }) | ||
|
|
||
| $(contactModal).modal('hide') | ||
| $(contactModal).modal('hide') | ||
| } catch (error) { | ||
| console.error(error) | ||
| } finally { | ||
| submitButton.disabled = false | ||
| } | ||
| }) | ||
|
|
||
| $(contactModal).modal('show') | ||
|
|
@@ -184,41 +205,124 @@ const copilotEventHandler = async (event) => { | |
|
|
||
| window.copilotEventHandler = copilotEventHandler | ||
|
|
||
| document.addEventListener("DOMContentLoaded", () => { | ||
| const observer = new MutationObserver((mutations, obs) => { | ||
| const copilot = document.getElementById("chainlit-copilot") | ||
| const shadow = copilot.shadowRoot | ||
| const observedShadows = new WeakSet() | ||
|
|
||
| const ensureDialogAccessibility = ({ | ||
| container, | ||
| titleText, | ||
| descriptionText, | ||
| titleId, | ||
| descriptionId | ||
| }) => { | ||
| if (!container) { | ||
| return | ||
| } | ||
|
|
||
| const resolvedTitleId = titleId || `${container.id || 'dialog'}-title` | ||
| const resolvedDescriptionId = | ||
| descriptionId || `${container.id || 'dialog'}-description` | ||
|
|
||
| if (!container.querySelector(`#${resolvedTitleId}`)) { | ||
| const dialogTitle = document.createElement('h2') | ||
| dialogTitle.id = resolvedTitleId | ||
| dialogTitle.setAttribute('data-radix-dialog-title', '') | ||
| dialogTitle.textContent = titleText | ||
| dialogTitle.classList.add('sr-only') | ||
|
|
||
| const modal = shadow.getElementById("new-chat-dialog") | ||
| const confirmButton = shadow.getElementById("confirm") | ||
| container.prepend(dialogTitle) | ||
| } | ||
|
|
||
| if (!container.getAttribute('aria-labelledby')) { | ||
| container.setAttribute('aria-labelledby', resolvedTitleId) | ||
| } | ||
|
|
||
| if (descriptionText) { | ||
| if (!container.querySelector(`#${resolvedDescriptionId}`)) { | ||
| const dialogDescription = document.createElement('p') | ||
| dialogDescription.id = resolvedDescriptionId | ||
| dialogDescription.textContent = descriptionText | ||
| dialogDescription.classList.add('sr-only') | ||
|
|
||
| container.prepend(dialogDescription) | ||
| } | ||
|
|
||
| if (!container.getAttribute('aria-describedby')) { | ||
| container.setAttribute('aria-describedby', resolvedDescriptionId) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (modal && confirmButton && !confirmButton.dataset.hasHandler) { | ||
| const handler = async (event) => { | ||
| event.stopPropagation() | ||
| const patchNewChatDialog = (shadow) => { | ||
| const modal = shadow.getElementById("new-chat-dialog") | ||
| const confirmButton = shadow.getElementById("confirm") | ||
|
|
||
| if (!modal || !confirmButton) { | ||
| return | ||
| } | ||
|
|
||
| const content = modal.matches?.('[data-radix-dialog-content]') | ||
| ? modal | ||
| : modal.querySelector?.('[data-radix-dialog-content]') || modal | ||
|
|
||
| ensureDialogAccessibility({ | ||
| container: content, | ||
| titleText: gettext('Start a new chat'), | ||
| descriptionText: gettext( | ||
| 'This will reset the current conversation and start a new chat.' | ||
| ), | ||
| titleId: 'chainlit-new-chat-title', | ||
| descriptionId: 'chainlit-new-chat-description' | ||
| }) | ||
|
|
||
| if (!confirmButton.dataset.hasHandler) { | ||
| confirmButton.dataset.hasHandler = "true" | ||
|
|
||
| confirmButton.addEventListener( | ||
| "click", | ||
| () => { | ||
| window.sendChainlitMessage({ | ||
| type: "system_message", | ||
| output: "", | ||
| metadata: { | ||
| "action": "reset_history", | ||
| "project": parseInt(projectId) | ||
| action: "reset_history", | ||
| project: projectId | ||
| } | ||
| }) | ||
| }, | ||
| { capture: true } | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| // remove this listener so we don’t fire again | ||
| confirmButton.removeEventListener("click", handler) | ||
| const applyCopilotPatches = () => { | ||
| const copilot = document.getElementById("chainlit-copilot") | ||
| if (!copilot) { | ||
| return | ||
| } | ||
|
|
||
| // trigger the original click (React handles it) | ||
| setTimeout(() => confirmButton.click(), 500) | ||
| const shadow = copilot.shadowRoot | ||
|
|
||
| // mark handler as attached to avoid duplicates | ||
| confirmButton.dataset.hasHandler = "true" | ||
| } | ||
| if (!shadow) { | ||
| return | ||
| } | ||
|
|
||
| // attach the listener | ||
| confirmButton.addEventListener("click", handler) | ||
| } | ||
| }) | ||
| patchNewChatDialog(shadow) | ||
|
|
||
| if (!observedShadows.has(shadow)) { | ||
| const shadowObserver = new MutationObserver(() => { | ||
| patchNewChatDialog(shadow) | ||
| }) | ||
|
|
||
| shadowObserver.observe(shadow, { childList: true, subtree: true }) | ||
| observedShadows.add(shadow) | ||
| } | ||
| } | ||
|
|
||
| document.addEventListener("DOMContentLoaded", () => { | ||
| const observer = new MutationObserver(applyCopilotPatches) | ||
|
|
||
| // Run once in case the widget is already rendered before we start observing. | ||
| applyCopilotPatches() | ||
|
|
||
| observer.observe(document.body, { childList: true, subtree: true }) | ||
| }); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
this returned a
Noneobject at the start of chat or something like that, so thatlang_codewasNone