forked from usemoss/moss-samples
-
Notifications
You must be signed in to change notification settings - Fork 0
cookbook-dspy-langchain #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,4 @@ | ||
| .mypy_cache | ||
| .ruff_cache | ||
| .DS_Store | ||
| __pycache__ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,310 @@ | ||
| { | ||
| "cells": [ | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "id": "245e75ab", | ||
| "metadata": {}, | ||
| "outputs": [ | ||
| { | ||
| "name": "stdout", | ||
| "output_type": "stream", | ||
| "text": [ | ||
| "Collecting inferedge_moss\n", | ||
| " Using cached inferedge_moss-1.0.0b12-py3-none-any.whl.metadata (8.6 kB)\n", | ||
| "Requirement already satisfied: transformers>=4.21.0 in /opt/homebrew/lib/python3.11/site-packages (from inferedge_moss) (4.57.3)\n", | ||
| "Requirement already satisfied: numpy>=1.26.4 in /opt/homebrew/lib/python3.11/site-packages (from inferedge_moss) (1.26.4)\n", | ||
| "Requirement already satisfied: typing-extensions>=4.0.0 in /Users/keshav/Library/Python/3.11/lib/python/site-packages (from inferedge_moss) (4.15.0)\n", | ||
| "Requirement already satisfied: httpx>=0.25.0 in /opt/homebrew/lib/python3.11/site-packages (from inferedge_moss) (0.28.1)\n", | ||
| "Requirement already satisfied: onnxruntime>=1.12.0 in /opt/homebrew/lib/python3.11/site-packages (from inferedge_moss) (1.23.2)\n", | ||
| "Collecting inferedge-moss-core==0.3.0 (from inferedge_moss)\n", | ||
| " Using cached inferedge_moss_core-0.3.0-cp311-cp311-macosx_11_0_arm64.whl.metadata (2.2 kB)\n", | ||
| "Requirement already satisfied: anyio in /opt/homebrew/lib/python3.11/site-packages (from httpx>=0.25.0->inferedge_moss) (4.11.0)\n", | ||
| "Requirement already satisfied: certifi in /opt/homebrew/lib/python3.11/site-packages (from httpx>=0.25.0->inferedge_moss) (2025.10.5)\n", | ||
| "Requirement already satisfied: httpcore==1.* in /opt/homebrew/lib/python3.11/site-packages (from httpx>=0.25.0->inferedge_moss) (1.0.9)\n", | ||
| "Requirement already satisfied: idna in /opt/homebrew/lib/python3.11/site-packages (from httpx>=0.25.0->inferedge_moss) (3.11)\n", | ||
| "Requirement already satisfied: h11>=0.16 in /opt/homebrew/lib/python3.11/site-packages (from httpcore==1.*->httpx>=0.25.0->inferedge_moss) (0.16.0)\n", | ||
| "Requirement already satisfied: coloredlogs in /opt/homebrew/lib/python3.11/site-packages (from onnxruntime>=1.12.0->inferedge_moss) (15.0.1)\n", | ||
| "Requirement already satisfied: flatbuffers in /opt/homebrew/lib/python3.11/site-packages (from onnxruntime>=1.12.0->inferedge_moss) (25.12.19)\n", | ||
| "Requirement already satisfied: packaging in /Users/keshav/Library/Python/3.11/lib/python/site-packages (from onnxruntime>=1.12.0->inferedge_moss) (25.0)\n", | ||
| "Requirement already satisfied: protobuf in /opt/homebrew/lib/python3.11/site-packages (from onnxruntime>=1.12.0->inferedge_moss) (6.33.2)\n", | ||
| "Requirement already satisfied: sympy in /opt/homebrew/lib/python3.11/site-packages (from onnxruntime>=1.12.0->inferedge_moss) (1.14.0)\n", | ||
| "Requirement already satisfied: filelock in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (3.20.1)\n", | ||
| "Requirement already satisfied: huggingface-hub<1.0,>=0.34.0 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (0.36.0)\n", | ||
| "Requirement already satisfied: pyyaml>=5.1 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (6.0.3)\n", | ||
| "Requirement already satisfied: regex!=2019.12.17 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (2025.11.3)\n", | ||
| "Requirement already satisfied: requests in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (2.32.5)\n", | ||
| "Requirement already satisfied: tokenizers<=0.23.0,>=0.22.0 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (0.22.1)\n", | ||
| "Requirement already satisfied: safetensors>=0.4.3 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (0.7.0)\n", | ||
| "Requirement already satisfied: tqdm>=4.27 in /opt/homebrew/lib/python3.11/site-packages (from transformers>=4.21.0->inferedge_moss) (4.67.1)\n", | ||
| "Requirement already satisfied: fsspec>=2023.5.0 in /opt/homebrew/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers>=4.21.0->inferedge_moss) (2025.9.0)\n", | ||
| "Requirement already satisfied: hf-xet<2.0.0,>=1.1.3 in /opt/homebrew/lib/python3.11/site-packages (from huggingface-hub<1.0,>=0.34.0->transformers>=4.21.0->inferedge_moss) (1.2.0)\n", | ||
| "Requirement already satisfied: sniffio>=1.1 in /opt/homebrew/lib/python3.11/site-packages (from anyio->httpx>=0.25.0->inferedge_moss) (1.3.1)\n", | ||
| "Requirement already satisfied: humanfriendly>=9.1 in /opt/homebrew/lib/python3.11/site-packages (from coloredlogs->onnxruntime>=1.12.0->inferedge_moss) (10.0)\n", | ||
| "Requirement already satisfied: charset_normalizer<4,>=2 in /opt/homebrew/lib/python3.11/site-packages (from requests->transformers>=4.21.0->inferedge_moss) (3.4.4)\n", | ||
| "Requirement already satisfied: urllib3<3,>=1.21.1 in /opt/homebrew/lib/python3.11/site-packages (from requests->transformers>=4.21.0->inferedge_moss) (2.6.2)\n", | ||
| "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /opt/homebrew/lib/python3.11/site-packages (from sympy->onnxruntime>=1.12.0->inferedge_moss) (1.3.0)\n", | ||
| "Using cached inferedge_moss-1.0.0b12-py3-none-any.whl (21 kB)\n", | ||
| "Using cached inferedge_moss_core-0.3.0-cp311-cp311-macosx_11_0_arm64.whl (733 kB)\n", | ||
| "Installing collected packages: inferedge-moss-core, inferedge_moss\n", | ||
| "\u001b[2K Attempting uninstall: inferedge-moss-core\n", | ||
| "\u001b[2K Found existing installation: inferedge-moss-core 0.2.3\n", | ||
| "\u001b[2K Uninstalling inferedge-moss-core-0.2.3:\n", | ||
| "\u001b[2K Successfully uninstalled inferedge-moss-core-0.2.32m0/2\u001b[0m [inferedge-moss-core]\n", | ||
| "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m2/2\u001b[0m [inferedge_moss]]\n", | ||
| "\u001b[1A\u001b[2KSuccessfully installed inferedge-moss-core-0.3.0 inferedge_moss-1.0.0b12\n", | ||
| "\n", | ||
| "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m25.3\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m26.0\u001b[0m\n", | ||
| "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49m/opt/homebrew/opt/python@3.11/bin/python3.11 -m pip install --upgrade pip\u001b[0m\n", | ||
| "Note: you may need to restart the kernel to use updated packages.\n" | ||
| ] | ||
| } | ||
| ], | ||
| "source": [ | ||
| "pip install inferedge_moss dspy" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": 2, | ||
| "id": "2afd4122", | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import asyncio\n", | ||
| "import dspy\n", | ||
| "from dspy.dsp.utils import dotdict\n", | ||
| "from dspy.primitives.prediction import Prediction\n", | ||
| "from dspy.retrievers.retrieve import Retrieve\n", | ||
| "from inferedge_moss import DocumentInfo, MossClient, QueryOptions\n", | ||
| "import nest_asyncio\n", | ||
| "import os\n", | ||
| "from dotenv import load_dotenv\n", | ||
| "\n", | ||
| "load_dotenv()\n", | ||
| "nest_asyncio.apply()\n", | ||
| "\n", | ||
| "def run_async(coro):\n", | ||
| " \"\"\"Helper to run async coroutines in a notebook environment.\"\"\"\n", | ||
| " try:\n", | ||
| " loop = asyncio.get_event_loop()\n", | ||
| " except RuntimeError:\n", | ||
| " loop = asyncio.new_event_loop()\n", | ||
| " asyncio.set_event_loop(loop)\n", | ||
| " \n", | ||
| " if loop.is_running():\n", | ||
| " return loop.run_until_complete(coro)\n", | ||
| " else:\n", | ||
| " return asyncio.run(coro)\n", | ||
| "\n", | ||
| "class MossRM(Retrieve):\n", | ||
| " \"\"\"A retrieval module that uses Moss (InferEdge) to return the top passages for a given query.\n", | ||
| "\n", | ||
| " Args:\n", | ||
| " index_name (str): The name of the Moss index.\n", | ||
| " moss_client (MossClient): An instance of the Moss client.\n", | ||
| " k (int, optional): The default number of top passages to retrieve. Default to 3.\n", | ||
| "\n", | ||
| " Examples:\n", | ||
| " Below is a code snippet that shows how to use Moss as the default retriever:\n", | ||
| " ```python\n", | ||
| " from inferedge_moss import MossClient\n", | ||
| " import dspy\n", | ||
| "\n", | ||
| " moss_client = MossClient(\"your-project-id\", \"your-project-key\")\n", | ||
| " retriever_model = MossRM(\"my_index_name\", moss_client=moss_client)\n", | ||
| " dspy.configure(rm=retriever_model)\n", | ||
| "\n", | ||
| " retrieve = dspy.Retrieve(k=1)\n", | ||
| " topK_passages = retrieve(\"what are the stages in planning, sanctioning and execution of public works\").passages\n", | ||
| " ```\n", | ||
| " \"\"\"\n", | ||
| "\n", | ||
| " def __init__(\n", | ||
| " self,\n", | ||
| " index_name: str,\n", | ||
| " moss_client: MossClient,\n", | ||
| " k: int = 3,\n", | ||
| " alpha: float = 0.5,\n", | ||
| " ):\n", | ||
| " self._index_name = index_name\n", | ||
| " self._moss_client = moss_client\n", | ||
| " self._alpha = alpha\n", | ||
| "\n", | ||
| " super().__init__(k=k)\n", | ||
| "\n", | ||
| " def forward(self, query_or_queries: str | list[str], k: int | None = None, **kwargs) -> Prediction:\n", | ||
| " \"\"\"Search with Moss for self.k top passages for query or queries.\n", | ||
| "\n", | ||
| " Args:\n", | ||
| " query_or_queries (Union[str, list[str]]): The query or queries to search for.\n", | ||
| " k (Optional[int]): The number of top passages to retrieve. Defaults to self.k.\n", | ||
| " kwargs : Additional arguments for Moss client.\n", | ||
| "\n", | ||
| " Returns:\n", | ||
| " dspy.Prediction: An object containing the retrieved passages.\n", | ||
| " \"\"\"\n", | ||
| " k = k if k is not None else self.k\n", | ||
| " queries = [query_or_queries] if isinstance(query_or_queries, str) else query_or_queries\n", | ||
| " queries = [q for q in queries if q]\n", | ||
| " passages = []\n", | ||
| "\n", | ||
| " for query in queries:\n", | ||
| " options = QueryOptions(top_k=k, alpha=self._alpha, **kwargs)\n", | ||
| " # Since MossClient methods are async, we use asyncio.run to call them synchronously.\n", | ||
| " # This assumes the loop is not already running, which is typical for DSPy RM calls.\n", | ||
| " result = asyncio.run(self._moss_client.query(self._index_name, query, options=options))\n", | ||
| "\n", | ||
| " for doc in result.docs:\n", | ||
| " passages.append(\n", | ||
| " dotdict({\"long_text\": doc.text, \"id\": doc.id, \"metadata\": doc.metadata, \"score\": doc.score})\n", | ||
| " )\n", | ||
| "\n", | ||
| " return passages\n", | ||
| "\n", | ||
| " def get_objects(self, num_samples: int = 5) -> list[dict]:\n", | ||
| " \"\"\"Get objects from Moss.\"\"\"\n", | ||
| " # Note: Moss's get_docs might return all docs or have limits.\n", | ||
| " # Here we attempt to fetch and return up to num_samples.\n", | ||
| " result = asyncio.run(self._moss_client.get_docs(self._index_name))\n", | ||
| " # result is likely a list of DocumentInfo or similar\n", | ||
| " objects = []\n", | ||
| " for i, doc in enumerate(result):\n", | ||
| " if i >= num_samples:\n", | ||
| " break\n", | ||
| " objects.append({\"id\": doc.id, \"text\": doc.text, \"metadata\": doc.metadata})\n", | ||
| " return objects\n", | ||
| "\n", | ||
| " def insert(self, new_object_properties: dict | list[dict]):\n", | ||
| " \"\"\"Insert one or more objects into Moss.\"\"\"\n", | ||
| " if isinstance(new_object_properties, dict):\n", | ||
| " new_object_properties = [new_object_properties]\n", | ||
| "\n", | ||
| " docs = [DocumentInfo(**props) for props in new_object_properties]\n", | ||
| " asyncio.run(self._moss_client.add_docs(self._index_name, docs))" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": 3, | ||
| "id": "71a53798", | ||
| "metadata": {}, | ||
| "outputs": [], | ||
| "source": [ | ||
| "import requests\n", | ||
| "import os\n", | ||
| "import asyncio\n", | ||
| "from inferedge_moss import MossClient, DocumentInfo\n", | ||
| "# 2. Initialize MossClient (Replace with your actual keys)\n", | ||
| "MOSS_PROJECT_ID = os.getenv(\"MOSS_PROJECT_ID\", os.getenv(\"MOSS_PROJECT_ID\"))\n", | ||
| "MOSS_PROJECT_KEY = os.getenv(\"MOSS_PROJECT_KEY\", os.getenv(\"MOSS_PROJECT_KEY\"))\n", | ||
| "\n", | ||
| "client = MossClient(MOSS_PROJECT_ID, MOSS_PROJECT_KEY)\n", | ||
| "INDEX_NAME = \"moss-cookbook\"\n", | ||
| "\n", | ||
| "llm = dspy.LM(model=\"gpt-4.1-mini\",api_key=\"sk-proj\")\n", | ||
| "# retriever_model = MossRM(INDEX_NAME, moss_client=client) ways to use Moss as retriever\n", | ||
| "# dspy.settings.configure(lm=llm, rm=retriever_model)\n", | ||
| "dspy.configure(lm=llm)" | ||
| ] | ||
| }, | ||
| { | ||
| "cell_type": "code", | ||
| "execution_count": null, | ||
| "id": "0f25a2e2", | ||
| "metadata": {}, | ||
| "outputs": [ | ||
| { | ||
| "name": "stderr", | ||
| "output_type": "stream", | ||
| "text": [ | ||
| "/var/folders/ny/7jk1wzqd7wz6z964crstxgqm0000gn/T/ipykernel_89530/729364508.py:22: RuntimeWarning: coroutine 'MossClient.load_index' was never awaited\n", | ||
| " client.load_index(INDEX)\n", | ||
| "RuntimeWarning: Enable tracemalloc to get the object allocation traceback\n" | ||
| ] | ||
| }, | ||
| { | ||
| "name": "stdout", | ||
| "output_type": "stream", | ||
| "text": [ | ||
| "[Tool DEBUG] Found 10 results for: shipping address\n", | ||
| "[Tool DEBUG] First snippet: How can I change my shipping address? Contact our customer service team....\n", | ||
| "Answer: The shipping address is near St. Mark's Square.\n", | ||
| "\n", | ||
| "Tool calls made (Trajectory):\n", | ||
| "thought_0\n", | ||
| "tool_name_0\n", | ||
| "tool_args_0\n", | ||
| "observation_0\n", | ||
| "thought_1\n", | ||
| "tool_name_1\n", | ||
| "tool_args_1\n", | ||
| "observation_1\n" | ||
| ] | ||
| } | ||
| ], | ||
| "source": [ | ||
| "# Create a ReAct agent using Moss as a tool\n", | ||
| "def moss_search(query: str):\n", | ||
| " \"\"\"Searches the Moss knowledge base for relevant passages.\"\"\"\n", | ||
| " \n", | ||
| " # 2. Configure query options\n", | ||
| " options = QueryOptions(top_k=TOP_K, alpha=0)\n", | ||
| " # 3. Use the run_async helper to call Moss from a sync function\n", | ||
| " # (Results are automatically returned as a list of documents)\n", | ||
| " results = run_async(client.query(INDEX, query, options=options))\n", | ||
| " # You can process multiple topK results as well\n", | ||
| " if results.docs:\n", | ||
| " print(f\"[Tool DEBUG] Found {len(results.docs)} results for: {query}\")\n", | ||
| " print(f\"[Tool DEBUG] First snippet: {results.docs[0].text}...\")\n", | ||
| " \n", | ||
| " if not results.docs:\n", | ||
| " return \"No relevant info found.\"\n", | ||
| " \n", | ||
| " return \"\\n\".join([f\"- {doc.text}\" for doc in results.docs])\n", | ||
| "\n", | ||
| "\n", | ||
| "INDEX = \"moss-cookbook\"\n", | ||
| "TOP_K = 10\n", | ||
| "client.load_index(INDEX)\n", | ||
| "\n", | ||
| "# Initialize the ReAct agent with the Moss search tool\n", | ||
| "react_agent = dspy.ReAct(\n", | ||
| " signature=\"question -> answer\",\n", | ||
| " tools=[moss_search],\n", | ||
| " max_iters=5\n", | ||
| ")\n", | ||
| "\n", | ||
| "# Example usage\n", | ||
| "question = \"whats the shipping address?\"\n", | ||
| "result = react_agent(question=question)\n", | ||
| "\n", | ||
| "print(f\"Answer: {result.answer}\")\n", | ||
| "print(\"\\nTool calls made (Trajectory):\")\n", | ||
| "for step in result.trajectory:\n", | ||
| " print(step)" | ||
| ] | ||
| } | ||
| ], | ||
| "metadata": { | ||
| "kernelspec": { | ||
| "display_name": "Python 3", | ||
| "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.14" | ||
| } | ||
| }, | ||
| "nbformat": 4, | ||
| "nbformat_minor": 5 | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # Moss LangChain Cookbook | ||
|
|
||
| This cookbook demonstrates how to integrate [Moss](https://moss.dev) with [LangChain](https://www.langchain.com/). | ||
|
|
||
| ## Overview | ||
|
|
||
| Moss is a semantic search platform that allows you to build and query high-performance vector indices without managing infrastructure. This integration provides: | ||
|
|
||
| 1. **MossRetriever**: A LangChain-compatible retriever for semantic search. | ||
| 2. **MossSearchTool**: A tool for LangChain agents to search your knowledge base. | ||
|
|
||
| ## Installation | ||
|
|
||
| Ensure you have the required packages installed: | ||
|
|
||
| ```bash | ||
| pip install inferedge-moss langchain langchain-openai python-dotenv | ||
| ``` | ||
|
|
||
| ## Setup | ||
|
|
||
| Create a `.env` file with your Moss credentials: | ||
|
|
||
| ```env | ||
| MOSS_PROJECT_ID=your_project_id | ||
| MOSS_PROJECT_KEY=your_project_key | ||
| MOSS_INDEX_NAME=your_index_name | ||
| OPENAI_API_KEY=your_openai_api_key | ||
| ``` | ||
|
|
||
| ## Usage | ||
|
|
||
| ### Using the Retriever | ||
|
|
||
| The `MossRetriever` can be used in any LangChain chain. | ||
|
|
||
| ```python | ||
| from moss_langchain import MossRetriever | ||
|
|
||
| retriever = MossRetriever( | ||
| project_id="your_id", | ||
| project_key="your_key", | ||
| index_name="your_index", | ||
| top_k=3, | ||
| alpha=0 | ||
| ) | ||
|
|
||
| docs = retriever.invoke("What is the refund policy?") | ||
| ``` | ||
|
|
||
| ### Using the Agent Tool | ||
|
|
||
| You can also use Moss as a tool for an agent. | ||
|
|
||
| ```python | ||
| from moss_langchain import get_moss_tool | ||
|
|
||
| tool = get_moss_tool( | ||
| project_id="your_id", | ||
| project_key="your_key", | ||
| index_name="your_index" | ||
| ) | ||
|
|
||
| # Add to agent tools | ||
| tools = [tool] | ||
| ``` | ||
|
|
||
| ## Examples | ||
|
|
||
| Check out the [moss_langchain.ipynb](moss_langchain.ipynb) notebook for complete examples including: | ||
|
|
||
| - Direct index querying | ||
| - Retrieval-Augmented Generation (RAG) | ||
| - ReAct Agent with Moss search | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the plan here? are. we shipping this new package to pypi?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah folks at langchain told me to add this to pypi.
langchain-ai/langchain-community#514