diff --git a/python/langsmith/client.py b/python/langsmith/client.py index d15cfa46f..66081653e 100644 --- a/python/langsmith/client.py +++ b/python/langsmith/client.py @@ -5291,6 +5291,65 @@ def pull_prompt_commit( **{"owner": owner, "repo": prompt_name, **response.json()} ) + def list_prompt_commits( + self, + prompt_identifier: str, + *, + limit: Optional[int] = None, + offset: int = 0, + include_model: bool = False, + ) -> Iterator[ls_schemas.ListedPromptCommit]: + """List commits for a given prompt. + + Args: + prompt_identifier (str): The identifier of the prompt in the format 'owner/repo_name'. + limit (Optional[int], optional): The maximum number of commits to return. If None, returns all commits. Defaults to None. + offset (int, optional): The number of commits to skip before starting to return results. Defaults to 0. + include_model (bool, optional): Whether to include the model information in the commit data. Defaults to False. + + Returns: + Iterator[ls_schemas.ListedPromptCommit]: An iterator of ListedPromptCommit objects representing the commits. + + Yields: + ls_schemas.ListedPromptCommit: A ListedPromptCommit object for each commit. + + Note: + This method uses pagination to retrieve commits. It will make multiple API calls if necessary to retrieve all commits + or up to the specified limit. + """ + owner, prompt_name, _ = ls_utils.parse_prompt_identifier(prompt_identifier) + + params = { + "limit": limit if limit is not None else 100, + "offset": offset, + "include_model": include_model, + } + i = 0 + while True: + params["offset"] = offset + response = self.request_with_retries( + "GET", + f"/commits/{owner}/{prompt_name}/", + params=params, + ) + val = response.json() + items = val["commits"] + total = val["total"] + + if not items: + break + for it in items: + i += 1 + yield ls_schemas.ListedPromptCommit( + **{"owner": owner, "repo": prompt_name, **it} + ) + if limit is not None and i >= limit: + break + + offset += len(items) + if offset >= total: + break + def pull_prompt( self, prompt_identifier: str, *, include_model: Optional[bool] = False ) -> Any: diff --git a/python/langsmith/schemas.py b/python/langsmith/schemas.py index 602f08293..33bb11c40 100644 --- a/python/langsmith/schemas.py +++ b/python/langsmith/schemas.py @@ -769,6 +769,49 @@ class PromptCommit(BaseModel): """The list of examples.""" +class ListedPromptCommit(BaseModel): + """Represents a listed prompt commit with associated metadata.""" + + id: UUID + """The unique identifier for the prompt commit.""" + + owner: str + """The owner of the prompt commit.""" + + repo: str + """The repository name of the prompt commit.""" + + manifest_id: Optional[UUID] = None + """The optional identifier for the manifest associated with this commit.""" + + repo_id: Optional[UUID] = None + """The optional identifier for the repository.""" + + parent_id: Optional[UUID] = None + """The optional identifier for the parent commit.""" + + commit_hash: Optional[str] = None + """The optional hash of the commit.""" + + created_at: Optional[datetime] = None + """The optional timestamp when the commit was created.""" + + updated_at: Optional[datetime] = None + """The optional timestamp when the commit was last updated.""" + + example_run_ids: Optional[List[UUID]] = Field(default_factory=list) + """A list of example run identifiers associated with this commit.""" + + num_downloads: Optional[int] = 0 + """The number of times this commit has been downloaded.""" + + num_views: Optional[int] = 0 + """The number of times this commit has been viewed.""" + + parent_commit_hash: Optional[str] = None + """The optional hash of the parent commit.""" + + class Prompt(BaseModel): """Represents a Prompt with metadata.""" diff --git a/python/pyproject.toml b/python/pyproject.toml index ab70f2b7e..098431c0e 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langsmith" -version = "0.1.127" +version = "0.1.128" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." authors = ["LangChain "] license = "MIT"