From ecfa53764e78e14403a426c0509ff9529071eb97 Mon Sep 17 00:00:00 2001 From: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:34:31 -0800 Subject: [PATCH] 0.5.1 (#132) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Tracing (#60) * Tracing to separate conversations * Basic Postgres Connection via Supabase * MVP Postgres Backed Chat Message History * Full binary install or psycopg3 * Use Supabase directly to avoid issues with postgres connections * .env.template update * 0.3.0 Long Term Memory (#62) * Add reply to discord and limit chat history to 10 messages * reverse returned messages and cleanup comments * Update changelog * increase cache limit * Switch to Azure OpenAI * Changelog * fix: update link to more recent blog post * Sanitize thoughts before sending them in the thought's channel (#65) * LayeredLRU Cache (#69) * Make BloomChain a static class * MVP Layered LRU Cache using Postgres * Remove testing variables * Async Mutex Lock on Cache * Stateless bug (#70) * Dynamic model switching * Fix hardcoding and add recovery logic for conversation tables * Add support for multiple conversations * Fix merge errors * Fix merge errors 2 * fix: top_p 0.5 to address gibberish * Custom Web UI (#76) * init nextjs * fast api init * styling and thoughts * streaming updates * connect to api * Add thoughts to the web UI * Refactor input to be a form for UX (e.g. pressing enter sends) * typing and thoughts * Refactor input to be a form for UX (e.g. pressing enter sends) * Revert "Merge remote-tracking branch 'origin/custom-web' into custom-web" This reverts commit 1eae74754fba200ffa883126f18246d9dd642651. * Skeleton Multiple Chat Window UI * MVP Layout * Tested Discord and Skeleton FastAPI * Add, Delete, and Set Conversations * Get and send messages * Edit message names * Local serving from FastAPI via static export * Deployment strategy for static files * Separate out apps * Vercel Deployment with Action * Re-add discord to fly.toml --------- Co-authored-by: hyusap Co-authored-by: Jacob Van Meter * Fix Github Action Workflow * Fix Github Action Workflow * add user prediction function * Honcho Changes (#77) * init nextjs * fast api init * styling and thoughts * streaming updates * connect to api * Add thoughts to the web UI * Refactor input to be a form for UX (e.g. pressing enter sends) * typing and thoughts * Refactor input to be a form for UX (e.g. pressing enter sends) * Revert "Merge remote-tracking branch 'origin/custom-web' into custom-web" This reverts commit 1eae74754fba200ffa883126f18246d9dd642651. * Skeleton Multiple Chat Window UI * MVP Layout * Tested Discord and Skeleton FastAPI * Add, Delete, and Set Conversations * Get and send messages * Edit message names * Local serving from FastAPI via static export * Deployment strategy for static files * Separate out apps * Vercel Deployment with Action * Re-add discord to fly.toml * Honcho Stream * Honcho Stream --------- Co-authored-by: hyusap Co-authored-by: Jacob Van Meter * Social Graph Changes * Authentication Form Styling * Working Auth * Stylistic changes * Address all linting errors * Naive Route Protection * Fly minimum machines * Open Graph Image Changes * Remove anonymous honcho usage, fix opengraph (#80) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * UI tweaks (#81) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * UI tweaks (#82) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * Open Graph, Block chat, delete convo * Sign Up UI * Sign Up UI 2 * Change open graph image * Open Graph Fix * Remove Streamlit * UI tweaks (#84) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * Open Graph, Block chat, delete convo * Sign Up UI * Sign Up UI 2 * Change open graph image * Remove native prompts for sweetalert * Changelog * Remove Honcho for discord * Web fixes (#89) * seperation between sidebar and window + formatting * make app pwa downloadable * move to new chat on button press * remove router * feat: Refactor code to use MarkdownWrapper component - Refactored the code in the `Home` component to replace usages of `ReactMarkdown` and `SyntaxHighlighter` with the new `MarkdownWrapper` component. - Updated the `Home` component to pass the `text` prop to the `MarkdownWrapper` component for each message. - Added a new component `MarkdownWrapper` to handle rendering markdown text with syntax highlighting. - Removed unused imports from the `page.tsx` file, including `ReactMarkdown`, `SyntaxHighlighter`, and `dark` styles. - Also removed unused imports from the `sidebar.tsx` file, including `useState` import. * Optimization (#96) * Usable without honcho and move metadata to creation points * Remove unused psycopg code * Add Sentry instrumentation * Sentry to python * Update env * Optimization (#98) * Usable without honcho and move metadata to creation points * Remove unused psycopg code * Add Sentry instrumentation * Sentry to python * Update env * Sentry & Posthog integration on web * Linting Errors * add latex support and incentive it (#104) * prevent unallowed messages (#111) * implement autoscroll (#112) * implement autoscroll Refactored imports in "page.tsx" to improve readability and maintainability. Updated the type of the "input" ref to be more specific. Added a new state and ref to track the scroll position of the message container. Set up an event listener to update the state when the scroll position changes. Made adjustments to the scroll position in certain event handlers. * update scroll --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * ✨ add multiline support (#118) * ♻️ refactor all of the api stuff (#119) * ♻️ refactor all of the api stuff a redo of the old refactor branch, but cleaner. moved all api calls to api.ts and supabase.ts * Minor Bug Fixes - Add `build-essential` to dockerfile - Fix signin button size - Add await for signout - Force re-render on conversation name change --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * ✨ implement dark mode (#120) automatically check for system mode manual control via animated thingy Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * Documentation (#121) * README update and start of supabase plus making next buildable * Supabase Local Setup and README additions * Update web .env template and note on supabase local auth * Force redirect for unauthenticated and add posthog events (#122) * Update version * Static banner * ✨ caching and skeletons (#127) * Revert "✨ caching and skeletons (#127)" This reverts commit 15e649e624086ff176e5d9ad4fcc6aeb780f61d2. * Http error handling (#129) * upgrade openai and langchain Co-authored-by: Jacob Vanmeter * extend supabase timeout * Handle moderation errors + other streaming errors explicitly * Streaming error handling * ✨ caching and skeletons (#127) * Revert "✨ caching and skeletons (#127)" This reverts commit 15e649e624086ff176e5d9ad4fcc6aeb780f61d2. --------- Co-authored-by: hyusap Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * ✨ caching and skeletons 2 (#130) * ✨ caching and skeletons * 🐛 fix the swr revalidation errors * 💄 fix dark mode typing indicator * Changelogs (#131) * Tutor-GPT 0.5.0 (#124) * Tracing (#60) * Tracing to separate conversations * Basic Postgres Connection via Supabase * MVP Postgres Backed Chat Message History * Full binary install or psycopg3 * Use Supabase directly to avoid issues with postgres connections * .env.template update * 0.3.0 Long Term Memory (#62) * Add reply to discord and limit chat history to 10 messages * reverse returned messages and cleanup comments * Update changelog * increase cache limit * Switch to Azure OpenAI * Changelog * fix: update link to more recent blog post * Sanitize thoughts before sending them in the thought's channel (#65) * LayeredLRU Cache (#69) * Make BloomChain a static class * MVP Layered LRU Cache using Postgres * Remove testing variables * Async Mutex Lock on Cache * Stateless bug (#70) * Dynamic model switching * Fix hardcoding and add recovery logic for conversation tables * Add support for multiple conversations * Fix merge errors * Fix merge errors 2 * fix: top_p 0.5 to address gibberish * Custom Web UI (#76) * init nextjs * fast api init * styling and thoughts * streaming updates * connect to api * Add thoughts to the web UI * Refactor input to be a form for UX (e.g. pressing enter sends) * typing and thoughts * Refactor input to be a form for UX (e.g. pressing enter sends) * Revert "Merge remote-tracking branch 'origin/custom-web' into custom-web" This reverts commit 1eae74754fba200ffa883126f18246d9dd642651. * Skeleton Multiple Chat Window UI * MVP Layout * Tested Discord and Skeleton FastAPI * Add, Delete, and Set Conversations * Get and send messages * Edit message names * Local serving from FastAPI via static export * Deployment strategy for static files * Separate out apps * Vercel Deployment with Action * Re-add discord to fly.toml --------- Co-authored-by: hyusap Co-authored-by: Jacob Van Meter * Fix Github Action Workflow * Fix Github Action Workflow * add user prediction function * Honcho Changes (#77) * init nextjs * fast api init * styling and thoughts * streaming updates * connect to api * Add thoughts to the web UI * Refactor input to be a form for UX (e.g. pressing enter sends) * typing and thoughts * Refactor input to be a form for UX (e.g. pressing enter sends) * Revert "Merge remote-tracking branch 'origin/custom-web' into custom-web" This reverts commit 1eae74754fba200ffa883126f18246d9dd642651. * Skeleton Multiple Chat Window UI * MVP Layout * Tested Discord and Skeleton FastAPI * Add, Delete, and Set Conversations * Get and send messages * Edit message names * Local serving from FastAPI via static export * Deployment strategy for static files * Separate out apps * Vercel Deployment with Action * Re-add discord to fly.toml * Honcho Stream * Honcho Stream --------- Co-authored-by: hyusap Co-authored-by: Jacob Van Meter * Social Graph Changes * Authentication Form Styling * Working Auth * Stylistic changes * Address all linting errors * Naive Route Protection * Fly minimum machines * Open Graph Image Changes * Remove anonymous honcho usage, fix opengraph (#80) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * UI tweaks (#81) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * UI tweaks (#82) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * Open Graph, Block chat, delete convo * Sign Up UI * Sign Up UI 2 * Change open graph image * Open Graph Fix * Remove Streamlit * UI tweaks (#84) * Remove anonymous honcho usage, fix opengraph * Remove extra excess logging and comment * I hate typescript * Open Graph, Block chat, delete convo * Sign Up UI * Sign Up UI 2 * Change open graph image * Remove native prompts for sweetalert * Changelog * Remove Honcho for discord * Web fixes (#89) * seperation between sidebar and window + formatting * make app pwa downloadable * move to new chat on button press * remove router * feat: Refactor code to use MarkdownWrapper component - Refactored the code in the `Home` component to replace usages of `ReactMarkdown` and `SyntaxHighlighter` with the new `MarkdownWrapper` component. - Updated the `Home` component to pass the `text` prop to the `MarkdownWrapper` component for each message. - Added a new component `MarkdownWrapper` to handle rendering markdown text with syntax highlighting. - Removed unused imports from the `page.tsx` file, including `ReactMarkdown`, `SyntaxHighlighter`, and `dark` styles. - Also removed unused imports from the `sidebar.tsx` file, including `useState` import. * Optimization (#96) * Usable without honcho and move metadata to creation points * Remove unused psycopg code * Add Sentry instrumentation * Sentry to python * Update env * Optimization (#98) * Usable without honcho and move metadata to creation points * Remove unused psycopg code * Add Sentry instrumentation * Sentry to python * Update env * Sentry & Posthog integration on web * Linting Errors * add latex support and incentive it (#104) * prevent unallowed messages (#111) * implement autoscroll (#112) * implement autoscroll Refactored imports in "page.tsx" to improve readability and maintainability. Updated the type of the "input" ref to be more specific. Added a new state and ref to track the scroll position of the message container. Set up an event listener to update the state when the scroll position changes. Made adjustments to the scroll position in certain event handlers. * update scroll --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * ✨ add multiline support (#118) * ♻️ refactor all of the api stuff (#119) * ♻️ refactor all of the api stuff a redo of the old refactor branch, but cleaner. moved all api calls to api.ts and supabase.ts * Minor Bug Fixes - Add `build-essential` to dockerfile - Fix signin button size - Add await for signout - Force re-render on conversation name change --------- Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * ✨ implement dark mode (#120) automatically check for system mode manual control via animated thingy Co-authored-by: Vineeth Voruganti <13438633+VVoruganti@users.noreply.github.com> * Documentation (#121) * README update and start of supabase plus making next buildable * Supabase Local Setup and README additions * Update web .env template and note on supabase local auth * Force redirect for unauthenticated and add posthog events (#122) * Update version * Static banner --------- Co-authored-by: vintro Co-authored-by: Jacob Vanmeter Co-authored-by: hyusap Co-authored-by: vintro <77507980+vintrocode@users.noreply.github.com> * Changelogs --------- Co-authored-by: vintro Co-authored-by: Jacob Vanmeter Co-authored-by: hyusap Co-authored-by: vintro <77507980+vintrocode@users.noreply.github.com> --------- Co-authored-by: vintro Co-authored-by: Jacob Vanmeter Co-authored-by: hyusap Co-authored-by: vintro <77507980+vintrocode@users.noreply.github.com> --- CHANGELOG.md | 21 +++ README.md | 2 +- agent/chain.py | 43 ++++-- agent/mediator.py | 6 +- poetry.lock | 234 +++++++++++----------------- pyproject.toml | 6 +- www/app/layout.tsx | 7 +- www/app/page.tsx | 239 +++++++++++++++++------------ www/components/conversationtab.tsx | 65 ++++++++ www/components/loading.tsx | 2 +- www/components/messagebox.tsx | 41 +++-- www/components/sidebar.tsx | 129 +++++++--------- www/components/typing.tsx | 2 +- www/package.json | 4 +- www/utils/api.ts | 48 ++++-- www/yarn.lock | 20 ++- 16 files changed, 502 insertions(+), 367 deletions(-) create mode 100644 www/components/conversationtab.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 130ddd2..198c1a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.5.1] - 2023-12-12 + +### Added + +- Dark mode +- Web Caching +- LateX Support +- Multiline support for chat textbox + +### Changed + +- Required Sign In +- No A/B for Honcho +- Error handling for content filter + +### Security + +- Update Langchain version to ^0.0.348 +- Update OpenAI Package to ^1.3.8 + + ## [0.4.1] – 2023-09-14 ### Added diff --git a/README.md b/README.md index 7cedae9..0bc9f7b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # tutor-gpt -![Static Badge](https://img.shields.io/badge/Version-0.4.0-blue) +![Static Badge](https://img.shields.io/badge/Version-0.5.1-blue) [![Discord](https://img.shields.io/discord/1076192451997474938?logo=discord&logoColor=%23ffffff&label=Bloom&labelColor=%235865F2)](https://discord.gg/bloombotai) ![GitHub License](https://img.shields.io/github/license/plastic-labs/tutor-gpt) ![GitHub Repo stars](https://img.shields.io/github/stars/plastic-labs/tutor-gpt) diff --git a/agent/chain.py b/agent/chain.py index c86df1d..8d535f9 100644 --- a/agent/chain.py +++ b/agent/chain.py @@ -5,6 +5,9 @@ ) from langchain.prompts import load_prompt, ChatPromptTemplate from langchain.schema import AIMessage, HumanMessage, BaseMessage + +from openai import BadRequestError + from dotenv import load_dotenv from collections.abc import AsyncIterator @@ -54,12 +57,11 @@ def think(cls, cache: Conversation, input: str): ]) chain = thought_prompt | cls.llm - cache.add_message("thought", HumanMessage(content=input)) + def save_new_messages(ai_response): + cache.add_message("response", HumanMessage(content=input)) + cache.add_message("response", AIMessage(content=ai_response)) - return Streamable( - chain.astream({}, {"tags": ["thought"], "metadata": {"conversation_id": cache.conversation_id, "user_id": cache.user_id}}), - lambda thought: cache.add_message("thought", AIMessage(content=thought)) - ) + return Streamable(chain.astream({}, {"tags": ["thought"], "metadata": {"conversation_id": cache.conversation_id, "user_id": cache.user_id}}), save_new_messages) @classmethod @sentry_sdk.trace @@ -72,13 +74,12 @@ def respond(cls, cache: Conversation, thought: str, input: str): ]) chain = response_prompt | cls.llm - cache.add_message("response", HumanMessage(content=input)) + def save_new_messages(ai_response): + cache.add_message("response", HumanMessage(content=input)) + cache.add_message("response", AIMessage(content=ai_response)) + + return Streamable(chain.astream({ "thought": thought }, {"tags": ["response"], "metadata": {"conversation_id": cache.conversation_id, "user_id": cache.user_id}}), save_new_messages) - return Streamable( - chain.astream({ "thought": thought }, {"tags": ["response"], "metadata": {"conversation_id": cache.conversation_id, "user_id": cache.user_id}}), - lambda response: cache.add_message("response", AIMessage(content=response)) - ) - @classmethod @sentry_sdk.trace async def think_user_prediction(cls, cache: Conversation): @@ -114,6 +115,7 @@ async def chat(cls, cache: Conversation, inp: str ) -> tuple[str, str]: return thought, response + class Streamable: "A async iterator wrapper for langchain streams that saves on completion via callback" @@ -121,20 +123,37 @@ def __init__(self, iterator: AsyncIterator[BaseMessage], callback): self.iterator = iterator self.callback = callback self.content = "" + self.stream_error = False def __aiter__(self): return self async def __anext__(self): try: + if self.stream_error: + raise StopAsyncIteration + data = await self.iterator.__anext__() self.content += data.content return data.content except StopAsyncIteration as e: self.callback(self.content) raise StopAsyncIteration + except BadRequestError as e: + if e.code == "content_filter": + self.stream_error = True + self.message = "Sorry, your message was flagged as inappropriate. Please try again." + + return self.message + else: + raise Exception(e) except Exception as e: - raise e + sentry_sdk.capture_exception(e) + + self.stream_error = True + self.message = "Sorry, an error occurred while streaming the response. Please try again." + + return self.message async def __call__(self): async for _ in self: diff --git a/agent/mediator.py b/agent/mediator.py index f5fb516..dbd8813 100644 --- a/agent/mediator.py +++ b/agent/mediator.py @@ -5,13 +5,17 @@ from dotenv import load_dotenv # Supabase for Postgres Management from supabase.client import create_client, Client +from supabase.lib.client_options import ClientOptions from typing import List, Tuple, Dict load_dotenv() class SupabaseMediator: @sentry_sdk.trace def __init__(self): - self.supabase: Client = create_client(os.environ['SUPABASE_URL'], os.environ['SUPABASE_KEY']) + # Change the network db timeout to 60 seconds since the default is only 5 seconds + timeout_client_options = ClientOptions(postgrest_client_timeout=60) + self.supabase: Client = create_client(os.environ['SUPABASE_URL'], os.environ['SUPABASE_KEY'], timeout_client_options) + self.memory_table = os.environ["MEMORY_TABLE"] self.conversation_table = os.environ["CONVERSATION_TABLE"] diff --git a/poetry.lock b/poetry.lock index 3d4963a..0123ba5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "aiohttp" version = "3.8.6" description = "Async http client/server framework (asyncio)" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -113,7 +112,6 @@ speedups = ["Brotli", "aiodns", "cchardet"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -128,7 +126,6 @@ frozenlist = ">=1.1.0" name = "annotated-types" version = "0.6.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -140,7 +137,6 @@ files = [ name = "anyio" version = "4.1.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -162,7 +158,6 @@ trio = ["trio (>=0.23)"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -174,7 +169,6 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -193,7 +187,6 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "certifi" version = "2023.11.17" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -205,7 +198,6 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -305,7 +297,6 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -320,7 +311,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -332,7 +322,6 @@ files = [ name = "dataclasses-json" version = "0.6.3" description = "Easily serialize dataclasses to and from JSON." -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -348,7 +337,6 @@ typing-inspect = ">=0.4.0,<1" name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -360,7 +348,6 @@ files = [ name = "deprecation" version = "2.1.0" description = "A library to handle automated deprecations" -category = "main" optional = false python-versions = "*" files = [ @@ -371,11 +358,21 @@ files = [ [package.dependencies] packaging = "*" +[[package]] +name = "distro" +version = "1.8.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.8.0-py3-none-any.whl", hash = "sha256:99522ca3e365cac527b44bde033f64c6945d90eb9f769703caaec52b09bbd3ff"}, + {file = "distro-1.8.0.tar.gz", hash = "sha256:02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8"}, +] + [[package]] name = "exceptiongroup" version = "1.2.0" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -390,7 +387,6 @@ test = ["pytest (>=6)"] name = "fastapi" version = "0.101.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -410,7 +406,6 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" name = "frozenlist" version = "1.4.0" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -481,7 +476,6 @@ files = [ name = "gotrue" version = "1.3.1" description = "Python Client Library for GoTrue" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -495,69 +489,69 @@ pydantic = ">=1.10,<3" [[package]] name = "greenlet" -version = "3.0.1" +version = "3.0.2" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=3.7" files = [ - {file = "greenlet-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f89e21afe925fcfa655965ca8ea10f24773a1791400989ff32f467badfe4a064"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28e89e232c7593d33cac35425b58950789962011cc274aa43ef8865f2e11f46d"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8ba29306c5de7717b5761b9ea74f9c72b9e2b834e24aa984da99cbfc70157fd"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19bbdf1cce0346ef7341705d71e2ecf6f41a35c311137f29b8a2dc2341374565"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:599daf06ea59bfedbec564b1692b0166a0045f32b6f0933b0dd4df59a854caf2"}, - {file = "greenlet-3.0.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b641161c302efbb860ae6b081f406839a8b7d5573f20a455539823802c655f63"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d57e20ba591727da0c230ab2c3f200ac9d6d333860d85348816e1dca4cc4792e"}, - {file = "greenlet-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5805e71e5b570d490938d55552f5a9e10f477c19400c38bf1d5190d760691846"}, - {file = "greenlet-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:52e93b28db27ae7d208748f45d2db8a7b6a380e0d703f099c949d0f0d80b70e9"}, - {file = "greenlet-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f7bfb769f7efa0eefcd039dd19d843a4fbfbac52f1878b1da2ed5793ec9b1a65"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91e6c7db42638dc45cf2e13c73be16bf83179f7859b07cfc139518941320be96"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1757936efea16e3f03db20efd0cd50a1c86b06734f9f7338a90c4ba85ec2ad5a"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19075157a10055759066854a973b3d1325d964d498a805bb68a1f9af4aaef8ec"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9d21aaa84557d64209af04ff48e0ad5e28c5cca67ce43444e939579d085da72"}, - {file = "greenlet-3.0.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2847e5d7beedb8d614186962c3d774d40d3374d580d2cbdab7f184580a39d234"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:97e7ac860d64e2dcba5c5944cfc8fa9ea185cd84061c623536154d5a89237884"}, - {file = "greenlet-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b2c02d2ad98116e914d4f3155ffc905fd0c025d901ead3f6ed07385e19122c94"}, - {file = "greenlet-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:22f79120a24aeeae2b4471c711dcf4f8c736a2bb2fabad2a67ac9a55ea72523c"}, - {file = "greenlet-3.0.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:100f78a29707ca1525ea47388cec8a049405147719f47ebf3895e7509c6446aa"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60d5772e8195f4e9ebf74046a9121bbb90090f6550f81d8956a05387ba139353"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:daa7197b43c707462f06d2c693ffdbb5991cbb8b80b5b984007de431493a319c"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea6b8aa9e08eea388c5f7a276fabb1d4b6b9d6e4ceb12cc477c3d352001768a9"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d11ebbd679e927593978aa44c10fc2092bc454b7d13fdc958d3e9d508aba7d0"}, - {file = "greenlet-3.0.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbd4c177afb8a8d9ba348d925b0b67246147af806f0b104af4d24f144d461cd5"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20107edf7c2c3644c67c12205dc60b1bb11d26b2610b276f97d666110d1b511d"}, - {file = "greenlet-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8bef097455dea90ffe855286926ae02d8faa335ed8e4067326257cb571fc1445"}, - {file = "greenlet-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:b2d3337dcfaa99698aa2377c81c9ca72fcd89c07e7eb62ece3f23a3fe89b2ce4"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80ac992f25d10aaebe1ee15df45ca0d7571d0f70b645c08ec68733fb7a020206"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:337322096d92808f76ad26061a8f5fccb22b0809bea39212cd6c406f6a7060d2"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9934adbd0f6e476f0ecff3c94626529f344f57b38c9a541f87098710b18af0a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4d815b794fd8868c4d67602692c21bf5293a75e4b607bb92a11e821e2b859a"}, - {file = "greenlet-3.0.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41bdeeb552d814bcd7fb52172b304898a35818107cc8778b5101423c9017b3de"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6e6061bf1e9565c29002e3c601cf68569c450be7fc3f7336671af7ddb4657166"}, - {file = "greenlet-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:fa24255ae3c0ab67e613556375a4341af04a084bd58764731972bcbc8baeba36"}, - {file = "greenlet-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:b489c36d1327868d207002391f662a1d163bdc8daf10ab2e5f6e41b9b96de3b1"}, - {file = "greenlet-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:f33f3258aae89da191c6ebaa3bc517c6c4cbc9b9f689e5d8452f7aedbb913fa8"}, - {file = "greenlet-3.0.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d2905ce1df400360463c772b55d8e2518d0e488a87cdea13dd2c71dcb2a1fa16"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a02d259510b3630f330c86557331a3b0e0c79dac3d166e449a39363beaae174"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55d62807f1c5a1682075c62436702aaba941daa316e9161e4b6ccebbbf38bda3"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3fcc780ae8edbb1d050d920ab44790201f027d59fdbd21362340a85c79066a74"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4eddd98afc726f8aee1948858aed9e6feeb1758889dfd869072d4465973f6bfd"}, - {file = "greenlet-3.0.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eabe7090db68c981fca689299c2d116400b553f4b713266b130cfc9e2aa9c5a9"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f2f6d303f3dee132b322a14cd8765287b8f86cdc10d2cb6a6fae234ea488888e"}, - {file = "greenlet-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d923ff276f1c1f9680d32832f8d6c040fe9306cbfb5d161b0911e9634be9ef0a"}, - {file = "greenlet-3.0.1-cp38-cp38-win32.whl", hash = "sha256:0b6f9f8ca7093fd4433472fd99b5650f8a26dcd8ba410e14094c1e44cd3ceddd"}, - {file = "greenlet-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:990066bff27c4fcf3b69382b86f4c99b3652bab2a7e685d968cd4d0cfc6f67c6"}, - {file = "greenlet-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ce85c43ae54845272f6f9cd8320d034d7a946e9773c693b27d620edec825e376"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89ee2e967bd7ff85d84a2de09df10e021c9b38c7d91dead95b406ed6350c6997"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87c8ceb0cf8a5a51b8008b643844b7f4a8264a2c13fcbcd8a8316161725383fe"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6a8c9d4f8692917a3dc7eb25a6fb337bff86909febe2f793ec1928cd97bedfc"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fbc5b8f3dfe24784cee8ce0be3da2d8a79e46a276593db6868382d9c50d97b1"}, - {file = "greenlet-3.0.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85d2b77e7c9382f004b41d9c72c85537fac834fb141b0296942d52bf03fe4a3d"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:696d8e7d82398e810f2b3622b24e87906763b6ebfd90e361e88eb85b0e554dc8"}, - {file = "greenlet-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:329c5a2e5a0ee942f2992c5e3ff40be03e75f745f48847f118a3cfece7a28546"}, - {file = "greenlet-3.0.1-cp39-cp39-win32.whl", hash = "sha256:cf868e08690cb89360eebc73ba4be7fb461cfbc6168dd88e2fbbe6f31812cd57"}, - {file = "greenlet-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac4a39d1abae48184d420aa8e5e63efd1b75c8444dd95daa3e03f6c6310e9619"}, - {file = "greenlet-3.0.1.tar.gz", hash = "sha256:816bd9488a94cba78d93e1abb58000e8266fa9cc2aa9ccdd6eb0696acb24005b"}, + {file = "greenlet-3.0.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9acd8fd67c248b8537953cb3af8787c18a87c33d4dcf6830e410ee1f95a63fd4"}, + {file = "greenlet-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:339c0272a62fac7e602e4e6ec32a64ff9abadc638b72f17f6713556ed011d493"}, + {file = "greenlet-3.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38878744926cec29b5cc3654ef47f3003f14bfbba7230e3c8492393fe29cc28b"}, + {file = "greenlet-3.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b3f0497db77cfd034f829678b28267eeeeaf2fc21b3f5041600f7617139e6773"}, + {file = "greenlet-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed1a8a08de7f68506a38f9a2ddb26bbd1480689e66d788fcd4b5f77e2d9ecfcc"}, + {file = "greenlet-3.0.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89a6f6ddcbef4000cda7e205c4c20d319488ff03db961d72d4e73519d2465309"}, + {file = "greenlet-3.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c1f647fe5b94b51488b314c82fdda10a8756d650cee8d3cd29f657c6031bdf73"}, + {file = "greenlet-3.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9560c580c896030ff9c311c603aaf2282234643c90d1dec738a1d93e3e53cd51"}, + {file = "greenlet-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2e9c5423046eec21f6651268cb674dfba97280701e04ef23d312776377313206"}, + {file = "greenlet-3.0.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1fd25dfc5879a82103b3d9e43fa952e3026c221996ff4d32a9c72052544835d"}, + {file = "greenlet-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfdc950dd25f25d6582952e58521bca749cf3eeb7a9bad69237024308c8196"}, + {file = "greenlet-3.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edf7a1daba1f7c54326291a8cde58da86ab115b78c91d502be8744f0aa8e3ffa"}, + {file = "greenlet-3.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4cf532bf3c58a862196b06947b1b5cc55503884f9b63bf18582a75228d9950e"}, + {file = "greenlet-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e79fb5a9fb2d0bd3b6573784f5e5adabc0b0566ad3180a028af99523ce8f6138"}, + {file = "greenlet-3.0.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:006c1028ac0cfcc4e772980cfe73f5476041c8c91d15d64f52482fc571149d46"}, + {file = "greenlet-3.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fefd5eb2c0b1adffdf2802ff7df45bfe65988b15f6b972706a0e55d451bffaea"}, + {file = "greenlet-3.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0c0fdb8142742ee68e97c106eb81e7d3e883cc739d9c5f2b28bc38a7bafeb6d1"}, + {file = "greenlet-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:8f8d14a0a4e8c670fbce633d8b9a1ee175673a695475acd838e372966845f764"}, + {file = "greenlet-3.0.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:654b84c9527182036747938b81938f1d03fb8321377510bc1854a9370418ab66"}, + {file = "greenlet-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bc4fde0842ff2b9cf33382ad0b4db91c2582db836793d58d174c569637144"}, + {file = "greenlet-3.0.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c27b142a9080bdd5869a2fa7ebf407b3c0b24bd812db925de90e9afe3c417fd6"}, + {file = "greenlet-3.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0df7eed98ea23b20e9db64d46eb05671ba33147df9405330695bcd81a73bb0c9"}, + {file = "greenlet-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb5d60805057d8948065338be6320d35e26b0a72f45db392eb32b70dd6dc9227"}, + {file = "greenlet-3.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0e28f5233d64c693382f66d47c362b72089ebf8ac77df7e12ac705c9fa1163d"}, + {file = "greenlet-3.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e4bfa752b3688d74ab1186e2159779ff4867644d2b1ebf16db14281f0445377"}, + {file = "greenlet-3.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c42bb589e6e9f9d8bdd79f02f044dff020d30c1afa6e84c0b56d1ce8a324553c"}, + {file = "greenlet-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:b2cedf279ca38ef3f4ed0d013a6a84a7fc3d9495a716b84a5fc5ff448965f251"}, + {file = "greenlet-3.0.2-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:6d65bec56a7bc352bcf11b275b838df618651109074d455a772d3afe25390b7d"}, + {file = "greenlet-3.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0acadbc3f72cb0ee85070e8d36bd2a4673d2abd10731ee73c10222cf2dd4713c"}, + {file = "greenlet-3.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14b5d999aefe9ffd2049ad19079f733c3aaa426190ffecadb1d5feacef8fe397"}, + {file = "greenlet-3.0.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f27aa32466993c92d326df982c4acccd9530fe354e938d9e9deada563e71ce76"}, + {file = "greenlet-3.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f34a765c5170c0673eb747213a0275ecc749ab3652bdbec324621ed5b2edaef"}, + {file = "greenlet-3.0.2-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:520fcb53a39ef90f5021c77606952dbbc1da75d77114d69b8d7bded4a8e1a813"}, + {file = "greenlet-3.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1fceb5351ab1601903e714c3028b37f6ea722be6873f46e349a960156c05650"}, + {file = "greenlet-3.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7363756cc439a503505b67983237d1cc19139b66488263eb19f5719a32597836"}, + {file = "greenlet-3.0.2-cp37-cp37m-win32.whl", hash = "sha256:d5547b462b8099b84746461e882a3eb8a6e3f80be46cb6afb8524eeb191d1a30"}, + {file = "greenlet-3.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:950e21562818f9c771989b5b65f990e76f4ac27af66e1bb34634ae67886ede2a"}, + {file = "greenlet-3.0.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:d64643317e76b4b41fdba659e7eca29634e5739b8bc394eda3a9127f697ed4b0"}, + {file = "greenlet-3.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f9ea7c2c9795549653b6f7569f6bc75d2c7d1f6b2854eb8ce0bc6ec3cb2dd88"}, + {file = "greenlet-3.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db4233358d3438369051a2f290f1311a360d25c49f255a6c5d10b5bcb3aa2b49"}, + {file = "greenlet-3.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ed9bf77b41798e8417657245b9f3649314218a4a17aefb02bb3992862df32495"}, + {file = "greenlet-3.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d0df07a38e41a10dfb62c6fc75ede196572b580f48ee49b9282c65639f3965"}, + {file = "greenlet-3.0.2-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10d247260db20887ae8857c0cbc750b9170f0b067dd7d38fb68a3f2334393bd3"}, + {file = "greenlet-3.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a37ae53cca36823597fd5f65341b6f7bac2dd69ecd6ca01334bb795460ab150b"}, + {file = "greenlet-3.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:80d068e4b6e2499847d916ef64176811ead6bf210a610859220d537d935ec6fd"}, + {file = "greenlet-3.0.2-cp38-cp38-win32.whl", hash = "sha256:b1405614692ac986490d10d3e1a05e9734f473750d4bee3cf7d1286ef7af7da6"}, + {file = "greenlet-3.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8756a94ed8f293450b0e91119eca2a36332deba69feb2f9ca410d35e74eae1e4"}, + {file = "greenlet-3.0.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:2c93cd03acb1499ee4de675e1a4ed8eaaa7227f7949dc55b37182047b006a7aa"}, + {file = "greenlet-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1dac09e3c0b78265d2e6d3cbac2d7c48bd1aa4b04a8ffeda3adde9f1688df2c3"}, + {file = "greenlet-3.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ee59c4627c8c4bb3e15949fbcd499abd6b7f4ad9e0bfcb62c65c5e2cabe0ec4"}, + {file = "greenlet-3.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18fe39d70d482b22f0014e84947c5aaa7211fb8e13dc4cc1c43ed2aa1db06d9a"}, + {file = "greenlet-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84bef3cfb6b6bfe258c98c519811c240dbc5b33a523a14933a252e486797c90"}, + {file = "greenlet-3.0.2-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aecea0442975741e7d69daff9b13c83caff8c13eeb17485afa65f6360a045765"}, + {file = "greenlet-3.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f260e6c2337871a52161824058923df2bbddb38bc11a5cbe71f3474d877c5bd9"}, + {file = "greenlet-3.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fc14dd9554f88c9c1fe04771589ae24db76cd56c8f1104e4381b383d6b71aff8"}, + {file = "greenlet-3.0.2-cp39-cp39-win32.whl", hash = "sha256:bfcecc984d60b20ffe30173b03bfe9ba6cb671b0be1e95c3e2056d4fe7006590"}, + {file = "greenlet-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:c235131bf59d2546bb3ebaa8d436126267392f2e51b85ff45ac60f3a26549af0"}, + {file = "greenlet-3.0.2.tar.gz", hash = "sha256:1c1129bc47266d83444c85a8e990ae22688cf05fb20d7951fd2866007c2ba9bc"}, ] [package.extras] @@ -568,7 +562,6 @@ test = ["objgraph", "psutil"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -580,7 +573,6 @@ files = [ name = "httpcore" version = "0.17.3" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -592,17 +584,16 @@ files = [ anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = ">=1.0.0,<2.0.0" +sniffio = "==1.*" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "httptools" version = "0.6.1" description = "A collection of framework independent HTTP protocol utils." -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -651,7 +642,6 @@ test = ["Cython (>=0.29.24,<0.30.0)"] name = "httpx" version = "0.24.1" description = "The next generation HTTP client." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -667,15 +657,14 @@ sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -687,7 +676,6 @@ files = [ name = "jsonpatch" version = "1.33" description = "Apply JSON-Patches (RFC 6902)" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" files = [ @@ -702,7 +690,6 @@ jsonpointer = ">=1.9" name = "jsonpointer" version = "2.4" description = "Identify specific nodes in a JSON document (RFC 6901)" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" files = [ @@ -714,7 +701,6 @@ files = [ name = "langchain" version = "0.0.348" description = "Building applications with LLMs through composability" -category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ @@ -755,7 +741,6 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"] name = "langchain-core" version = "0.0.12" description = "Building applications with LLMs through composability" -category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ @@ -780,7 +765,6 @@ extended-testing = ["jinja2 (>=3,<4)"] name = "langsmith" version = "0.0.69" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." -category = "main" optional = false python-versions = ">=3.8.1,<4.0" files = [ @@ -796,7 +780,6 @@ requests = ">=2,<3" name = "marshmallow" version = "3.20.1" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -817,7 +800,6 @@ tests = ["pytest", "pytz", "simplejson"] name = "multidict" version = "6.0.4" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -901,7 +883,6 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -913,7 +894,6 @@ files = [ name = "numpy" version = "1.26.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -957,32 +937,31 @@ files = [ [[package]] name = "openai" -version = "0.27.10" -description = "Python client library for the OpenAI API" -category = "main" +version = "1.3.8" +description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-0.27.10-py3-none-any.whl", hash = "sha256:beabd1757e3286fa166dde3b70ebb5ad8081af046876b47c14c41e203ed22a14"}, - {file = "openai-0.27.10.tar.gz", hash = "sha256:60e09edf7100080283688748c6803b7b3b52d5a55d21890f3815292a0552d83b"}, + {file = "openai-1.3.8-py3-none-any.whl", hash = "sha256:ac5a17352b96db862390d2e6f51de9f7eb32e733f412467b2f160fbd3d0f2609"}, + {file = "openai-1.3.8.tar.gz", hash = "sha256:54963ff247abe185aad6ee443820e48ad9f87eb4de970acb2514bc113ced748c"}, ] [package.dependencies] -aiohttp = "*" -requests = ">=2.20" -tqdm = "*" +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.5,<5" [package.extras] -datalib = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] -dev = ["black (>=21.6b0,<22.0)", "pytest (>=6.0.0,<7.0.0)", "pytest-asyncio", "pytest-mock"] -embeddings = ["matplotlib", "numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "plotly", "scikit-learn (>=1.0.2)", "scipy", "tenacity (>=8.0.1)"] -wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)", "wandb"] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] [[package]] name = "packaging" version = "23.2" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -994,7 +973,6 @@ files = [ name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -1009,7 +987,6 @@ ptyprocess = ">=0.5" name = "postgrest" version = "0.11.0" description = "PostgREST client for Python. This library provides an ORM interface to PostgREST." -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1027,7 +1004,6 @@ strenum = ">=0.4.9,<0.5.0" name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -1039,7 +1015,6 @@ files = [ name = "py-cord" version = "2.4.1" description = "A Python wrapper for the Discord API" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1060,7 +1035,6 @@ voice = ["PyNaCl (>=1.3.0,<1.6)"] name = "pydantic" version = "2.5.2" description = "Data validation using Python type hints" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1080,7 +1054,6 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.14.5" description = "" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1198,7 +1171,6 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1213,7 +1185,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.0" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1228,7 +1199,6 @@ cli = ["click (>=5.0)"] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1278,7 +1248,6 @@ files = [ name = "realtime" version = "1.0.2" description = "" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1295,7 +1264,6 @@ websockets = ">=11.0,<12.0" name = "regex" version = "2023.10.3" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1393,7 +1361,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1415,7 +1382,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "sentry-sdk" version = "1.38.0" description = "Python client for Sentry (https://sentry.io)" -category = "main" optional = false python-versions = "*" files = [ @@ -1462,7 +1428,6 @@ tornado = ["tornado (>=5)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -1474,7 +1439,6 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1486,7 +1450,6 @@ files = [ name = "sqlalchemy" version = "2.0.23" description = "Database Abstraction Library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1542,7 +1505,7 @@ files = [ ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\""} typing-extensions = ">=4.2.0" [package.extras] @@ -1574,7 +1537,6 @@ sqlcipher = ["sqlcipher3-binary"] name = "starlette" version = "0.27.0" description = "The little ASGI library that shines." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1592,7 +1554,6 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam name = "storage3" version = "0.6.1" description = "Supabase Storage client for Python." -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1609,7 +1570,6 @@ typing-extensions = ">=4.2.0,<5.0.0" name = "strenum" version = "0.4.15" description = "An Enum that inherits from str." -category = "main" optional = false python-versions = "*" files = [ @@ -1626,7 +1586,6 @@ test = ["pylint", "pytest", "pytest-black", "pytest-cov", "pytest-pylint"] name = "supabase" version = "1.2.0" description = "Supabase client for Python." -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1646,7 +1605,6 @@ supafunc = ">=0.2.3,<0.3.0" name = "supafunc" version = "0.2.3" description = "Library for Supabase Functions" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -1661,7 +1619,6 @@ httpx = ">=0.24.0,<0.25.0" name = "tenacity" version = "8.2.3" description = "Retry code until it succeeds" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1676,7 +1633,6 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] name = "tiktoken" version = "0.3.3" description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1722,7 +1678,6 @@ blobfile = ["blobfile (>=2)"] name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1743,7 +1698,6 @@ telegram = ["requests"] name = "typing-extensions" version = "4.8.0" description = "Backported and Experimental Type Hints for Python 3.8+" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1755,7 +1709,6 @@ files = [ name = "typing-inspect" version = "0.9.0" description = "Runtime inspection utilities for typing module." -category = "main" optional = false python-versions = "*" files = [ @@ -1771,7 +1724,6 @@ typing-extensions = ">=3.7.4" name = "urllib3" version = "2.1.0" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1788,7 +1740,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "uvicorn" version = "0.23.2" description = "The lightning-fast ASGI server." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1804,7 +1755,7 @@ httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standar python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""} typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} -uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "sys_platform != \"win32\" and sys_platform != \"cygwin\" and platform_python_implementation != \"PyPy\" and extra == \"standard\""} +uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""} watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""} websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""} @@ -1815,7 +1766,6 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "uvloop" version = "0.19.0" description = "Fast implementation of asyncio event loop on top of libuv" -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -1860,7 +1810,6 @@ test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)" name = "validators" version = "0.20.0" description = "Python Data Validation for Humans™." -category = "main" optional = false python-versions = ">=3.4" files = [ @@ -1877,7 +1826,6 @@ test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] name = "watchfiles" version = "0.21.0" description = "Simple, modern and high performance file watching and code reload in python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1965,7 +1913,6 @@ anyio = ">=3.0.0" name = "websockets" version = "11.0.3" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2045,7 +1992,6 @@ files = [ name = "yarl" version = "1.9.4" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2148,4 +2094,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "de65f7b1a717885db91dfb3339f4c308bb37ebc0de4a2560ea47e60cec3ade91" +content-hash = "9fe9ef40d2de2669c4d0be84af96fda16fdb9de6481b8fa180468decdc2d27c8" diff --git a/pyproject.toml b/pyproject.toml index e87bcd5..3903720 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,17 +1,17 @@ [tool.poetry] name = "tutor-gpt" -version = "0.5.0" +version = "0.5.1" description = "LangChain LLM application. Dynamic few-shot metaprompting for the task of tutoring." authors = ["vintro ", "VVoruganti {children} - + ); } diff --git a/www/app/page.tsx b/www/app/page.tsx index b8a8b86..e8fffb0 100644 --- a/www/app/page.tsx +++ b/www/app/page.tsx @@ -1,5 +1,6 @@ "use client"; import Image from "next/image"; +import useSWR from "swr"; import banner from "@/public/bloom2x1.svg"; import darkBanner from "@/public/bloom2x1dark.svg"; @@ -8,41 +9,33 @@ import Thoughts from "@/components/thoughts"; import Sidebar from "@/components/sidebar"; import { FaLightbulb, FaPaperPlane, FaBars } from "react-icons/fa"; -import { - useRef, - useEffect, - useState, - ElementRef, -} from "react"; - -import Swal from "sweetalert2" +import { useRef, useEffect, useState, ElementRef } from "react"; + +import Swal from "sweetalert2"; import { useRouter } from "next/navigation"; -import { usePostHog } from 'posthog-js/react' +import { usePostHog } from "posthog-js/react"; import Link from "next/link"; import MarkdownWrapper from "@/components/markdownWrapper"; import { DarkModeSwitch } from "react-toggle-dark-mode"; import { Message, Conversation, API } from "@/utils/api"; +import { getId } from "@/utils/supabase"; +import { data } from "autoprefixer"; +import { Session } from "@supabase/supabase-js"; const URL = process.env.NEXT_PUBLIC_API_URL; -const defaultMessage: Message = { - text: `I'm your Aristotelian learning companion — here to help you follow your curiosity in whatever direction you like. My engineering makes me extremely receptive to your needs and interests. You can reply normally, and I’ll always respond!\n\nIf I'm off track, just say so!\n\nNeed to leave or just done chatting? Let me know! I’m conversational by design so I’ll say goodbye 😊.`, - isUser: false, -}; export default function Home() { + const [userId, setUserId] = useState(); + const [session, setSession] = useState(null); + const [isThoughtsOpen, setIsThoughtsOpen] = useState(false); const [isSidebarOpen, setIsSidebarOpen] = useState(false); const [thought, setThought] = useState(""); const [canSend, setCanSend] = useState(false); - const [api, setApi] = useState(); - - const [messages, setMessages] = useState([defaultMessage]); - const [conversations, setConversations] = useState([]); - const [currentConversation, setCurrentConversation] = - useState(); + const [conversationId, setConversationId] = useState(); const router = useRouter(); const posthog = usePostHog(); @@ -58,44 +51,26 @@ export default function Home() { useEffect(() => { (async () => { - setIsDarkMode( - window.matchMedia("(prefers-color-scheme: dark)").matches - ); - const api = await API.create(URL!); - if (!api.session) { + const { userId, session } = await getId(); + setUserId(userId); + setSession(session); + setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches); + if (!session) { Swal.fire({ title: "Notice: Bloombot now requires signing in for usage", text: "Due to surging demand for Bloom we are requiring users to stay signed in to user Bloom", icon: "warning", confirmButtonColor: "#3085d6", - confirmButtonText: "Sign In" - }) - .then((res) => { - router.push("/auth") - }) + confirmButtonText: "Sign In", + }).then((res) => { + router.push("/auth"); + }); } else { - posthog?.identify( - api.userId, - { "email": api.session.user.email } - ); - setApi(api); - const conversations = await api.getConversations(); - setConversations(conversations); - setCurrentConversation(conversations[0]); - setCanSend(true); + posthog?.identify(userId, { email: session.user.email }); } })(); }, []); - useEffect(() => { - (async () => { - if (!currentConversation) return; - const messages = await currentConversation.getMessages(); - setMessages([defaultMessage, ...messages]); - // console.log("set messages", messages); - })(); - }, [currentConversation]); - useEffect(() => { const messageContainer = messageContainerRef.current; if (!messageContainer) return; @@ -115,7 +90,36 @@ export default function Home() { }; }, []); + const conversationsFetcher = async (userId: string) => { + const api = new API({ url: URL!, userId }); + return api.getConversations(); + }; + + const { + data: conversations, + mutate: mutateConversations, + error, + } = useSWR(userId, conversationsFetcher, { + onSuccess: (conversations) => { + setConversationId(conversations[0].conversationId); + setCanSend(true); + }, + }); + const messagesFetcher = async (conversationId: string) => { + if (!userId) return Promise.resolve([]); + if (!conversationId) return Promise.resolve([]); + + const api = new API({ url: URL!, userId }); + return api.getMessages(conversationId); + }; + + const { + data: messages, + mutate: mutateMessages, + isLoading: messagesLoading, + error: _, + } = useSWR(conversationId, messagesFetcher); async function chat() { const textbox = input.current!; @@ -125,8 +129,8 @@ export default function Home() { setCanSend(false); // Disable sending more messages until the current generation is done - setMessages((prev) => [ - ...prev, + const newMessages = [ + ...messages!, { text: message, isUser: true, @@ -135,9 +139,16 @@ export default function Home() { text: "", isUser: false, }, - ]); + ]; + mutateMessages(newMessages, { revalidate: false }); + + // sleep for 1 second to give the user the illusion of typing + await new Promise((resolve) => setTimeout(resolve, 1000)); - const reader = await currentConversation!.chat(message); + // const reader = await currentConversation!.chat(message); + const reader = await conversations! + .find((conversation) => conversation.conversationId === conversationId)! + .chat(message); const messageContainer = messageContainerRef.current; if (messageContainer) { @@ -147,6 +158,8 @@ export default function Home() { let isThinking = true; setThought(""); + let currentModelOutput = ""; + while (true) { const { done, value } = await reader.read(); if (done) { @@ -162,15 +175,29 @@ export default function Home() { continue; } setThought((prev) => prev + value); + mutateMessages(newMessages, { revalidate: false }); } else { if (value.includes("❀")) { setCanSend(true); // Bloom delimeter continue; } - setMessages((prev) => { - prev[prev.length - 1].text += value; - return [...prev]; - }); + // setMessages((prev) => { + // prev[prev.length - 1].text += value; + // return [...prev]; + // }); + + currentModelOutput += value; + + mutateMessages( + [ + ...newMessages?.slice(0, -1)!, + { + text: currentModelOutput, + isUser: false, + }, + ], + { revalidate: false } + ); if (isAtBottom.current) { const messageContainer = messageContainerRef.current; @@ -180,6 +207,8 @@ export default function Home() { } } } + + mutateMessages(); } return ( @@ -188,13 +217,14 @@ export default function Home() { }`} >