diff --git a/libs/langchain/langchain/hub.py b/libs/langchain/langchain/hub.py index adaf0de05f5..f1c022b762b 100644 --- a/libs/langchain/langchain/hub.py +++ b/libs/langchain/langchain/hub.py @@ -3,27 +3,37 @@ from __future__ import annotations import json -from typing import TYPE_CHECKING, Any, Optional +from typing import Any, Optional, Sequence from langchain_core.load.dump import dumps from langchain_core.load.load import loads from langchain_core.prompts import BasePromptTemplate -if TYPE_CHECKING: - from langchainhub import Client - -def _get_client(api_url: Optional[str] = None, api_key: Optional[str] = None) -> Client: +def _get_client( + api_key: Optional[str] = None, + api_url: Optional[str] = None, +) -> Any: try: - from langchainhub import Client - except ImportError as e: - raise ImportError( - "Could not import langchainhub, please install with `pip install " - "langchainhub`." - ) from e + from langsmith import Client as LangSmithClient - # Client logic will also attempt to load URL/key from environment variables - return Client(api_url, api_key=api_key) + ls_client = LangSmithClient(api_url, api_key=api_key) + if hasattr(ls_client, "push_prompt") and hasattr(ls_client, "pull_prompt"): + return ls_client + else: + from langchainhub import Client as LangChainHubClient + + return LangChainHubClient(api_url, api_key=api_key) + except ImportError: + try: + from langchainhub import Client as LangChainHubClient + + return LangChainHubClient(api_url, api_key=api_key) + except ImportError as e: + raise ImportError( + "Could not import langsmith or langchainhub (deprecated)," + "please install with `pip install langsmith`." + ) from e def push( @@ -32,27 +42,43 @@ def push( *, api_url: Optional[str] = None, api_key: Optional[str] = None, - parent_commit_hash: Optional[str] = "latest", - new_repo_is_public: bool = True, - new_repo_description: str = "", + parent_commit_hash: Optional[str] = None, + new_repo_is_public: bool = False, + new_repo_description: Optional[str] = None, + readme: Optional[str] = None, + tags: Optional[Sequence[str]] = None, ) -> str: """ Push an object to the hub and returns the URL it can be viewed at in a browser. - :param repo_full_name: The full name of the repo to push to in the format of - `owner/repo`. + :param repo_full_name: The full name of the prompt to push to in the format of + `owner/prompt_name` or `prompt_name`. :param object: The LangChain to serialize and push to the hub. :param api_url: The URL of the LangChain Hub API. Defaults to the hosted API service if you have an api key set, or a localhost instance if not. :param api_key: The API key to use to authenticate with the LangChain Hub API. :param parent_commit_hash: The commit hash of the parent commit to push to. Defaults to the latest commit automatically. - :param new_repo_is_public: Whether the repo should be public. Defaults to - True (Public by default). - :param new_repo_description: The description of the repo. Defaults to an empty + :param new_repo_is_public: Whether the prompt should be public. Defaults to + False (Private by default). + :param new_repo_description: The description of the prompt. Defaults to an empty string. """ - client = _get_client(api_url=api_url, api_key=api_key) + client = _get_client(api_key=api_key, api_url=api_url) + + # Then it's langsmith + if hasattr(client, "push_prompt"): + return client.push_prompt( + repo_full_name, + object=object, + parent_commit_hash=parent_commit_hash, + is_public=new_repo_is_public, + description=new_repo_description, + readme=readme, + tags=tags, + ) + + # Then it's langchainhub manifest_json = dumps(object) message = client.push( repo_full_name, @@ -67,20 +93,28 @@ def push( def pull( owner_repo_commit: str, *, + include_model: Optional[bool] = None, api_url: Optional[str] = None, api_key: Optional[str] = None, ) -> Any: """ Pull an object from the hub and returns it as a LangChain object. - :param owner_repo_commit: The full name of the repo to pull from in the format of - `owner/repo:commit_hash`. + :param owner_repo_commit: The full name of the prompt to pull from in the format of + `owner/prompt_name:commit_hash` or `owner/prompt_name` + or just `prompt_name` if it's your own prompt. :param api_url: The URL of the LangChain Hub API. Defaults to the hosted API service if you have an api key set, or a localhost instance if not. :param api_key: The API key to use to authenticate with the LangChain Hub API. """ - client = _get_client(api_url=api_url, api_key=api_key) + client = _get_client(api_key=api_key, api_url=api_url) + # Then it's langsmith + if hasattr(client, "pull_prompt"): + response = client.pull_prompt(owner_repo_commit, include_model=include_model) + return response + + # Then it's langchainhub if hasattr(client, "pull_repo"): # >= 0.1.15 res_dict = client.pull_repo(owner_repo_commit) @@ -93,6 +127,6 @@ def pull( obj.metadata["lc_hub_commit_hash"] = res_dict["commit_hash"] return obj - # Then it's < 0.1.15 + # Then it's < 0.1.15 langchainhub resp: str = client.pull(owner_repo_commit) return loads(resp)