From 2cb532caaa130726a984fb894714e22de4846849 Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Fri, 19 Jul 2024 17:12:55 +0100 Subject: [PATCH 1/9] Turned off semantic routing, added endpoint to return all available tools --- core-api/core_api/routes/chat.py | 70 +++++++++++++--------------- core-api/core_api/semantic_routes.py | 67 +++++++++++++++++++++----- core-api/tests/routes/test_chat.py | 58 +++++++++-------------- redbox-core/redbox/models/chain.py | 13 ++++-- redbox-core/redbox/models/chat.py | 11 +++++ 5 files changed, 130 insertions(+), 89 deletions(-) diff --git a/core-api/core_api/routes/chat.py b/core-api/core_api/routes/chat.py index 5f2544907..b834c4e2a 100644 --- a/core-api/core_api/routes/chat.py +++ b/core-api/core_api/routes/chat.py @@ -8,13 +8,13 @@ from fastapi import Depends, FastAPI, WebSocket from fastapi.encoders import jsonable_encoder from langchain_core.runnables import Runnable +from langchain_core.tools import Tool from openai import APIError -from pydantic import BaseModel from semantic_router import RouteLayer from redbox.api.runnables import map_to_chat_response -from redbox.models.chain import ChainInput -from redbox.models.chat import ChatRequest, ChatResponse, SourceDocument +from redbox.models.chain import ChainInput, ChainChatMessage +from redbox.models.chat import ChatRequest, ChatResponse, SourceDocument, ClientResponse, ErrorDetail from redbox.models.errors import NoDocumentSelected, QuestionLengthError from redbox.transform import map_document_to_source_document @@ -32,10 +32,6 @@ version="0.1.0", openapi_tags=[ {"name": "chat", "description": "Chat interactions with LLM and RAG backend"}, - { - "name": "embedding", - "description": "Embedding interactions with SentenceTransformer", - }, {"name": "llm", "description": "LLM information and parameters"}, ], docs_url="/docs", @@ -44,8 +40,10 @@ ) -async def semantic_router_to_chain( - chat_request: ChatRequest, user_uuid: UUID, routable_chains: dict[str, Runnable], route_layer: RouteLayer +async def route_chat( + chat_request: ChatRequest, + user_uuid: UUID, + routable_chains: dict[str, Tool] ) -> tuple[Runnable, ChainInput]: question = chat_request.message_history[-1].text @@ -59,20 +57,17 @@ def select_chat_chain(chat_request: ChatRequest, routable_chains: dict[str, Runn # Match keyword route_match = re_keyword_pattern.search(question) - if route_match: - route_name = route_match.group()[1:] - selected_chain = routable_chains.get(route_name) - - # Semantic route - if selected_chain is None: - route_name = route_layer(question).name - selected_chain = routable_chains.get(route_name, select_chat_chain(chat_request, routable_chains)) + route_name = route_match.group()[1:] if route_match else None + selected_chain = routable_chains.get(route_name, select_chat_chain(chat_request, routable_chains)) params = ChainInput( question=chat_request.message_history[-1].text, - file_uuids=[f.uuid for f in chat_request.selected_files], - user_uuid=user_uuid, - chat_history=chat_request.message_history[:-1], + file_uuids=[str(f.uuid) for f in chat_request.selected_files], + user_uuid=str(user_uuid), + chat_history=[ + ChainChatMessage(role=message.role, text=message.text) + for message in chat_request.message_history[:-1] + ], ) log.info("Routed to %s", route_name) @@ -85,29 +80,30 @@ def select_chat_chain(chat_request: ChatRequest, routable_chains: dict[str, Runn async def rag_chat( chat_request: ChatRequest, user_uuid: Annotated[UUID, Depends(get_user_uuid)], - routable_chains: Annotated[dict[str, Runnable], Depends(get_routable_chains)], - route_layer: Annotated[RouteLayer, Depends(get_semantic_route_layer)], + routable_chains: Annotated[dict[str, Tool], Depends(get_routable_chains)], ) -> ChatResponse: """REST endpoint. Get a LLM response to a question history and file.""" - selected_chain, params = await semantic_router_to_chain(chat_request, user_uuid, routable_chains, route_layer) - return (selected_chain | map_to_chat_response).invoke(params.model_dump()) - + selected_chain, params = await route_chat(chat_request, user_uuid, routable_chains) + return (selected_chain | map_to_chat_response).invoke(params.dict()) -class ErrorDetail(BaseModel): - code: str - message: str - - -class ClientResponse(BaseModel): - # Needs to match CoreChatResponse in django_app/redbox_app/redbox_core/consumers.py - resource_type: Literal["text", "documents", "route_name", "end", "error"] - data: list[SourceDocument] | str | ErrorDetail | None = None +@chat_app.get("/tools", tags=["chat"]) +async def available_tools( + routable_chains: Annotated[dict[str, Tool], Depends(get_routable_chains)], +): + """REST endpoint. Get a mapping of all tools available via chat.""" + return [ + { + "name": chat_tool.name, + "description": chat_tool.description + } + for chat_tool in routable_chains.values() + ] @chat_app.websocket("/rag") async def rag_chat_streamed( websocket: WebSocket, - routable_chains: Annotated[dict[str, Runnable], Depends(get_routable_chains)], + routable_chains: Annotated[dict[str, Tool], Depends(get_routable_chains)], route_layer: Annotated[RouteLayer, Depends(get_semantic_route_layer)], ): """Websocket. Get a LLM response to a question history and file.""" @@ -118,10 +114,10 @@ async def rag_chat_streamed( request = await websocket.receive_text() chat_request = ChatRequest.model_validate_json(request) - selected_chain, params = await semantic_router_to_chain(chat_request, user_uuid, routable_chains, route_layer) + selected_chain, params = await route_chat(chat_request, user_uuid, routable_chains) try: - async for event in selected_chain.astream(params.model_dump()): + async for event in selected_chain.astream(params.dict()): response: str = event.get("response", "") source_documents: list[SourceDocument] = [ map_document_to_source_document(doc) for doc in event.get("source_documents", []) diff --git a/core-api/core_api/semantic_routes.py b/core-api/core_api/semantic_routes.py index fec973f56..4fe497630 100644 --- a/core-api/core_api/semantic_routes.py +++ b/core-api/core_api/semantic_routes.py @@ -1,21 +1,23 @@ from typing import Annotated +from uuid import UUID from core_api.build_chains import ( build_chat_chain, build_chat_with_docs_chain, build_condense_retrieval_chain, build_static_response_chain, - build_summary_chain, ) from core_api.dependencies import get_env from fastapi import Depends from langchain_core.runnables import Runnable +from langchain_community.tools import Tool from semantic_router import Route from semantic_router.encoders import AzureOpenAIEncoder, BaseEncoder, OpenAIEncoder from semantic_router.layer import RouteLayer from redbox.models import Settings -from redbox.models.chat import ChatRoute +from redbox.models.chat import ChatRoute, ChatMessage +from redbox.models.chain import ChainInput # === Pre-canned responses for non-LLM routes === INFO_RESPONSE = """ @@ -125,22 +127,63 @@ def get_semantic_route_layer( return __semantic_route_layer +def as_chat_tool( + name: str, + runnable: Runnable, + description: str, +): + return runnable.as_tool( + name=name, + description=description, + args_schema=ChainInput + ) + def get_routable_chains( - summary_chain: Annotated[Runnable, Depends(build_summary_chain)], condense_chain: Annotated[Runnable, Depends(build_condense_retrieval_chain)], chat_chain: Annotated[Runnable, Depends(build_chat_chain)], chat_with_docs_chain: Annotated[Runnable, Depends(build_chat_with_docs_chain)], -): +) -> dict[str, Tool]: global __routable_chains # noqa: PLW0603 if not __routable_chains: + chat_tools = ( + as_chat_tool( + name=ChatRoute.info, + runnable=build_static_response_chain(INFO_RESPONSE, ChatRoute.info), + description="Give helpful information about Redbox", + ), + as_chat_tool( + name=ChatRoute.ability, + runnable=build_static_response_chain(ABILITY_RESPONSE, ChatRoute.ability), + description="Describe what Redbox can do", + ), + as_chat_tool( + name=ChatRoute.coach, + runnable=build_static_response_chain(COACH_RESPONSE, ChatRoute.coach), + description="Help users to use Redbox well", + ), + as_chat_tool( + name=ChatRoute.gratitude, + runnable=build_static_response_chain("You're welcome!", ChatRoute.gratitude), + description="Respond to thanks", + ), + as_chat_tool( + name=ChatRoute.chat, + runnable=chat_chain, + description="Answer questions as a helpful assistant", + ), + as_chat_tool( + name=ChatRoute.chat_with_docs, + runnable=chat_with_docs_chain, + description="Answer questions as a helpful assistant using the documents provided", + ), + as_chat_tool( + name=ChatRoute.search, + runnable=condense_chain, + description="Search for an answer to a question in provided documents", + ) + ) __routable_chains = { - ChatRoute.info: build_static_response_chain(INFO_RESPONSE, ChatRoute.info), - ChatRoute.ability: build_static_response_chain(ABILITY_RESPONSE, ChatRoute.ability), - ChatRoute.coach: build_static_response_chain(COACH_RESPONSE, ChatRoute.coach), - ChatRoute.gratitude: build_static_response_chain("You're welcome!", ChatRoute.gratitude), - ChatRoute.chat: chat_chain, - ChatRoute.chat_with_docs: chat_with_docs_chain, - ChatRoute.search: condense_chain, - ChatRoute.summarise: summary_chain, + chat_tool.name: chat_tool + for chat_tool in chat_tools } return __routable_chains diff --git a/core-api/tests/routes/test_chat.py b/core-api/tests/routes/test_chat.py index f75a8fc31..d96aba4ed 100644 --- a/core-api/tests/routes/test_chat.py +++ b/core-api/tests/routes/test_chat.py @@ -134,17 +134,6 @@ def mock_streaming_client(): chat_app.dependency_overrides = {} -def test_rag_chat_rest_gratitude(mock_client, headers): - response = mock_client.post( - "/chat/rag", - json={"message_history": [{"role": "user", "text": "Thank you"}]}, - headers=headers, - ) - chat_response = ChatResponse.model_validate(response.json()) - assert chat_response.output_text == "You're welcome!" - assert chat_response.route_name == ChatRoute.gratitude - - def test_rag(mock_client, headers): response = mock_client.post( "/chat/rag", @@ -162,44 +151,31 @@ def test_rag(mock_client, headers): ), f"Expected route [{ChatRoute.chat_with_docs}] received [{chat_response.route_name}]" -def test_summary(mock_client, headers): - response = mock_client.post( - "/chat/rag", - headers=headers, - json={ - "message_history": [ - {"text": "Summarise the documents", "role": "user"}, - ], - "selected_files": [{"uuid": UPLOADED_FILE_UUID}], - }, - ) - assert response.status_code == 200 - chat_response = ChatResponse.model_validate(response.json()) - assert chat_response.output_text == RAG_LLM_RESPONSE - assert ( - chat_response.route_name == ChatRoute.chat_with_docs - ), f"Expected route [{ChatRoute.chat_with_docs}] received [{chat_response.route_name}]" - - -def test_keyword(mock_client, headers): +@pytest.mark.parametrize( + ("keyword"), + ( + "search", + "gratitude", + "info" + ) +) +def test_keywords(mock_client, headers, keyword): """Given a history that should summarise, force retrieval.""" response = mock_client.post( "/chat/rag", headers=headers, json={ "message_history": [ - {"text": "What can I do for you?", "role": "system"}, - {"text": "Summarise the provided docs? @search", "role": "user"}, + {"text": f" @{keyword} Silly question", "role": "user"}, ], "selected_files": [{"uuid": UPLOADED_FILE_UUID}], }, ) assert response.status_code == 200 chat_response = ChatResponse.model_validate(response.json()) - assert chat_response.output_text == RAG_LLM_RESPONSE assert ( - chat_response.route_name == ChatRoute.search - ), f"Expected route [{ChatRoute.search}] received [{chat_response.route_name}]" + chat_response.route_name.startswith(keyword) + ), f"Expected route to match keyword[{keyword}] received [{chat_response.route_name}]" def test_rag_chat_streamed(mock_client, headers): @@ -231,3 +207,13 @@ def test_rag_chat_streamed(mock_client, headers): text = "".join(all_text) assert text == RAG_LLM_RESPONSE assert route_name == ChatRoute.chat_with_docs + + +def test_available_tools(mock_client, headers): + response = mock_client.get("/chat/tools", headers=headers) + assert response.status_code==200 + tool_definitions = response.json() + assert len(tool_definitions) > 0 + for tool_definition in tool_definitions: + assert "name" in tool_definition + assert "description" in tool_definition \ No newline at end of file diff --git a/redbox-core/redbox/models/chain.py b/redbox-core/redbox/models/chain.py index ff06c60c1..82bfbe003 100644 --- a/redbox-core/redbox/models/chain.py +++ b/redbox-core/redbox/models/chain.py @@ -1,11 +1,16 @@ -from pydantic import BaseModel, Field +from typing import TypedDict +from langchain_core.pydantic_v1 import BaseModel, Field from redbox.models.chat import ChatMessage from redbox.models.file import UUID +class ChainChatMessage(TypedDict): + role: str + text: str + class ChainInput(BaseModel): question: str = Field(description="The last user chat message") - file_uuids: list[UUID] = Field(description="List of files to process") - user_uuid: UUID = Field(description="User the chain in executing for") - chat_history: list[ChatMessage] = Field(description="All previous messages in chat (excluding question)") + file_uuids: list[str] = Field(description="List of files to process") + user_uuid: str = Field(description="User the chain in executing for") + chat_history: list[ChainChatMessage] = Field(description="All previous messages in chat (excluding question)") \ No newline at end of file diff --git a/redbox-core/redbox/models/chat.py b/redbox-core/redbox/models/chat.py index 8b615d390..ebfa6379f 100644 --- a/redbox-core/redbox/models/chat.py +++ b/redbox-core/redbox/models/chat.py @@ -85,3 +85,14 @@ class ChatResponse(BaseModel): examples=["The current Prime Minister of the UK is The Rt Hon. Rishi Sunak MP."], ) route_name: ChatRoute = Field(description="the conversation route taken") + + +class ErrorDetail(BaseModel): + code: str + message: str + + +class ClientResponse(BaseModel): + # Needs to match CoreChatResponse in django_app/redbox_app/redbox_core/consumers.py + resource_type: Literal["text", "documents", "route_name", "end", "error"] + data: list[SourceDocument] | str | ErrorDetail | None = None \ No newline at end of file From f39cf3b3917bb7976925b526cafd8dc499e3272c Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Fri, 19 Jul 2024 17:17:07 +0100 Subject: [PATCH 2/9] Fixed tests using ChainInput and added a note to the module about the weirdness --- core-api/tests/test_runnables.py | 24 ++++++++++++------------ redbox-core/redbox/models/chain.py | 6 ++++++ tests/test_e2e.py | 21 --------------------- 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/core-api/tests/test_runnables.py b/core-api/tests/test_runnables.py index f45544d79..25f5064f0 100644 --- a/core-api/tests/test_runnables.py +++ b/core-api/tests/test_runnables.py @@ -74,9 +74,9 @@ def test_rag_runnable(mock_llm, chunked_file, env): input=ChainInput( question="Who are all these people?", chat_history=previous_history, - file_uuids=[chunked_file.uuid], - user_uuid=chunked_file.creator_user_uuid, - ).model_dump() + file_uuids=[str(chunked_file.uuid)], + user_uuid=str(chunked_file.creator_user_uuid), + ).dict() ) assert response["response"] == "<>" @@ -98,9 +98,9 @@ def test_condense_runnable(mock_llm, chunked_file, env): input=ChainInput( question="Who are all these people?", chat_history=previous_history, - file_uuids=[chunked_file.uuid], - user_uuid=chunked_file.creator_user_uuid, - ).model_dump() + file_uuids=[str(chunked_file.uuid)], + user_uuid=str(chunked_file.creator_user_uuid), + ).dict() ) assert response["response"] == "<>" assert response["route_name"].startswith("search") @@ -125,9 +125,9 @@ def test_summary_runnable_large_file(all_chunks_retriever, mock_llm, large_chunk input=ChainInput( question="Who are all these people?", chat_history=previous_history, - file_uuids=[large_chunked_file.uuid], - user_uuid=large_chunked_file.creator_user_uuid, - ).model_dump() + file_uuids=[str(large_chunked_file.uuid)], + user_uuid=str(large_chunked_file.creator_user_uuid), + ).dict() ) assert response["response"] == "<>" @@ -149,9 +149,9 @@ def test_summary_runnable_small_file(all_chunks_retriever, mock_llm, chunked_fil input=ChainInput( question="Who are all these people?", chat_history=previous_history, - file_uuids=[chunked_file.uuid], - user_uuid=chunked_file.creator_user_uuid, - ).model_dump() + file_uuids=[str(chunked_file.uuid)], + user_uuid=str(chunked_file.creator_user_uuid), + ).dict() ) assert response["response"] == "<>" diff --git a/redbox-core/redbox/models/chain.py b/redbox-core/redbox/models/chain.py index 82bfbe003..b246eb230 100644 --- a/redbox-core/redbox/models/chain.py +++ b/redbox-core/redbox/models/chain.py @@ -1,3 +1,9 @@ +""" +There is some repeated definition and non-pydantic style code in here. +These classes are pydantic v1 which is compatible with langchain tools classes, we need +to provide a pydantic v1 definition to work with these. As these models are mostly +used in conjunction with langchain this is the tidiest boxing of pydantic v1 we can do +""" from typing import TypedDict from langchain_core.pydantic_v1 import BaseModel, Field diff --git a/tests/test_e2e.py b/tests/test_e2e.py index 21cefd635..ce0737ed5 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -157,27 +157,6 @@ def test_post_rag_fail(self, user_uuid): TestEndToEnd.route_name = rag_response.json()["route_name"] assert TestEndToEnd.route_name == "search" - @pytest.mark.parametrize("user_uuid", USER_UUIDS) - def test_post_rag_summarisation(self, user_uuid): - rag_response = requests.post( - f"http://{TEST_ORIGIN}/chat/rag", - json={ - "message_history": [ - { - "role": "user", - "text": "@summarise Please summarise the contents of the uploaded files.", - } - ], - "selected_files": [{"uuid": TestEndToEnd.file_uuids[user_uuid]}], - }, - headers=make_headers(user_uuid), - timeout=30, - ) - assert rag_response.status_code == HTTPStatus.OK - - TestEndToEnd.route_name = rag_response.json()["route_name"] - assert TestEndToEnd.route_name.startswith("summarise") - @pytest.mark.parametrize("user_uuid", USER_UUIDS) def test_permissions(self, user_uuid): """ From de21fdc93d39a292577bbf09072e7a8b889371e9 Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 10:06:03 +0100 Subject: [PATCH 3/9] Removed fixed responses other than info --- core-api/core_api/routes/chat.py | 22 ++--- core-api/core_api/semantic_routes.py | 143 ++------------------------- core-api/tests/routes/test_chat.py | 21 ++-- redbox-core/redbox/models/chain.py | 8 +- redbox-core/redbox/models/chat.py | 2 +- tests/test_e2e.py | 37 ------- 6 files changed, 28 insertions(+), 205 deletions(-) diff --git a/core-api/core_api/routes/chat.py b/core-api/core_api/routes/chat.py index b834c4e2a..f9a2e20b5 100644 --- a/core-api/core_api/routes/chat.py +++ b/core-api/core_api/routes/chat.py @@ -1,16 +1,15 @@ import logging import re -from typing import Annotated, Literal +from typing import Annotated from uuid import UUID from core_api.auth import get_user_uuid, get_ws_user_uuid -from core_api.semantic_routes import get_routable_chains, get_semantic_route_layer +from core_api.semantic_routes import get_routable_chains from fastapi import Depends, FastAPI, WebSocket from fastapi.encoders import jsonable_encoder from langchain_core.runnables import Runnable from langchain_core.tools import Tool from openai import APIError -from semantic_router import RouteLayer from redbox.api.runnables import map_to_chat_response from redbox.models.chain import ChainInput, ChainChatMessage @@ -41,9 +40,7 @@ async def route_chat( - chat_request: ChatRequest, - user_uuid: UUID, - routable_chains: dict[str, Tool] + chat_request: ChatRequest, user_uuid: UUID, routable_chains: dict[str, Tool] ) -> tuple[Runnable, ChainInput]: question = chat_request.message_history[-1].text @@ -65,8 +62,7 @@ def select_chat_chain(chat_request: ChatRequest, routable_chains: dict[str, Runn file_uuids=[str(f.uuid) for f in chat_request.selected_files], user_uuid=str(user_uuid), chat_history=[ - ChainChatMessage(role=message.role, text=message.text) - for message in chat_request.message_history[:-1] + ChainChatMessage(role=message.role, text=message.text) for message in chat_request.message_history[:-1] ], ) @@ -92,19 +88,13 @@ async def available_tools( routable_chains: Annotated[dict[str, Tool], Depends(get_routable_chains)], ): """REST endpoint. Get a mapping of all tools available via chat.""" - return [ - { - "name": chat_tool.name, - "description": chat_tool.description - } - for chat_tool in routable_chains.values() - ] + return [{"name": chat_tool.name, "description": chat_tool.description} for chat_tool in routable_chains.values()] + @chat_app.websocket("/rag") async def rag_chat_streamed( websocket: WebSocket, routable_chains: Annotated[dict[str, Tool], Depends(get_routable_chains)], - route_layer: Annotated[RouteLayer, Depends(get_semantic_route_layer)], ): """Websocket. Get a LLM response to a question history and file.""" await websocket.accept() diff --git a/core-api/core_api/semantic_routes.py b/core-api/core_api/semantic_routes.py index 4fe497630..bd06bd83b 100644 --- a/core-api/core_api/semantic_routes.py +++ b/core-api/core_api/semantic_routes.py @@ -1,5 +1,4 @@ from typing import Annotated -from uuid import UUID from core_api.build_chains import ( build_chat_chain, @@ -7,16 +6,11 @@ build_condense_retrieval_chain, build_static_response_chain, ) -from core_api.dependencies import get_env from fastapi import Depends from langchain_core.runnables import Runnable from langchain_community.tools import Tool -from semantic_router import Route -from semantic_router.encoders import AzureOpenAIEncoder, BaseEncoder, OpenAIEncoder -from semantic_router.layer import RouteLayer -from redbox.models import Settings -from redbox.models.chat import ChatRoute, ChatMessage +from redbox.models.chat import ChatRoute from redbox.models.chain import ChainInput # === Pre-canned responses for non-LLM routes === @@ -25,118 +19,17 @@ Ministers triage and summarise information from a wide variety of sources. """ -ABILITY_RESPONSE = """ -* I can help you search over selected documents and do Q&A on them. -* I can help you summarise selected documents. -* I can help you extract information from selected documents. -* I can return information in a variety of formats, such as bullet points. -""" - -COACH_RESPONSE = """ -I am sorry that didn't work. -You could try rephrasing your task, i.e if you want to summarise a document please use the term, -"Summarise the selected document" or "extract all action items from the selected document." -If you want the results to be returned in a specific format, please specify the format in as much detail as possible. -""" - -# === Set up the semantic router === -info = Route( - name=ChatRoute.info.value, - utterances=[ - "What is your name?", - "Who are you?", - "What is Redbox?", - ], -) - -ability = Route( - name=ChatRoute.ability.value, - utterances=[ - "What can you do?", - "What can you do?", - "How can you help me?", - "What does Redbox do?", - "What can Redbox do", - "What don't you do", - "Please help me", - "Please help", - "Help me!", - "help", - ], -) -coach = Route( - name=ChatRoute.coach.value, - utterances=[ - "That is not the answer I wanted", - "Rubbish", - "No good", - "That's not what I wanted", - "How can I improve the results?", - ], -) +def as_chat_tool( + name: str, + runnable: Runnable, + description: str, +): + return runnable.as_tool(name=name, description=description, args_schema=ChainInput) -gratitude = Route( - name=ChatRoute.gratitude.value, - utterances=[ - "Thank you", - "Thank you ever so much for your help!", - "I'm really grateful for your assistance.", - "Cheers for the detailed response!", - "Thanks a lot, that was very informative.", - "Nice one", - "Thanks!", - ], -) __routable_chains = None -__semantic_route_layer = None - - -def get_semantic_routes(): - return (info, ability, coach, gratitude) - - -def get_semantic_routing_encoder(env: Annotated[Settings, Depends(get_env)]): - """ - TODO: This is a duplication of the logic for getting the LangChain embedding model used elsewhere - We should replace semanticrouter with our own implementation to avoid this - """ - if env.embedding_backend == "azure": - return AzureOpenAIEncoder( - azure_endpoint=env.azure_openai_endpoint, api_version="2023-05-15", model=env.azure_embedding_model - ) - elif env.embedding_backend == "openai": - return OpenAIEncoder( - openai_base_url=env.embedding_openai_base_url, - openai_api_key=env.openai_api_key, - name=env.embedding_openai_model, - ) - - -def get_semantic_route_layer( - routes: Annotated[list[Route], Depends(get_semantic_routes)], - encoder: Annotated[BaseEncoder, Depends(get_semantic_routing_encoder)], -): - """ - Manual singleton creation as lru_cache can't handle the semantic router classes (non hashable) - """ - global __semantic_route_layer # noqa: PLW0603 - if not __semantic_route_layer: - __semantic_route_layer = RouteLayer(encoder=encoder, routes=routes) - return __semantic_route_layer - -def as_chat_tool( - name: str, - runnable: Runnable, - description: str, -): - return runnable.as_tool( - name=name, - description=description, - args_schema=ChainInput - ) def get_routable_chains( condense_chain: Annotated[Runnable, Depends(build_condense_retrieval_chain)], @@ -151,21 +44,6 @@ def get_routable_chains( runnable=build_static_response_chain(INFO_RESPONSE, ChatRoute.info), description="Give helpful information about Redbox", ), - as_chat_tool( - name=ChatRoute.ability, - runnable=build_static_response_chain(ABILITY_RESPONSE, ChatRoute.ability), - description="Describe what Redbox can do", - ), - as_chat_tool( - name=ChatRoute.coach, - runnable=build_static_response_chain(COACH_RESPONSE, ChatRoute.coach), - description="Help users to use Redbox well", - ), - as_chat_tool( - name=ChatRoute.gratitude, - runnable=build_static_response_chain("You're welcome!", ChatRoute.gratitude), - description="Respond to thanks", - ), as_chat_tool( name=ChatRoute.chat, runnable=chat_chain, @@ -180,10 +58,7 @@ def get_routable_chains( name=ChatRoute.search, runnable=condense_chain, description="Search for an answer to a question in provided documents", - ) + ), ) - __routable_chains = { - chat_tool.name: chat_tool - for chat_tool in chat_tools - } + __routable_chains = {chat_tool.name: chat_tool for chat_tool in chat_tools} return __routable_chains diff --git a/core-api/tests/routes/test_chat.py b/core-api/tests/routes/test_chat.py index d96aba4ed..6d2929b22 100644 --- a/core-api/tests/routes/test_chat.py +++ b/core-api/tests/routes/test_chat.py @@ -30,6 +30,8 @@ RAG_LLM_RESPONSE = "Based on your documents the answer to your question is 7" UPLOADED_FILE_UUID = "9aa1aa15-dde0-471f-ab27-fd410612025b" +EXPECTED_AVAILABLE_ROUTES = ("chat", "search", "info") + def mock_chat_prompt(): return ChatPromptValue( @@ -104,7 +106,6 @@ def mock_client(alice): chat_app.dependency_overrides[dependencies.get_parameterised_retriever] = lambda: mock_parameterised_retriever( alice ) - chat_app.dependency_overrides[semantic_routes.get_semantic_routing_encoder] = mock_semantic_route_encoder yield TestClient(application) chat_app.dependency_overrides = {} @@ -151,14 +152,7 @@ def test_rag(mock_client, headers): ), f"Expected route [{ChatRoute.chat_with_docs}] received [{chat_response.route_name}]" -@pytest.mark.parametrize( - ("keyword"), - ( - "search", - "gratitude", - "info" - ) -) +@pytest.mark.parametrize(("keyword"), EXPECTED_AVAILABLE_ROUTES) def test_keywords(mock_client, headers, keyword): """Given a history that should summarise, force retrieval.""" response = mock_client.post( @@ -173,8 +167,8 @@ def test_keywords(mock_client, headers, keyword): ) assert response.status_code == 200 chat_response = ChatResponse.model_validate(response.json()) - assert ( - chat_response.route_name.startswith(keyword) + assert chat_response.route_name.startswith( + keyword ), f"Expected route to match keyword[{keyword}] received [{chat_response.route_name}]" @@ -211,9 +205,10 @@ def test_rag_chat_streamed(mock_client, headers): def test_available_tools(mock_client, headers): response = mock_client.get("/chat/tools", headers=headers) - assert response.status_code==200 + assert response.status_code == 200 tool_definitions = response.json() assert len(tool_definitions) > 0 + assert set(EXPECTED_AVAILABLE_ROUTES).issubset({item["name"] for item in tool_definitions}) for tool_definition in tool_definitions: assert "name" in tool_definition - assert "description" in tool_definition \ No newline at end of file + assert "description" in tool_definition diff --git a/redbox-core/redbox/models/chain.py b/redbox-core/redbox/models/chain.py index b246eb230..9d1697364 100644 --- a/redbox-core/redbox/models/chain.py +++ b/redbox-core/redbox/models/chain.py @@ -1,22 +1,22 @@ """ There is some repeated definition and non-pydantic style code in here. -These classes are pydantic v1 which is compatible with langchain tools classes, we need +These classes are pydantic v1 which is compatible with langchain tools classes, we need to provide a pydantic v1 definition to work with these. As these models are mostly used in conjunction with langchain this is the tidiest boxing of pydantic v1 we can do """ + from typing import TypedDict from langchain_core.pydantic_v1 import BaseModel, Field -from redbox.models.chat import ChatMessage -from redbox.models.file import UUID class ChainChatMessage(TypedDict): role: str text: str + class ChainInput(BaseModel): question: str = Field(description="The last user chat message") file_uuids: list[str] = Field(description="List of files to process") user_uuid: str = Field(description="User the chain in executing for") - chat_history: list[ChainChatMessage] = Field(description="All previous messages in chat (excluding question)") \ No newline at end of file + chat_history: list[ChainChatMessage] = Field(description="All previous messages in chat (excluding question)") diff --git a/redbox-core/redbox/models/chat.py b/redbox-core/redbox/models/chat.py index ebfa6379f..85fdd98bb 100644 --- a/redbox-core/redbox/models/chat.py +++ b/redbox-core/redbox/models/chat.py @@ -95,4 +95,4 @@ class ErrorDetail(BaseModel): class ClientResponse(BaseModel): # Needs to match CoreChatResponse in django_app/redbox_app/redbox_core/consumers.py resource_type: Literal["text", "documents", "route_name", "end", "error"] - data: list[SourceDocument] | str | ErrorDetail | None = None \ No newline at end of file + data: list[SourceDocument] | str | ErrorDetail | None = None diff --git a/tests/test_e2e.py b/tests/test_e2e.py index ce0737ed5..37f7a87b3 100644 --- a/tests/test_e2e.py +++ b/tests/test_e2e.py @@ -211,40 +211,3 @@ async def test_streaming_rag(self, user_uuid): TestEndToEnd.source_document_file_uuids[user_uuid] = source_document_file_uuids assert TestEndToEnd.route_name == "search" - - @pytest.mark.asyncio() - @pytest.mark.parametrize("user_uuid", USER_UUIDS) - async def test_streaming_gratitude(self, user_uuid): - """ - Given a pleasant message - When I send to ws:///chat/rag - I expect a pleasant response! - """ - message_history = { - "message_history": [ - {"role": "user", "text": "thank you"}, - ] - } - all_text, source_documents = [], [] - - async for websocket in websockets.connect( - f"ws://{TEST_ORIGIN}/chat/rag", extra_headers=make_headers(user_uuid) - ): - await websocket.send(json.dumps(message_history)) - - try: - while True: - actual_str = await websocket.recv() - actual = json.loads(actual_str) - if actual["resource_type"] == "text": - all_text.append(actual["data"]) - elif actual["resource_type"] == "documents": - source_documents.extend(actual["data"]) - elif actual["resource_type"] == "route_name": - TestEndToEnd.route_name = actual["data"] - except ConnectionClosed: - break - - assert all_text == ["You're welcome!"] - - assert TestEndToEnd.route_name == "gratitude" From 79c9c8b12137550faee05c723ccb1c945d370ea7 Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 10:16:07 +0100 Subject: [PATCH 4/9] Removed semantic-router dependency --- core-api/poetry.lock | 457 ++++++++++++---------------------------- core-api/pyproject.toml | 1 - 2 files changed, 137 insertions(+), 321 deletions(-) diff --git a/core-api/poetry.lock b/core-api/poetry.lock index 6ba936df5..80db9d486 100644 --- a/core-api/poetry.lock +++ b/core-api/poetry.lock @@ -214,17 +214,17 @@ lxml = ["lxml"] [[package]] name = "boto3" -version = "1.34.144" +version = "1.34.145" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.144-py3-none-any.whl", hash = "sha256:b8433d481d50b68a0162c0379c0dd4aabfc3d1ad901800beb5b87815997511c1"}, - {file = "boto3-1.34.144.tar.gz", hash = "sha256:2f3e88b10b8fcc5f6100a9d74cd28230edc9d4fa226d99dd40a3ab38ac213673"}, + {file = "boto3-1.34.145-py3-none-any.whl", hash = "sha256:69d5afb7a017d07dd6bdfb680d2912d5d369b3fafa0a45161207d9f393b14d7e"}, + {file = "boto3-1.34.145.tar.gz", hash = "sha256:ac770fb53dde1743aec56bd8e56b7ee2e2f5ad42a37825968ec4ff8428822640"}, ] [package.dependencies] -botocore = ">=1.34.144,<1.35.0" +botocore = ">=1.34.145,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -233,13 +233,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.144" +version = "1.34.145" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.144-py3-none-any.whl", hash = "sha256:a2cf26e1bf10d5917a2285e50257bc44e94a1d16574f282f3274f7a5d8d1f08b"}, - {file = "botocore-1.34.144.tar.gz", hash = "sha256:4215db28d25309d59c99507f1f77df9089e5bebbad35f6e19c7c44ec5383a3e8"}, + {file = "botocore-1.34.145-py3-none-any.whl", hash = "sha256:2e72e262de02adcb0264ac2bac159a28f55dbba8d9e52aa0308773a42950dff5"}, + {file = "botocore-1.34.145.tar.gz", hash = "sha256:edf0fb4c02186ae29b76263ac5fda18b0a085d334a310551c9984407cf1079e6"}, ] [package.dependencies] @@ -460,29 +460,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -[[package]] -name = "cohere" -version = "5.5.8" -description = "" -optional = false -python-versions = "<4.0,>=3.8" -files = [ - {file = "cohere-5.5.8-py3-none-any.whl", hash = "sha256:e1ed84b90eadd13c6a68ee28e378a0bb955f8945eadc6eb7ee126b3399cafd54"}, - {file = "cohere-5.5.8.tar.gz", hash = "sha256:84ce7666ff8fbdf4f41fb5f6ca452ab2639a514bc88967a2854a9b1b820d6ea0"}, -] - -[package.dependencies] -boto3 = ">=1.34.0,<2.0.0" -fastavro = ">=1.9.4,<2.0.0" -httpx = ">=0.21.2" -httpx-sse = ">=0.4.0,<0.5.0" -parameterized = ">=0.9.0,<0.10.0" -pydantic = ">=1.9.2" -requests = ">=2.0.0,<3.0.0" -tokenizers = ">=0.15,<1" -types-requests = ">=2.0.0,<3.0.0" -typing_extensions = ">=4.0.0" - [[package]] name = "colorama" version = "0.4.6" @@ -511,23 +488,6 @@ humanfriendly = ">=9.1" [package.extras] cron = ["capturer (>=2.4)"] -[[package]] -name = "colorlog" -version = "6.8.2" -description = "Add colours to the output of Python's logging module." -optional = false -python-versions = ">=3.6" -files = [ - {file = "colorlog-6.8.2-py3-none-any.whl", hash = "sha256:4dcbb62368e2800cb3c5abd348da7e53f6c362dda502ec27c560b2e58a66bd33"}, - {file = "colorlog-6.8.2.tar.gz", hash = "sha256:3e3e079a41feb5a1b64f978b5ea4f46040a94f11f0e8bbb8261e3dbbeca64d44"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -development = ["black", "flake8", "mypy", "pytest", "types-colorama"] - [[package]] name = "contourpy" version = "1.2.1" @@ -657,43 +617,38 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "42.0.8" +version = "43.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:81d8a521705787afe7a18d5bfb47ea9d9cc068206270aad0b96a725022e18d2e"}, - {file = "cryptography-42.0.8-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:961e61cefdcb06e0c6d7e3a1b22ebe8b996eb2bf50614e89384be54c48c6b63d"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ec3672626e1b9e55afd0df6d774ff0e953452886e06e0f1eb7eb0c832e8902"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e599b53fd95357d92304510fb7bda8523ed1f79ca98dce2f43c115950aa78801"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5226d5d21ab681f432a9c1cf8b658c0cb02533eece706b155e5fbd8a0cdd3949"}, - {file = "cryptography-42.0.8-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6b7c4f03ce01afd3b76cf69a5455caa9cfa3de8c8f493e0d3ab7d20611c8dae9"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:2346b911eb349ab547076f47f2e035fc8ff2c02380a7cbbf8d87114fa0f1c583"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad803773e9df0b92e0a817d22fd8a3675493f690b96130a5e24f1b8fabbea9c7"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:2f66d9cd9147ee495a8374a45ca445819f8929a3efcd2e3df6428e46c3cbb10b"}, - {file = "cryptography-42.0.8-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:d45b940883a03e19e944456a558b67a41160e367a719833c53de6911cabba2b7"}, - {file = "cryptography-42.0.8-cp37-abi3-win32.whl", hash = "sha256:a0c5b2b0585b6af82d7e385f55a8bc568abff8923af147ee3c07bd8b42cda8b2"}, - {file = "cryptography-42.0.8-cp37-abi3-win_amd64.whl", hash = "sha256:57080dee41209e556a9a4ce60d229244f7a66ef52750f813bfbe18959770cfba"}, - {file = "cryptography-42.0.8-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:dea567d1b0e8bc5764b9443858b673b734100c2871dc93163f58c46a97a83d28"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4783183f7cb757b73b2ae9aed6599b96338eb957233c58ca8f49a49cc32fd5e"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0608251135d0e03111152e41f0cc2392d1e74e35703960d4190b2e0f4ca9c70"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dc0fdf6787f37b1c6b08e6dfc892d9d068b5bdb671198c72072828b80bd5fe4c"}, - {file = "cryptography-42.0.8-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9c0c1716c8447ee7dbf08d6db2e5c41c688544c61074b54fc4564196f55c25a7"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fff12c88a672ab9c9c1cf7b0c80e3ad9e2ebd9d828d955c126be4fd3e5578c9e"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:cafb92b2bc622cd1aa6a1dce4b93307792633f4c5fe1f46c6b97cf67073ec961"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:31f721658a29331f895a5a54e7e82075554ccfb8b163a18719d342f5ffe5ecb1"}, - {file = "cryptography-42.0.8-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b297f90c5723d04bcc8265fc2a0f86d4ea2e0f7ab4b6994459548d3a6b992a14"}, - {file = "cryptography-42.0.8-cp39-abi3-win32.whl", hash = "sha256:2f88d197e66c65be5e42cd72e5c18afbfae3f741742070e3019ac8f4ac57262c"}, - {file = "cryptography-42.0.8-cp39-abi3-win_amd64.whl", hash = "sha256:fa76fbb7596cc5839320000cdd5d0955313696d9511debab7ee7278fc8b5c84a"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ba4f0a211697362e89ad822e667d8d340b4d8d55fae72cdd619389fb5912eefe"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:81884c4d096c272f00aeb1f11cf62ccd39763581645b0812e99a91505fa48e0c"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c9bb2ae11bfbab395bdd072985abde58ea9860ed84e59dbc0463a5d0159f5b71"}, - {file = "cryptography-42.0.8-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7016f837e15b0a1c119d27ecd89b3515f01f90a8615ed5e9427e30d9cdbfed3d"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5a94eccb2a81a309806027e1670a358b99b8fe8bfe9f8d329f27d72c094dde8c"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:dec9b018df185f08483f294cae6ccac29e7a6e0678996587363dc352dc65c842"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:343728aac38decfdeecf55ecab3264b015be68fc2816ca800db649607aeee648"}, - {file = "cryptography-42.0.8-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:013629ae70b40af70c9a7a5db40abe5d9054e6f4380e50ce769947b73bf3caad"}, - {file = "cryptography-42.0.8.tar.gz", hash = "sha256:8d09d05439ce7baa8e9e95b07ec5b6c886f548deb7e0f69ef25f64b3bce842f2"}, + {file = "cryptography-43.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:64c3f16e2a4fc51c0d06af28441881f98c5d91009b8caaff40cf3548089e9c74"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dcdedae5c7710b9f97ac6bba7e1052b95c7083c9d0e9df96e02a1932e777895"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d9a1eca329405219b605fac09ecfc09ac09e595d6def650a437523fcd08dd22"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ea9e57f8ea880eeea38ab5abf9fbe39f923544d7884228ec67d666abd60f5a47"}, + {file = "cryptography-43.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9a8d6802e0825767476f62aafed40532bd435e8a5f7d23bd8b4f5fd04cc80ecf"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cc70b4b581f28d0a254d006f26949245e3657d40d8857066c2ae22a61222ef55"}, + {file = "cryptography-43.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4a997df8c1c2aae1e1e5ac49c2e4f610ad037fc5a3aadc7b64e39dea42249431"}, + {file = "cryptography-43.0.0-cp37-abi3-win32.whl", hash = "sha256:6e2b11c55d260d03a8cf29ac9b5e0608d35f08077d8c087be96287f43af3ccdc"}, + {file = "cryptography-43.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:31e44a986ceccec3d0498e16f3d27b2ee5fdf69ce2ab89b52eaad1d2f33d8778"}, + {file = "cryptography-43.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:7b3f5fe74a5ca32d4d0f302ffe6680fcc5c28f8ef0dc0ae8f40c0f3a1b4fca66"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac1955ce000cb29ab40def14fd1bbfa7af2017cca696ee696925615cafd0dce5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299d3da8e00b7e2b54bb02ef58d73cd5f55fb31f33ebbf33bd00d9aa6807df7e"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ee0c405832ade84d4de74b9029bedb7b31200600fa524d218fc29bfa371e97f5"}, + {file = "cryptography-43.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb013933d4c127349b3948aa8aaf2f12c0353ad0eccd715ca789c8a0f671646f"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fdcb265de28585de5b859ae13e3846a8e805268a823a12a4da2597f1f5afc9f0"}, + {file = "cryptography-43.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2905ccf93a8a2a416f3ec01b1a7911c3fe4073ef35640e7ee5296754e30b762b"}, + {file = "cryptography-43.0.0-cp39-abi3-win32.whl", hash = "sha256:47ca71115e545954e6c1d207dd13461ab81f4eccfcb1345eac874828b5e3eaaf"}, + {file = "cryptography-43.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:0663585d02f76929792470451a5ba64424acc3cd5227b03921dab0e2f27b1709"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c6d112bf61c5ef44042c253e4859b3cbbb50df2f78fa8fae6747a7814484a70"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:844b6d608374e7d08f4f6e6f9f7b951f9256db41421917dfb2d003dde4cd6b66"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:51956cf8730665e2bdf8ddb8da0056f699c1a5715648c1b0144670c1ba00b48f"}, + {file = "cryptography-43.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:aae4d918f6b180a8ab8bf6511a419473d107df4dbb4225c7b48c5c9602c38c7f"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:232ce02943a579095a339ac4b390fbbe97f5b5d5d107f8a08260ea2768be8cc2"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5bcb8a5620008a8034d39bce21dc3e23735dfdb6a33a06974739bfa04f853947"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:08a24a7070b2b6804c1940ff0f910ff728932a9d0e80e7814234269f9d46d069"}, + {file = "cryptography-43.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e9c5266c432a1e23738d178e51c2c7a5e2ddf790f248be939448c0ba2021f9d1"}, + {file = "cryptography-43.0.0.tar.gz", hash = "sha256:b88075ada2d51aa9f18283532c9f60e72170041bba88d7f37e49cbb10275299e"}, ] [package.dependencies] @@ -706,7 +661,7 @@ nox = ["nox"] pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "cryptography-vectors (==43.0.0)", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] @@ -801,13 +756,13 @@ optimize = ["orjson"] [[package]] name = "deepeval" -version = "0.21.65" +version = "0.21.68" description = "The open-source evaluation framework for LLMs." optional = false python-versions = "*" files = [ - {file = "deepeval-0.21.65-py3-none-any.whl", hash = "sha256:aa4ffc988f55bb452ec696e5fb5a752e4ec397ea853d59160b0de8eb8d542585"}, - {file = "deepeval-0.21.65.tar.gz", hash = "sha256:9e3ffdfd2208c2e1bcb611ccebf4c5f9aa9af18949a58ebea8c96c4ea7e5a815"}, + {file = "deepeval-0.21.68-py3-none-any.whl", hash = "sha256:eeff7d707f849eef223c560246f04483d4a9bf470170bda772c858d4c88983ea"}, + {file = "deepeval-0.21.68.tar.gz", hash = "sha256:e4c6011952ed6cad014fc341f50a8813966001d7a917616b875089121dc2eafb"}, ] [package.dependencies] @@ -1099,52 +1054,6 @@ typer = ">=0.12.3" [package.extras] standard = ["fastapi", "uvicorn[standard] (>=0.15.0)"] -[[package]] -name = "fastavro" -version = "1.9.5" -description = "Fast read/write of AVRO files" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fastavro-1.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:61253148e95dd2b6457247b441b7555074a55de17aef85f5165bfd5facf600fc"}, - {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b604935d671ad47d888efc92a106f98e9440874108b444ac10e28d643109c937"}, - {file = "fastavro-1.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0adbf4956fd53bd74c41e7855bb45ccce953e0eb0e44f5836d8d54ad843f9944"}, - {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:53d838e31457db8bf44460c244543f75ed307935d5fc1d93bc631cc7caef2082"}, - {file = "fastavro-1.9.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:07b6288e8681eede16ff077632c47395d4925c2f51545cd7a60f194454db2211"}, - {file = "fastavro-1.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:ef08cf247fdfd61286ac0c41854f7194f2ad05088066a756423d7299b688d975"}, - {file = "fastavro-1.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c52d7bb69f617c90935a3e56feb2c34d4276819a5c477c466c6c08c224a10409"}, - {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85e05969956003df8fa4491614bc62fe40cec59e94d06e8aaa8d8256ee3aab82"}, - {file = "fastavro-1.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06e6df8527493a9f0d9a8778df82bab8b1aa6d80d1b004e5aec0a31dc4dc501c"}, - {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:27820da3b17bc01cebb6d1687c9d7254b16d149ef458871aaa207ed8950f3ae6"}, - {file = "fastavro-1.9.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:195a5b8e33eb89a1a9b63fa9dce7a77d41b3b0cd785bac6044df619f120361a2"}, - {file = "fastavro-1.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:be612c109efb727bfd36d4d7ed28eb8e0506617b7dbe746463ebbf81e85eaa6b"}, - {file = "fastavro-1.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b133456c8975ec7d2a99e16a7e68e896e45c821b852675eac4ee25364b999c14"}, - {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf586373c3d1748cac849395aad70c198ee39295f92e7c22c75757b5c0300fbe"}, - {file = "fastavro-1.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:724ef192bc9c55d5b4c7df007f56a46a21809463499856349d4580a55e2b914c"}, - {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bfd11fe355a8f9c0416803afac298960eb4c603a23b1c74ff9c1d3e673ea7185"}, - {file = "fastavro-1.9.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9827d1654d7bcb118ef5efd3e5b2c9ab2a48d44dac5e8c6a2327bc3ac3caa828"}, - {file = "fastavro-1.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:d84b69dca296667e6137ae7c9a96d060123adbc0c00532cc47012b64d38b47e9"}, - {file = "fastavro-1.9.5-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:fb744e9de40fb1dc75354098c8db7da7636cba50a40f7bef3b3fb20f8d189d88"}, - {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:240df8bacd13ff5487f2465604c007d686a566df5cbc01d0550684eaf8ff014a"}, - {file = "fastavro-1.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3bb35c25bbc3904e1c02333bc1ae0173e0a44aa37a8e95d07e681601246e1f1"}, - {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:b47a54a9700de3eabefd36dabfb237808acae47bc873cada6be6990ef6b165aa"}, - {file = "fastavro-1.9.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:48c7b5e6d2f3bf7917af301c275b05c5be3dd40bb04e80979c9e7a2ab31a00d1"}, - {file = "fastavro-1.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:05d13f98d4e325be40387e27da9bd60239968862fe12769258225c62ec906f04"}, - {file = "fastavro-1.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5b47948eb196263f6111bf34e1cd08d55529d4ed46eb50c1bc8c7c30a8d18868"}, - {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85b7a66ad521298ad9373dfe1897a6ccfc38feab54a47b97922e213ae5ad8870"}, - {file = "fastavro-1.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44cb154f863ad80e41aea72a709b12e1533b8728c89b9b1348af91a6154ab2f5"}, - {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5f7f2b1fe21231fd01f1a2a90e714ae267fe633cd7ce930c0aea33d1c9f4901"}, - {file = "fastavro-1.9.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:88fbbe16c61d90a89d78baeb5a34dc1c63a27b115adccdbd6b1fb6f787deacf2"}, - {file = "fastavro-1.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:753f5eedeb5ca86004e23a9ce9b41c5f25eb64a876f95edcc33558090a7f3e4b"}, - {file = "fastavro-1.9.5.tar.gz", hash = "sha256:6419ebf45f88132a9945c51fe555d4f10bb97c236288ed01894f957c6f914553"}, -] - -[package.extras] -codecs = ["cramjam", "lz4", "zstandard"] -lz4 = ["lz4"] -snappy = ["cramjam"] -zstandard = ["zstandard"] - [[package]] name = "faststream" version = "0.4.7" @@ -1562,61 +1471,61 @@ test = ["objgraph", "psutil"] [[package]] name = "grpcio" -version = "1.64.1" +version = "1.65.1" description = "HTTP/2-based RPC framework" optional = false python-versions = ">=3.8" files = [ - {file = "grpcio-1.64.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:55697ecec192bc3f2f3cc13a295ab670f51de29884ca9ae6cd6247df55df2502"}, - {file = "grpcio-1.64.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:3b64ae304c175671efdaa7ec9ae2cc36996b681eb63ca39c464958396697daff"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:bac71b4b28bc9af61efcdc7630b166440bbfbaa80940c9a697271b5e1dabbc61"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c024ffc22d6dc59000faf8ad781696d81e8e38f4078cb0f2630b4a3cf231a90"}, - {file = "grpcio-1.64.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7cd5c1325f6808b8ae31657d281aadb2a51ac11ab081ae335f4f7fc44c1721d"}, - {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0a2813093ddb27418a4c99f9b1c223fab0b053157176a64cc9db0f4557b69bd9"}, - {file = "grpcio-1.64.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2981c7365a9353f9b5c864595c510c983251b1ab403e05b1ccc70a3d9541a73b"}, - {file = "grpcio-1.64.1-cp310-cp310-win32.whl", hash = "sha256:1262402af5a511c245c3ae918167eca57342c72320dffae5d9b51840c4b2f86d"}, - {file = "grpcio-1.64.1-cp310-cp310-win_amd64.whl", hash = "sha256:19264fc964576ddb065368cae953f8d0514ecc6cb3da8903766d9fb9d4554c33"}, - {file = "grpcio-1.64.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:58b1041e7c870bb30ee41d3090cbd6f0851f30ae4eb68228955d973d3efa2e61"}, - {file = "grpcio-1.64.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bbc5b1d78a7822b0a84c6f8917faa986c1a744e65d762ef6d8be9d75677af2ca"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:5841dd1f284bd1b3d8a6eca3a7f062b06f1eec09b184397e1d1d43447e89a7ae"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8caee47e970b92b3dd948371230fcceb80d3f2277b3bf7fbd7c0564e7d39068e"}, - {file = "grpcio-1.64.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73819689c169417a4f978e562d24f2def2be75739c4bed1992435d007819da1b"}, - {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6503b64c8b2dfad299749cad1b595c650c91e5b2c8a1b775380fcf8d2cbba1e9"}, - {file = "grpcio-1.64.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1de403fc1305fd96cfa75e83be3dee8538f2413a6b1685b8452301c7ba33c294"}, - {file = "grpcio-1.64.1-cp311-cp311-win32.whl", hash = "sha256:d4d29cc612e1332237877dfa7fe687157973aab1d63bd0f84cf06692f04c0367"}, - {file = "grpcio-1.64.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e56462b05a6f860b72f0fa50dca06d5b26543a4e88d0396259a07dc30f4e5aa"}, - {file = "grpcio-1.64.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:4657d24c8063e6095f850b68f2d1ba3b39f2b287a38242dcabc166453e950c59"}, - {file = "grpcio-1.64.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:62b4e6eb7bf901719fce0ca83e3ed474ae5022bb3827b0a501e056458c51c0a1"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:ee73a2f5ca4ba44fa33b4d7d2c71e2c8a9e9f78d53f6507ad68e7d2ad5f64a22"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:198908f9b22e2672a998870355e226a725aeab327ac4e6ff3a1399792ece4762"}, - {file = "grpcio-1.64.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39b9d0acaa8d835a6566c640f48b50054f422d03e77e49716d4c4e8e279665a1"}, - {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5e42634a989c3aa6049f132266faf6b949ec2a6f7d302dbb5c15395b77d757eb"}, - {file = "grpcio-1.64.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b1a82e0b9b3022799c336e1fc0f6210adc019ae84efb7321d668129d28ee1efb"}, - {file = "grpcio-1.64.1-cp312-cp312-win32.whl", hash = "sha256:55260032b95c49bee69a423c2f5365baa9369d2f7d233e933564d8a47b893027"}, - {file = "grpcio-1.64.1-cp312-cp312-win_amd64.whl", hash = "sha256:c1a786ac592b47573a5bb7e35665c08064a5d77ab88a076eec11f8ae86b3e3f6"}, - {file = "grpcio-1.64.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:a011ac6c03cfe162ff2b727bcb530567826cec85eb8d4ad2bfb4bd023287a52d"}, - {file = "grpcio-1.64.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4d6dab6124225496010bd22690f2d9bd35c7cbb267b3f14e7a3eb05c911325d4"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:a5e771d0252e871ce194d0fdcafd13971f1aae0ddacc5f25615030d5df55c3a2"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3c1b90ab93fed424e454e93c0ed0b9d552bdf1b0929712b094f5ecfe7a23ad"}, - {file = "grpcio-1.64.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20405cb8b13fd779135df23fabadc53b86522d0f1cba8cca0e87968587f50650"}, - {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0cc79c982ccb2feec8aad0e8fb0d168bcbca85bc77b080d0d3c5f2f15c24ea8f"}, - {file = "grpcio-1.64.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a3a035c37ce7565b8f4f35ff683a4db34d24e53dc487e47438e434eb3f701b2a"}, - {file = "grpcio-1.64.1-cp38-cp38-win32.whl", hash = "sha256:1257b76748612aca0f89beec7fa0615727fd6f2a1ad580a9638816a4b2eb18fd"}, - {file = "grpcio-1.64.1-cp38-cp38-win_amd64.whl", hash = "sha256:0a12ddb1678ebc6a84ec6b0487feac020ee2b1659cbe69b80f06dbffdb249122"}, - {file = "grpcio-1.64.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:75dbbf415026d2862192fe1b28d71f209e2fd87079d98470db90bebe57b33179"}, - {file = "grpcio-1.64.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e3d9f8d1221baa0ced7ec7322a981e28deb23749c76eeeb3d33e18b72935ab62"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:5f8b75f64d5d324c565b263c67dbe4f0af595635bbdd93bb1a88189fc62ed2e5"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c84ad903d0d94311a2b7eea608da163dace97c5fe9412ea311e72c3684925602"}, - {file = "grpcio-1.64.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:940e3ec884520155f68a3b712d045e077d61c520a195d1a5932c531f11883489"}, - {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f10193c69fc9d3d726e83bbf0f3d316f1847c3071c8c93d8090cf5f326b14309"}, - {file = "grpcio-1.64.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ac15b6c2c80a4d1338b04d42a02d376a53395ddf0ec9ab157cbaf44191f3ffdd"}, - {file = "grpcio-1.64.1-cp39-cp39-win32.whl", hash = "sha256:03b43d0ccf99c557ec671c7dede64f023c7da9bb632ac65dbc57f166e4970040"}, - {file = "grpcio-1.64.1-cp39-cp39-win_amd64.whl", hash = "sha256:ed6091fa0adcc7e4ff944090cf203a52da35c37a130efa564ded02b7aff63bcd"}, - {file = "grpcio-1.64.1.tar.gz", hash = "sha256:8d51dd1c59d5fa0f34266b80a3805ec29a1f26425c2a54736133f6d87fc4968a"}, + {file = "grpcio-1.65.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:3dc5f928815b8972fb83b78d8db5039559f39e004ec93ebac316403fe031a062"}, + {file = "grpcio-1.65.1-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:8333ca46053c35484c9f2f7e8d8ec98c1383a8675a449163cea31a2076d93de8"}, + {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:7af64838b6e615fff0ec711960ed9b6ee83086edfa8c32670eafb736f169d719"}, + {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbb64b4166362d9326f7efbf75b1c72106c1aa87f13a8c8b56a1224fac152f5c"}, + {file = "grpcio-1.65.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8422dc13ad93ec8caa2612b5032a2b9cd6421c13ed87f54db4a3a2c93afaf77"}, + {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:4effc0562b6c65d4add6a873ca132e46ba5e5a46f07c93502c37a9ae7f043857"}, + {file = "grpcio-1.65.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a6c71575a2fedf259724981fd73a18906513d2f306169c46262a5bae956e6364"}, + {file = "grpcio-1.65.1-cp310-cp310-win32.whl", hash = "sha256:34966cf526ef0ea616e008d40d989463e3db157abb213b2f20c6ce0ae7928875"}, + {file = "grpcio-1.65.1-cp310-cp310-win_amd64.whl", hash = "sha256:ca931de5dd6d9eb94ff19a2c9434b23923bce6f767179fef04dfa991f282eaad"}, + {file = "grpcio-1.65.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:bbb46330cc643ecf10bd9bd4ca8e7419a14b6b9dedd05f671c90fb2c813c6037"}, + {file = "grpcio-1.65.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d827a6fb9215b961eb73459ad7977edb9e748b23e3407d21c845d1d8ef6597e5"}, + {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:6e71aed8835f8d9fbcb84babc93a9da95955d1685021cceb7089f4f1e717d719"}, + {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a1c84560b3b2d34695c9ba53ab0264e2802721c530678a8f0a227951f453462"}, + {file = "grpcio-1.65.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27adee2338d697e71143ed147fe286c05810965d5d30ec14dd09c22479bfe48a"}, + {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f62652ddcadc75d0e7aa629e96bb61658f85a993e748333715b4ab667192e4e8"}, + {file = "grpcio-1.65.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:71a05fd814700dd9cb7d9a507f2f6a1ef85866733ccaf557eedacec32d65e4c2"}, + {file = "grpcio-1.65.1-cp311-cp311-win32.whl", hash = "sha256:b590f1ad056294dfaeac0b7e1b71d3d5ace638d8dd1f1147ce4bd13458783ba8"}, + {file = "grpcio-1.65.1-cp311-cp311-win_amd64.whl", hash = "sha256:12e9bdf3b5fd48e5fbe5b3da382ad8f97c08b47969f3cca81dd9b36b86ed39e2"}, + {file = "grpcio-1.65.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:54cb822e177374b318b233e54b6856c692c24cdbd5a3ba5335f18a47396bac8f"}, + {file = "grpcio-1.65.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:aaf3c54419a28d45bd1681372029f40e5bfb58e5265e3882eaf21e4a5f81a119"}, + {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:557de35bdfbe8bafea0a003dbd0f4da6d89223ac6c4c7549d78e20f92ead95d9"}, + {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8bfd95ef3b097f0cc86ade54eafefa1c8ed623aa01a26fbbdcd1a3650494dd11"}, + {file = "grpcio-1.65.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e6a8f3d6c41e6b642870afe6cafbaf7b61c57317f9ec66d0efdaf19db992b90"}, + {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1faaf7355ceed07ceaef0b9dcefa4c98daf1dd8840ed75c2de128c3f4a4d859d"}, + {file = "grpcio-1.65.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:60f1f38eed830488ad2a1b11579ef0f345ff16fffdad1d24d9fbc97ba31804ff"}, + {file = "grpcio-1.65.1-cp312-cp312-win32.whl", hash = "sha256:e75acfa52daf5ea0712e8aa82f0003bba964de7ae22c26d208cbd7bc08500177"}, + {file = "grpcio-1.65.1-cp312-cp312-win_amd64.whl", hash = "sha256:ff5a84907e51924973aa05ed8759210d8cdae7ffcf9e44fd17646cf4a902df59"}, + {file = "grpcio-1.65.1-cp38-cp38-linux_armv7l.whl", hash = "sha256:1fbd6331f18c3acd7e09d17fd840c096f56eaf0ef830fbd50af45ae9dc8dfd83"}, + {file = "grpcio-1.65.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:de5b6be29116e094c5ef9d9e4252e7eb143e3d5f6bd6d50a78075553ab4930b0"}, + {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:e4a3cdba62b2d6aeae6027ae65f350de6dc082b72e6215eccf82628e79efe9ba"}, + {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941c4869aa229d88706b78187d60d66aca77fe5c32518b79e3c3e03fc26109a2"}, + {file = "grpcio-1.65.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f40cebe5edb518d78b8131e87cb83b3ee688984de38a232024b9b44e74ee53d3"}, + {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2ca684ba331fb249d8a1ce88db5394e70dbcd96e58d8c4b7e0d7b141a453dce9"}, + {file = "grpcio-1.65.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8558f0083ddaf5de64a59c790bffd7568e353914c0c551eae2955f54ee4b857f"}, + {file = "grpcio-1.65.1-cp38-cp38-win32.whl", hash = "sha256:8d8143a3e3966f85dce6c5cc45387ec36552174ba5712c5dc6fcc0898fb324c0"}, + {file = "grpcio-1.65.1-cp38-cp38-win_amd64.whl", hash = "sha256:76e81a86424d6ca1ce7c16b15bdd6a964a42b40544bf796a48da241fdaf61153"}, + {file = "grpcio-1.65.1-cp39-cp39-linux_armv7l.whl", hash = "sha256:cb5175f45c980ff418998723ea1b3869cce3766d2ab4e4916fbd3cedbc9d0ed3"}, + {file = "grpcio-1.65.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b12c1aa7b95abe73b3e04e052c8b362655b41c7798da69f1eaf8d186c7d204df"}, + {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:3019fb50128b21a5e018d89569ffaaaa361680e1346c2f261bb84a91082eb3d3"}, + {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ae15275ed98ea267f64ee9ddedf8ecd5306a5b5bb87972a48bfe24af24153e8"}, + {file = "grpcio-1.65.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f096ffb881f37e8d4f958b63c74bfc400c7cebd7a944b027357cd2fb8d91a57"}, + {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2f56b5a68fdcf17a0a1d524bf177218c3c69b3947cb239ea222c6f1867c3ab68"}, + {file = "grpcio-1.65.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:941596d419b9736ab548aa0feb5bbba922f98872668847bf0720b42d1d227b9e"}, + {file = "grpcio-1.65.1-cp39-cp39-win32.whl", hash = "sha256:5fd7337a823b890215f07d429f4f193d24b80d62a5485cf88ee06648591a0c57"}, + {file = "grpcio-1.65.1-cp39-cp39-win_amd64.whl", hash = "sha256:1bceeec568372cbebf554eae1b436b06c2ff24cfaf04afade729fb9035408c6c"}, + {file = "grpcio-1.65.1.tar.gz", hash = "sha256:3c492301988cd720cd145d84e17318d45af342e29ef93141228f9cd73222368b"}, ] [package.extras] -protobuf = ["grpcio-tools (>=1.64.1)"] +protobuf = ["grpcio-tools (>=1.65.1)"] [[package]] name = "grpcio-status" @@ -1738,26 +1647,15 @@ cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -[[package]] -name = "httpx-sse" -version = "0.4.0" -description = "Consume Server-Sent Event (SSE) messages with HTTPX." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721"}, - {file = "httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f"}, -] - [[package]] name = "huggingface-hub" -version = "0.23.5" +version = "0.24.0" description = "Client library to download and publish models, datasets and other repos on the huggingface.co hub" optional = false python-versions = ">=3.8.0" files = [ - {file = "huggingface_hub-0.23.5-py3-none-any.whl", hash = "sha256:d7a7d337615e11a45cc14a0ce5a605db6b038dc24af42866f731684825226e90"}, - {file = "huggingface_hub-0.23.5.tar.gz", hash = "sha256:67a9caba79b71235be3752852ca27da86bd54311d2424ca8afdb8dda056edf98"}, + {file = "huggingface_hub-0.24.0-py3-none-any.whl", hash = "sha256:7ad92edefb93d8145c061f6df8d99df2ff85f8379ba5fac8a95aca0642afa5d7"}, + {file = "huggingface_hub-0.24.0.tar.gz", hash = "sha256:6c7092736b577d89d57b3cdfea026f1b0dc2234ae783fa0d59caf1bf7d52dfa7"}, ] [package.dependencies] @@ -1770,17 +1668,17 @@ tqdm = ">=4.42.1" typing-extensions = ">=3.7.4.3" [package.extras] -all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +all = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] cli = ["InquirerPy (==0.3.4)"] -dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.3.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] +dev = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "mypy (==1.5.1)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "ruff (>=0.5.0)", "soundfile", "types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)", "urllib3 (<2.0)"] fastai = ["fastai (>=2.4)", "fastcore (>=1.3.27)", "toml"] hf-transfer = ["hf-transfer (>=0.1.4)"] inference = ["aiohttp", "minijinja (>=1.0)"] -quality = ["mypy (==1.5.1)", "ruff (>=0.3.0)"] +quality = ["mypy (==1.5.1)", "ruff (>=0.5.0)"] tensorflow = ["graphviz", "pydot", "tensorflow"] tensorflow-testing = ["keras (<3.0)", "tensorflow"] -testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] -torch = ["safetensors", "torch"] +testing = ["InquirerPy (==0.3.4)", "Jinja2", "Pillow", "aiohttp", "fastapi", "gradio", "jedi", "minijinja (>=1.0)", "numpy", "pytest (>=8.1.1,<8.2.2)", "pytest-asyncio", "pytest-cov", "pytest-env", "pytest-mock", "pytest-rerunfailures", "pytest-vcr", "pytest-xdist", "soundfile", "urllib3 (<2.0)"] +torch = ["safetensors[torch]", "torch"] typing = ["types-PyYAML", "types-requests", "types-simplejson", "types-toml", "types-tqdm", "types-urllib3", "typing-extensions (>=4.8.0)"] [[package]] @@ -2114,18 +2012,18 @@ testing = ["matplotlib (>=2.2.5)", "pytest (>=5.0.1)", "pytest-cov (>=3.0.0)"] [[package]] name = "langchain" -version = "0.2.8" +version = "0.2.10" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain-0.2.8-py3-none-any.whl", hash = "sha256:53e7dfe50294a14200f33bec22b4e14cb63857ccf0a5500b0d18b0fd51285d58"}, - {file = "langchain-0.2.8.tar.gz", hash = "sha256:7fecb309e3558cde4e5cf7e9ffb7c1ab3f07121c40a7ff3b0c27135f8120c296"}, + {file = "langchain-0.2.10-py3-none-any.whl", hash = "sha256:b4fb58c7faf4f4999cfe3325474979a7121a1737dd101655a723a1d957ef0617"}, + {file = "langchain-0.2.10.tar.gz", hash = "sha256:1f861c1b59ac9c91b02bb0fa58d3adad1c1d0686636872b5b357bbce3ce41d06"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" -langchain-core = ">=0.2.19,<0.3.0" +langchain-core = ">=0.2.22,<0.3.0" langchain-text-splitters = ">=0.2.0,<0.3.0" langsmith = ">=0.1.17,<0.2.0" numpy = {version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""} @@ -2137,20 +2035,20 @@ tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<9.0.0" [[package]] name = "langchain-community" -version = "0.2.7" +version = "0.2.9" description = "Community contributed LangChain integrations." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_community-0.2.7-py3-none-any.whl", hash = "sha256:c236e74249ab68a318c94c95327cbe75a76489b61f7bf93f14117d9233ce70b1"}, - {file = "langchain_community-0.2.7.tar.gz", hash = "sha256:f52659dbb8a8f0c011cc7d634247686d11d768843cc3e5fe9e6f52321cde82c0"}, + {file = "langchain_community-0.2.9-py3-none-any.whl", hash = "sha256:b51d3adf9346a1161c1098917585b9e303cf24e2f5c71f5d232a0504edada5f2"}, + {file = "langchain_community-0.2.9.tar.gz", hash = "sha256:1e7c180232916cbe35fe00509680dd1f805e32d7c87b5e80b3a9ec8754ecae37"}, ] [package.dependencies] aiohttp = ">=3.8.3,<4.0.0" dataclasses-json = ">=0.5.7,<0.7" -langchain = ">=0.2.7,<0.3.0" -langchain-core = ">=0.2.12,<0.3.0" +langchain = ">=0.2.9,<0.3.0" +langchain-core = ">=0.2.22,<0.3.0" langsmith = ">=0.1.0,<0.2.0" numpy = {version = ">=1.26.0,<2.0.0", markers = "python_version >= \"3.12\""} PyYAML = ">=5.3" @@ -2160,13 +2058,13 @@ tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<9.0.0" [[package]] name = "langchain-core" -version = "0.2.19" +version = "0.2.22" description = "Building applications with LLMs through composability" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_core-0.2.19-py3-none-any.whl", hash = "sha256:5b3cd34395be274c89e822c84f0e03c4da14168c177a83921c5b9414ac7a0651"}, - {file = "langchain_core-0.2.19.tar.gz", hash = "sha256:13043a83e5c9ab58b9f5ce2a56896e7e88b752e8891b2958960a98e71801471e"}, + {file = "langchain_core-0.2.22-py3-none-any.whl", hash = "sha256:7731a86440c0958b3186c003fb9b26b2d5a682a6344bda7bfb9174e2898f8b43"}, + {file = "langchain_core-0.2.22.tar.gz", hash = "sha256:582d6f929a43b830139444e4124123cd415331ad62f25757b1406252958cdcac"}, ] [package.dependencies] @@ -2197,17 +2095,17 @@ langchain-core = ">=0.1.50,<0.3" [[package]] name = "langchain-openai" -version = "0.1.16" +version = "0.1.17" description = "An integration package connecting OpenAI and LangChain" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchain_openai-0.1.16-py3-none-any.whl", hash = "sha256:bff90e9d0be786495920a7851ae4d55247fb084d3a11d1b15bfe91904ce1cb0f"}, - {file = "langchain_openai-0.1.16.tar.gz", hash = "sha256:3dedcc785a64a488ad6a313cc59b0dccea025d27413b55cec73a20dcf3ded4da"}, + {file = "langchain_openai-0.1.17-py3-none-any.whl", hash = "sha256:30bef5574ecbbbb91b8025b2dc5a1bd81fd62157d3ad1a35d820141f31c5b443"}, + {file = "langchain_openai-0.1.17.tar.gz", hash = "sha256:c5d70ddecdcb93e146f376bdbadbb6ec69de9ac0f402cd5b83de50b655ba85ee"}, ] [package.dependencies] -langchain-core = ">=0.2.17,<0.3.0" +langchain-core = ">=0.2.20,<0.3.0" openai = ">=1.32.0,<2.0.0" tiktoken = ">=0.7,<1" @@ -2241,13 +2139,13 @@ six = "*" [[package]] name = "langsmith" -version = "0.1.86" +version = "0.1.93" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.86-py3-none-any.whl", hash = "sha256:55ed80cc6e98f9761f9b3ec3c49e01f6745d13e40bef80d9f831acabfd9a8a1e"}, - {file = "langsmith-0.1.86.tar.gz", hash = "sha256:2e66577817253327b99b727588c3173fbba217fe0ca07ac6b7cdd23fc4894104"}, + {file = "langsmith-0.1.93-py3-none-any.whl", hash = "sha256:811210b9d5f108f36431bd7b997eb9476a9ecf5a2abd7ddbb606c1cdcf0f43ce"}, + {file = "langsmith-0.1.93.tar.gz", hash = "sha256:285b6ad3a54f50fa8eb97b5f600acc57d0e37e139dd8cf2111a117d0435ba9b4"}, ] [package.dependencies] @@ -2290,13 +2188,13 @@ tesseract = ["pytesseract"] [[package]] name = "litellm" -version = "1.41.23" +version = "1.41.25" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.41.23-py3-none-any.whl", hash = "sha256:ccfe7763e694ae43b50229fc78bb999a18507b654ec2046c55c6e2a2ea48bf96"}, - {file = "litellm-1.41.23.tar.gz", hash = "sha256:320afcd172fb936f1297ce135075e3397141cf245cdb936f01871c9d6ed56516"}, + {file = "litellm-1.41.25-py3-none-any.whl", hash = "sha256:80ef35f141402be4ef106a9c720169f6f613ff47df717ab3d1b8ba845c2a5b38"}, + {file = "litellm-1.41.25.tar.gz", hash = "sha256:f6f000b8e666b51914436c26659d4a91d67b350bcc44e47b3837d3b8f0e1640d"}, ] [package.dependencies] @@ -3220,13 +3118,13 @@ sympy = "*" [[package]] name = "openai" -version = "1.35.14" +version = "1.36.1" description = "The official Python library for the openai API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-1.35.14-py3-none-any.whl", hash = "sha256:adadf8c176e0b8c47ad782ed45dc20ef46438ee1f02c7103c4155cff79c8f68b"}, - {file = "openai-1.35.14.tar.gz", hash = "sha256:394ba1dfd12ecec1d634c50e512d24ff1858bbc2674ffcce309b822785a058de"}, + {file = "openai-1.36.1-py3-none-any.whl", hash = "sha256:d399b9d476dbbc167aceaac6bc6ed0b2e2bb6c9e189c7f7047f822743ae62e64"}, + {file = "openai-1.36.1.tar.gz", hash = "sha256:41be9e0302e95dba8a9374b885c5cb1cec2202816a70b98736fee25a2cadd1f2"}, ] [package.dependencies] @@ -3521,20 +3419,6 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] -[[package]] -name = "parameterized" -version = "0.9.0" -description = "Parameterized testing with any Python test framework" -optional = false -python-versions = ">=3.7" -files = [ - {file = "parameterized-0.9.0-py2.py3-none-any.whl", hash = "sha256:4e0758e3d41bea3bbd05ec14fc2c24736723f243b28d702081aef438c9372b1b"}, - {file = "parameterized-0.9.0.tar.gz", hash = "sha256:7fc905272cefa4f364c1a3429cbbe9c0f98b793988efb5bf90aac80f08db09b1"}, -] - -[package.extras] -dev = ["jinja2"] - [[package]] name = "pdf2image" version = "1.17.0" @@ -4195,13 +4079,13 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pypdf" -version = "4.3.0" +version = "4.3.1" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" optional = false python-versions = ">=3.6" files = [ - {file = "pypdf-4.3.0-py3-none-any.whl", hash = "sha256:eeea4d019b57c099d02a0e1692eaaab23341ae3f255c1dafa3c8566b4636496d"}, - {file = "pypdf-4.3.0.tar.gz", hash = "sha256:0d7a4c67fd03782f5a09d3f48c11c7a31e0bb9af78861a25229bb49259ed0504"}, + {file = "pypdf-4.3.1-py3-none-any.whl", hash = "sha256:64b31da97eda0771ef22edb1bfecd5deee4b72c3d1736b7df2689805076d6418"}, + {file = "pypdf-4.3.1.tar.gz", hash = "sha256:b2f37fe9a3030aa97ca86067a56ba3f9d3565f9a791b305c7355d8392c30d91b"}, ] [package.extras] @@ -4271,33 +4155,33 @@ Pillow = ">=8.0.0" [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, + {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, + {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.23.7" +version = "0.23.8" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest_asyncio-0.23.7-py3-none-any.whl", hash = "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b"}, - {file = "pytest_asyncio-0.23.7.tar.gz", hash = "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268"}, + {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, + {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, ] [package.dependencies] @@ -4919,23 +4803,6 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "requests-mock" -version = "1.12.1" -description = "Mock out responses from the requests package" -optional = false -python-versions = ">=3.5" -files = [ - {file = "requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"}, - {file = "requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563"}, -] - -[package.dependencies] -requests = ">=2.22,<3" - -[package.extras] -fixture = ["fixtures"] - [[package]] name = "requests-toolbelt" version = "1.0.0" @@ -5290,42 +5157,6 @@ dev = ["cython-lint (>=0.12.2)", "doit (>=0.36.0)", "mypy (==1.10.0)", "pycodest doc = ["jupyterlite-pyodide-kernel", "jupyterlite-sphinx (>=0.13.1)", "jupytext", "matplotlib (>=3.5)", "myst-nb", "numpydoc", "pooch", "pydata-sphinx-theme (>=0.15.2)", "sphinx (>=5.0.0)", "sphinx-design (>=0.4.0)"] test = ["Cython", "array-api-strict", "asv", "gmpy2", "hypothesis (>=6.30)", "meson", "mpmath", "ninja", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] -[[package]] -name = "semantic-router" -version = "0.0.48" -description = "Super fast semantic router for AI decision making" -optional = false -python-versions = "<3.13,>=3.9" -files = [ - {file = "semantic_router-0.0.48-py3-none-any.whl", hash = "sha256:830ae0a3eb278d4154b369d3f8c4484ecb48a87512fdbf63cd9bdda3894fb883"}, - {file = "semantic_router-0.0.48.tar.gz", hash = "sha256:23427c921ae9f2261d7e914896afb13e16890cec087320a9e5adf031d23524fe"}, -] - -[package.dependencies] -aiohttp = ">=3.9.5,<4.0.0" -cohere = ">=5.00,<6.00" -colorama = ">=0.4.6,<0.5.0" -colorlog = ">=6.8.0,<7.0.0" -numpy = ">=1.25.2,<2.0.0" -openai = ">=1.10.0,<2.0.0" -pydantic = ">=2.5.3,<3.0.0" -pyyaml = ">=6.0.1,<7.0.0" -regex = ">=2023.12.25" -requests-mock = ">=1.12.1,<2.0.0" -tiktoken = ">=0.6.0,<1.0.0" - -[package.extras] -bedrock = ["boto3 (>=1.34.98,<2.0.0)", "botocore (>=1.34.110,<2.0.0)"] -fastembed = ["fastembed (>=0.3.0,<0.4.0)"] -google = ["google-cloud-aiplatform (>=1.45.0,<2.0.0)"] -hybrid = ["pinecone-text (>=0.7.1,<0.10.0)"] -local = ["llama-cpp-python (>=0.2.28,<0.3.0)", "tokenizers (>=0.19)", "torch (>=2.1.0,<2.6.0)", "transformers (>=4.36.2)"] -mistralai = ["mistralai (>=0.0.12,<0.1.0)"] -pinecone = ["pinecone-client (>=3.0.0,<4.0.0)"] -processing = ["matplotlib (>=3.8.3,<4.0.0)"] -qdrant = ["qdrant-client (>=1.8.0,<2.0.0)"] -vision = ["pillow (>=10.2.0,<11.0.0)", "torch (>=2.1.0,<2.6.0)", "torchvision (>=0.17.0,<0.18.0)", "transformers (>=4.36.2)"] - [[package]] name = "sentry-sdk" version = "2.10.0" @@ -5641,13 +5472,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "sympy" -version = "1.13.0" +version = "1.13.1" description = "Computer algebra system (CAS) in Python" optional = false python-versions = ">=3.8" files = [ - {file = "sympy-1.13.0-py3-none-any.whl", hash = "sha256:6b0b32a4673fb91bd3cac3b55406c8e01d53ae22780be467301cc452f6680c92"}, - {file = "sympy-1.13.0.tar.gz", hash = "sha256:3b6af8f4d008b9a1a6a4268b335b984b23835f26d1d60b0526ebc71d48a25f57"}, + {file = "sympy-1.13.1-py3-none-any.whl", hash = "sha256:db36cdc64bf61b9b24578b6f7bab1ecdd2452cf008f34faa33776680c26d66f8"}, + {file = "sympy-1.13.1.tar.gz", hash = "sha256:9cebf7e04ff162015ce31c9c6c9144daa34a93bd082f54fd8f12deca4f47515f"}, ] [package.dependencies] @@ -6075,20 +5906,6 @@ rich = ">=10.11.0" shellingham = ">=1.3.0" typing-extensions = ">=3.7.4.3" -[[package]] -name = "types-requests" -version = "2.32.0.20240712" -description = "Typing stubs for requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-requests-2.32.0.20240712.tar.gz", hash = "sha256:90c079ff05e549f6bf50e02e910210b98b8ff1ebdd18e19c873cd237737c1358"}, - {file = "types_requests-2.32.0.20240712-py3-none-any.whl", hash = "sha256:f754283e152c752e46e70942fa2a146b5bc70393522257bb85bd1ef7e019dcc3"}, -] - -[package.dependencies] -urllib3 = ">=2" - [[package]] name = "typing-extensions" version = "4.12.2" @@ -6336,13 +6153,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.30.1" +version = "0.30.3" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, - {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, + {file = "uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503"}, + {file = "uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81"}, ] [package.dependencies] @@ -6943,4 +6760,4 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools", [metadata] lock-version = "2.0" python-versions = ">=3.12,<3.13" -content-hash = "2dbe48e530e96ef0dcaf2bdd7022ab2e868cf5a540d8e4a6fa8d06d022565bbd" +content-hash = "e8165ce15080962981384a39086226610037dc3710a6edac2ce15b9721559ee2" diff --git a/core-api/pyproject.toml b/core-api/pyproject.toml index 8cb7d9957..cf7e871bb 100644 --- a/core-api/pyproject.toml +++ b/core-api/pyproject.toml @@ -18,7 +18,6 @@ pydantic = "^2.7.1" langchain = "^0.2.6" tiktoken = "^0.7.0" boto3 = "^1.34.139" -semantic-router = "^0.0.48" faststream = {extras = ["redis"], version = "<0.5.0"} fastapi = "^0.111.0" uvicorn = "^0.30.1" From b0991068a3f525e5123328a3c6c447db9a46ccd0 Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 10:24:55 +0100 Subject: [PATCH 5/9] Ruff --- redbox-core/redbox/models/chain.py | 1 - 1 file changed, 1 deletion(-) diff --git a/redbox-core/redbox/models/chain.py b/redbox-core/redbox/models/chain.py index 9d1697364..b12cc8f2c 100644 --- a/redbox-core/redbox/models/chain.py +++ b/redbox-core/redbox/models/chain.py @@ -9,7 +9,6 @@ from langchain_core.pydantic_v1 import BaseModel, Field - class ChainChatMessage(TypedDict): role: str text: str From 24ca734b518a157d1a2b86c714b11c0f2ac757af Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 10:57:34 +0100 Subject: [PATCH 6/9] Improved types in ChainInput --- redbox-core/redbox/models/chain.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/redbox-core/redbox/models/chain.py b/redbox-core/redbox/models/chain.py index b12cc8f2c..eb2a27e9d 100644 --- a/redbox-core/redbox/models/chain.py +++ b/redbox-core/redbox/models/chain.py @@ -5,17 +5,18 @@ used in conjunction with langchain this is the tidiest boxing of pydantic v1 we can do """ -from typing import TypedDict +from typing import TypedDict, Literal +from uuid import UUID from langchain_core.pydantic_v1 import BaseModel, Field class ChainChatMessage(TypedDict): - role: str + role: Literal["user", "ai", "system"] text: str class ChainInput(BaseModel): question: str = Field(description="The last user chat message") - file_uuids: list[str] = Field(description="List of files to process") - user_uuid: str = Field(description="User the chain in executing for") + file_uuids: list[UUID] = Field(description="List of files to process") + user_uuid: UUID = Field(description="User the chain in executing for") chat_history: list[ChainChatMessage] = Field(description="All previous messages in chat (excluding question)") From 0b2a261b7cb02c89b2a28f1f62cabde12e9a70cf Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 11:01:53 +0100 Subject: [PATCH 7/9] Fixing core-api tests --- core-api/tests/routes/test_chat.py | 1 - 1 file changed, 1 deletion(-) diff --git a/core-api/tests/routes/test_chat.py b/core-api/tests/routes/test_chat.py index 6d2929b22..79bc99b91 100644 --- a/core-api/tests/routes/test_chat.py +++ b/core-api/tests/routes/test_chat.py @@ -15,7 +15,6 @@ from langchain_core.prompt_values import ChatPromptValue from langchain_core.runnables import Runnable, RunnableLambda from langchain_core.runnables.schema import StreamEvent -from semantic_router.encoders import TfidfEncoder from starlette.websockets import WebSocketDisconnect from redbox.models.chat import ChatResponse, ChatRoute From eb7e330173643b4af008a53c7864a2c69d13b09f Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 11:03:34 +0100 Subject: [PATCH 8/9] Removing unnecessary test mock in core-api --- core-api/tests/routes/test_chat.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core-api/tests/routes/test_chat.py b/core-api/tests/routes/test_chat.py index 79bc99b91..362f424ae 100644 --- a/core-api/tests/routes/test_chat.py +++ b/core-api/tests/routes/test_chat.py @@ -91,13 +91,6 @@ def mock_all_chunks_retriever(alice): return RunnableLambda(lambda _: docs) -def mock_semantic_route_encoder(): - encoder = TfidfEncoder() - routes = semantic_routes.get_semantic_routes() - encoder.fit(routes) - return encoder - - @pytest.fixture(scope="session") def mock_client(alice): chat_app.dependency_overrides[dependencies.get_llm] = mock_get_llm([RAG_LLM_RESPONSE] * 32) From c85d3b555b41b5e88e3fc7e2609c4b27600a8cda Mon Sep 17 00:00:00 2001 From: jamesrichards Date: Mon, 22 Jul 2024 11:29:56 +0100 Subject: [PATCH 9/9] Correcting journey tests --- tests/test_journey.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_journey.py b/tests/test_journey.py index d0d3de735..920ea7ad2 100644 --- a/tests/test_journey.py +++ b/tests/test_journey.py @@ -95,8 +95,6 @@ def test_user_journey(page: Page, email_address: str): ("chat", True, False), ("search", False, True), ("search", True, True), - ("summarise", False, False), - ("summarise", True, False), ("info", False, False), ]: question = f"@{route} What do I need to install?"