From 8380c0563afffea22ca895c2ee8b4fce06615893 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Mon, 2 Oct 2023 22:44:02 -0400 Subject: [PATCH] x --- examples/chain/client.ipynb | 156 +++++++++++++++++++++++++++++++++++- examples/chain/server.py | 29 +++++-- langserve/validation.py | 2 +- poetry.lock | 13 ++- 4 files changed, 187 insertions(+), 13 deletions(-) diff --git a/examples/chain/client.ipynb b/examples/chain/client.ipynb index bd3d7bd6..160cfa3e 100644 --- a/examples/chain/client.ipynb +++ b/examples/chain/client.ipynb @@ -12,6 +12,24 @@ { "cell_type": "code", "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import sys" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "sys.path.insert(0, '/home/eugene/src/langchain/libs/langchain/')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, "metadata": { "tags": [] }, @@ -20,12 +38,13 @@ "from langchain.prompts.chat import (\n", " HumanMessagePromptTemplate,\n", " SystemMessagePromptTemplate,\n", + "\n", ")" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": { "tags": [] }, @@ -36,6 +55,23 @@ "remote_runnable = RemoteRunnable(\"http://localhost:8000/\")" ] }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\"title\":\"RunnableSequenceConfig\",\"type\":\"object\",\"properties\":{\"configurable\":{\"$ref\":\"#/definitions/Configurable\"}},\"definitions\":{\"Configurable\":{\"title\":\"Configurable\",\"type\":\"object\",\"properties\":{\"llm\":{\"title\":\"LLM\",\"default\":\"default\",\"anyOf\":[{\"enum\":[\"high_temp\"],\"type\":\"string\"},{\"enum\":[\"low_temp\"],\"type\":\"string\"},{\"enum\":[\"mid_temp\"],\"type\":\"string\"},{\"enum\":[\"default\"],\"type\":\"string\"}]},\"topic\":{\"title\":\"Topic\",\"description\":\"The topic of the joke\",\"default\":\"tell me a joke about {topic}\",\"type\":\"string\"}}}}}" + ] + } + ], + "source": [ + "!curl localhost:8000/config_schema" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -45,13 +81,125 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'content': \"Why don't dogs make good dancers? \\n\\nBecause they have two left feet-paws!\",\n", + " 'additional_kwargs': {},\n", + " 'type': 'ai',\n", + " 'example': False,\n", + " 'is_chunk': False}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# r = remote_runnable.with_config( {\"configurable\": {\"llm\": \"low_temp\"}})\n", + "remote_runnable.invoke({'topic': 'dog'}, config={\"configurable\": {\"llm\": \"low_temp\", \"template\": \"how to say {topic} in french\"}})" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'content': \"Why don't scientists trust atoms?\\n\\nBecause they make up everything!\",\n", + " 'additional_kwargs': {},\n", + " 'type': 'ai',\n", + " 'example': False,\n", + " 'is_chunk': False}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "r = remote_runnable.with_config( {\"configurable\": {\"template\": \"reverse the word {topic}\"}})\n", + "r.invoke({'topic': 'poof'})" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "unterminated string literal (detected at line 1) (522816454.py, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m Cell \u001b[0;32mIn[30], line 1\u001b[0;36m\u001b[0m\n\u001b[0;31m r.invoke({\"topic\": \"cats'})\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m unterminated string literal (detected at line 1)\n" + ] + } + ], + "source": [ + "r.invoke({\"topic" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'content': \"Why don't cats play poker in the wild?\\n\\nToo many cheetahs!\",\n", + " 'additional_kwargs': {},\n", + " 'type': 'ai',\n", + " 'example': False,\n", + " 'is_chunk': False}" + ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 68, "metadata": { "tags": [] }, - "outputs": [], + "outputs": [ + { + "ename": "HTTPStatusError", + "evalue": "Server error '500 Internal Server Error' for url 'http://localhost:8000/invoke'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500 for Internal Server Error", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mHTTPStatusError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m~/.pyenv/versions/3.11.4/envs/langchain_3_11_4/lib/python3.11/site-packages/langserve/client.py:40\u001b[0m, in \u001b[0;36m_raise_for_status\u001b[0;34m(response)\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 40\u001b[0m \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 41\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m httpx\u001b[38;5;241m.\u001b[39mHTTPStatusError \u001b[38;5;28;01mas\u001b[39;00m e:\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.4/envs/langchain_3_11_4/lib/python3.11/site-packages/httpx/_models.py:749\u001b[0m, in \u001b[0;36mResponse.raise_for_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 748\u001b[0m message \u001b[38;5;241m=\u001b[39m message\u001b[38;5;241m.\u001b[39mformat(\u001b[38;5;28mself\u001b[39m, error_type\u001b[38;5;241m=\u001b[39merror_type)\n\u001b[0;32m--> 749\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m HTTPStatusError(message, request\u001b[38;5;241m=\u001b[39mrequest, response\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m)\n", + "\u001b[0;31mHTTPStatusError\u001b[0m: Server error '500 Internal Server Error' for url 'http://localhost:8000/invoke'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mHTTPStatusError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[68], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m remote_runnable\u001b[38;5;241m.\u001b[39mainvoke({\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtopic\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msports\u001b[39m\u001b[38;5;124m\"\u001b[39m}, {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mconfigurable\u001b[39m\u001b[38;5;124m\"\u001b[39m: {\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprompt_template\u001b[39m\u001b[38;5;124m\"\u001b[39m: \u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{topic}\u001b[39;00m\u001b[38;5;124m meow \u001b[39m\u001b[38;5;132;01m{topic}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m}})\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.4/envs/langchain_3_11_4/lib/python3.11/site-packages/langserve/client.py:158\u001b[0m, in \u001b[0;36mRemoteRunnable.ainvoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 156\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs:\n\u001b[1;32m 157\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mNotImplementedError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mkwargs not implemented yet.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 158\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_acall_with_config(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ainvoke, \u001b[38;5;28minput\u001b[39m, config)\n", + "File \u001b[0;32m~/src/langchain/libs/langchain/langchain/schema/runnable/base.py:556\u001b[0m, in \u001b[0;36mRunnable._acall_with_config\u001b[0;34m(self, func, input, config, run_type, **kwargs)\u001b[0m\n\u001b[1;32m 549\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m 550\u001b[0m dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m 551\u001b[0m \u001b[38;5;28minput\u001b[39m,\n\u001b[1;32m 552\u001b[0m run_type\u001b[38;5;241m=\u001b[39mrun_type,\n\u001b[1;32m 553\u001b[0m name\u001b[38;5;241m=\u001b[39mconfig\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_name\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[1;32m 554\u001b[0m )\n\u001b[1;32m 555\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 556\u001b[0m output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m acall_func_with_variable_args(\n\u001b[1;32m 557\u001b[0m func, \u001b[38;5;28minput\u001b[39m, run_manager, config, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[1;32m 558\u001b[0m )\n\u001b[1;32m 559\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 560\u001b[0m \u001b[38;5;28;01mawait\u001b[39;00m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n", + "File \u001b[0;32m~/src/langchain/libs/langchain/langchain/schema/runnable/config.py:195\u001b[0m, in \u001b[0;36macall_func_with_variable_args\u001b[0;34m(func, input, run_manager, config, **kwargs)\u001b[0m\n\u001b[1;32m 193\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m accepts_run_manager(func):\n\u001b[1;32m 194\u001b[0m kwargs[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mrun_manager\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m run_manager\n\u001b[0;32m--> 195\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mawait\u001b[39;00m func(\u001b[38;5;28minput\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.4/envs/langchain_3_11_4/lib/python3.11/site-packages/langserve/client.py:150\u001b[0m, in \u001b[0;36mRemoteRunnable._ainvoke\u001b[0;34m(self, input, config, **kwargs)\u001b[0m\n\u001b[1;32m 139\u001b[0m \u001b[38;5;28;01masync\u001b[39;00m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_ainvoke\u001b[39m(\n\u001b[1;32m 140\u001b[0m \u001b[38;5;28mself\u001b[39m, \u001b[38;5;28minput\u001b[39m: Input, config: Optional[RunnableConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any\n\u001b[1;32m 141\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Output:\n\u001b[1;32m 142\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mawait\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39masync_client\u001b[38;5;241m.\u001b[39mpost(\n\u001b[1;32m 143\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m/invoke\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 144\u001b[0m json\u001b[38;5;241m=\u001b[39m{\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 148\u001b[0m },\n\u001b[1;32m 149\u001b[0m )\n\u001b[0;32m--> 150\u001b[0m \u001b[43m_raise_for_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43mresponse\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 151\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m load(response\u001b[38;5;241m.\u001b[39mjson())[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124moutput\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n", + "File \u001b[0;32m~/.pyenv/versions/3.11.4/envs/langchain_3_11_4/lib/python3.11/site-packages/langserve/client.py:48\u001b[0m, in \u001b[0;36m_raise_for_status\u001b[0;34m(response)\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m e\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mtext:\n\u001b[1;32m 46\u001b[0m message \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m for \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;241m.\u001b[39mresponse\u001b[38;5;241m.\u001b[39mtext\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m---> 48\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m httpx\u001b[38;5;241m.\u001b[39mHTTPStatusError(\n\u001b[1;32m 49\u001b[0m message\u001b[38;5;241m=\u001b[39mmessage,\n\u001b[1;32m 50\u001b[0m request\u001b[38;5;241m=\u001b[39me\u001b[38;5;241m.\u001b[39mrequest,\n\u001b[1;32m 51\u001b[0m response\u001b[38;5;241m=\u001b[39me\u001b[38;5;241m.\u001b[39mresponse,\n\u001b[1;32m 52\u001b[0m )\n", + "\u001b[0;31mHTTPStatusError\u001b[0m: Server error '500 Internal Server Error' for url 'http://localhost:8000/invoke'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500 for Internal Server Error" + ] + } + ], "source": [ - "response = await remote_runnable.ainvoke({\"topic\": \"sports\"})" + "response = await remote_runnable.ainvoke({\"topic\": \"sports\"}, {\"configurable\": {\"prompt_template\": \"{topic} meow {topic}\"}})" ] }, { diff --git a/examples/chain/server.py b/examples/chain/server.py index d4b71fbf..5d178f36 100755 --- a/examples/chain/server.py +++ b/examples/chain/server.py @@ -1,14 +1,33 @@ #!/usr/bin/env python """Example LangChain server exposes a chain composed of a prompt and an LLM.""" from fastapi import FastAPI -from langchain.chat_models import ChatOpenAI -from langchain.prompts import ChatPromptTemplate from typing_extensions import TypedDict +from langchain.chat_models import ChatOpenAI +from langchain.prompts import PromptTemplate, ChatPromptTemplate +from langchain.schema.runnable.utils import ConfigurableField from langserve import add_routes -model = ChatOpenAI() -prompt = ChatPromptTemplate.from_template("tell me a joke about {topic}") +model = ChatOpenAI().configurable_alternatives( + ConfigurableField(id="llm", name="LLM"), + high_temp=ChatOpenAI(temperature=0.9), + low_temp=ChatOpenAI(temperature=0.1, max_tokens=1), + mid_temp=ChatOpenAI(temperature=0.5), +) + +# prompt = ChatPromptTemplate.from_messages( +# [("system", "tell the user a joke about {topic}")] +# ) +# + +prompt = PromptTemplate.from_template( + "tell me a joke about {topic}" +).configurable_fields( + template=ConfigurableField( + id="topic", name="Topic", description="The topic of the joke" + ) +) + chain = prompt | model app = FastAPI( @@ -28,7 +47,7 @@ class ChainInput(TypedDict): """The topic of the joke.""" -add_routes(app, chain, input_type=ChainInput) +add_routes(app, chain, input_type=ChainInput, config_keys=["configurable"]) # Alternatively, you can rely on langchain's type inference # to infer the input type from the runnable interface. diff --git a/langserve/validation.py b/langserve/validation.py index d317905e..35bb2d86 100644 --- a/langserve/validation.py +++ b/langserve/validation.py @@ -22,7 +22,7 @@ def create_invoke_request_model( invoke_request_type = create_model( f"{namespace}InvokeRequest", input=(input_type, ...), - config=(config, Field(default_factory=dict)), + config=(dict, Field(default_factory=dict)), kwargs=(dict, Field(default_factory=dict)), ) invoke_request_type.update_forward_refs() diff --git a/poetry.lock b/poetry.lock index 9f38cb85..5510f61c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1658,7 +1658,7 @@ files = [ ] [package.dependencies] -aiohttp = ">=3.8.3,<4.0.0" +aiohttp = "^3.8.3" anyio = "<4.0" async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} dataclasses-json = ">=0.5.7,<0.7" @@ -1667,9 +1667,9 @@ langsmith = ">=0.0.40,<0.1.0" numpy = ">=1,<2" pydantic = ">=1,<3" PyYAML = ">=5.3" -requests = ">=2,<3" +requests = "^2" SQLAlchemy = ">=1.4,<3" -tenacity = ">=8.1.0,<9.0.0" +tenacity = "^8.1.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.6.8,<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)", "libdeeplake (>=0.0.60,<0.0.61)", "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.5.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 (>=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)"] @@ -1685,6 +1685,13 @@ openai = ["openai (>=0,<1)", "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)"] +[package.source] +type = "git" +url = "https://github.com/langchain-ai/langchain" +reference = "HEAD" +resolved_reference = "933655b4acd74d5d158271151be3def0b909db98" +subdirectory = "libs/langchain" + [[package]] name = "langsmith" version = "0.0.41"