From 939106596db672cad13323236d5b9fc4326348b5 Mon Sep 17 00:00:00 2001 From: Nuno Campos Date: Mon, 20 Nov 2023 11:31:10 +0000 Subject: [PATCH] Reorganize api --- backend/app/api/__init__.py | 23 ++ backend/app/api/assistants.py | 59 ++++ backend/app/api/runs.py | 200 ++++++++++++ backend/app/api/threads.py | 51 ++++ backend/app/schema.py | 14 + backend/app/server.py | 284 +----------------- backend/app/storage.py | 4 +- backend/app/stream.py | 14 +- .../agent_executor/permchain.py | 10 +- .../packages/gizmo-agent/gizmo_agent/main.py | 2 +- .../packages/gizmo-agent/gizmo_agent/tools.py | 4 +- backend/poetry.lock | 36 ++- backend/pyproject.toml | 6 +- frontend/src/hooks/useSchemas.ts | 18 +- frontend/vite.config.ts | 11 +- 15 files changed, 404 insertions(+), 332 deletions(-) create mode 100644 backend/app/api/__init__.py create mode 100644 backend/app/api/assistants.py create mode 100644 backend/app/api/runs.py create mode 100644 backend/app/api/threads.py diff --git a/backend/app/api/__init__.py b/backend/app/api/__init__.py new file mode 100644 index 00000000..25ecacf2 --- /dev/null +++ b/backend/app/api/__init__.py @@ -0,0 +1,23 @@ +from fastapi import APIRouter + +from app.api.assistants import router as assistants_router +from app.api.runs import router as runs_router +from app.api.threads import router as threads_router + +router = APIRouter() + +router.include_router( + assistants_router, + prefix="/assistants", + tags=["assistants"], +) +router.include_router( + runs_router, + prefix="/runs", + tags=["runs"], +) +router.include_router( + threads_router, + prefix="/threads", + tags=["threads"], +) diff --git a/backend/app/api/assistants.py b/backend/app/api/assistants.py new file mode 100644 index 00000000..ceae27d8 --- /dev/null +++ b/backend/app/api/assistants.py @@ -0,0 +1,59 @@ +from typing import Annotated, List, Optional + +from fastapi import APIRouter, Cookie, Path, Query +from pydantic import BaseModel, Field + +import app.storage as storage +from app.schema import Assistant, AssistantWithoutUserId, OpengptsUserId + +router = APIRouter() + +FEATURED_PUBLIC_ASSISTANTS = [ + "ba721964-b7e4-474c-b817-fb089d94dc5f", + "dc3ec482-aafc-4d90-8a1a-afb9b2876cde", +] + + +@router.get("/") +def list_assistants(opengpts_user_id: OpengptsUserId) -> List[AssistantWithoutUserId]: + """List all assistants for the current user.""" + return storage.list_assistants(opengpts_user_id) + + +@router.get("/public/") +def list_public_assistants( + shared_id: Annotated[ + Optional[str], Query(description="ID of a publicly shared assistant.") + ] = None, +) -> List[AssistantWithoutUserId]: + """List all public assistants.""" + return storage.list_public_assistants( + FEATURED_PUBLIC_ASSISTANTS + ([shared_id] if shared_id else []) + ) + + +class AssistantPayload(BaseModel): + """Payload for creating an assistant.""" + + name: str = Field(..., description="The name of the assistant.") + config: dict = Field(..., description="The assistant config.") + public: bool = Field(default=False, description="Whether the assistant is public.") + + +AssistantID = Annotated[str, Path(description="The ID of the assistant.")] + + +@router.put("/{aid}") +def put_assistant( + opengpts_user_id: Annotated[str, Cookie()], + aid: AssistantID, + payload: AssistantPayload, +) -> Assistant: + """Create or update an assistant.""" + return storage.put_assistant( + opengpts_user_id, + aid, + name=payload.name, + config=payload.config, + public=payload.public, + ) diff --git a/backend/app/api/runs.py b/backend/app/api/runs.py new file mode 100644 index 00000000..b35cf5d7 --- /dev/null +++ b/backend/app/api/runs.py @@ -0,0 +1,200 @@ +import asyncio +import json +from typing import AsyncIterator, Sequence +from uuid import uuid4 + +import langsmith.client +import orjson +from fastapi import APIRouter, BackgroundTasks, HTTPException, Request +from fastapi.exceptions import RequestValidationError +from gizmo_agent import agent +from langchain.pydantic_v1 import ValidationError +from langchain.schema.messages import AnyMessage, FunctionMessage +from langchain.schema.output import ChatGeneration +from langchain.schema.runnable import RunnableConfig +from langserve.callbacks import AsyncEventAggregatorCallback +from langserve.schema import FeedbackCreateRequest +from langserve.serialization import WellKnownLCSerializer +from langserve.server import _get_base_run_id_as_str, _unpack_input +from langsmith.utils import tracing_is_enabled +from pydantic import BaseModel +from sse_starlette import EventSourceResponse + +from app.schema import OpengptsUserId +from app.storage import get_assistant, get_thread_messages, public_user_id +from app.stream import StreamMessagesHandler + +router = APIRouter() + + +_serializer = WellKnownLCSerializer() + + +class AgentInput(BaseModel): + """An input into an agent.""" + + messages: Sequence[AnyMessage] + + +class CreateRunPayload(BaseModel): + """Payload for creating a run.""" + + assistant_id: str + thread_id: str + stream: bool + # TODO make optional + input: AgentInput + + +@router.post("") +async def create_run( + request: Request, + payload: CreateRunPayload, # for openapi docs + opengpts_user_id: OpengptsUserId, + background_tasks: BackgroundTasks, +): + """Create a run.""" + try: + body = await request.json() + except json.JSONDecodeError: + raise RequestValidationError(errors=["Invalid JSON body"]) + assistant, public_assistant, state = await asyncio.gather( + asyncio.get_running_loop().run_in_executor( + None, get_assistant, opengpts_user_id, body["assistant_id"] + ), + asyncio.get_running_loop().run_in_executor( + None, get_assistant, public_user_id, body["assistant_id"] + ), + asyncio.get_running_loop().run_in_executor( + None, get_thread_messages, opengpts_user_id, body["thread_id"] + ), + ) + assistant = assistant or public_assistant + if not assistant: + raise HTTPException(status_code=404, detail="Assistant not found") + config: RunnableConfig = { + **assistant["config"], + "configurable": { + **assistant["config"]["configurable"], + "user_id": opengpts_user_id, + "thread_id": body["thread_id"], + "assistant_id": body["assistant_id"], + }, + } + try: + input_ = _unpack_input(agent.get_input_schema(config).validate(body["input"])) + except ValidationError as e: + raise RequestValidationError(e.errors(), body=body) + if body["stream"]: + streamer = StreamMessagesHandler(state["messages"] + input_["messages"]) + event_aggregator = AsyncEventAggregatorCallback() + config["callbacks"] = [streamer, event_aggregator] + + # Call the runnable in streaming mode, + # add each chunk to the output stream + async def consume_astream() -> None: + try: + async for chunk in agent.astream(input_, config): + await streamer.send_stream.send(chunk) + # hack: function messages aren't generated by chat model + # so the callback handler doesn't know about them + message = chunk["messages"][-1] + if isinstance(message, FunctionMessage): + streamer.output[uuid4()] = ChatGeneration(message=message) + except Exception as e: + await streamer.send_stream.send(e) + finally: + await streamer.send_stream.aclose() + + # Start the runnable in the background + task = asyncio.create_task(consume_astream()) + + # Consume the stream into an EventSourceResponse + async def _stream() -> AsyncIterator[dict]: + has_sent_metadata = False + + async for chunk in streamer.receive_stream: + if isinstance(chunk, BaseException): + yield { + "event": "error", + # Do not expose the error message to the client since + # the message may contain sensitive information. + # We'll add client side errors for validation as well. + "data": orjson.dumps( + {"status_code": 500, "message": "Internal Server Error"} + ).decode(), + } + raise chunk + else: + if not has_sent_metadata and event_aggregator.callback_events: + yield { + "event": "metadata", + "data": orjson.dumps( + {"run_id": _get_base_run_id_as_str(event_aggregator)} + ).decode(), + } + has_sent_metadata = True + + yield { + # EventSourceResponse expects a string for data + # so after serializing into bytes, we decode into utf-8 + # to get a string. + "data": _serializer.dumps(chunk).decode("utf-8"), + "event": "data", + } + + # Send an end event to signal the end of the stream + yield {"event": "end"} + # Wait for the runnable to finish + await task + + return EventSourceResponse(_stream()) + else: + background_tasks.add_task(agent.ainvoke, input_, config) + return {"status": "ok"} # TODO add a run id + + +@router.get("/input_schema") +async def input_schema() -> dict: + """Return the input schema of the runnable.""" + return agent.get_input_schema().schema() + + +@router.get("/output_schema") +async def output_schema() -> dict: + """Return the output schema of the runnable.""" + return agent.get_output_schema().schema() + + +@router.get("/config_schema") +async def config_schema() -> dict: + """Return the config schema of the runnable.""" + return agent.config_schema().schema() + + +if tracing_is_enabled(): + langsmith_client = langsmith.client.Client() + + @router.post("/feedback") + def create_run_feedback(feedback_create_req: FeedbackCreateRequest) -> dict: + """ + Send feedback on an individual run to langsmith + + Note that a successful response means that feedback was successfully + submitted. It does not guarantee that the feedback is recorded by + langsmith. Requests may be silently rejected if they are + unauthenticated or invalid by the server. + """ + + langsmith_client.create_feedback( + feedback_create_req.run_id, + feedback_create_req.key, + score=feedback_create_req.score, + value=feedback_create_req.value, + comment=feedback_create_req.comment, + source_info={ + "from_langserve": True, + }, + ) + + return {"status": "ok"} diff --git a/backend/app/api/threads.py b/backend/app/api/threads.py new file mode 100644 index 00000000..3e2d040c --- /dev/null +++ b/backend/app/api/threads.py @@ -0,0 +1,51 @@ +from typing import Annotated, List + +from fastapi import APIRouter, Path +from pydantic import BaseModel, Field + +import app.storage as storage +from app.schema import OpengptsUserId, Thread, ThreadWithoutUserId + +router = APIRouter() + + +ThreadID = Annotated[str, Path(description="The ID of the thread.")] + + +class ThreadPutRequest(BaseModel): + """Payload for creating a thread.""" + + name: str = Field(..., description="The name of the thread.") + assistant_id: str = Field(..., description="The ID of the assistant to use.") + + +@router.get("/") +def list_threads_endpoint( + opengpts_user_id: OpengptsUserId +) -> List[ThreadWithoutUserId]: + """List all threads for the current user.""" + return storage.list_threads(opengpts_user_id) + + +@router.get("/{tid}/messages") +def get_thread_messages_endpoint( + opengpts_user_id: OpengptsUserId, + tid: ThreadID, +): + """Get all messages for a thread.""" + return storage.get_thread_messages(opengpts_user_id, tid) + + +@router.put("/{tid}") +def put_thread_endpoint( + opengpts_user_id: OpengptsUserId, + tid: ThreadID, + thread_put_request: ThreadPutRequest, +) -> Thread: + """Update a thread.""" + return storage.put_thread( + opengpts_user_id, + tid, + assistant_id=thread_put_request.assistant_id, + name=thread_put_request.name, + ) diff --git a/backend/app/schema.py b/backend/app/schema.py index e96dbc01..336493cf 100644 --- a/backend/app/schema.py +++ b/backend/app/schema.py @@ -1,5 +1,7 @@ from datetime import datetime +from typing import Annotated +from fastapi import Cookie from typing_extensions import TypedDict @@ -41,3 +43,15 @@ class Thread(ThreadWithoutUserId): user_id: str """The ID of the user that owns the thread.""" + + +OpengptsUserId = Annotated[ + str, + Cookie( + description=( + "A cookie that identifies the user. This is not an authentication " + "mechanism that should be used in an actual production environment that " + "contains sensitive information." + ) + ), +] diff --git a/backend/app/server.py b/backend/app/server.py index af78f08f..c27bda10 100644 --- a/backend/app/server.py +++ b/backend/app/server.py @@ -1,301 +1,29 @@ -import asyncio -import json from pathlib import Path -from typing import Annotated, AsyncIterator, List, Optional, Sequence -from uuid import uuid4 import orjson -from fastapi import BackgroundTasks, Cookie, FastAPI, Form, Query, Request, UploadFile -from fastapi.exceptions import RequestValidationError +from fastapi import FastAPI, Form, UploadFile from fastapi.staticfiles import StaticFiles -from gizmo_agent import agent, ingest_runnable -from langchain.pydantic_v1 import ValidationError -from langchain.schema.messages import AnyMessage, FunctionMessage -from langchain.schema.output import ChatGeneration -from langchain.schema.runnable import RunnableConfig -from langserve import add_routes -from langserve.callbacks import AsyncEventAggregatorCallback -from langserve.serialization import WellKnownLCSerializer -from langserve.server import _get_base_run_id_as_str, _unpack_input -from pydantic import BaseModel, Field -from sse_starlette import EventSourceResponse +from gizmo_agent import ingest_runnable -from app.schema import Assistant, AssistantWithoutUserId, Thread, ThreadWithoutUserId -from app.storage import ( - get_assistant, - get_thread_messages, - list_assistants, - list_public_assistants, - list_threads, - put_assistant, - put_thread, -) -from app.stream import StreamMessagesHandler +from app.api import router as api_router app = FastAPI() -FEATURED_PUBLIC_ASSISTANTS = [ - "ba721964-b7e4-474c-b817-fb089d94dc5f", - "dc3ec482-aafc-4d90-8a1a-afb9b2876cde", -] # Get root of app, used to point to directory containing static files ROOT = Path(__file__).parent.parent -OpengptsUserId = Annotated[ - str, - Cookie( - description=( - "A cookie that identifies the user. This is not an authentication " - "mechanism that should be used in an actual production environment that " - "contains sensitive information." - ) - ), -] +app.include_router(api_router) -def attach_user_id_to_config( - config: RunnableConfig, - request: Request, -) -> RunnableConfig: - """Attach the user id to the runnable config. - Args: - config: The runnable config. - request: The request. - - Returns: - A modified runnable config that contains information about the user - who made the request in the `configurable.user_id` field. - """ - config["configurable"]["user_id"] = request.cookies["opengpts_user_id"] - return config - - -add_routes( - app, - agent, - config_keys=["configurable"], - per_req_config_modifier=attach_user_id_to_config, - enable_feedback_endpoint=True, -) - -serializer = WellKnownLCSerializer() - - -class AgentInput(BaseModel): - """An input into an agent.""" - - messages: Sequence[AnyMessage] - - -class CreateRunPayload(BaseModel): - """Payload for creating a run.""" - - assistant_id: str - thread_id: str - stream: bool - # TODO make optional - input: AgentInput - - -@app.post("/runs") -async def create_run_endpoint( - request: Request, - opengpts_user_id: Annotated[str, Cookie()], - background_tasks: BackgroundTasks, -): - """Create a run.""" - try: - body = await request.json() - except json.JSONDecodeError: - raise RequestValidationError(errors=["Invalid JSON body"]) - assistant, state = await asyncio.gather( - asyncio.get_running_loop().run_in_executor( - None, get_assistant, opengpts_user_id, body["assistant_id"] - ), - asyncio.get_running_loop().run_in_executor( - None, get_thread_messages, opengpts_user_id, body["thread_id"] - ), - ) - config: RunnableConfig = attach_user_id_to_config( - { - **assistant["config"], - "configurable": { - **assistant["config"]["configurable"], - "thread_id": body["thread_id"], - "assistant_id": body["assistant_id"], - }, - }, - request, - ) - try: - input_ = _unpack_input(agent.get_input_schema(config).validate(body["input"])) - except ValidationError as e: - raise RequestValidationError(e.errors(), body=body) - if body["stream"]: - streamer = StreamMessagesHandler(state["messages"] + input_["messages"]) - event_aggregator = AsyncEventAggregatorCallback() - config["callbacks"] = [streamer, event_aggregator] - - # Call the runnable in streaming mode, - # add each chunk to the output stream - async def consume_astream() -> None: - try: - async for chunk in agent.astream(input_, config): - await streamer.send_stream.send(chunk) - # hack: function messages aren't generated by chat model - # so the callback handler doesn't know about them - message = chunk["messages"][-1] - if isinstance(message, FunctionMessage): - streamer.output[uuid4()] = ChatGeneration(message=message) - except Exception as e: - await streamer.send_stream.send(e) - finally: - await streamer.send_stream.aclose() - - # Start the runnable in the background - task = asyncio.create_task(consume_astream()) - - # Consume the stream into an EventSourceResponse - async def _stream() -> AsyncIterator[dict]: - has_sent_metadata = False - - async for chunk in streamer.receive_stream: - if isinstance(chunk, BaseException): - yield { - "event": "error", - # Do not expose the error message to the client since - # the message may contain sensitive information. - # We'll add client side errors for validation as well. - "data": orjson.dumps( - {"status_code": 500, "message": "Internal Server Error"} - ).decode(), - } - raise chunk - else: - if not has_sent_metadata and event_aggregator.callback_events: - yield { - "event": "metadata", - "data": orjson.dumps( - {"run_id": _get_base_run_id_as_str(event_aggregator)} - ).decode(), - } - has_sent_metadata = True - - yield { - # EventSourceResponse expects a string for data - # so after serializing into bytes, we decode into utf-8 - # to get a string. - "data": serializer.dumps(chunk).decode("utf-8"), - "event": "data", - } - - # Send an end event to signal the end of the stream - yield {"event": "end"} - # Wait for the runnable to finish - await task - - return EventSourceResponse(_stream()) - else: - background_tasks.add_task(agent.ainvoke, input_, config) - return {"status": "ok"} # TODO add a run id - - -@app.post("/ingest", description="Upload files to the given user.") -def ingest_endpoint(files: list[UploadFile], config: str = Form(...)) -> None: +@app.post("/ingest", description="Upload files to the given assistant.") +def ingest_files(files: list[UploadFile], config: str = Form(...)) -> None: """Ingest a list of files.""" config = orjson.loads(config) return ingest_runnable.batch([file.file for file in files], config) -@app.get("/assistants/") -def list_assistants_endpoint( - opengpts_user_id: OpengptsUserId -) -> List[AssistantWithoutUserId]: - """List all assistants for the current user.""" - return list_assistants(opengpts_user_id) - - -@app.get("/assistants/public/") -def list_public_assistants_endpoint( - shared_id: Annotated[ - Optional[str], Query(description="ID of a publicly shared assistant.") - ] = None, -) -> List[AssistantWithoutUserId]: - """List all public assistants.""" - return list_public_assistants( - FEATURED_PUBLIC_ASSISTANTS + ([shared_id] if shared_id else []) - ) - - -class AssistantPayload(BaseModel): - """Payload for creating an assistant.""" - - name: str = Field(..., description="The name of the assistant.") - config: dict = Field(..., description="The assistant config.") - public: bool = Field(default=False, description="Whether the assistant is public.") - - -AssistantID = Annotated[str, Path(description="The ID of the assistant.")] -ThreadID = Annotated[str, Path(description="The ID of the thread.")] - - -@app.put("/assistants/{aid}") -def put_assistant_endpoint( - opengpts_user_id: Annotated[str, Cookie()], - aid: AssistantID, - payload: AssistantPayload, -) -> Assistant: - """Create or update an assistant.""" - return put_assistant( - opengpts_user_id, - aid, - name=payload.name, - config=payload.config, - public=payload.public, - ) - - -@app.get("/threads/") -def list_threads_endpoint( - opengpts_user_id: OpengptsUserId -) -> List[ThreadWithoutUserId]: - """List all threads for the current user.""" - return list_threads(opengpts_user_id) - - -@app.get("/threads/{tid}/messages") -def get_thread_messages_endpoint( - opengpts_user_id: OpengptsUserId, - tid: ThreadID, -): - """Get all messages for a thread.""" - return get_thread_messages(opengpts_user_id, tid) - - -class ThreadPutRequest(BaseModel): - """Payload for creating a thread.""" - - name: str = Field(..., description="The name of the thread.") - assistant_id: str = Field(..., description="The ID of the assistant to use.") - - -@app.put("/threads/{tid}") -def put_thread_endpoint( - opengpts_user_id: OpengptsUserId, - tid: ThreadID, - thread_put_request: ThreadPutRequest, -) -> Thread: - """Update a thread.""" - return put_thread( - opengpts_user_id, - tid, - assistant_id=thread_put_request.assistant_id, - name=thread_put_request.name, - ) - - app.mount("", StaticFiles(directory=str(ROOT / "ui"), html=True), name="ui") if __name__ == "__main__": diff --git a/backend/app/storage.py b/backend/app/storage.py index 9a39bb01..228c925b 100644 --- a/backend/app/storage.py +++ b/backend/app/storage.py @@ -61,11 +61,11 @@ def list_assistants(user_id: str) -> List[Assistant]: return [load(assistant_hash_keys, values) for values in assistants] -def get_assistant(user_id: str, assistant_id: str) -> Assistant: +def get_assistant(user_id: str, assistant_id: str) -> Assistant | None: """Get an assistant by ID.""" client = _get_redis_client() values = client.hmget(assistant_key(user_id, assistant_id), *assistant_hash_keys) - return load(assistant_hash_keys, values) + return load(assistant_hash_keys, values) if any(values) else None def list_public_assistants( diff --git a/backend/app/stream.py b/backend/app/stream.py index 96af0af6..b8a4a19e 100644 --- a/backend/app/stream.py +++ b/backend/app/stream.py @@ -4,19 +4,19 @@ from anyio import create_memory_object_stream from langchain.callbacks.base import BaseCallbackHandler -from langchain.schema.output import ChatGenerationChunk, GenerationChunk from langchain.schema.messages import ( + AIMessage, + AIMessageChunk, BaseMessage, BaseMessageChunk, - AIMessageChunk, - HumanMessageChunk, - HumanMessage, - AIMessage, - FunctionMessage, - FunctionMessageChunk, ChatMessage, ChatMessageChunk, + FunctionMessage, + FunctionMessageChunk, + HumanMessage, + HumanMessageChunk, ) +from langchain.schema.output import ChatGenerationChunk, GenerationChunk class StreamMessagesHandler(BaseCallbackHandler): diff --git a/backend/packages/agent-executor/agent_executor/permchain.py b/backend/packages/agent-executor/agent_executor/permchain.py index 23d5f6ed..5ae891dc 100644 --- a/backend/packages/agent-executor/agent_executor/permchain.py +++ b/backend/packages/agent-executor/agent_executor/permchain.py @@ -2,18 +2,18 @@ from operator import itemgetter from typing import Sequence -from permchain import Channel, Pregel, ReservedChannels -from permchain.channels import Topic -from permchain.checkpoint.base import BaseCheckpointAdapter +from langchain.schema.agent import AgentAction, AgentActionMessageLog, AgentFinish +from langchain.schema.messages import AIMessage, AnyMessage, FunctionMessage from langchain.schema.runnable import ( Runnable, RunnableConfig, RunnableLambda, RunnablePassthrough, ) -from langchain.schema.agent import AgentAction, AgentFinish, AgentActionMessageLog -from langchain.schema.messages import AIMessage, FunctionMessage, AnyMessage from langchain.tools import BaseTool +from permchain import Channel, Pregel, ReservedChannels +from permchain.channels import Topic +from permchain.checkpoint.base import BaseCheckpointAdapter def _create_agent_message( diff --git a/backend/packages/gizmo-agent/gizmo_agent/main.py b/backend/packages/gizmo-agent/gizmo_agent/main.py index e261785e..8fa93027 100644 --- a/backend/packages/gizmo-agent/gizmo_agent/main.py +++ b/backend/packages/gizmo-agent/gizmo_agent/main.py @@ -1,6 +1,6 @@ from typing import Any, Mapping, Optional, Sequence -from agent_executor.checkpoint import RedisCheckpoint +from agent_executor.checkpoint import RedisCheckpoint from agent_executor.permchain import get_agent_executor from langchain.pydantic_v1 import BaseModel, Field from langchain.schema.messages import AnyMessage diff --git a/backend/packages/gizmo-agent/gizmo_agent/tools.py b/backend/packages/gizmo-agent/gizmo_agent/tools.py index f0fd470b..cdefd966 100644 --- a/backend/packages/gizmo-agent/gizmo_agent/tools.py +++ b/backend/packages/gizmo-agent/gizmo_agent/tools.py @@ -5,10 +5,10 @@ from langchain.retrievers.you import YouRetriever from langchain.tools import ArxivQueryRun, DuckDuckGoSearchRun from langchain.tools.retriever import create_retriever_tool +from langchain.tools.tavily_search import TavilyAnswer, TavilySearchResults from langchain.utilities import ArxivAPIWrapper -from langchain.vectorstores.redis import RedisFilter from langchain.utilities.tavily_search import TavilySearchAPIWrapper -from langchain.tools.tavily_search import TavilySearchResults, TavilyAnswer +from langchain.vectorstores.redis import RedisFilter from gizmo_agent.ingest import vstore diff --git a/backend/poetry.lock b/backend/poetry.lock index a4e647ad..71b7ec90 100644 --- a/backend/poetry.lock +++ b/backend/poetry.lock @@ -1382,13 +1382,13 @@ requests = ">=2" [[package]] name = "langchain" -version = "0.0.335" +version = "0.0.338" description = "Building applications with LLMs through composability" optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "langchain-0.0.335-py3-none-any.whl", hash = "sha256:f74c98366070a46953c071c69f6c01671a9437569c08406cace256ccaabdfcaf"}, - {file = "langchain-0.0.335.tar.gz", hash = "sha256:93136fe6cc9ac06a80ccf7cf581e58af5cfcc31fef1083b30165df9a9bc53f5d"}, + {file = "langchain-0.0.338-py3-none-any.whl", hash = "sha256:d9fa750f01f99c0ce04bfac4c614a142702f7b7715928c6db74ea80f4514d3dd"}, + {file = "langchain-0.0.338.tar.gz", hash = "sha256:c928cceca770b5c62b48024de163aaca5ca0539b613e7726369f2671e2934e80"}, ] [package.dependencies] @@ -1406,17 +1406,17 @@ SQLAlchemy = ">=1.4,<3" tenacity = ">=8.1.0,<9.0.0" [package.extras] -all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "amadeus (>=8.1.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "awadb (>=0.3.9,<0.4.0)", "azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clarifai (>=9.1.0)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=4,<5)", "deeplake (>=3.8.3,<4.0.0)", "docarray[hnswlib] (>=0.32.0,<0.33.0)", "duckduckgo-search (>=3.8.3,<4.0.0)", "elasticsearch (>=8,<9)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-auth (>=2.18.1,<3.0.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "langkit (>=0.0.6,<0.1.0)", "lark (>=1.1.5,<2.0.0)", "librosa (>=0.10.0.post2,<0.11.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "marqo (>=1.2.4,<2.0.0)", "momento (>=1.10.1,<2.0.0)", "nebula3-python (>=3.4.0,<4.0.0)", "neo4j (>=5.8.1,<6.0.0)", "networkx (>=2.6.3,<4)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pymongo (>=4.3.3,<5.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "python-arango (>=7.5.9,<8.0.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.3.1,<2.0.0)", "rdflib (>=6.3.2,<7.0.0)", "redis (>=4,<5)", "requests-toolbelt (>=1.0.0,<2.0.0)", "sentence-transformers (>=2,<3)", "singlestoredb (>=0.7.1,<0.8.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tigrisdb (>=1.0.0b6,<2.0.0)", "tiktoken (>=0.3.2,<0.6.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"] -azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (>=0,<1)"] +all = ["O365 (>=2.0.26,<3.0.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "amadeus (>=8.1.0)", "arxiv (>=1.4,<2.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "awadb (>=0.3.9,<0.4.0)", "azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "beautifulsoup4 (>=4,<5)", "clarifai (>=9.1.0)", "clickhouse-connect (>=0.5.14,<0.6.0)", "cohere (>=4,<5)", "deeplake (>=3.8.3,<4.0.0)", "docarray[hnswlib] (>=0.32.0,<0.33.0)", "duckduckgo-search (>=3.8.3,<4.0.0)", "elasticsearch (>=8,<9)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "google-api-python-client (==2.70.0)", "google-auth (>=2.18.1,<3.0.0)", "google-search-results (>=2,<3)", "gptcache (>=0.1.7)", "html2text (>=2020.1.16,<2021.0.0)", "huggingface_hub (>=0,<1)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "lancedb (>=0.1,<0.2)", "langkit (>=0.0.6,<0.1.0)", "lark (>=1.1.5,<2.0.0)", "librosa (>=0.10.0.post2,<0.11.0)", "lxml (>=4.9.2,<5.0.0)", "manifest-ml (>=0.0.1,<0.0.2)", "marqo (>=1.2.4,<2.0.0)", "momento (>=1.13.0,<2.0.0)", "nebula3-python (>=3.4.0,<4.0.0)", "neo4j (>=5.8.1,<6.0.0)", "networkx (>=2.6.3,<4)", "nlpcloud (>=1,<2)", "nltk (>=3,<4)", "nomic (>=1.0.43,<2.0.0)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "opensearch-py (>=2.0.0,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pexpect (>=4.8.0,<5.0.0)", "pgvector (>=0.1.6,<0.2.0)", "pinecone-client (>=2,<3)", "pinecone-text (>=0.4.2,<0.5.0)", "psycopg2-binary (>=2.9.5,<3.0.0)", "pymongo (>=4.3.3,<5.0.0)", "pyowm (>=3.3.0,<4.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pytesseract (>=0.3.10,<0.4.0)", "python-arango (>=7.5.9,<8.0.0)", "pyvespa (>=0.33.0,<0.34.0)", "qdrant-client (>=1.3.1,<2.0.0)", "rdflib (>=6.3.2,<7.0.0)", "redis (>=4,<5)", "requests-toolbelt (>=1.0.0,<2.0.0)", "sentence-transformers (>=2,<3)", "singlestoredb (>=0.7.1,<0.8.0)", "tensorflow-text (>=2.11.0,<3.0.0)", "tigrisdb (>=1.0.0b6,<2.0.0)", "tiktoken (>=0.3.2,<0.6.0)", "torch (>=1,<3)", "transformers (>=4,<5)", "weaviate-client (>=3,<4)", "wikipedia (>=1,<2)", "wolframalpha (==5.0.0)"] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] clarifai = ["clarifai (>=9.1.0)"] cli = ["typer (>=0.9.0,<0.10.0)"] cohere = ["cohere (>=4,<5)"] docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] embeddings = ["sentence-transformers (>=2,<3)"] -extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "dashvector (>=1.0.1,<2.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.6.0,<0.7.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (>=0,<1)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "dashvector (>=1.0.1,<2.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.6.0,<0.7.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] javascript = ["esprima (>=4.0.1,<5.0.0)"] -llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (>=0,<1)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] -openai = ["openai (>=0,<1)", "tiktoken (>=0.3.2,<0.6.0)"] +llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] +openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] text-helpers = ["chardet (>=5.1.0,<6.0.0)"] @@ -1885,17 +1885,17 @@ image = ["Pillow"] [[package]] name = "permchain" -version = "0.0.5" +version = "0.0.6" description = "permchain" optional = false python-versions = ">=3.8.1,<4.0" files = [ - {file = "permchain-0.0.5-py3-none-any.whl", hash = "sha256:2e8101efd3ca7cffc3303942c10372c8f571928cdde7388480ebadba982a5bb3"}, - {file = "permchain-0.0.5.tar.gz", hash = "sha256:9dd1d98eb111f02d9bbf84fa7f0fd69ac901540e66196bd3f82e64659262e414"}, + {file = "permchain-0.0.6-py3-none-any.whl", hash = "sha256:420891760db90b5f5398e53ced5361f548712d79ac7957864c769a6534392c72"}, + {file = "permchain-0.0.6.tar.gz", hash = "sha256:505171943e068f567c0dc2f4692d8654d8444347a9e9965614033cd70d5982fd"}, ] [package.dependencies] -langchain = ">=0.0.335,<0.0.336" +langchain = ">=0.0.335" [[package]] name = "pluggy" @@ -2324,6 +2324,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2331,8 +2332,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2349,6 +2357,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2356,6 +2365,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3435,4 +3445,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "f6a9ba64d054fd74a043c419bf02f9f3a79b950a071998c574531ee041e54d47" +content-hash = "04f1e333bbde31ba430df4441e11111b5b7d513c6db3141da3b645e9474b882a" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 3c5e9332..709458a1 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,5 +1,5 @@ [tool.poetry] -name = "lang-gizmo" +name = "opengpts" version = "0.1.0" description = "" authors = ["Your Name "] @@ -22,8 +22,8 @@ orjson = "^3.9.10" redis = "^5.0.1" python-multipart = "^0.0.6" tiktoken = "^0.5.1" -langchain = "^0.0.335" -permchain = "^0.0.5" +langchain = ">=0.0.338" +permchain = "0.0.6" [tool.poetry.group.dev.dependencies] uvicorn = "^0.23.2" diff --git a/frontend/src/hooks/useSchemas.ts b/frontend/src/hooks/useSchemas.ts index c9591d34..dbe8ecdb 100644 --- a/frontend/src/hooks/useSchemas.ts +++ b/frontend/src/hooks/useSchemas.ts @@ -22,39 +22,27 @@ export interface Schemas { }; }; }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - inputSchema: null | any; configDefaults: null | { configurable?: { [key: string]: unknown; }; }; - inputDefaults: null | Record; } export function useSchemas() { const [schemas, setSchemas] = useState({ configSchema: null, - inputSchema: null, configDefaults: null, - inputDefaults: null, }); useEffect(() => { async function save() { - const [configSchema, inputSchema] = await Promise.all([ - fetch("/config_schema") - .then((r) => r.json()) - .then(simplifySchema), - fetch("/input_schema") - .then((r) => r.json()) - .then(simplifySchema), - ]); + const configSchema = await fetch("/runs/config_schema") + .then((r) => r.json()) + .then(simplifySchema); setSchemas({ configSchema, - inputSchema, configDefaults: getDefaults(configSchema) as Record, - inputDefaults: getDefaults(inputSchema) as Record, }); } diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 785eb90f..9702f992 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -6,12 +6,11 @@ export default defineConfig({ plugins: [react()], server: { proxy: { - "^/(config_schema|input_schema|stream|assistants|threads|ingest|feedback|runs)": - { - target: "http://127.0.0.1:8100", - changeOrigin: true, - rewrite: (path) => path.replace("/____LANGSERVE_BASE_URL", ""), - }, + "^/(assistants|threads|ingest|runs)": { + target: "http://127.0.0.1:8100", + changeOrigin: true, + rewrite: (path) => path.replace("/____LANGSERVE_BASE_URL", ""), + }, }, }, });