| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382 |
- """Schemas for the LangSmith API."""
- from __future__ import annotations
- from collections.abc import Iterator
- from datetime import datetime, timedelta, timezone
- from decimal import Decimal
- from enum import Enum
- from typing import (
- Annotated,
- Any,
- NamedTuple,
- Optional,
- Protocol,
- Union,
- runtime_checkable,
- )
- from uuid import UUID
- from typing_extensions import NotRequired, TypedDict
- try:
- from pydantic.v1 import (
- BaseModel,
- Field, # type: ignore[import]
- PrivateAttr,
- StrictBool,
- StrictFloat,
- StrictInt,
- )
- except ImportError:
- from pydantic import ( # type: ignore[assignment]
- BaseModel,
- Field,
- PrivateAttr,
- StrictBool,
- StrictFloat,
- StrictInt,
- )
- from pathlib import Path
- from typing_extensions import Literal
- SCORE_TYPE = Union[StrictBool, StrictInt, StrictFloat, None]
- VALUE_TYPE = Union[dict, str, None]
- class Attachment(NamedTuple):
- """Annotated type that will be stored as an attachment if used.
- Examples:
- ```python
- from langsmith import traceable
- from langsmith.schemas import Attachment
- @traceable
- def my_function(bar: int, my_val: Attachment):
- # my_val will be stored as an attachment
- # bar will be stored as inputs
- return bar
- ```
- """
- mime_type: str
- data: Union[bytes, Path]
- Attachments = dict[str, Union[tuple[str, bytes], Attachment, tuple[str, Path]]]
- """Attachments associated with the run.
- Each entry is a tuple of `(mime_type, bytes)`, or `(mime_type, file_path)`
- """
- @runtime_checkable
- class BinaryIOLike(Protocol):
- """Protocol for binary IO-like objects."""
- def read(self, size: int = -1) -> bytes:
- """Read function."""
- ...
- def seek(self, offset: int, whence: int = 0) -> int:
- """Seek function."""
- ...
- def getvalue(self) -> bytes:
- """Get value function."""
- ...
- class ExampleBase(BaseModel):
- """Example base model."""
- dataset_id: UUID
- inputs: Optional[dict[str, Any]] = Field(default=None)
- outputs: Optional[dict[str, Any]] = Field(default=None)
- metadata: Optional[dict[str, Any]] = Field(default=None)
- class Config:
- """Configuration class for the schema."""
- frozen = True
- arbitrary_types_allowed = True
- class _AttachmentDict(TypedDict):
- mime_type: str
- data: Union[bytes, Path]
- _AttachmentLike = Union[
- Attachment, _AttachmentDict, tuple[str, bytes], tuple[str, Path]
- ]
- class ExampleCreate(BaseModel):
- """Example upload with attachments."""
- id: Optional[UUID]
- created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
- inputs: Optional[dict[str, Any]] = Field(default=None)
- outputs: Optional[dict[str, Any]] = Field(default=None)
- metadata: Optional[dict[str, Any]] = Field(default=None)
- split: Optional[Union[str, list[str]]] = None
- attachments: Optional[dict[str, _AttachmentLike]] = None
- use_source_run_io: bool = False
- use_source_run_attachments: Optional[list[str]] = None
- source_run_id: Optional[UUID] = None
- def __init__(self, **data):
- """Initialize from dict."""
- super().__init__(**data)
- ExampleUploadWithAttachments = ExampleCreate
- class ExampleUpsertWithAttachments(ExampleCreate):
- """Example create with attachments."""
- dataset_id: UUID
- class AttachmentInfo(TypedDict):
- """Info for an attachment."""
- presigned_url: str
- reader: BinaryIOLike
- mime_type: Optional[str]
- class Example(ExampleBase):
- """Example model."""
- id: UUID
- created_at: datetime = Field(
- default_factory=lambda: datetime.fromtimestamp(0, tz=timezone.utc)
- )
- dataset_id: UUID = Field(default=UUID("00000000-0000-0000-0000-000000000000"))
- modified_at: Optional[datetime] = Field(default=None)
- source_run_id: Optional[UUID] = None
- attachments: Optional[dict[str, AttachmentInfo]] = Field(default=None)
- """Dictionary with attachment names as keys and a tuple of the S3 url
- and a reader of the data for the file."""
- _host_url: Optional[str] = PrivateAttr(default=None)
- _tenant_id: Optional[UUID] = PrivateAttr(default=None)
- def __init__(
- self,
- _host_url: Optional[str] = None,
- _tenant_id: Optional[UUID] = None,
- **kwargs: Any,
- ) -> None:
- """Initialize a Dataset object."""
- super().__init__(**kwargs)
- self._host_url = _host_url
- self._tenant_id = _tenant_id
- @property
- def url(self) -> Optional[str]:
- """URL of this run within the app."""
- if self._host_url:
- path = f"/datasets/{self.dataset_id}/e/{self.id}"
- if self._tenant_id:
- return f"{self._host_url}/o/{str(self._tenant_id)}{path}"
- return f"{self._host_url}{path}"
- return None
- def __repr__(self):
- """Return a string representation of the RunBase object."""
- return f"{self.__class__}(id={self.id}, dataset_id={self.dataset_id}, link='{self.url}')"
- class ExampleSearch(ExampleBase):
- """Example returned via search."""
- id: UUID
- class AttachmentsOperations(BaseModel):
- """Operations to perform on attachments."""
- rename: dict[str, str] = Field(
- default_factory=dict, description="Mapping of old attachment names to new names"
- )
- retain: list[str] = Field(
- default_factory=list, description="List of attachment names to keep"
- )
- class ExampleUpdate(BaseModel):
- """Example update with attachments."""
- id: UUID
- dataset_id: Optional[UUID] = None
- inputs: Optional[dict[str, Any]] = Field(default=None)
- outputs: Optional[dict[str, Any]] = Field(default=None)
- metadata: Optional[dict[str, Any]] = Field(default=None)
- split: Optional[Union[str, list[str]]] = None
- attachments: Optional[Attachments] = None
- attachments_operations: Optional[AttachmentsOperations] = None
- class Config:
- """Configuration class for the schema."""
- frozen = True
- def __init__(self, **data):
- """Initialize from dict."""
- super().__init__(**data)
- ExampleUpdateWithAttachments = ExampleUpdate
- class DataType(str, Enum):
- """Enum for dataset data types."""
- kv = "kv"
- llm = "llm"
- chat = "chat"
- class DatasetBase(BaseModel):
- """Dataset base model."""
- name: str
- description: Optional[str] = None
- data_type: Optional[DataType] = None
- class Config:
- """Configuration class for the schema."""
- frozen = True
- DatasetTransformationType = Literal[
- "remove_system_messages",
- "convert_to_openai_message",
- "convert_to_openai_tool",
- "remove_extra_fields",
- "extract_tools_from_run",
- ]
- class DatasetTransformation(TypedDict, total=False):
- """Schema for dataset transformations."""
- path: list[str]
- transformation_type: Union[DatasetTransformationType, str]
- class Dataset(DatasetBase):
- """Dataset ORM model."""
- id: UUID
- created_at: datetime
- modified_at: Optional[datetime] = Field(default=None)
- example_count: Optional[int] = None
- session_count: Optional[int] = None
- last_session_start_time: Optional[datetime] = None
- inputs_schema: Optional[dict[str, Any]] = None
- outputs_schema: Optional[dict[str, Any]] = None
- transformations: Optional[list[DatasetTransformation]] = None
- metadata: Optional[dict[str, Any]] = None
- _host_url: Optional[str] = PrivateAttr(default=None)
- _tenant_id: Optional[UUID] = PrivateAttr(default=None)
- _public_path: Optional[str] = PrivateAttr(default=None)
- def __init__(
- self,
- _host_url: Optional[str] = None,
- _tenant_id: Optional[UUID] = None,
- _public_path: Optional[str] = None,
- **kwargs: Any,
- ) -> None:
- """Initialize a Dataset object."""
- if "inputs_schema_definition" in kwargs:
- kwargs["inputs_schema"] = kwargs.pop("inputs_schema_definition")
- if "outputs_schema_definition" in kwargs:
- kwargs["outputs_schema"] = kwargs.pop("outputs_schema_definition")
- super().__init__(**kwargs)
- self._host_url = _host_url
- self._tenant_id = _tenant_id
- self._public_path = _public_path
- @property
- def url(self) -> Optional[str]:
- """URL of this run within the app."""
- if self._host_url:
- if self._public_path:
- return f"{self._host_url}{self._public_path}"
- if self._tenant_id:
- return f"{self._host_url}/o/{str(self._tenant_id)}/datasets/{self.id}"
- return f"{self._host_url}/datasets/{self.id}"
- return None
- class DatasetVersion(BaseModel):
- """Class representing a dataset version."""
- tags: Optional[list[str]] = None
- as_of: datetime
- def _default_extra():
- return {"metadata": {}}
- class RunBase(BaseModel):
- """Base Run schema.
- A Run is a span representing a single unit of work or operation within your LLM app.
- This could be a single call to an LLM or chain, to a prompt formatting call,
- to a runnable lambda invocation. If you are familiar with OpenTelemetry,
- you can think of a run as a span.
- """
- id: UUID
- """Unique identifier for the run."""
- name: str
- """Human-readable name for the run."""
- start_time: datetime
- """Start time of the run."""
- run_type: str
- """The type of run, such as tool, chain, llm, retriever,
- embedding, prompt, parser."""
- end_time: Optional[datetime] = None
- """End time of the run, if applicable."""
- extra: Optional[dict] = Field(default_factory=_default_extra)
- """Additional metadata or settings related to the run."""
- error: Optional[str] = None
- """Error message, if the run encountered any issues."""
- serialized: Optional[dict] = None
- """Serialized object that executed the run for potential reuse."""
- events: Optional[list[dict]] = None
- """List of events associated with the run, like
- start and end events."""
- inputs: dict = Field(default_factory=dict)
- """Inputs used for the run."""
- outputs: Optional[dict] = None
- """Outputs generated by the run, if any."""
- reference_example_id: Optional[UUID] = None
- """Reference to an example that this run may be based on."""
- parent_run_id: Optional[UUID] = None
- """Identifier for a parent run, if this run is a sub-run."""
- tags: Optional[list[str]] = None
- """Tags for categorizing or annotating the run."""
- attachments: Union[Attachments, dict[str, AttachmentInfo]] = Field(
- default_factory=dict
- )
- """Attachments associated with the run.
-
- Each entry is a tuple of `(mime_type, bytes)`.
- """
- @property
- def metadata(self) -> dict[str, Any]:
- """Retrieve the metadata (if any)."""
- if self.extra is None:
- self.extra = {}
- return self.extra.setdefault("metadata", {})
- @property
- def revision_id(self) -> Optional[UUID]:
- """Retrieve the revision ID (if any)."""
- return self.metadata.get("revision_id")
- @property
- def latency(self) -> Optional[float]:
- """Latency in seconds."""
- if self.end_time is None:
- return None
- return (self.end_time - self.start_time).total_seconds()
- def __repr__(self):
- """Return a string representation of the RunBase object."""
- return f"{self.__class__}(id={self.id}, name='{self.name}', run_type='{self.run_type}')"
- class Config:
- """Configuration class for the schema."""
- arbitrary_types_allowed = True
- class Run(RunBase):
- """Run schema when loading from the DB."""
- session_id: Optional[UUID] = None
- """The project ID this run belongs to."""
- child_run_ids: Optional[list[UUID]] = None
- """Deprecated: The child run IDs of this run."""
- child_runs: Optional[list[Run]] = None
- """The child runs of this run, if instructed to load using the client
- These are not populated by default, as it is a heavier query to make."""
- feedback_stats: Optional[dict[str, Any]] = None
- """Feedback stats for this run."""
- app_path: Optional[str] = None
- """Relative URL path of this run within the app."""
- manifest_id: Optional[UUID] = None
- """Unique ID of the serialized object for this run."""
- status: Optional[str] = None
- """Status of the run (e.g., 'success')."""
- prompt_tokens: Optional[int] = None
- """Number of tokens used for the prompt."""
- completion_tokens: Optional[int] = None
- """Number of tokens generated as output."""
- total_tokens: Optional[int] = None
- """Total tokens for prompt and completion."""
- prompt_token_details: Optional[dict[str, int]] = None
- """Breakdown of prompt (input) token counts.
- Does *not* need to sum to full prompt token count.
- """
- completion_token_details: Optional[dict[str, int]] = None
- """Breakdown of completion (output) token counts.
- Does *not* need to sum to full completion token count.
- """
- first_token_time: Optional[datetime] = None
- """Time the first token was processed."""
- total_cost: Optional[Decimal] = None
- """The total estimated LLM cost associated with the completion tokens."""
- prompt_cost: Optional[Decimal] = None
- """The estimated cost associated with the prompt (input) tokens."""
- completion_cost: Optional[Decimal] = None
- """The estimated cost associated with the completion tokens."""
- prompt_cost_details: Optional[dict[str, Decimal]] = None
- """Breakdown of prompt (input) token costs.
- Does *not* need to sum to full prompt token cost.
- """
- completion_cost_details: Optional[dict[str, Decimal]] = None
- """Breakdown of completion (output) token costs.
- Does *not* need to sum to full completion token cost.
- """
- parent_run_ids: Optional[list[UUID]] = None
- """List of parent run IDs."""
- trace_id: UUID
- """Unique ID assigned to every run within this nested trace."""
- dotted_order: str = Field(default="")
- """Dotted order for the run.
- This is a string composed of {time}{run-uuid}.* so that a trace can be
- sorted in the order it was executed.
- Example:
- - Parent: 20230914T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8
- - Children:
- - 20230914T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8.20230914T223155649Z809ed3a2-0172-4f4d-8a02-a64e9b7a0f8a
- - 20230915T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8.20230914T223155650Zc8d9f4c5-6c5a-4b2d-9b1c-3d9d7a7c5c7c
- """ # noqa: E501
- in_dataset: Optional[bool] = None
- """Whether this run is in a dataset."""
- _host_url: Optional[str] = PrivateAttr(default=None)
- def __init__(self, _host_url: Optional[str] = None, **kwargs: Any) -> None:
- """Initialize a Run object."""
- if not kwargs.get("trace_id"):
- kwargs = {"trace_id": kwargs.get("id"), **kwargs}
- inputs = kwargs.pop("inputs", None) or {}
- super().__init__(**kwargs, inputs=inputs)
- self._host_url = _host_url
- if not self.dotted_order.strip() and not self.parent_run_id:
- self.dotted_order = f"{self.start_time.isoformat()}{self.id}"
- @property
- def url(self) -> Optional[str]:
- """URL of this run within the app."""
- if self._host_url and self.app_path:
- return f"{self._host_url}{self.app_path}"
- return None
- @property
- def input_tokens(self) -> int | None:
- """Alias for prompt_tokens."""
- return self.prompt_tokens
- @property
- def output_tokens(self) -> int | None:
- """Alias for completion_tokens."""
- return self.completion_tokens
- @property
- def input_cost(self) -> Decimal | None:
- """Alias for prompt_cost."""
- return self.prompt_cost
- @property
- def output_cost(self) -> Decimal | None:
- """Alias for completion_cost."""
- return self.completion_cost
- @property
- def input_token_details(self) -> dict[str, int] | None:
- """Alias for prompt_token_details."""
- return self.prompt_token_details
- @property
- def output_token_details(self) -> dict[str, int] | None:
- """Alias for output_token_details."""
- return self.completion_token_details
- @property
- def input_cost_details(self) -> dict[str, Decimal] | None:
- """Alias for prompt_cost_details."""
- return self.prompt_cost_details
- @property
- def output_cost_details(self) -> dict[str, Decimal] | None:
- """Alias for completion_cost_details."""
- return self.completion_cost_details
- class RunTypeEnum(str, Enum):
- """(Deprecated) Enum for run types. Use string directly."""
- tool = "tool"
- chain = "chain"
- llm = "llm"
- retriever = "retriever"
- embedding = "embedding"
- prompt = "prompt"
- parser = "parser"
- class RunLikeDict(TypedDict, total=False):
- """Run-like dictionary, for type-hinting."""
- name: str
- run_type: RunTypeEnum
- start_time: datetime
- inputs: Optional[dict]
- outputs: Optional[dict]
- end_time: Optional[datetime]
- extra: Optional[dict]
- error: Optional[str]
- serialized: Optional[dict]
- parent_run_id: Optional[UUID]
- manifest_id: Optional[UUID]
- events: Optional[list[dict]]
- tags: Optional[list[str]]
- inputs_s3_urls: Optional[dict]
- outputs_s3_urls: Optional[dict]
- id: Optional[UUID]
- session_id: Optional[UUID]
- session_name: Optional[str]
- reference_example_id: Optional[UUID]
- input_attachments: Optional[dict]
- output_attachments: Optional[dict]
- trace_id: UUID
- dotted_order: str
- attachments: Attachments
- class RunWithAnnotationQueueInfo(RunBase):
- """Run schema with annotation queue info."""
- last_reviewed_time: Optional[datetime] = None
- """The last time this run was reviewed."""
- added_at: Optional[datetime] = None
- """The time this run was added to the queue."""
- class FeedbackSourceBase(BaseModel):
- """Base class for feedback sources.
- This represents whether feedback is submitted from the API, model, human labeler,
- etc.
- """
- type: str
- """The type of the feedback source."""
- metadata: Optional[dict[str, Any]] = Field(default_factory=dict)
- """Additional metadata for the feedback source."""
- user_id: Optional[Union[UUID, str]] = None
- """The user ID associated with the feedback source."""
- user_name: Optional[str] = None
- """The user name associated with the feedback source."""
- class APIFeedbackSource(FeedbackSourceBase):
- """API feedback source."""
- type: Literal["api"] = "api"
- class ModelFeedbackSource(FeedbackSourceBase):
- """Model feedback source."""
- type: Literal["model"] = "model"
- class FeedbackSourceType(Enum):
- """Feedback source type."""
- API = "api"
- """General feedback submitted from the API."""
- MODEL = "model"
- """Model-assisted feedback."""
- class FeedbackBase(BaseModel):
- """Feedback schema."""
- id: UUID
- """The unique ID of the feedback."""
- created_at: Optional[datetime] = None
- """The time the feedback was created."""
- modified_at: Optional[datetime] = None
- """The time the feedback was last modified."""
- run_id: Optional[UUID]
- """The associated run ID this feedback is logged for."""
- trace_id: Optional[UUID]
- """The associated trace ID this feedback is logged for."""
- key: str
- """The metric name, tag, or aspect to provide feedback on."""
- score: SCORE_TYPE = None
- """Value or score to assign the run."""
- value: VALUE_TYPE = None
- """The display value, tag or other value for the feedback if not a metric."""
- comment: Optional[str] = None
- """Comment or explanation for the feedback."""
- correction: Union[str, dict, None] = None
- """Correction for the run."""
- feedback_source: Optional[FeedbackSourceBase] = None
- """The source of the feedback."""
- session_id: Optional[UUID] = None
- """The associated project ID (Session = Project) this feedback is logged for."""
- comparative_experiment_id: Optional[UUID] = None
- """If logged within a 'comparative experiment', this is the ID of the experiment."""
- feedback_group_id: Optional[UUID] = None
- """For preference scoring, this group ID is shared across feedbacks for each
- run in the group that was being compared."""
- extra: Optional[dict] = None
- """The metadata of the feedback."""
- class Config:
- """Configuration class for the schema."""
- frozen = True
- class FeedbackCategory(TypedDict, total=False):
- """Specific value and label pair for feedback."""
- value: float
- """The numeric value associated with this feedback category."""
- label: Optional[str]
- """An optional label to interpret the value for this feedback category."""
- class FeedbackConfig(TypedDict, total=False):
- """Represents _how_ a feedback value ought to be interpreted."""
- type: Literal["continuous", "categorical", "freeform"]
- """The type of feedback."""
- min: Optional[float]
- """The minimum value for continuous feedback."""
- max: Optional[float]
- """The maximum value for continuous feedback."""
- categories: Optional[list[FeedbackCategory]]
- """If feedback is categorical, this defines the valid categories the server will accept.
- Not applicable to continuous or freeform feedback types.""" # noqa
- class FeedbackCreate(FeedbackBase):
- """Schema used for creating feedback."""
- feedback_source: FeedbackSourceBase
- """The source of the feedback."""
- feedback_config: Optional[FeedbackConfig] = None
- """The config for the feedback"""
- error: Optional[bool] = None
- class Feedback(FeedbackBase):
- """Schema for getting feedback."""
- id: UUID
- created_at: datetime
- """The time the feedback was created."""
- modified_at: datetime
- """The time the feedback was last modified."""
- feedback_source: Optional[FeedbackSourceBase] = None
- """The source of the feedback. In this case"""
- class TracerSession(BaseModel):
- """TracerSession schema for the API.
- Sessions are also referred to as "Projects" in the UI.
- """
- id: UUID
- """The ID of the project."""
- start_time: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
- """The time the project was created."""
- end_time: Optional[datetime] = None
- """The time the project was ended."""
- description: Optional[str] = None
- """The description of the project."""
- name: Optional[str] = None
- """The name of the session."""
- extra: Optional[dict[str, Any]] = None
- """Extra metadata for the project."""
- tenant_id: UUID
- """The tenant ID this project belongs to."""
- reference_dataset_id: Optional[UUID]
- """The reference dataset IDs this project's runs were generated on."""
- _host_url: Optional[str] = PrivateAttr(default=None)
- def __init__(self, _host_url: Optional[str] = None, **kwargs: Any) -> None:
- """Initialize a Run object."""
- super().__init__(**kwargs)
- self._host_url = _host_url
- if self.start_time.tzinfo is None:
- self.start_time = self.start_time.replace(tzinfo=timezone.utc)
- @property
- def url(self) -> Optional[str]:
- """URL of this run within the app."""
- if self._host_url:
- return f"{self._host_url}/o/{self.tenant_id}/projects/p/{self.id}"
- return None
- @property
- def metadata(self) -> dict[str, Any]:
- """Retrieve the metadata (if any)."""
- if self.extra is None or "metadata" not in self.extra:
- return {}
- return self.extra["metadata"]
- @property
- def tags(self) -> list[str]:
- """Retrieve the tags (if any)."""
- if self.extra is None or "tags" not in self.extra:
- return []
- return self.extra["tags"]
- class TracerSessionResult(TracerSession):
- """A project, hydrated with additional information.
- Sessions are also referred to as "Projects" in the UI.
- """
- run_count: Optional[int]
- """The number of runs in the project."""
- latency_p50: Optional[timedelta]
- """The median (50th percentile) latency for the project."""
- latency_p99: Optional[timedelta]
- """The 99th percentile latency for the project."""
- total_tokens: Optional[int]
- """The total number of tokens consumed in the project."""
- prompt_tokens: Optional[int]
- """The total number of prompt tokens consumed in the project."""
- completion_tokens: Optional[int]
- """The total number of completion tokens consumed in the project."""
- last_run_start_time: Optional[datetime]
- """The start time of the last run in the project."""
- feedback_stats: Optional[dict[str, Any]]
- """Feedback stats for the project."""
- session_feedback_stats: Optional[dict[str, Any]]
- """Summary feedback stats for the project."""
- run_facets: Optional[list[dict[str, Any]]]
- """Facets for the runs in the project."""
- total_cost: Optional[Decimal]
- """The total estimated LLM cost associated with the completion tokens."""
- prompt_cost: Optional[Decimal]
- """The estimated cost associated with the prompt (input) tokens."""
- completion_cost: Optional[Decimal]
- """The estimated cost associated with the completion tokens."""
- first_token_p50: Optional[timedelta]
- """The median (50th percentile) time to process the first token."""
- first_token_p99: Optional[timedelta]
- """The 99th percentile time to process the first token."""
- error_rate: Optional[float]
- """The error rate for the project."""
- @runtime_checkable
- class BaseMessageLike(Protocol):
- """A protocol representing objects similar to BaseMessage."""
- content: str
- """The content of the message."""
- additional_kwargs: dict[Any, Any]
- """Additional keyword arguments associated with the message."""
- @property
- def type(self) -> str:
- """Type of the Message, used for serialization."""
- class DatasetShareSchema(TypedDict, total=False):
- """Represents the schema for a dataset share."""
- dataset_id: UUID
- """The ID of the dataset."""
- share_token: UUID
- """The token for sharing the dataset."""
- url: str
- """The URL of the shared dataset."""
- class AnnotationQueue(BaseModel):
- """Represents an annotation queue."""
- id: UUID
- """The unique identifier of the annotation queue."""
- name: str
- """The name of the annotation queue."""
- description: Optional[str] = None
- """An optional description of the annotation queue."""
- created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
- """The timestamp when the annotation queue was created."""
- updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))
- """The timestamp when the annotation queue was last updated."""
- tenant_id: UUID
- """The ID of the tenant associated with the annotation queue."""
- class AnnotationQueueWithDetails(AnnotationQueue):
- """Represents an annotation queue with details."""
- rubric_instructions: Optional[str] = None
- """The rubric instructions for the annotation queue."""
- class BatchIngestConfig(TypedDict, total=False):
- """Configuration for batch ingestion."""
- use_multipart_endpoint: bool
- """Whether to use the multipart endpoint for batch ingestion."""
- scale_up_qsize_trigger: int
- """The queue size threshold that triggers scaling up."""
- scale_up_nthreads_limit: int
- """The maximum number of threads to scale up to."""
- scale_down_nempty_trigger: int
- """The number of empty threads that triggers scaling down."""
- size_limit: int
- """The maximum size limit for the batch."""
- size_limit_bytes: Optional[int]
- """The maximum size limit in bytes for the batch."""
- class LangSmithInfo(BaseModel):
- """Information about the LangSmith server."""
- version: str = ""
- """The version of the LangSmith server."""
- license_expiration_time: Optional[datetime] = None
- """The time the license will expire."""
- batch_ingest_config: Optional[BatchIngestConfig] = None
- """The instance flags."""
- instance_flags: Optional[dict[str, Any]] = None
- Example.update_forward_refs()
- class LangSmithSettings(BaseModel):
- """Settings for the LangSmith tenant."""
- id: str
- """The ID of the tenant."""
- display_name: str
- """The display name of the tenant."""
- created_at: datetime
- """The creation time of the tenant."""
- tenant_handle: Optional[str] = None
- class FeedbackIngestToken(BaseModel):
- """Represents the schema for a feedback ingest token."""
- id: UUID
- """The ID of the feedback ingest token."""
- url: str
- """The URL to GET when logging the feedback."""
- expires_at: datetime
- """The expiration time of the token."""
- class RunEvent(TypedDict, total=False):
- """Run event schema."""
- name: str
- """Type of event."""
- time: Union[datetime, str]
- """Time of the event."""
- kwargs: Optional[dict[str, Any]]
- """Additional metadata for the event."""
- class TimeDeltaInput(TypedDict, total=False):
- """Timedelta input schema."""
- days: int
- """Number of days."""
- hours: int
- """Number of hours."""
- minutes: int
- """Number of minutes."""
- class DatasetDiffInfo(BaseModel):
- """Represents the difference information between two datasets."""
- examples_modified: list[UUID]
- """A list of UUIDs representing the modified examples."""
- examples_added: list[UUID]
- """A list of UUIDs representing the added examples."""
- examples_removed: list[UUID]
- """A list of UUIDs representing the removed examples."""
- class ComparativeExperiment(BaseModel):
- """Represents a comparative experiment.
- This information summarizes evaluation results comparing
- two or more models on a given dataset.
- """
- id: UUID
- """The unique identifier for the comparative experiment."""
- name: Optional[str] = None
- """The optional name of the comparative experiment."""
- description: Optional[str] = None
- """An optional description of the comparative experiment."""
- tenant_id: UUID
- """The identifier of the tenant associated with this experiment."""
- created_at: datetime
- """The timestamp when the comparative experiment was created."""
- modified_at: datetime
- """The timestamp when the comparative experiment was last modified."""
- reference_dataset_id: UUID
- """The identifier of the reference dataset used in this experiment."""
- extra: Optional[dict[str, Any]] = None
- """Optional additional information about the experiment."""
- experiments_info: Optional[list[dict]] = None
- """Optional list of dictionaries containing information about individual experiments."""
- feedback_stats: Optional[dict[str, Any]] = None
- """Optional dictionary containing feedback statistics for the experiment."""
- @property
- def metadata(self) -> dict[str, Any]:
- """Retrieve the metadata (if any)."""
- if self.extra is None or "metadata" not in self.extra:
- return {}
- return self.extra["metadata"]
- class PromptCommit(BaseModel):
- """Represents a Prompt with a manifest."""
- owner: str
- """The handle of the owner of the prompt."""
- repo: str
- """The name of the prompt."""
- commit_hash: str
- """The commit hash of the prompt."""
- manifest: dict[str, Any]
- """The manifest of the prompt."""
- examples: list[dict]
- """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."""
- repo_handle: str
- """The name of the prompt."""
- description: Optional[str] = None
- """The description of the prompt."""
- readme: Optional[str] = None
- """The README of the prompt."""
- id: str
- """The ID of the prompt."""
- tenant_id: str
- """The tenant ID of the prompt owner."""
- created_at: datetime
- """The creation time of the prompt."""
- updated_at: datetime
- """The last update time of the prompt."""
- is_public: bool
- """Whether the prompt is public."""
- is_archived: bool
- """Whether the prompt is archived."""
- tags: list[str]
- """The tags associated with the prompt."""
- original_repo_id: Optional[str] = None
- """The ID of the original prompt, if forked."""
- upstream_repo_id: Optional[str] = None
- """The ID of the upstream prompt, if forked."""
- owner: Optional[str]
- """The handle of the owner of the prompt."""
- full_name: str
- """The full name of the prompt. (owner + repo_handle)"""
- num_likes: int
- """The number of likes."""
- num_downloads: int
- """The number of downloads."""
- num_views: int
- """The number of views."""
- liked_by_auth_user: Optional[bool] = None
- """Whether the prompt is liked by the authenticated user."""
- last_commit_hash: Optional[str] = None
- """The hash of the last commit."""
- num_commits: int
- """The number of commits."""
- original_repo_full_name: Optional[str] = None
- """The full name of the original prompt, if forked."""
- upstream_repo_full_name: Optional[str] = None
- """The full name of the upstream prompt, if forked."""
- class ListPromptsResponse(BaseModel):
- """A list of prompts with metadata."""
- repos: list[Prompt]
- """The list of prompts."""
- total: int
- """The total number of prompts."""
- class PromptSortField(str, Enum):
- """Enum for sorting fields for prompts."""
- num_downloads = "num_downloads"
- """Number of downloads."""
- num_views = "num_views"
- """Number of views."""
- updated_at = "updated_at"
- """Last updated time."""
- num_likes = "num_likes"
- """Number of likes."""
- class InputTokenDetails(TypedDict, total=False):
- """Breakdown of input token counts.
- Does *not* need to sum to full input token count. Does *not* need to have all keys.
- """
- audio: int
- """Audio input tokens."""
- cache_creation: int
- """Input tokens that were cached and there was a cache miss.
- Since there was a cache miss, the cache was created from these tokens.
- """
- cache_read: int
- """Input tokens that were cached and there was a cache hit.
- Since there was a cache hit, the tokens were read from the cache. More precisely,
- the model state given these tokens was read from the cache.
- """
- class OutputTokenDetails(TypedDict, total=False):
- """Breakdown of output token counts.
- Does *not* need to sum to full output token count. Does *not* need to have all keys.
- """
- audio: int
- """Audio output tokens."""
- reasoning: int
- """Reasoning output tokens.
- Tokens generated by the model in a chain of thought process (i.e. by OpenAI's o1
- models) that are not returned as part of model output.
- """
- class InputCostDetails(TypedDict, total=False):
- """Breakdown of input token costs.
- Does *not* need to sum to full input cost. Does *not* need to have all keys.
- """
- audio: float
- """Cost of audio input tokens."""
- cache_creation: float
- """Cost of input tokens that were cached and there was a cache miss.
- Since there was a cache miss, the cache was created from these tokens.
- """
- cache_read: float
- """Cost of input tokens that were cached and there was a cache hit.
- Since there was a cache hit, the tokens were read from the cache. More precisely,
- the model state given these tokens was read from the cache.
- """
- class OutputCostDetails(TypedDict, total=False):
- """Breakdown of output token costs.
- Does *not* need to sum to full output cost. Does *not* need to have all keys.
- """
- audio: float
- """Cost of audio output tokens."""
- reasoning: float
- """Cost of reasoning output tokens.
- Tokens generated by the model in a chain of thought process (i.e. by OpenAI's o1
- models) that are not returned as part of model output.
- """
- class UsageMetadata(TypedDict):
- """Usage metadata for a message, such as token counts.
- This is a standard representation of token usage that is consistent across models.
- """
- input_tokens: int
- """Count of input (or prompt) tokens. Sum of all input token types."""
- output_tokens: int
- """Count of output (or completion) tokens. Sum of all output token types."""
- total_tokens: int
- """Total token count. Sum of input_tokens + output_tokens."""
- input_token_details: NotRequired[InputTokenDetails]
- """Breakdown of input token counts.
- Does *not* need to sum to full input token count. Does *not* need to have all keys.
- """
- output_token_details: NotRequired[OutputTokenDetails]
- """Breakdown of output token counts.
- Does *not* need to sum to full output token count. Does *not* need to have all keys.
- """
- input_cost: NotRequired[float]
- """The cost of the input tokens."""
- output_cost: NotRequired[float]
- """The cost of the output tokens."""
- total_cost: NotRequired[float]
- """The total cost of the tokens."""
- input_cost_details: NotRequired[InputCostDetails]
- """The cost details of the input tokens."""
- output_cost_details: NotRequired[OutputCostDetails]
- """The cost details of the output tokens."""
- class ExtractedUsageMetadata(TypedDict, total=False):
- """Usage metadata dictionary extracted from a run.
- Should be the same as UsageMetadata, but does not require all
- keys to be present.
- """
- input_tokens: int
- """The number of tokens used for the prompt."""
- output_tokens: int
- """The number of tokens generated as output."""
- total_tokens: int
- """The total number of tokens used."""
- input_token_details: InputTokenDetails
- """The details of the input tokens."""
- output_token_details: OutputTokenDetails
- """The details of the output tokens."""
- input_cost: float
- """The cost of the input tokens."""
- output_cost: float
- """The cost of the output tokens."""
- total_cost: float
- """The total cost of the tokens."""
- input_cost_details: InputCostDetails
- """The cost details of the input tokens."""
- output_cost_details: OutputCostDetails
- """The cost details of the output tokens."""
- class UpsertExamplesResponse(TypedDict):
- """Response object returned from the upsert_examples_multipart method."""
- count: int
- """The number of examples that were upserted."""
- example_ids: list[str]
- """The ids of the examples that were upserted."""
- class ExampleWithRuns(Example):
- """Example with runs."""
- runs: list[Run] = Field(default_factory=list)
- """The runs of the example."""
- class ExperimentRunStats(TypedDict):
- """Run statistics for an experiment."""
- run_count: Optional[int]
- """The number of runs in the project."""
- latency_p50: Optional[timedelta]
- """The median (50th percentile) latency for the project."""
- latency_p99: Optional[timedelta]
- """The 99th percentile latency for the project."""
- total_tokens: Optional[int]
- """The total number of tokens consumed in the project."""
- prompt_tokens: Optional[int]
- """The total number of prompt tokens consumed in the project."""
- completion_tokens: Optional[int]
- """The total number of completion tokens consumed in the project."""
- last_run_start_time: Optional[datetime]
- """The start time of the last run in the project."""
- run_facets: Optional[list[dict[str, Any]]]
- """Facets for the runs in the project."""
- total_cost: Optional[Decimal]
- """The total estimated LLM cost associated with the completion tokens."""
- prompt_cost: Optional[Decimal]
- """The estimated cost associated with the prompt (input) tokens."""
- completion_cost: Optional[Decimal]
- """The estimated cost associated with the completion tokens."""
- first_token_p50: Optional[timedelta]
- """The median (50th percentile) time to process the first token."""
- first_token_p99: Optional[timedelta]
- """The 99th percentile time to process the first token."""
- error_rate: Optional[float]
- """The error rate for the project."""
- class ExperimentResults(TypedDict):
- """Results container for experiment data with stats and examples.
- Breaking change in v0.4.32:
- The 'stats' field has been split into 'feedback_stats' and 'run_stats'.
- """
- feedback_stats: dict
- """Feedback statistics for the experiment."""
- run_stats: ExperimentRunStats
- """Run statistics (latency, token count, etc.)."""
- examples_with_runs: Iterator[ExampleWithRuns]
- class InsightsReport(BaseModel):
- """An Insights Report created by the Insights Agent over a tracing project."""
- id: UUID | str
- name: str
- status: str
- error: str | None = None
- project_id: UUID | str
- host_url: str
- tenant_id: UUID | str
- @property
- def link(self) -> str:
- """URL to view this Insights Report in LangSmith UI."""
- return f"{self.host_url}/o/{str(self.tenant_id)}/projects/p/{str(self.project_id)}?tab=4&clusterJobId={str(self.id)}"
- def _repr_html_(self) -> str:
- return f'<a href="{self.link}", target="_blank" rel="noopener">InsightsReport(\'{self.name}\')</a>'
- class FeedbackFormulaWeightedVariable(BaseModel):
- """A feedback key and weight used when calculating feedback formulas."""
- part_type: Literal["weighted_key"]
- weight: float
- key: Annotated[str, Field(min_length=1)]
- class FeedbackFormulaCreate(BaseModel):
- """Schema used for creating a feedback formula."""
- dataset_id: Optional[UUID] = None
- session_id: Optional[UUID] = None
- feedback_key: str
- aggregation_type: Literal["sum", "avg"]
- formula_parts: list[FeedbackFormulaWeightedVariable] = Field(
- ..., min_items=1, max_items=50
- )
- class FeedbackFormulaUpdate(BaseModel):
- """Schema used for updating a feedback formula."""
- feedback_key: str
- aggregation_type: Literal["sum", "avg"]
- formula_parts: list[FeedbackFormulaWeightedVariable] = Field(
- ..., min_items=1, max_items=50
- )
- class FeedbackFormula(FeedbackFormulaCreate):
- """Schema for getting feedback formulas."""
- id: UUID
- created_at: datetime
- modified_at: datetime
|