mirror of
https://github.com/langchain-ai/langgraph-memory.git
synced 2026-07-01 09:25:02 -04:00
Use Fireworks Embeddings
This commit is contained in:
@@ -1 +1,69 @@
|
||||
# langgraph-memory
|
||||
# LangGraph Memory Service
|
||||
|
||||
This repo provides a simple example of memory service you can build and deploy using LanGraph.
|
||||
|
||||
Inspired by papers like [MemGPT](https://memgpt.ai/) and distilled from our own works on long-term memory, the graph
|
||||
extracts memories from chat interactions and persists them to a database. This information can later be read or queried semantically
|
||||
to provide personalized context when your bot is responding to a particular user.
|
||||
|
||||
## Quickstart
|
||||
|
||||
This quick start will get your memory service deployed on [LangGraph Cloud](https://langchain-ai.github.io/langgraph/cloud/). Once created, you can interact with it from any API.
|
||||
|
||||
#### Prerequisites
|
||||
|
||||
This example defaults to using Pinecone for its memory database, and `nomic-ai/nomic-embed-text-v1.5` as the text encoder (hosted on Fireworks).
|
||||
|
||||
1. [Create an index](https://docs.pinecone.io/reference/api/control-plane/create_index) with a dimension size of `768`. Note down your Pinecone API key, index name, and namespac for the next step.
|
||||
2. [Create an API Key](https://fireworks.ai/api-keys) to use for the LLM & embeddings models served on Fireworks.
|
||||
|
||||
#### Deploy to LangGraph Cloud
|
||||
|
||||
**Note:** (_Closed Beta_) LangGraph Cloud is a managed service for deploying and hosting LangGraph applications. It is currently (as of 26 June, 2024) in closed beta. If you are interested in applying for access, please fill out [this form](https://www.langchain.com/langgraph-cloud-beta).
|
||||
|
||||
To deploy this example on LangGraph, fork the [repo](https://github.com/langchain-ai/langgraph-memory).
|
||||
|
||||
Next, navigate to the 🚀 deployments tab on [LangSmith](https://smith.langchain.com/o/ebbaf2eb-769b-4505-aca2-d11de10372a4/).
|
||||
|
||||
**If you have not deployed to LangGraph Cloud before:** there will be a button that shows up saying `Import from GitHub`. You’ll need to follow that flow to connect LangGraph Cloud to GitHub.
|
||||
|
||||
Once you have set up your GitHub connection, select **+New Deployment**. Fill out the required information, including:
|
||||
|
||||
1. Your GitHub username (or organization) and the name of the repo you just forked.
|
||||
2. You can leave the defaults for the config file (`langgraph.config`) and branch (`main`)
|
||||
3. Environment variables (see below)
|
||||
|
||||
The default required environment variables can be found in [.env.example](.env.example) and are copied below:
|
||||
|
||||
```bash
|
||||
# .env
|
||||
PINECONE_API_KEY=...
|
||||
PINECONE_INDEX_NAME=...
|
||||
PINECONE_NAMESPACE=...
|
||||
FIREWORKS_API_KEY=...
|
||||
|
||||
# You can add other keys as appropriate, depending on
|
||||
# the services you are using.
|
||||
```
|
||||
|
||||
You can fill these out locally, copy the .env file contents, and paste them in the first `Name` argument.
|
||||
|
||||
Assuming you've followed the steps above, in just a couple of minutes, you should have a working memory service deployed!
|
||||
|
||||
Now let's try it out.
|
||||
|
||||
#### How to connect to the memory service
|
||||
|
||||
Check out the [example notebook](./example.ipynb) to show how to connect your chat bot (in this case a second graph) to your new memory service.
|
||||
|
||||
This chat bot reads from the same memory DB as your memory service to easily query from "recall memory".
|
||||
|
||||
## How to evaluate
|
||||
|
||||
Memory management can be challenging to get right. To make sure your schemas suit your applications' needs, we recommend starting from an evaluation set,
|
||||
adding to it over time as you find and address common errors in your service.
|
||||
|
||||
We have provided a few example evaluation cases in [the test file here](./tests/evals/test_memories.py). As you can see, the metrics themselves don't have to be terribly complicated,
|
||||
especially not at the outset.
|
||||
|
||||
We use [LangSmith's @test decorator](https://docs.smith.langchain.com/how_to_guides/evaluation/unit_testing#write-a-test) to sync all the evalutions to LangSmith so you can better optimize your system and identify the root cause of any issues that may arise.
|
||||
|
||||
+627
@@ -0,0 +1,627 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# How to connect a chat bot to your memory service"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"True"
|
||||
]
|
||||
},
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import dotenv\n",
|
||||
"\n",
|
||||
"dotenv.load_dotenv(\".env\", override=True)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from langgraph_sdk import get_client\n",
|
||||
"\n",
|
||||
"# Update to your URL. Copy this from page of ryour LangGraph Deployment\n",
|
||||
"deployment_url = (\n",
|
||||
" \"https://simple-memory-service-d10393f9ecba58d48b1d4d0520a-ffoprvkqsa-uc.a.run.app\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"client = get_client(url=deployment_url)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Example Chat Bot\n",
|
||||
"\n",
|
||||
"The bot fetches user memories my semantic similarity, templates them, then responds!"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import uuid\n",
|
||||
"from datetime import datetime, timezone\n",
|
||||
"from typing import List, Optional\n",
|
||||
"\n",
|
||||
"import langsmith\n",
|
||||
"from langchain.chat_models import init_chat_model\n",
|
||||
"from langchain_core.messages import AnyMessage\n",
|
||||
"from langchain_core.prompts import ChatPromptTemplate\n",
|
||||
"from langchain_core.runnables import RunnableConfig\n",
|
||||
"from langgraph.checkpoint import MemorySaver\n",
|
||||
"from langgraph.graph import START, StateGraph, add_messages\n",
|
||||
"from langgraph_sdk import get_client\n",
|
||||
"from pydantic.v1 import BaseModel, Field\n",
|
||||
"from typing_extensions import Annotated, TypedDict\n",
|
||||
"\n",
|
||||
"from memory_service import (\n",
|
||||
" _constants as constants,\n",
|
||||
" _settings as settings,\n",
|
||||
" _utils as utils,\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class ChatState(TypedDict):\n",
|
||||
" \"\"\"The state of the chatbot.\"\"\"\n",
|
||||
"\n",
|
||||
" messages: Annotated[List[AnyMessage], add_messages]\n",
|
||||
" user_memories: List[dict]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class ChatConfigurable(TypedDict):\n",
|
||||
" \"\"\"The configurable fields for the chatbot.\"\"\"\n",
|
||||
"\n",
|
||||
" user_id: str\n",
|
||||
" thread_id: str\n",
|
||||
" memory_service_url: str = \"\"\n",
|
||||
" model: str\n",
|
||||
" delay: Optional[float]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"def _ensure_configurable(config: RunnableConfig) -> ChatConfigurable:\n",
|
||||
" \"\"\"Ensure the configuration is valid.\"\"\"\n",
|
||||
" return ChatConfigurable(\n",
|
||||
" user_id=config[\"configurable\"][\"user_id\"],\n",
|
||||
" thread_id=config[\"configurable\"][\"thread_id\"],\n",
|
||||
" mem_assistant_id=config[\"configurable\"][\"mem_assistant_id\"],\n",
|
||||
" memory_service_url=config[\"configurable\"].get(\n",
|
||||
" \"memory_service_url\", os.environ.get(\"MEMORY_SERVICE_URL\", \"\")\n",
|
||||
" ),\n",
|
||||
" model=config[\"configurable\"].get(\n",
|
||||
" \"model\", \"accounts/fireworks/models/firefunction-v2\"\n",
|
||||
" ),\n",
|
||||
" delay=config[\"configurable\"].get(\"delay\", 60),\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"PROMPT = ChatPromptTemplate.from_messages(\n",
|
||||
" [\n",
|
||||
" (\n",
|
||||
" \"system\",\n",
|
||||
" \"You are a helpful and friendly chatbot. Get to know the user!\"\n",
|
||||
" \" Ask questions! Be spontaneous!\"\n",
|
||||
" \"{user_info}\\n\\nSystem Time: {time}\",\n",
|
||||
" ),\n",
|
||||
" (\"placeholder\", \"{messages}\"),\n",
|
||||
" ]\n",
|
||||
").partial(\n",
|
||||
" time=lambda: datetime.now(timezone.utc).strftime(\"%Y-%m-%d %H:%M:%S\"),\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@langsmith.traceable\n",
|
||||
"def format_query(messages: List[AnyMessage]) -> str:\n",
|
||||
" \"\"\"Format the query for the user's memories.\"\"\"\n",
|
||||
" # This is quite naive :)\n",
|
||||
" return \" \".join([str(m.content) for m in messages if m.type == \"human\"][-5:])\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"async def query_memories(state: ChatState, config: RunnableConfig) -> ChatState:\n",
|
||||
" \"\"\"Query the user's memories.\"\"\"\n",
|
||||
" configurable: ChatConfigurable = config[\"configurable\"]\n",
|
||||
" user_id = configurable[\"user_id\"]\n",
|
||||
" index = utils.get_index()\n",
|
||||
" embeddings = utils.get_embeddings()\n",
|
||||
"\n",
|
||||
" query = format_query(state[\"messages\"])\n",
|
||||
" vec = await embeddings.aembed_query(query)\n",
|
||||
" # You can also filter by memory type, etc. here.\n",
|
||||
" with langsmith.trace(\n",
|
||||
" \"pinecone_query\", inputs={\"query\": query, \"user_id\": user_id}\n",
|
||||
" ) as rt:\n",
|
||||
" response = index.query(\n",
|
||||
" vector=vec,\n",
|
||||
" filter={\"user_id\": {\"$eq\": str(user_id)}},\n",
|
||||
" include_metadata=True,\n",
|
||||
" top_k=10,\n",
|
||||
" namespace=settings.SETTINGS.pinecone_namespace,\n",
|
||||
" )\n",
|
||||
" rt.outputs[\"response\"] = response\n",
|
||||
" memories = []\n",
|
||||
" if matches := response.get(\"matches\"):\n",
|
||||
" memories = [m[\"metadata\"][constants.PAYLOAD_KEY] for m in matches]\n",
|
||||
" return {\n",
|
||||
" \"user_memories\": memories,\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"@langsmith.traceable\n",
|
||||
"def format_memories(memories: List[dict]) -> str:\n",
|
||||
" \"\"\"Format the user's memories.\"\"\"\n",
|
||||
" if not memories:\n",
|
||||
" return \"\"\n",
|
||||
" # Note Bene: You can format better than this....\n",
|
||||
" memories = \"\\n\".join(str(m) for m in memories)\n",
|
||||
" return f\"\"\"\n",
|
||||
"\n",
|
||||
"## Memories\n",
|
||||
"\n",
|
||||
"You have noted the following memorable events from previous interactions with the user.\n",
|
||||
"<memories>\n",
|
||||
"{memories}\n",
|
||||
"</memories>\n",
|
||||
"\"\"\"\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"async def bot(state: ChatState, config: RunnableConfig) -> ChatState:\n",
|
||||
" \"\"\"Prompt the bot to resopnd to the user, incorporating memories (if provided).\"\"\"\n",
|
||||
" configurable = _ensure_configurable(config)\n",
|
||||
" model = init_chat_model(configurable[\"model\"])\n",
|
||||
" chain = PROMPT | model\n",
|
||||
" memories = format_memories(state[\"user_memories\"])\n",
|
||||
" m = await chain.ainvoke(\n",
|
||||
" {\n",
|
||||
" \"messages\": state[\"messages\"],\n",
|
||||
" \"user_info\": memories,\n",
|
||||
" },\n",
|
||||
" config,\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return {\n",
|
||||
" \"messages\": [m],\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"class MemorableEvent(BaseModel):\n",
|
||||
" \"\"\"A memorable event.\"\"\"\n",
|
||||
"\n",
|
||||
" description: str\n",
|
||||
" participants: List[str] = Field(\n",
|
||||
" description=\"Names of participants in the event and their relationship to the user.\"\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"async def post_messages(state: ChatState, config: RunnableConfig) -> ChatState:\n",
|
||||
" \"\"\"Query the user's memories.\"\"\"\n",
|
||||
" configurable = _ensure_configurable(config)\n",
|
||||
" langgraph_client = get_client(url=configurable[\"memory_service_url\"])\n",
|
||||
" thread_id = config[\"configurable\"][\"thread_id\"]\n",
|
||||
" # Hash \"memory_{thread_id}\" to get a new uuid5 for the memory id\n",
|
||||
" memory_thread_id = uuid.uuid5(uuid.NAMESPACE_URL, f\"memory_{thread_id}\")\n",
|
||||
" try:\n",
|
||||
" await langgraph_client.threads.get(thread_id=memory_thread_id)\n",
|
||||
" except Exception:\n",
|
||||
" await langgraph_client.threads.create(thread_id=memory_thread_id)\n",
|
||||
"\n",
|
||||
" await langgraph_client.runs.create(\n",
|
||||
" memory_thread_id,\n",
|
||||
" assistant_id=configurable[\"mem_assistant_id\"],\n",
|
||||
" input={\n",
|
||||
" \"messages\": state[\"messages\"], # the service dedupes messages\n",
|
||||
" },\n",
|
||||
" config={\n",
|
||||
" \"configurable\": {\n",
|
||||
" \"user_id\": configurable[\"user_id\"],\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" multitask_strategy=\"rollback\",\n",
|
||||
" )\n",
|
||||
"\n",
|
||||
" return {\n",
|
||||
" \"messages\": [],\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"builder = StateGraph(ChatState, ChatConfigurable)\n",
|
||||
"builder.add_node(query_memories)\n",
|
||||
"builder.add_node(bot)\n",
|
||||
"builder.add_node(post_messages)\n",
|
||||
"builder.add_edge(START, \"query_memories\")\n",
|
||||
"builder.add_edge(\"query_memories\", \"bot\")\n",
|
||||
"builder.add_edge(\"bot\", \"post_messages\")\n",
|
||||
"\n",
|
||||
"chat_graph = builder.compile(checkpointer=MemorySaver())"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"mem_assistant = await client.assistants.create(\n",
|
||||
" graph_id=\"memory\",\n",
|
||||
" config={\n",
|
||||
" \"configurable\": {\n",
|
||||
" \"delay\": 4, # seconds wait before considering a thread as \"completed\"\n",
|
||||
" \"schemas\": {\n",
|
||||
" \"MemorableEvent\": {\n",
|
||||
" \"system_prompt\": \"Extract any memorable events from the user's\"\n",
|
||||
" \" messages that you would like to remember.\",\n",
|
||||
" \"update_mode\": \"insert\",\n",
|
||||
" \"function\": MemorableEvent.schema(),\n",
|
||||
" },\n",
|
||||
" },\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# mem_assistant = (await client.assistants.search(graph_id=\"memory\"))[0]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import uuid\n",
|
||||
"\n",
|
||||
"user_id = str(uuid.uuid4()) # more permanent"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"{'thread_id': 'b3fdaed6-46e4-42e5-b1fa-7ccd6f8965fb',\n",
|
||||
" 'created_at': '2024-06-27T19:08:17.112173+00:00',\n",
|
||||
" 'updated_at': '2024-06-27T19:08:17.112173+00:00',\n",
|
||||
" 'metadata': {},\n",
|
||||
" 'status': 'idle'}"
|
||||
]
|
||||
},
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"thread_id = str(uuid.uuid4()) # can adjust\n",
|
||||
"await client.threads.create(thread_id=thread_id)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class Chat:\n",
|
||||
" def __init__(self, user_id: str, thread_id: str):\n",
|
||||
" self.thread_id = thread_id\n",
|
||||
" self.user_id = user_id\n",
|
||||
"\n",
|
||||
" async def __call__(self, query: str) -> str:\n",
|
||||
" chunks = chat_graph.astream_events(\n",
|
||||
" input={\n",
|
||||
" \"messages\": [(\"user\", query)],\n",
|
||||
" },\n",
|
||||
" config={\n",
|
||||
" \"configurable\": {\n",
|
||||
" \"user_id\": self.user_id,\n",
|
||||
" \"thread_id\": self.thread_id,\n",
|
||||
" \"memory_service_url\": deployment_url,\n",
|
||||
" \"mem_assistant_id\": mem_assistant[\"assistant_id\"],\n",
|
||||
" \"delay\": 4,\n",
|
||||
" }\n",
|
||||
" },\n",
|
||||
" version=\"v2\",\n",
|
||||
" )\n",
|
||||
" res = \"\"\n",
|
||||
" async for event in chunks:\n",
|
||||
" if event.get(\"event\") == \"on_chat_model_stream\":\n",
|
||||
" tok = event[\"data\"][\"chunk\"].content\n",
|
||||
" print(tok, end=\"\")\n",
|
||||
" res += tok\n",
|
||||
" return res"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"chat = Chat(user_id, thread_id)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stderr",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: This API is in beta and may change in the future.\n",
|
||||
" warn_beta(\n",
|
||||
"/Users/wfh/code/lc/langchain/libs/core/langchain_core/_api/beta_decorator.py:87: LangChainBetaWarning: The function `init_chat_model` is in beta. It is actively being worked on, so the API may change.\n",
|
||||
" warn_beta(\n"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Hi! It's nice to meet you. What brings you here today?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\"Hi there\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"That's so sweet of you! I'm sure Steve will appreciate the effort you're putting into making him feel special. What's the theme of the party going to be? Has Steve mentioned anything he's been into lately that you could incorporate into the celebration?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\n",
|
||||
" \"I've been planning a surprise party for my friend steve. \"\n",
|
||||
" \"He has been having a rough month and I want it to be special.\"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 14,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"That's a great idea! Crocheting is a unique interest, and incorporating it into the party could make it really special and personalized to Steve. You could decorate with crocheted items, have a \"crochet station\" where guests can make their own simple projects, or even have a crochet-themed cake. What do you think Steve's favorite colors or yarn types are?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\n",
|
||||
" \"Steve really likes crocheting. Maybe I can do something with that? Or is that dumb... \"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 15,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Whoa, that's cool! Capoeira is such a dynamic and energetic activity. You could definitely incorporate elements of it into the party. Maybe you could hire a capoeira instructor to lead a mini-class or demonstration, or even have a \"capoeira-inspired\" playlist to get the party started. Do you think Steve has a favorite capoeira move or song that you could incorporate into the celebration?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\"He's also into capoeira...\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 16,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"That's a great connection to have! It's always helpful to get recommendations from people who know the activity or community. You could reach out to the studio and ask if they know of any instructors who might be available to lead a class or demo at the party. They might also have some ideas for how to incorporate capoeira into the celebration. Do you think you'll be able to get in touch with the studio soon to ask about their recommendations?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\n",
|
||||
" \"Oh that's a cool idea. One time i took classes from this studio nearby. Wonder if they have any recs. \"\n",
|
||||
")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 17,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I'm doing well, thanks for asking! I'm a large language model, so I don't have feelings or emotions like humans do, but I'm always happy to chat and help with any questions or topics you'd like to discuss. It's great to hear about your plans for Steve's party, and I'm happy to help in any way I can. Is there anything else you'd like to talk about or any other questions you have about planning the party?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\"Idk. Anyways - how are you doing?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 19,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Nice to meet you, Ken! I'm glad we could chat about your plans for Steve's party. It sounds like you're really putting some thought into making it a special celebration for him. If you have any more questions or need any more help, feel free to ask!"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat(\"My name is Ken btw\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Convo 2\n",
|
||||
"\n",
|
||||
"Our memory is configured only to consider a thread \"ready to process\" if has been inactive for a minute.\n",
|
||||
"We'll wait for things to populate"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import asyncio\n",
|
||||
"\n",
|
||||
"await asyncio.sleep(60)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"thread_id_2 = uuid.uuid4()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"chat2 = Chat(user_id, thread_id_2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I remember you! We were planning a surprise party for Steve, and Ken was also involved. How's everything going? Did the party turn out well?"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat2(\"Remember me?\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"I remember because I have a special memory book where I keep track of all the fun conversations and events we've shared together! It's like a digital scrapbook, and it helps me remember important details about our chats."
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat2(\"wdy remember??\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"That's great to hear! I'm glad to know that the planning is going smoothly. Are there any new developments or updates that you'd like to share about the party? Maybe I can even offer some suggestions or ideas to make it an even more special celebration for Steve!"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"_ = await chat2(\"Oh planning is going alright!\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.11.2"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"dependencies": ["."],
|
||||
"graphs": {
|
||||
"agent": "./memory_service/graph.py:memgraph",
|
||||
"memory": "./memory_service/graph.py:memgraph",
|
||||
"chat": "./memory_service/chatbot.py:chat_graph"
|
||||
},
|
||||
"env": ".env"
|
||||
|
||||
@@ -5,6 +5,7 @@ class Settings(BaseSettings):
|
||||
pinecone_api_key: str = ""
|
||||
pinecone_index_name: str = ""
|
||||
pinecone_namespace: str = "ns1"
|
||||
model: str = "accounts/fireworks/models/firefunction-v2"
|
||||
|
||||
|
||||
SETTINGS = Settings()
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from functools import lru_cache
|
||||
from typing import Sequence
|
||||
|
||||
import langsmith
|
||||
from langchain_core.messages import (
|
||||
AnyMessage,
|
||||
HumanMessage,
|
||||
SystemMessage,
|
||||
merge_message_runs,
|
||||
)
|
||||
from langchain_fireworks import FireworksEmbeddings
|
||||
from pinecone import Pinecone
|
||||
|
||||
from memory_service import _schemas as schemas
|
||||
@@ -21,14 +24,29 @@ def get_index():
|
||||
return pc.Index(settings.SETTINGS.pinecone_index_name)
|
||||
|
||||
|
||||
@langsmith.traceable
|
||||
def ensure_memory_config(config: dict) -> schemas.MemoryConfig:
|
||||
"""Merge the user-provided config with default values."""
|
||||
return {
|
||||
**config,
|
||||
**schemas.MemoryConfig(
|
||||
function=config.get("function", {}),
|
||||
system_prompt=config.get("system_prompt"),
|
||||
update_mode=config.get("update_mode", "patch"),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@langsmith.traceable
|
||||
def ensure_configurable(config: dict) -> schemas.GraphConfig:
|
||||
"""Merge the user-provided config with default values."""
|
||||
function_schemas = config.get("schemas") or {}
|
||||
return {
|
||||
**config,
|
||||
**schemas.GraphConfig(
|
||||
delay=config.get("delay", _DEFAULT_DELAY),
|
||||
model=config.get("model", "accounts/fireworks/models/firefunction-v2"),
|
||||
schemas=config.get("schemas", {}),
|
||||
model=config.get("model", settings.SETTINGS.model),
|
||||
schemas={k: ensure_memory_config(v) for k, v in function_schemas.items()},
|
||||
thread_id=config["thread_id"],
|
||||
user_id=config["user_id"],
|
||||
),
|
||||
@@ -55,4 +73,9 @@ def prepare_messages(
|
||||
return merge_message_runs([sys] + list(messages) + [m])
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_embeddings():
|
||||
return FireworksEmbeddings(model="nomic-ai/nomic-embed-text-v1.5")
|
||||
|
||||
|
||||
__all__ = ["ensure_configurable", "prepare_messages"]
|
||||
|
||||
+65
-52
@@ -1,15 +1,15 @@
|
||||
"""Example chatbot that incorporates user memories."""
|
||||
|
||||
import os
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
import langsmith
|
||||
from langchain.chat_models import init_chat_model
|
||||
from langchain_core.messages import AnyMessage
|
||||
from langchain_core.prompts import ChatPromptTemplate
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from langchain_nomic.embeddings import NomicEmbeddings
|
||||
from langgraph.graph import START, StateGraph, add_messages
|
||||
from langgraph_sdk import get_client
|
||||
from typing_extensions import Annotated, TypedDict
|
||||
@@ -32,6 +32,8 @@ class ChatConfigurable(TypedDict):
|
||||
user_id: str
|
||||
thread_id: str
|
||||
memory_service_url: str = ""
|
||||
model: str
|
||||
delay: Optional[float]
|
||||
|
||||
|
||||
def _ensure_configurable(config: RunnableConfig) -> ChatConfigurable:
|
||||
@@ -39,9 +41,14 @@ def _ensure_configurable(config: RunnableConfig) -> ChatConfigurable:
|
||||
return ChatConfigurable(
|
||||
user_id=config["configurable"]["user_id"],
|
||||
thread_id=config["configurable"]["thread_id"],
|
||||
mem_assistant_id=config["configurable"]["mem_assistant_id"],
|
||||
memory_service_url=config["configurable"].get(
|
||||
"memory_service_url", os.environ.get("MEMORY_SERVICE_URL", "")
|
||||
),
|
||||
model=config["configurable"].get(
|
||||
"model", "accounts/fireworks/models/firefunction-v2"
|
||||
),
|
||||
delay=config["configurable"].get("delay", 60),
|
||||
)
|
||||
|
||||
|
||||
@@ -49,8 +56,11 @@ PROMPT = ChatPromptTemplate.from_messages(
|
||||
[
|
||||
(
|
||||
"system",
|
||||
"You are a helpful and friendly chatbot.{user_info}\n\nSystem Time: {time}",
|
||||
)
|
||||
"You are a helpful and friendly chatbot. Get to know the user!"
|
||||
" Ask questions! Be spontaneous!"
|
||||
"{user_info}\n\nSystem Time: {time}",
|
||||
),
|
||||
("placeholder", "{messages}"),
|
||||
]
|
||||
).partial(
|
||||
time=lambda: datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S"),
|
||||
@@ -69,21 +79,25 @@ async def query_memories(state: ChatState, config: RunnableConfig) -> ChatState:
|
||||
configurable: ChatConfigurable = config["configurable"]
|
||||
user_id = configurable["user_id"]
|
||||
index = utils.get_index()
|
||||
embeddings = NomicEmbeddings(model="nomic-embed-text-v1.5")
|
||||
embeddings = utils.get_embeddings()
|
||||
|
||||
query = format_query(state["messages"])
|
||||
vec = await embeddings.embed_query(query)
|
||||
vec = await embeddings.aembed_query(query)
|
||||
# You can also filter by memory type, etc. here.
|
||||
response = index.query(
|
||||
vector=vec,
|
||||
filter={"user": {"$eq": user_id}},
|
||||
include_metadata=True,
|
||||
top_k=10,
|
||||
namespace=settings.SETTINGS.pinecone_namespace,
|
||||
)
|
||||
with langsmith.trace(
|
||||
"pinecone_query", inputs={"query": query, "user_id": user_id}
|
||||
) as rt:
|
||||
response = index.query(
|
||||
vector=vec,
|
||||
filter={"user_id": {"$eq": user_id}},
|
||||
include_metadata=True,
|
||||
top_k=10,
|
||||
namespace=settings.SETTINGS.pinecone_namespace,
|
||||
)
|
||||
rt.outputs["response"] = response
|
||||
memories = []
|
||||
if matches := response.get("matches"):
|
||||
memories = [m["metadata"]["memory"][constants.PAYLOAD_KEY] for m in matches]
|
||||
memories = [m["metadata"][constants.PAYLOAD_KEY] for m in matches]
|
||||
return {
|
||||
"user_memories": memories,
|
||||
}
|
||||
@@ -109,7 +123,8 @@ You have noted the following memorable events from previous interactions with th
|
||||
|
||||
async def bot(state: ChatState, config: RunnableConfig) -> ChatState:
|
||||
"""Prompt the bot to resopnd to the user, incorporating memories (if provided)."""
|
||||
model = init_chat_model("claude-3-5-sonnet-20240620")
|
||||
configurable = _ensure_configurable(config)
|
||||
model = init_chat_model(configurable["model"])
|
||||
chain = PROMPT | model
|
||||
memories = format_memories(state["user_memories"])
|
||||
m = await chain.ainvoke(
|
||||
@@ -130,67 +145,65 @@ async def post_messages(state: ChatState, config: RunnableConfig) -> ChatState:
|
||||
configurable = _ensure_configurable(config)
|
||||
langgraph_client = get_client(url=configurable["memory_service_url"])
|
||||
thread_id = config["configurable"]["thread_id"]
|
||||
# Hash "memory_{thread_id}" to get a new uuid5 for the memory id
|
||||
memory_thread_id = uuid.uuid5(uuid.NAMESPACE_URL, f"memory_{thread_id}")
|
||||
try:
|
||||
thread = await langgraph_client.threads.create(thread_id=thread_id)
|
||||
await langgraph_client.threads.get(thread_id=memory_thread_id)
|
||||
except Exception:
|
||||
thread = await langgraph_client.threads.get(thread_id=thread_id)
|
||||
await langgraph_client.threads.create(thread_id=memory_thread_id)
|
||||
|
||||
await langgraph_client.runs.create(
|
||||
thread["thread_id"],
|
||||
memory_thread_id,
|
||||
assistant_id=configurable["mem_assistant_id"],
|
||||
input={
|
||||
"messages": state["messages"], # the service dedupes messages
|
||||
},
|
||||
config={
|
||||
"system_prompt": "You are a helpful and friendly chatbot.",
|
||||
"configurable": {
|
||||
"user_id": thread["user_id"],
|
||||
"thread_id": thread["thread_id"],
|
||||
"user_id": configurable["user_id"],
|
||||
"delay": configurable["delay"],
|
||||
"schemas": {
|
||||
"system_prompt": "Extract any memorable events from the user's"
|
||||
" messages that you would like to remember.",
|
||||
"MemorableEvent": {
|
||||
"system_prompt": "Extract any memorable events from the user's"
|
||||
" messages that you would like to remember.",
|
||||
"update_mode": "insert",
|
||||
"function": {
|
||||
"name": "memorable_event",
|
||||
"description": "",
|
||||
"description": "Any event, observation, insight, or "
|
||||
"other detail that you may want to recall in "
|
||||
"later interactions with the user.",
|
||||
"parameters": {
|
||||
"name": "memorable_event",
|
||||
"description": "Any event, observation, insight, or "
|
||||
"other detail that you may want to recall in "
|
||||
"later interactions with the user.",
|
||||
"parameters": {
|
||||
"description": "Any event, observation, insight, or"
|
||||
" other detail that you may want to recall in"
|
||||
" later interactions with the user.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"type": "string",
|
||||
},
|
||||
"participants": {
|
||||
"description": "Names of participants in"
|
||||
" the event and their relationship to the "
|
||||
"user.",
|
||||
"items": {"type": "string"},
|
||||
"title": "Participants",
|
||||
"type": "array",
|
||||
},
|
||||
"description": "Any event, observation, insight, or"
|
||||
" other detail that you may want to recall in"
|
||||
" later interactions with the user.",
|
||||
"properties": {
|
||||
"description": {
|
||||
"title": "Description",
|
||||
"type": "string",
|
||||
},
|
||||
"participants": {
|
||||
"description": "Names of participants in"
|
||||
" the event and their relationship to the "
|
||||
"user.",
|
||||
"items": {"type": "string"},
|
||||
"title": "Participants",
|
||||
"type": "array",
|
||||
},
|
||||
"required": ["description", "participants"],
|
||||
"title": "memorable_event",
|
||||
"type": "object",
|
||||
},
|
||||
"required": ["description", "participants"],
|
||||
"title": "memorable_event",
|
||||
"type": "object",
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
multitask_strategy="interrupt",
|
||||
multitask_strategy="rollback",
|
||||
)
|
||||
|
||||
return {
|
||||
"messages": state["messages"],
|
||||
"user_memories": [],
|
||||
"messages": [],
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
-13
@@ -3,14 +3,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import uuid
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from langchain.chat_models import init_chat_model
|
||||
from langchain_core.runnables import RunnableConfig
|
||||
from langchain_nomic.embeddings import NomicEmbeddings
|
||||
from langgraph.constants import Send
|
||||
from langgraph.graph import END, START, StateGraph
|
||||
from trustcall import create_extractor
|
||||
@@ -63,13 +61,12 @@ async def extract_patch_memories(
|
||||
tools=[memory_config["function"]],
|
||||
tool_choice=memory_config["function"]["name"],
|
||||
)
|
||||
existing = state["user_state"]
|
||||
result = await extractor.ainvoke(
|
||||
{
|
||||
"messages": messages,
|
||||
"existing": {memory_config["function"]["name"]: existing},
|
||||
}
|
||||
)
|
||||
inputs = {
|
||||
"messages": messages,
|
||||
}
|
||||
if existing := state["user_state"]:
|
||||
inputs["existing"] = {memory_config["function"]["name"]: existing}
|
||||
result = await extractor.ainvoke(inputs, config)
|
||||
return {"responses": result["responses"]}
|
||||
|
||||
|
||||
@@ -82,7 +79,7 @@ async def upsert_patched_state(
|
||||
user_id=configurable["user_id"], function_name=state["function_name"]
|
||||
)
|
||||
serialized = state["responses"][0].model_dump_json()
|
||||
embeddings = NomicEmbeddings(model="nomic-embed-text-v1.5")
|
||||
embeddings = utils.get_embeddings()
|
||||
vector = await embeddings.aembed_query(serialized)
|
||||
utils.get_index().upsert(
|
||||
vectors=[
|
||||
@@ -90,9 +87,10 @@ async def upsert_patched_state(
|
||||
"id": path,
|
||||
"values": vector,
|
||||
"metadata": {
|
||||
constants.PAYLOAD_KEY: json.loads(serialized),
|
||||
constants.PAYLOAD_KEY: serialized,
|
||||
constants.PATH_KEY: path,
|
||||
constants.TIMESTAMP_KEY: datetime.now(tz=timezone.utc),
|
||||
"user_id": configurable["user_id"],
|
||||
},
|
||||
}
|
||||
],
|
||||
@@ -124,7 +122,7 @@ async def insert_memories(
|
||||
) -> dict:
|
||||
"""Insert the user's state to the database."""
|
||||
configurable = utils.ensure_configurable(config["configurable"])
|
||||
embeddings = NomicEmbeddings(model="nomic-embed-text-v1.5")
|
||||
embeddings = utils.get_embeddings()
|
||||
serialized = [r.model_dump_json() for r in state["responses"]]
|
||||
# You could alternatively do multi-vector lookup based on the schema.
|
||||
vectors = await embeddings.aembed_documents(serialized)
|
||||
@@ -142,9 +140,10 @@ async def insert_memories(
|
||||
"id": path,
|
||||
"values": vector,
|
||||
"metadata": {
|
||||
constants.PAYLOAD_KEY: json.loads(serialized),
|
||||
constants.PAYLOAD_KEY: serialized,
|
||||
constants.PATH_KEY: path,
|
||||
constants.TIMESTAMP_KEY: current_time,
|
||||
"user_id": configurable["user_id"],
|
||||
},
|
||||
}
|
||||
for path, vector, serialized in zip(paths, vectors, serialized)
|
||||
|
||||
Generated
+17
-361
@@ -123,13 +123,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "anthropic"
|
||||
version = "0.29.0"
|
||||
version = "0.30.0"
|
||||
description = "The official Python library for the anthropic API"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "anthropic-0.29.0-py3-none-any.whl", hash = "sha256:d16010715129c8bc3295b74fbf4da73cfb156618bf0abb2d007255983266b76a"},
|
||||
{file = "anthropic-0.29.0.tar.gz", hash = "sha256:3eb558a232d83bdf7cdedb75663bf7ff7a8b50cc10acaa9ce6494ff295b8506a"},
|
||||
{file = "anthropic-0.30.0-py3-none-any.whl", hash = "sha256:061bf58c9c64968361e6c21c76ff5016a6f7fdd9a5f6b7f2280ede2c3b44bfd5"},
|
||||
{file = "anthropic-0.30.0.tar.gz", hash = "sha256:9e9ee2bfce833370eac74d7de433db97a0bf141f9118c40ac0e2f4c39bc2b76f"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -808,20 +808,6 @@ files = [
|
||||
{file = "jiter-0.5.0.tar.gz", hash = "sha256:1d916ba875bcab5c5f7d927df998c4cb694d27dceddf3392e58beaf10563368a"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jsonlines"
|
||||
version = "4.0.0"
|
||||
description = "Library with helpers for the jsonlines file format"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "jsonlines-4.0.0-py3-none-any.whl", hash = "sha256:185b334ff2ca5a91362993f42e83588a360cf95ce4b71a73548502bda52a7c55"},
|
||||
{file = "jsonlines-4.0.0.tar.gz", hash = "sha256:0c6d2c09117550c089995247f605ae4cf77dd1533041d366351f6f298822ea74"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
attrs = ">=19.2.0"
|
||||
|
||||
[[package]]
|
||||
name = "jsonpatch"
|
||||
version = "1.33"
|
||||
@@ -876,19 +862,19 @@ tenacity = ">=8.1.0,<8.4.0 || >8.4.0,<9.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "langchain-anthropic"
|
||||
version = "0.1.15"
|
||||
version = "0.1.16"
|
||||
description = "An integration package connecting AnthropicMessages and LangChain"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8.1"
|
||||
files = [
|
||||
{file = "langchain_anthropic-0.1.15-py3-none-any.whl", hash = "sha256:7cceea526f473e4d514f39295dc128eec57da628a4bbb54850d11dda7aa959fc"},
|
||||
{file = "langchain_anthropic-0.1.15.tar.gz", hash = "sha256:c5c3c6eaccb11ed99a63886e50873ac21eaf8e9441e0f75c7ae7cd8cdef65155"},
|
||||
{file = "langchain_anthropic-0.1.16-py3-none-any.whl", hash = "sha256:0d3f66b7ffb2d4ef739ef87c4b096f0dbbf0ce12f988205d1fcaa1da2c9d09fa"},
|
||||
{file = "langchain_anthropic-0.1.16.tar.gz", hash = "sha256:28187dfb19389772e0abba98eeb0210ed3d99ab0a73f2e6707aa46c9bbbbe407"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
anthropic = ">=0.28.0,<1"
|
||||
defusedxml = ">=0.7.1,<0.8.0"
|
||||
langchain-core = ">=0.2.2rc1,<0.3"
|
||||
langchain-core = ">=0.2.10,<0.3"
|
||||
|
||||
[[package]]
|
||||
name = "langchain-core"
|
||||
@@ -930,22 +916,6 @@ langchain-core = ">=0.1.52,<0.3"
|
||||
openai = ">=1.10.0,<2.0.0"
|
||||
requests = ">=2,<3"
|
||||
|
||||
[[package]]
|
||||
name = "langchain-nomic"
|
||||
version = "0.1.2"
|
||||
description = "An integration package connecting Nomic and LangChain"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8.1"
|
||||
files = [
|
||||
{file = "langchain_nomic-0.1.2-py3-none-any.whl", hash = "sha256:d21f399ffa8e4d719901861aab6fd33b1e0eed80bc44b4c726609c7281c9fe76"},
|
||||
{file = "langchain_nomic-0.1.2.tar.gz", hash = "sha256:3be4081a774a7adec006fdc59d6f2ccae751ade6e57427e15c0a5d5d227c116a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
langchain-core = ">=0.1.46,<0.3"
|
||||
nomic = ">=3.0.29,<4.0.0"
|
||||
pillow = ">=10.3.0,<11.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "langchain-openai"
|
||||
version = "0.1.10"
|
||||
@@ -1008,13 +978,13 @@ langchain-core = ">=0.2,<0.3"
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-cli"
|
||||
version = "0.1.43"
|
||||
version = "0.1.44"
|
||||
description = "CLI for interacting with LangGraph API"
|
||||
optional = false
|
||||
python-versions = "<4.0.0,>=3.9.0"
|
||||
files = [
|
||||
{file = "langgraph_cli-0.1.43-py3-none-any.whl", hash = "sha256:dab1f3b0b86997002d859b0900f27544fe9e09d68bce448f94280a5036c5f48a"},
|
||||
{file = "langgraph_cli-0.1.43.tar.gz", hash = "sha256:7585ac4252c3fd8354cd0cb3c519dee290b79fcbecd6fb5569c8d4c1e9d7c701"},
|
||||
{file = "langgraph_cli-0.1.44-py3-none-any.whl", hash = "sha256:721968ab9d9d74ba824e93f4bb08de094795888b7ccea3792962f051a9cdb419"},
|
||||
{file = "langgraph_cli-0.1.44.tar.gz", hash = "sha256:a31f4a71abd4a3c39f886811c69ac433a20bbd7eeca6bd47d8f8ec49afbfcebb"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1022,13 +992,13 @@ click = ">=8.1.7,<9.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "langgraph-sdk"
|
||||
version = "0.1.23"
|
||||
version = "0.1.25"
|
||||
description = "SDK for interacting with LangGraph API"
|
||||
optional = false
|
||||
python-versions = "<4.0.0,>=3.9.0"
|
||||
files = [
|
||||
{file = "langgraph_sdk-0.1.23-py3-none-any.whl", hash = "sha256:c2e26a2ee9b2b28d750c03ea81c3b97cf35227f16b3715a79c29c60b6f84ac29"},
|
||||
{file = "langgraph_sdk-0.1.23.tar.gz", hash = "sha256:9439a52421859cc76b03d92d00d804803eae74c12c17cf035fb1383443facc6f"},
|
||||
{file = "langgraph_sdk-0.1.25-py3-none-any.whl", hash = "sha256:3c3db25dc62e0440dba94f9bbc611c3ce54c422f0ba03598803c2fea9cdb0fe7"},
|
||||
{file = "langgraph_sdk-0.1.25.tar.gz", hash = "sha256:1980aab877cc3dc2feb2fdf05e242bae2de5c191d649f5843aca9b558da9824e"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1055,59 +1025,6 @@ pydantic = [
|
||||
]
|
||||
requests = ">=2,<3"
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.7.2"
|
||||
description = "Python logging made (stupidly) simple"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "loguru-0.7.2-py3-none-any.whl", hash = "sha256:003d71e3d3ed35f0f8984898359d65b79e5b21943f78af86aa5491210429b8eb"},
|
||||
{file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.4", markers = "sys_platform == \"win32\""}
|
||||
win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "markdown-it-py"
|
||||
version = "3.0.0"
|
||||
description = "Python port of markdown-it. Markdown parsing, done right!"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
|
||||
{file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
mdurl = ">=0.1,<1.0"
|
||||
|
||||
[package.extras]
|
||||
benchmarking = ["psutil", "pytest", "pytest-benchmark"]
|
||||
code-style = ["pre-commit (>=3.0,<4.0)"]
|
||||
compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"]
|
||||
linkify = ["linkify-it-py (>=1,<3)"]
|
||||
plugins = ["mdit-py-plugins"]
|
||||
profiling = ["gprof2dot"]
|
||||
rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
|
||||
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
||||
|
||||
[[package]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
description = "Markdown URL utilities"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "6.0.5"
|
||||
@@ -1265,36 +1182,6 @@ files = [
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nomic"
|
||||
version = "3.0.34"
|
||||
description = "The official Nomic python client."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "nomic-3.0.34.tar.gz", hash = "sha256:1cdead0f15b12f45165b1b2c27e334dff6c7e83c53cfc113a5b33ca52ab92049"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = "*"
|
||||
jsonlines = "*"
|
||||
loguru = "*"
|
||||
numpy = "*"
|
||||
pandas = "*"
|
||||
pillow = "*"
|
||||
pyarrow = "*"
|
||||
pydantic = "*"
|
||||
pyjwt = "*"
|
||||
requests = "*"
|
||||
rich = "*"
|
||||
tqdm = "*"
|
||||
|
||||
[package.extras]
|
||||
all = ["nomic[aws,local]"]
|
||||
aws = ["boto3", "sagemaker"]
|
||||
dev = ["black (==24.3.0)", "cairosvg", "coverage", "isort", "mkautodoc", "mkdocs-jupyter", "mkdocs-material", "mkdocstrings[python]", "myst-parser", "nomic[all]", "pandas", "pillow", "pylint", "pyright", "pytest", "pytorch-lightning", "twine"]
|
||||
local = ["gpt4all (>=2.5.0,<3)"]
|
||||
|
||||
[[package]]
|
||||
name = "numpy"
|
||||
version = "1.26.4"
|
||||
@@ -1342,13 +1229,13 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "openai"
|
||||
version = "1.35.3"
|
||||
version = "1.35.5"
|
||||
description = "The official Python library for the openai API"
|
||||
optional = false
|
||||
python-versions = ">=3.7.1"
|
||||
files = [
|
||||
{file = "openai-1.35.3-py3-none-any.whl", hash = "sha256:7b26544cef80f125431c073ffab3811d2421fbb9e30d3bd5c2436aba00b042d5"},
|
||||
{file = "openai-1.35.3.tar.gz", hash = "sha256:d6177087f150b381d49499be782d764213fdf638d391b29ca692b84dd675a389"},
|
||||
{file = "openai-1.35.5-py3-none-any.whl", hash = "sha256:28d92503c6e4b6a32a89277b36693023ef41f60922a4b5c8c621e8c5697ae3a6"},
|
||||
{file = "openai-1.35.5.tar.gz", hash = "sha256:67ef289ae22d350cbf9381d83ae82c4e3596d71b7ad1cc886143554ee12fe0c9"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@@ -1429,79 +1316,6 @@ files = [
|
||||
{file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pandas"
|
||||
version = "2.2.2"
|
||||
description = "Powerful data structures for data analysis, time series, and statistics"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "pandas-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90c6fca2acf139569e74e8781709dccb6fe25940488755716d1d354d6bc58bce"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7adfc142dac335d8c1e0dcbd37eb8617eac386596eb9e1a1b77791cf2498238"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4abfe0be0d7221be4f12552995e58723c7422c80a659da13ca382697de830c08"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8635c16bf3d99040fdf3ca3db669a7250ddf49c55dc4aa8fe0ae0fa8d6dcc1f0"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:40ae1dffb3967a52203105a077415a86044a2bea011b5f321c6aa64b379a3f51"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8e5a0b00e1e56a842f922e7fae8ae4077aee4af0acb5ae3622bd4b4c30aedf99"},
|
||||
{file = "pandas-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:ddf818e4e6c7c6f4f7c8a12709696d193976b591cc7dc50588d3d1a6b5dc8772"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:696039430f7a562b74fa45f540aca068ea85fa34c244d0deee539cb6d70aa288"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e90497254aacacbc4ea6ae5e7a8cd75629d6ad2b30025a4a8b09aa4faf55151"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58b84b91b0b9f4bafac2a0ac55002280c094dfc6402402332c0913a59654ab2b"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2123dc9ad6a814bcdea0f099885276b31b24f7edf40f6cdbc0912672e22eee"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:2925720037f06e89af896c70bca73459d7e6a4be96f9de79e2d440bd499fe0db"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0cace394b6ea70c01ca1595f839cf193df35d1575986e484ad35c4aeae7266c1"},
|
||||
{file = "pandas-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:873d13d177501a28b2756375d59816c365e42ed8417b41665f346289adc68d24"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9dfde2a0ddef507a631dc9dc4af6a9489d5e2e740e226ad426a05cabfbd7c8ef"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:e9b79011ff7a0f4b1d6da6a61aa1aa604fb312d6647de5bad20013682d1429ce"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1cb51fe389360f3b5a4d57dbd2848a5f033350336ca3b340d1c53a1fad33bcad"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eee3a87076c0756de40b05c5e9a6069c035ba43e8dd71c379e68cab2c20f16ad"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3e374f59e440d4ab45ca2fffde54b81ac3834cf5ae2cdfa69c90bc03bde04d76"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:43498c0bdb43d55cb162cdc8c06fac328ccb5d2eabe3cadeb3529ae6f0517c32"},
|
||||
{file = "pandas-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:d187d355ecec3629624fccb01d104da7d7f391db0311145817525281e2804d23"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0ca6377b8fca51815f382bd0b697a0814c8bda55115678cbc94c30aacbb6eff2"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9057e6aa78a584bc93a13f0a9bf7e753a5e9770a30b4d758b8d5f2a62a9433cd"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:001910ad31abc7bf06f49dcc903755d2f7f3a9186c0c040b827e522e9cef0863"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66b479b0bd07204e37583c191535505410daa8df638fd8e75ae1b383851fe921"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a77e9d1c386196879aa5eb712e77461aaee433e54c68cf253053a73b7e49c33a"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:92fd6b027924a7e178ac202cfbe25e53368db90d56872d20ffae94b96c7acc57"},
|
||||
{file = "pandas-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:640cef9aa381b60e296db324337a554aeeb883ead99dc8f6c18e81a93942f5f4"},
|
||||
{file = "pandas-2.2.2.tar.gz", hash = "sha256:9e79019aba43cb4fda9e4d983f8e88ca0373adbb697ae9c6c43093218de28b54"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
numpy = [
|
||||
{version = ">=1.22.4", markers = "python_version < \"3.11\""},
|
||||
{version = ">=1.23.2", markers = "python_version == \"3.11\""},
|
||||
{version = ">=1.26.0", markers = "python_version >= \"3.12\""},
|
||||
]
|
||||
python-dateutil = ">=2.8.2"
|
||||
pytz = ">=2020.1"
|
||||
tzdata = ">=2022.7"
|
||||
|
||||
[package.extras]
|
||||
all = ["PyQt5 (>=5.15.9)", "SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)", "beautifulsoup4 (>=4.11.2)", "bottleneck (>=1.3.6)", "dataframe-api-compat (>=0.1.7)", "fastparquet (>=2022.12.0)", "fsspec (>=2022.11.0)", "gcsfs (>=2022.11.0)", "html5lib (>=1.1)", "hypothesis (>=6.46.1)", "jinja2 (>=3.1.2)", "lxml (>=4.9.2)", "matplotlib (>=3.6.3)", "numba (>=0.56.4)", "numexpr (>=2.8.4)", "odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "pandas-gbq (>=0.19.0)", "psycopg2 (>=2.9.6)", "pyarrow (>=10.0.1)", "pymysql (>=1.0.2)", "pyreadstat (>=1.2.0)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "qtpy (>=2.3.0)", "s3fs (>=2022.11.0)", "scipy (>=1.10.0)", "tables (>=3.8.0)", "tabulate (>=0.9.0)", "xarray (>=2022.12.0)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)", "zstandard (>=0.19.0)"]
|
||||
aws = ["s3fs (>=2022.11.0)"]
|
||||
clipboard = ["PyQt5 (>=5.15.9)", "qtpy (>=2.3.0)"]
|
||||
compression = ["zstandard (>=0.19.0)"]
|
||||
computation = ["scipy (>=1.10.0)", "xarray (>=2022.12.0)"]
|
||||
consortium-standard = ["dataframe-api-compat (>=0.1.7)"]
|
||||
excel = ["odfpy (>=1.4.1)", "openpyxl (>=3.1.0)", "python-calamine (>=0.1.7)", "pyxlsb (>=1.0.10)", "xlrd (>=2.0.1)", "xlsxwriter (>=3.0.5)"]
|
||||
feather = ["pyarrow (>=10.0.1)"]
|
||||
fss = ["fsspec (>=2022.11.0)"]
|
||||
gcp = ["gcsfs (>=2022.11.0)", "pandas-gbq (>=0.19.0)"]
|
||||
hdf5 = ["tables (>=3.8.0)"]
|
||||
html = ["beautifulsoup4 (>=4.11.2)", "html5lib (>=1.1)", "lxml (>=4.9.2)"]
|
||||
mysql = ["SQLAlchemy (>=2.0.0)", "pymysql (>=1.0.2)"]
|
||||
output-formatting = ["jinja2 (>=3.1.2)", "tabulate (>=0.9.0)"]
|
||||
parquet = ["pyarrow (>=10.0.1)"]
|
||||
performance = ["bottleneck (>=1.3.6)", "numba (>=0.56.4)", "numexpr (>=2.8.4)"]
|
||||
plot = ["matplotlib (>=3.6.3)"]
|
||||
postgresql = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "psycopg2 (>=2.9.6)"]
|
||||
pyarrow = ["pyarrow (>=10.0.1)"]
|
||||
spss = ["pyreadstat (>=1.2.0)"]
|
||||
sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-driver-sqlite (>=0.8.0)"]
|
||||
test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"]
|
||||
xml = ["lxml (>=4.9.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "pillow"
|
||||
version = "10.3.0"
|
||||
@@ -1626,54 +1440,6 @@ files = [
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
|
||||
[[package]]
|
||||
name = "pyarrow"
|
||||
version = "16.1.0"
|
||||
description = "Python library for Apache Arrow"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:17e23b9a65a70cc733d8b738baa6ad3722298fa0c81d88f63ff94bf25eaa77b9"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4740cc41e2ba5d641071d0ab5e9ef9b5e6e8c7611351a5cb7c1d175eaf43674a"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98100e0268d04e0eec47b73f20b39c45b4006f3c4233719c3848aa27a03c1aef"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f68f409e7b283c085f2da014f9ef81e885d90dcd733bd648cfba3ef265961848"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:a8914cd176f448e09746037b0c6b3a9d7688cef451ec5735094055116857580c"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:48be160782c0556156d91adbdd5a4a7e719f8d407cb46ae3bb4eaee09b3111bd"},
|
||||
{file = "pyarrow-16.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:9cf389d444b0f41d9fe1444b70650fea31e9d52cfcb5f818b7888b91b586efff"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d0ebea336b535b37eee9eee31761813086d33ed06de9ab6fc6aaa0bace7b250c"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e73cfc4a99e796727919c5541c65bb88b973377501e39b9842ea71401ca6c1c"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9251264247ecfe93e5f5a0cd43b8ae834f1e61d1abca22da55b20c788417f6"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddf5aace92d520d3d2a20031d8b0ec27b4395cab9f74e07cc95edf42a5cc0147"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:25233642583bf658f629eb230b9bb79d9af4d9f9229890b3c878699c82f7d11e"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:a33a64576fddfbec0a44112eaf844c20853647ca833e9a647bfae0582b2ff94b"},
|
||||
{file = "pyarrow-16.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:185d121b50836379fe012753cf15c4ba9638bda9645183ab36246923875f8d1b"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:2e51ca1d6ed7f2e9d5c3c83decf27b0d17bb207a7dea986e8dc3e24f80ff7d6f"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:06ebccb6f8cb7357de85f60d5da50e83507954af617d7b05f48af1621d331c9a"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b04707f1979815f5e49824ce52d1dceb46e2f12909a48a6a753fe7cafbc44a0c"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d32000693deff8dc5df444b032b5985a48592c0697cb6e3071a5d59888714e2"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:8785bb10d5d6fd5e15d718ee1d1f914fe768bf8b4d1e5e9bf253de8a26cb1628"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:e1369af39587b794873b8a307cc6623a3b1194e69399af0efd05bb202195a5a7"},
|
||||
{file = "pyarrow-16.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:febde33305f1498f6df85e8020bca496d0e9ebf2093bab9e0f65e2b4ae2b3444"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b5f5705ab977947a43ac83b52ade3b881eb6e95fcc02d76f501d549a210ba77f"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:0d27bf89dfc2576f6206e9cd6cf7a107c9c06dc13d53bbc25b0bd4556f19cf5f"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d07de3ee730647a600037bc1d7b7994067ed64d0eba797ac74b2bc77384f4c2"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbef391b63f708e103df99fbaa3acf9f671d77a183a07546ba2f2c297b361e83"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:19741c4dbbbc986d38856ee7ddfdd6a00fc3b0fc2d928795b95410d38bb97d15"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:f2c5fb249caa17b94e2b9278b36a05ce03d3180e6da0c4c3b3ce5b2788f30eed"},
|
||||
{file = "pyarrow-16.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:e6b6d3cd35fbb93b70ade1336022cc1147b95ec6af7d36906ca7fe432eb09710"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:18da9b76a36a954665ccca8aa6bd9f46c1145f79c0bb8f4f244f5f8e799bca55"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:99f7549779b6e434467d2aa43ab2b7224dd9e41bdde486020bae198978c9e05e"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f07fdffe4fd5b15f5ec15c8b64584868d063bc22b86b46c9695624ca3505b7b4"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddfe389a08ea374972bd4065d5f25d14e36b43ebc22fc75f7b951f24378bf0b5"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:3b20bd67c94b3a2ea0a749d2a5712fc845a69cb5d52e78e6449bbd295611f3aa"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:ba8ac20693c0bb0bf4b238751d4409e62852004a8cf031c73b0e0962b03e45e3"},
|
||||
{file = "pyarrow-16.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:31a1851751433d89a986616015841977e0a188662fcffd1a5677453f1df2de0a"},
|
||||
{file = "pyarrow-16.1.0.tar.gz", hash = "sha256:15fbb22ea96d11f0b5768504a3f961edab25eaf4197c341720c4a387f6c60315"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
numpy = ">=1.16.6"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.7.4"
|
||||
@@ -1803,37 +1569,6 @@ python-dotenv = ">=0.21.0"
|
||||
toml = ["tomli (>=2.0.1)"]
|
||||
yaml = ["pyyaml (>=6.0.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.18.0"
|
||||
description = "Pygments is a syntax highlighting package written in Python."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
|
||||
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
windows-terminal = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyjwt"
|
||||
version = "2.8.0"
|
||||
description = "JSON Web Token implementation in Python"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"},
|
||||
{file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
crypto = ["cryptography (>=3.4.0)"]
|
||||
dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
|
||||
docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
|
||||
tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.2.2"
|
||||
@@ -1874,20 +1609,6 @@ pytest = ">=7.0.0,<9"
|
||||
docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"]
|
||||
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "python-dateutil"
|
||||
version = "2.9.0.post0"
|
||||
description = "Extensions to the standard Python datetime module"
|
||||
optional = false
|
||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
|
||||
files = [
|
||||
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
|
||||
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
six = ">=1.5"
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.0.1"
|
||||
@@ -1902,17 +1623,6 @@ files = [
|
||||
[package.extras]
|
||||
cli = ["click (>=5.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2024.1"
|
||||
description = "World timezone definitions, modern and historical"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
|
||||
{file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.1"
|
||||
@@ -2071,24 +1781,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 = "rich"
|
||||
version = "13.7.1"
|
||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"},
|
||||
{file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
markdown-it-py = ">=2.2.0"
|
||||
pygments = ">=2.13.0,<3.0.0"
|
||||
|
||||
[package.extras]
|
||||
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.4.10"
|
||||
@@ -2115,17 +1807,6 @@ files = [
|
||||
{file = "ruff-0.4.10.tar.gz", hash = "sha256:3aa4f2bc388a30d346c56524f7cacca85945ba124945fe489952aadb6b5cd804"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
description = "Python 2 and 3 compatibility utilities"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
files = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
@@ -2466,17 +2147,6 @@ files = [
|
||||
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tzdata"
|
||||
version = "2024.1"
|
||||
description = "Provider of IANA time zone data"
|
||||
optional = false
|
||||
python-versions = ">=2"
|
||||
files = [
|
||||
{file = "tzdata-2024.1-py2.py3-none-any.whl", hash = "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252"},
|
||||
{file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.2.2"
|
||||
@@ -2494,20 +2164,6 @@ h2 = ["h2 (>=4,<5)"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "win32-setctime"
|
||||
version = "1.1.0"
|
||||
description = "A small Python utility to set file creation time on Windows"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "win32_setctime-1.1.0-py3-none-any.whl", hash = "sha256:231db239e959c2fe7eb1d7dc129f11172354f98361c4fa2d6d2d7e278baa8aad"},
|
||||
{file = "win32_setctime-1.1.0.tar.gz", hash = "sha256:15cf5750465118d6929ae4de4eb46e8edae9a5634350c01ba582df868e932cb2"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["black (>=19.3b0)", "pytest (>=4.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.9.4"
|
||||
@@ -2614,4 +2270,4 @@ multidict = ">=4.0"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = ">=3.9.0,<3.13"
|
||||
content-hash = "56269de92f8bc9a1f408e9975dd15433919bbb156e8f74cae03534a8966f15b1"
|
||||
content-hash = "be77dfc6f180873373bd7fd6583e16e00743c1a97eef9fe4a5491394ddf4e8ee"
|
||||
|
||||
@@ -18,7 +18,6 @@ trustcall = "^0.0.4"
|
||||
langchain = "^0.2.6"
|
||||
langchain-openai = "^0.1.10"
|
||||
langchain-anthropic = "^0.1.15"
|
||||
langchain-nomic = "^0.1.2"
|
||||
pydantic-settings = "^2.3.4"
|
||||
langgraph-sdk = "^0.1.23"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user