codekingpro/portable-devtools
114k
1"""Schemas for the LangSmith API."""2 3from __future__ import annotations4 5from collections.abc import Iterator6from datetime import datetime, timedelta, timezone7from decimal import Decimal8from enum import Enum9from pathlib import Path10from typing import (11 Annotated,12 Any,13 NamedTuple,14 Optional,15 Protocol,16 Union,17 runtime_checkable,18)19from uuid import UUID20 21from pydantic import (22 BaseModel,23 ConfigDict,24 Field,25 PrivateAttr,26 StrictBool,27 StrictFloat,28 StrictInt,29)30from typing_extensions import Literal, NotRequired, TypedDict31 32SCORE_TYPE = Union[StrictBool, StrictInt, StrictFloat, None]33VALUE_TYPE = Union[dict, str, StrictBool, StrictInt, StrictFloat, None]34 35 36class Attachment(NamedTuple):37 """Annotated type that will be stored as an attachment if used.38 39 Examples:40 ```python41 from langsmith import traceable42 from langsmith.schemas import Attachment43 44 45 @traceable46 def my_function(bar: int, my_val: Attachment):47 # my_val will be stored as an attachment48 # bar will be stored as inputs49 return bar50 ```51 """52 53 mime_type: str54 data: Union[bytes, Path]55 56 57Attachments = dict[str, Union[tuple[str, bytes], Attachment, tuple[str, Path]]]58"""Attachments associated with the run.59 60Each entry is a tuple of `(mime_type, bytes)`, or `(mime_type, file_path)`61"""62 63 64@runtime_checkable65class BinaryIOLike(Protocol):66 """Protocol for binary IO-like objects."""67 68 def read(self, size: int = -1) -> bytes:69 """Read function."""70 ...71 72 def seek(self, offset: int, whence: int = 0) -> int:73 """Seek function."""74 ...75 76 def getvalue(self) -> bytes:77 """Get value function."""78 ...79 80 81class ExampleBase(BaseModel):82 """Example base model."""83 84 dataset_id: UUID85 inputs: Optional[dict[str, Any]] = Field(default=None)86 outputs: Optional[dict[str, Any]] = Field(default=None)87 metadata: Optional[dict[str, Any]] = Field(default=None)88 89 model_config = ConfigDict(frozen=True, arbitrary_types_allowed=True)90 91 92class _AttachmentDict(TypedDict):93 mime_type: str94 data: Union[bytes, Path]95 96 97_AttachmentLike = Union[98 Attachment, _AttachmentDict, tuple[str, bytes], tuple[str, Path]99]100 101 102class ExampleCreate(BaseModel):103 """Example upload with attachments."""104 105 id: Optional[UUID] = None106 created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))107 inputs: Optional[dict[str, Any]] = Field(default=None)108 outputs: Optional[dict[str, Any]] = Field(default=None)109 metadata: Optional[dict[str, Any]] = Field(default=None)110 split: Optional[Union[str, list[str]]] = None111 attachments: Optional[dict[str, _AttachmentLike]] = None112 use_source_run_io: bool = False113 use_source_run_attachments: Optional[list[str]] = None114 source_run_id: Optional[UUID] = None115 116 def __init__(self, **data):117 """Initialize from dict."""118 super().__init__(**data)119 120 121ExampleUploadWithAttachments = ExampleCreate122 123 124class ExampleUpsertWithAttachments(ExampleCreate):125 """Example create with attachments."""126 127 dataset_id: UUID128 129 130class AttachmentInfo(TypedDict):131 """Info for an attachment."""132 133 presigned_url: str134 reader: BinaryIOLike135 mime_type: Optional[str]136 137 138class Example(ExampleBase):139 """Example model."""140 141 id: UUID142 created_at: datetime = Field(143 default_factory=lambda: datetime.fromtimestamp(0, tz=timezone.utc)144 )145 dataset_id: UUID = Field(default=UUID("00000000-0000-0000-0000-000000000000"))146 modified_at: Optional[datetime] = Field(default=None)147 source_run_id: Optional[UUID] = None148 attachments: Optional[dict[str, AttachmentInfo]] = Field(default=None)149 """Dictionary with attachment names as keys and a tuple of the S3 url150 and a reader of the data for the file."""151 _host_url: Optional[str] = PrivateAttr(default=None)152 _tenant_id: Optional[UUID] = PrivateAttr(default=None)153 154 def __init__(155 self,156 _host_url: Optional[str] = None,157 _tenant_id: Optional[UUID] = None,158 **kwargs: Any,159 ) -> None:160 """Initialize a Dataset object."""161 super().__init__(**kwargs)162 self._host_url = _host_url163 self._tenant_id = _tenant_id164 165 @property166 def url(self) -> Optional[str]:167 """URL of this run within the app."""168 if self._host_url:169 path = f"/datasets/{self.dataset_id}/e/{self.id}"170 if self._tenant_id:171 return f"{self._host_url}/o/{str(self._tenant_id)}{path}"172 return f"{self._host_url}{path}"173 return None174 175 def __repr__(self):176 """Return a string representation of the RunBase object."""177 return f"{self.__class__}(id={self.id}, dataset_id={self.dataset_id}, link='{self.url}')"178 179 180class AttachmentsOperations(BaseModel):181 """Operations to perform on attachments."""182 183 rename: dict[str, str] = Field(184 default_factory=dict, description="Mapping of old attachment names to new names"185 )186 retain: list[str] = Field(187 default_factory=list, description="List of attachment names to keep"188 )189 190 191class ExampleUpdate(BaseModel):192 """Example update with attachments."""193 194 id: UUID195 dataset_id: Optional[UUID] = None196 inputs: Optional[dict[str, Any]] = Field(default=None)197 outputs: Optional[dict[str, Any]] = Field(default=None)198 metadata: Optional[dict[str, Any]] = Field(default=None)199 split: Optional[Union[str, list[str]]] = None200 attachments: Optional[Attachments] = None201 attachments_operations: Optional[AttachmentsOperations] = None202 203 model_config = ConfigDict(frozen=True)204 205 def __init__(self, **data):206 """Initialize from dict."""207 super().__init__(**data)208 209 210ExampleUpdateWithAttachments = ExampleUpdate211 212 213class DataType(str, Enum):214 """Enum for dataset data types."""215 216 kv = "kv"217 llm = "llm"218 chat = "chat"219 220 221class DatasetBase(BaseModel):222 """Dataset base model."""223 224 name: str225 description: Optional[str] = None226 data_type: Optional[DataType] = None227 228 model_config = ConfigDict(frozen=True)229 230 231DatasetTransformationType = Literal[232 "remove_system_messages",233 "convert_to_openai_message",234 "convert_to_openai_tool",235 "remove_extra_fields",236 "extract_tools_from_run",237]238 239 240class DatasetTransformation(TypedDict, total=False):241 """Schema for dataset transformations."""242 243 path: list[str]244 transformation_type: Union[DatasetTransformationType, str]245 246 247class Dataset(DatasetBase):248 """Dataset ORM model."""249 250 id: UUID251 created_at: datetime252 modified_at: Optional[datetime] = Field(default=None)253 example_count: Optional[int] = None254 session_count: Optional[int] = None255 last_session_start_time: Optional[datetime] = None256 inputs_schema: Optional[dict[str, Any]] = None257 outputs_schema: Optional[dict[str, Any]] = None258 transformations: Optional[list[DatasetTransformation]] = None259 metadata: Optional[dict[str, Any]] = None260 _host_url: Optional[str] = PrivateAttr(default=None)261 _tenant_id: Optional[UUID] = PrivateAttr(default=None)262 _public_path: Optional[str] = PrivateAttr(default=None)263 264 def __init__(265 self,266 _host_url: Optional[str] = None,267 _tenant_id: Optional[UUID] = None,268 _public_path: Optional[str] = None,269 **kwargs: Any,270 ) -> None:271 """Initialize a Dataset object."""272 if "inputs_schema_definition" in kwargs:273 kwargs["inputs_schema"] = kwargs.pop("inputs_schema_definition")274 275 if "outputs_schema_definition" in kwargs:276 kwargs["outputs_schema"] = kwargs.pop("outputs_schema_definition")277 278 super().__init__(**kwargs)279 self._host_url = _host_url280 self._tenant_id = _tenant_id281 self._public_path = _public_path282 283 @property284 def url(self) -> Optional[str]:285 """URL of this run within the app."""286 if self._host_url:287 if self._public_path:288 return f"{self._host_url}{self._public_path}"289 if self._tenant_id:290 return f"{self._host_url}/o/{str(self._tenant_id)}/datasets/{self.id}"291 return f"{self._host_url}/datasets/{self.id}"292 return None293 294 295class DatasetVersion(BaseModel):296 """Class representing a dataset version."""297 298 tags: Optional[list[str]] = None299 as_of: datetime300 301 302def _default_extra():303 return {"metadata": {}}304 305 306class RunBase(BaseModel):307 """Base Run schema.308 309 A Run is a span representing a single unit of work or operation within your LLM app.310 This could be a single call to an LLM or chain, to a prompt formatting call,311 to a runnable lambda invocation. If you are familiar with OpenTelemetry,312 you can think of a run as a span.313 """314 315 id: UUID316 """Unique identifier for the run."""317 318 name: str319 """Human-readable name for the run."""320 321 start_time: datetime322 """Start time of the run."""323 324 run_type: str325 """The type of run, such as tool, chain, llm, retriever,326 embedding, prompt, parser."""327 328 end_time: Optional[datetime] = None329 """End time of the run, if applicable."""330 331 extra: Optional[dict] = Field(default_factory=_default_extra)332 """Additional metadata or settings related to the run."""333 334 error: Optional[str] = None335 """Error message, if the run encountered any issues."""336 337 serialized: Optional[dict] = None338 """Serialized object that executed the run for potential reuse."""339 340 events: Optional[list[dict]] = None341 """List of events associated with the run, like342 start and end events."""343 344 inputs: dict = Field(default_factory=dict)345 """Inputs used for the run."""346 347 outputs: Optional[dict] = None348 """Outputs generated by the run, if any."""349 350 reference_example_id: Optional[UUID] = None351 """Reference to an example that this run may be based on."""352 353 parent_run_id: Optional[UUID] = None354 """Identifier for a parent run, if this run is a sub-run."""355 356 tags: Optional[list[str]] = None357 """Tags for categorizing or annotating the run."""358 359 attachments: Union[Attachments, dict[str, AttachmentInfo]] = Field(360 default_factory=dict361 )362 """Attachments associated with the run.363 364 Each entry is a tuple of `(mime_type, bytes)`.365 """366 367 @property368 def metadata(self) -> dict[str, Any]:369 """Retrieve the metadata (if any)."""370 if self.extra is None:371 self.extra = {}372 return self.extra.setdefault("metadata", {})373 374 @property375 def revision_id(self) -> Optional[UUID]:376 """Retrieve the revision ID (if any)."""377 return self.metadata.get("revision_id")378 379 @property380 def latency(self) -> Optional[float]:381 """Latency in seconds."""382 if self.end_time is None:383 return None384 return (self.end_time - self.start_time).total_seconds()385 386 def __repr__(self):387 """Return a string representation of the RunBase object."""388 return f"{self.__class__}(id={self.id}, name='{self.name}', run_type='{self.run_type}')"389 390 model_config = ConfigDict(arbitrary_types_allowed=True)391 392 393class Run(RunBase):394 """Run schema when loading from the DB."""395 396 session_id: Optional[UUID] = None397 """The project ID this run belongs to."""398 child_run_ids: Optional[list[UUID]] = None399 """Deprecated: The child run IDs of this run."""400 child_runs: Optional[list[Run]] = None401 """The child runs of this run, if instructed to load using the client402 These are not populated by default, as it is a heavier query to make."""403 feedback_stats: Optional[dict[str, Any]] = None404 """Feedback stats for this run."""405 app_path: Optional[str] = None406 """Relative URL path of this run within the app."""407 manifest_id: Optional[UUID] = None408 """Unique ID of the serialized object for this run."""409 status: Optional[str] = None410 """Status of the run (e.g., 'success')."""411 prompt_tokens: Optional[int] = None412 """Number of tokens used for the prompt."""413 completion_tokens: Optional[int] = None414 """Number of tokens generated as output."""415 total_tokens: Optional[int] = None416 """Total tokens for prompt and completion."""417 prompt_token_details: Optional[dict[str, int]] = None418 """Breakdown of prompt (input) token counts.419 420 Does *not* need to sum to full prompt token count.421 """422 completion_token_details: Optional[dict[str, int]] = None423 """Breakdown of completion (output) token counts.424 425 Does *not* need to sum to full completion token count.426 """427 first_token_time: Optional[datetime] = None428 """Time the first token was processed."""429 total_cost: Optional[Decimal] = None430 """The total estimated LLM cost associated with the completion tokens."""431 prompt_cost: Optional[Decimal] = None432 """The estimated cost associated with the prompt (input) tokens."""433 completion_cost: Optional[Decimal] = None434 """The estimated cost associated with the completion tokens."""435 prompt_cost_details: Optional[dict[str, Decimal]] = None436 """Breakdown of prompt (input) token costs.437 438 Does *not* need to sum to full prompt token cost.439 """440 completion_cost_details: Optional[dict[str, Decimal]] = None441 """Breakdown of completion (output) token costs.442 443 Does *not* need to sum to full completion token cost.444 """445 parent_run_ids: Optional[list[UUID]] = None446 """List of parent run IDs."""447 trace_id: UUID448 """Unique ID assigned to every run within this nested trace."""449 dotted_order: str = Field(default="")450 """Dotted order for the run.451 452 This is a string composed of {time}{run-uuid}.* so that a trace can be453 sorted in the order it was executed.454 455 Example:456 - Parent: 20230914T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8457 - Children:458 - 20230914T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8.20230914T223155649Z809ed3a2-0172-4f4d-8a02-a64e9b7a0f8a459 - 20230915T223155647Z1b64098b-4ab7-43f6-afee-992304f198d8.20230914T223155650Zc8d9f4c5-6c5a-4b2d-9b1c-3d9d7a7c5c7c460 """ # noqa: E501461 in_dataset: Optional[bool] = None462 """Whether this run is in a dataset."""463 _host_url: Optional[str] = PrivateAttr(default=None)464 465 def __init__(self, _host_url: Optional[str] = None, **kwargs: Any) -> None:466 """Initialize a Run object."""467 if not kwargs.get("trace_id"):468 kwargs = {"trace_id": kwargs.get("id"), **kwargs}469 inputs = kwargs.pop("inputs", None) or {}470 super().__init__(**kwargs, inputs=inputs)471 self._host_url = _host_url472 if self.start_time.tzinfo is None:473 self.start_time = self.start_time.replace(tzinfo=timezone.utc)474 if self.end_time is not None and self.end_time.tzinfo is None:475 self.end_time = self.end_time.replace(tzinfo=timezone.utc)476 if not self.dotted_order.strip() and not self.parent_run_id:477 self.dotted_order = f"{self.start_time.isoformat()}{self.id}"478 479 @property480 def url(self) -> Optional[str]:481 """URL of this run within the app."""482 if self._host_url and self.app_path:483 return f"{self._host_url}{self.app_path}"484 return None485 486 @property487 def input_tokens(self) -> int | None:488 """Alias for prompt_tokens."""489 return self.prompt_tokens490 491 @property492 def output_tokens(self) -> int | None:493 """Alias for completion_tokens."""494 return self.completion_tokens495 496 @property497 def input_cost(self) -> Decimal | None:498 """Alias for prompt_cost."""499 return self.prompt_cost500 501 @property502 def output_cost(self) -> Decimal | None:503 """Alias for completion_cost."""504 return self.completion_cost505 506 @property507 def input_token_details(self) -> dict[str, int] | None:508 """Alias for prompt_token_details."""509 return self.prompt_token_details510 511 @property512 def output_token_details(self) -> dict[str, int] | None:513 """Alias for output_token_details."""514 return self.completion_token_details515 516 @property517 def input_cost_details(self) -> dict[str, Decimal] | None:518 """Alias for prompt_cost_details."""519 return self.prompt_cost_details520 521 @property522 def output_cost_details(self) -> dict[str, Decimal] | None:523 """Alias for completion_cost_details."""524 return self.completion_cost_details525 526 527class RunTypeEnum(str, Enum):528 """(Deprecated) Enum for run types. Use string directly."""529 530 tool = "tool"531 chain = "chain"532 llm = "llm"533 retriever = "retriever"534 embedding = "embedding"535 prompt = "prompt"536 parser = "parser"537 538 539class RunLikeDict(TypedDict, total=False):540 """Run-like dictionary, for type-hinting."""541 542 name: str543 run_type: RunTypeEnum544 start_time: datetime545 inputs: Optional[dict]546 outputs: Optional[dict]547 end_time: Optional[datetime]548 extra: Optional[dict]549 error: Optional[str]550 serialized: Optional[dict]551 parent_run_id: Optional[UUID]552 manifest_id: Optional[UUID]553 events: Optional[list[dict]]554 tags: Optional[list[str]]555 inputs_s3_urls: Optional[dict]556 outputs_s3_urls: Optional[dict]557 id: Optional[UUID]558 session_id: Optional[UUID]559 session_name: Optional[str]560 reference_example_id: Optional[UUID]561 input_attachments: Optional[dict]562 output_attachments: Optional[dict]563 trace_id: UUID564 dotted_order: str565 attachments: Attachments566 567 568class RunWithAnnotationQueueInfo(RunBase):569 """Run schema with annotation queue info."""570 571 last_reviewed_time: Optional[datetime] = None572 """The last time this run was reviewed."""573 added_at: Optional[datetime] = None574 """The time this run was added to the queue."""575 576 577class FeedbackSourceBase(BaseModel):578 """Base class for feedback sources.579 580 This represents whether feedback is submitted from the API, model, human labeler,581 etc.582 """583 584 type: str585 """The type of the feedback source."""586 metadata: Optional[dict[str, Any]] = Field(default_factory=dict)587 """Additional metadata for the feedback source."""588 user_id: Optional[Union[UUID, str]] = None589 """The user ID associated with the feedback source."""590 user_name: Optional[str] = None591 """The user name associated with the feedback source."""592 593 594class APIFeedbackSource(FeedbackSourceBase):595 """API feedback source."""596 597 type: Literal["api"] = "api"598 599 600class ModelFeedbackSource(FeedbackSourceBase):601 """Model feedback source."""602 603 type: Literal["model"] = "model"604 605 606class FeedbackSourceType(Enum):607 """Feedback source type."""608 609 API = "api"610 """General feedback submitted from the API."""611 MODEL = "model"612 """Model-assisted feedback."""613 614 615class FeedbackBase(BaseModel):616 """Feedback schema."""617 618 id: UUID619 """The unique ID of the feedback."""620 created_at: Optional[datetime] = None621 """The time the feedback was created."""622 modified_at: Optional[datetime] = None623 """The time the feedback was last modified."""624 run_id: Optional[UUID]625 """The associated run ID this feedback is logged for."""626 trace_id: Optional[UUID]627 """The associated trace ID this feedback is logged for."""628 key: str629 """The metric name, tag, or aspect to provide feedback on."""630 score: SCORE_TYPE = None631 """Value or score to assign the run."""632 value: VALUE_TYPE = None633 """The display value, tag or other value for the feedback if not a metric."""634 comment: Optional[str] = None635 """Comment or explanation for the feedback."""636 correction: Union[str, dict, None] = None637 """Correction for the run."""638 feedback_source: Optional[FeedbackSourceBase] = None639 """The source of the feedback."""640 session_id: Optional[UUID] = None641 """The associated project ID (Session = Project) this feedback is logged for."""642 start_time: Optional[datetime] = None643 """The start time of the run this feedback is associated with."""644 comparative_experiment_id: Optional[UUID] = None645 """If logged within a 'comparative experiment', this is the ID of the experiment."""646 feedback_group_id: Optional[UUID] = None647 """For preference scoring, this group ID is shared across feedbacks for each648 649 run in the group that was being compared."""650 extra: Optional[dict] = None651 """The metadata of the feedback."""652 653 model_config = ConfigDict(frozen=True)654 655 656class FeedbackCategory(TypedDict, total=False):657 """Specific value and label pair for feedback."""658 659 value: float660 """The numeric value associated with this feedback category."""661 label: Optional[str]662 """An optional label to interpret the value for this feedback category."""663 664 665class FeedbackConfig(TypedDict, total=False):666 """Represents _how_ a feedback value ought to be interpreted."""667 668 type: Literal["continuous", "categorical", "freeform"]669 """The type of feedback."""670 min: Optional[float]671 """The minimum value for continuous feedback."""672 max: Optional[float]673 """The maximum value for continuous feedback."""674 categories: Optional[list[FeedbackCategory]]675 """If feedback is categorical, this defines the valid categories the server will accept.676 Not applicable to continuous or freeform feedback types.""" # noqa677 678 679class FeedbackCreate(FeedbackBase):680 """Schema used for creating feedback."""681 682 feedback_source: FeedbackSourceBase683 """The source of the feedback."""684 feedback_config: Optional[FeedbackConfig] = None685 """The config for the feedback"""686 error: Optional[bool] = None687 688 689class Feedback(FeedbackBase):690 """Schema for getting feedback."""691 692 id: UUID693 created_at: datetime694 """The time the feedback was created."""695 modified_at: datetime696 """The time the feedback was last modified."""697 feedback_source: Optional[FeedbackSourceBase] = None698 """The source of the feedback. In this case"""699 700 701class TracerSession(BaseModel):702 """TracerSession schema for the API.703 704 Sessions are also referred to as "Projects" in the UI.705 """706 707 id: UUID708 """The ID of the project."""709 start_time: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))710 """The time the project was created."""711 end_time: Optional[datetime] = None712 """The time the project was ended."""713 description: Optional[str] = None714 """The description of the project."""715 name: Optional[str] = None716 """The name of the session."""717 extra: Optional[dict[str, Any]] = None718 """Extra metadata for the project."""719 tenant_id: UUID720 """The tenant ID this project belongs to."""721 reference_dataset_id: Optional[UUID]722 """The reference dataset IDs this project's runs were generated on."""723 724 _host_url: Optional[str] = PrivateAttr(default=None)725 726 def __init__(self, _host_url: Optional[str] = None, **kwargs: Any) -> None:727 """Initialize a Run object."""728 super().__init__(**kwargs)729 self._host_url = _host_url730 if self.start_time.tzinfo is None:731 self.start_time = self.start_time.replace(tzinfo=timezone.utc)732 733 @property734 def url(self) -> Optional[str]:735 """URL of this run within the app."""736 if self._host_url:737 return f"{self._host_url}/o/{self.tenant_id}/projects/p/{self.id}"738 return None739 740 @property741 def metadata(self) -> dict[str, Any]:742 """Retrieve the metadata (if any)."""743 if self.extra is None or "metadata" not in self.extra:744 return {}745 return self.extra["metadata"]746 747 @property748 def tags(self) -> list[str]:749 """Retrieve the tags (if any)."""750 if self.extra is None or "tags" not in self.extra:751 return []752 return self.extra["tags"]753 754 755class TracerSessionResult(TracerSession):756 """A project, hydrated with additional information.757 758 Sessions are also referred to as "Projects" in the UI.759 """760 761 run_count: Optional[int] = None762 """The number of runs in the project."""763 latency_p50: Optional[timedelta] = None764 """The median (50th percentile) latency for the project."""765 latency_p99: Optional[timedelta] = None766 """The 99th percentile latency for the project."""767 total_tokens: Optional[int] = None768 """The total number of tokens consumed in the project."""769 prompt_tokens: Optional[int] = None770 """The total number of prompt tokens consumed in the project."""771 completion_tokens: Optional[int] = None772 """The total number of completion tokens consumed in the project."""773 last_run_start_time: Optional[datetime] = None774 """The start time of the last run in the project."""775 feedback_stats: Optional[dict[str, Any]] = None776 """Feedback stats for the project."""777 session_feedback_stats: Optional[dict[str, Any]] = None778 """Summary feedback stats for the project."""779 run_facets: Optional[list[dict[str, Any]]] = None780 """Facets for the runs in the project."""781 total_cost: Optional[Decimal] = None782 """The total estimated LLM cost associated with the completion tokens."""783 prompt_cost: Optional[Decimal] = None784 """The estimated cost associated with the prompt (input) tokens."""785 completion_cost: Optional[Decimal] = None786 """The estimated cost associated with the completion tokens."""787 first_token_p50: Optional[timedelta] = None788 """The median (50th percentile) time to process the first token."""789 first_token_p99: Optional[timedelta] = None790 """The 99th percentile time to process the first token."""791 error_rate: Optional[float] = None792 """The error rate for the project."""793 794 795@runtime_checkable796class BaseMessageLike(Protocol):797 """A protocol representing objects similar to BaseMessage."""798 799 content: str800 """The content of the message."""801 additional_kwargs: dict[Any, Any]802 """Additional keyword arguments associated with the message."""803 804 @property805 def type(self) -> str:806 """Type of the Message, used for serialization."""807 808 809class DatasetShareSchema(TypedDict, total=False):810 """Represents the schema for a dataset share."""811 812 dataset_id: UUID813 """The ID of the dataset."""814 share_token: UUID815 """The token for sharing the dataset."""816 url: str817 """The URL of the shared dataset."""818 819 820class AnnotationQueueRubricItem(TypedDict, total=False):821 """Represents a rubric item assigned to an annotation queue.822 823 Links a feedback config to a queue with optional per-queue customization.824 """825 826 feedback_key: str827 """The feedback key to include in this queue's rubric."""828 description: Optional[str]829 """Instructions for annotators on how to evaluate this item."""830 value_descriptions: Optional[dict[str, str]]831 """Display text for categorical feedback values."""832 score_descriptions: Optional[dict[str, str]]833 """Display text for score ranges."""834 is_required: Optional[bool]835 """Whether feedback for this rubric item is required before submission."""836 837 838class AnnotationQueue(BaseModel):839 """Represents an annotation queue."""840 841 id: UUID842 """The unique identifier of the annotation queue."""843 name: str844 """The name of the annotation queue."""845 description: Optional[str] = None846 """An optional description of the annotation queue."""847 created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))848 """The timestamp when the annotation queue was created."""849 updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc))850 """The timestamp when the annotation queue was last updated."""851 tenant_id: UUID852 """The ID of the tenant associated with the annotation queue."""853 854 855class AnnotationQueueWithDetails(AnnotationQueue):856 """Represents an annotation queue with details."""857 858 rubric_instructions: Optional[str] = None859 """The rubric instructions for the annotation queue."""860 861 862class BatchIngestConfig(TypedDict, total=False):863 """Configuration for batch ingestion."""864 865 use_multipart_endpoint: bool866 """Whether to use the multipart endpoint for batch ingestion."""867 scale_up_qsize_trigger: int868 """The queue size threshold that triggers scaling up."""869 scale_up_nthreads_limit: int870 """The maximum number of threads to scale up to."""871 scale_down_nempty_trigger: int872 """The number of empty threads that triggers scaling down."""873 size_limit: int874 """The maximum size limit for the batch."""875 size_limit_bytes: Optional[int]876 """The maximum size limit in bytes for the batch."""877 878 879class LangSmithInfo(BaseModel):880 """Information about the LangSmith server."""881 882 version: str = ""883 """The version of the LangSmith server."""884 license_expiration_time: Optional[datetime] = None885 """The time the license will expire."""886 batch_ingest_config: Optional[BatchIngestConfig] = None887 """The instance flags."""888 instance_flags: Optional[dict[str, Any]] = None889 890 891Example.model_rebuild()892 893 894class LangSmithSettings(BaseModel):895 """Settings for the LangSmith tenant."""896 897 id: str898 """The ID of the tenant."""899 display_name: str900 """The display name of the tenant."""901 created_at: datetime902 """The creation time of the tenant."""903 tenant_handle: Optional[str] = None904 905 906class FeedbackIngestToken(BaseModel):907 """Represents the schema for a feedback ingest token."""908 909 id: UUID910 """The ID of the feedback ingest token."""911 url: str912 """The URL to GET when logging the feedback."""913 expires_at: datetime914 """The expiration time of the token."""915 916 917class RunEvent(TypedDict, total=False):918 """Run event schema."""919 920 name: str921 """Type of event."""922 time: Union[datetime, str]923 """Time of the event."""924 kwargs: Optional[dict[str, Any]]925 """Additional metadata for the event."""926 927 928class TimeDeltaInput(TypedDict, total=False):929 """Timedelta input schema."""930 931 days: int932 """Number of days."""933 hours: int934 """Number of hours."""935 minutes: int936 """Number of minutes."""937 938 939class DatasetDiffInfo(BaseModel):940 """Represents the difference information between two datasets."""941 942 examples_modified: list[UUID]943 """A list of UUIDs representing the modified examples."""944 examples_added: list[UUID]945 """A list of UUIDs representing the added examples."""946 examples_removed: list[UUID]947 """A list of UUIDs representing the removed examples."""948 949 950class ComparativeExperiment(BaseModel):951 """Represents a comparative experiment.952 953 This information summarizes evaluation results comparing954 two or more models on a given dataset.955 """956 957 id: UUID958 """The unique identifier for the comparative experiment."""959 name: Optional[str] = None960 """The optional name of the comparative experiment."""961 description: Optional[str] = None962 """An optional description of the comparative experiment."""963 tenant_id: UUID964 """The identifier of the tenant associated with this experiment."""965 created_at: datetime966 """The timestamp when the comparative experiment was created."""967 modified_at: datetime968 """The timestamp when the comparative experiment was last modified."""969 reference_dataset_id: UUID970 """The identifier of the reference dataset used in this experiment."""971 extra: Optional[dict[str, Any]] = None972 """Optional additional information about the experiment."""973 experiments_info: Optional[list[dict]] = None974 """Optional list of dictionaries containing information about individual experiments."""975 feedback_stats: Optional[dict[str, Any]] = None976 """Optional dictionary containing feedback statistics for the experiment."""977 978 @property979 def metadata(self) -> dict[str, Any]:980 """Retrieve the metadata (if any)."""981 if self.extra is None or "metadata" not in self.extra:982 return {}983 return self.extra["metadata"]984 985 986class PromptCommit(BaseModel):987 """Represents a Prompt with a manifest."""988 989 model_config = ConfigDict(populate_by_name=True)990 991 owner: str992 """The handle of the owner of the prompt."""993 repo: str994 """The name of the prompt."""995 commit_hash: str996 """The commit hash of the prompt."""997 manifest: dict[str, Any]998 """The manifest of the prompt."""999 examples: list[dict]1000 """The list of examples."""1001 description: Optional[str] = None1002 """Optional human-readable description for the commit."""1003 hub_model_config: Optional[dict] = Field(default=None, alias="model_config")1004 """The model configuration for the prompt."""1005 hub_model_provider: Optional[str] = Field(default=None, alias="model_provider")1006 """The model provider (e.g. ChatOpenAI)."""1007 1008 1009class ListedPromptCommit(BaseModel):1010 """Represents a listed prompt commit with associated metadata."""1011 1012 id: UUID1013 """The unique identifier for the prompt commit."""1014 1015 owner: str1016 """The owner of the prompt commit."""1017 1018 repo: str1019 """The repository name of the prompt commit."""1020 1021 manifest_id: Optional[UUID] = None1022 """The optional identifier for the manifest associated with this commit."""1023 1024 repo_id: Optional[UUID] = None1025 """The optional identifier for the repository."""1026 1027 parent_id: Optional[UUID] = None1028 """The optional identifier for the parent commit."""1029 1030 commit_hash: Optional[str] = None1031 """The optional hash of the commit."""1032 1033 created_at: Optional[datetime] = None1034 """The optional timestamp when the commit was created."""1035 1036 updated_at: Optional[datetime] = None1037 """The optional timestamp when the commit was last updated."""1038 1039 example_run_ids: Optional[list[UUID]] = Field(default_factory=list)1040 """A list of example run identifiers associated with this commit."""1041 1042 num_downloads: Optional[int] = 01043 """The number of times this commit has been downloaded."""1044 1045 num_views: Optional[int] = 01046 """The number of times this commit has been viewed."""1047 1048 parent_commit_hash: Optional[str] = None1049 """The optional hash of the parent commit."""1050 1051 description: Optional[str] = None1052 """Optional human-readable description for the commit."""1053 1054 1055class Prompt(BaseModel):1056 """Represents a Prompt with metadata."""1057 1058 repo_handle: str1059 """The name of the prompt."""1060 description: Optional[str] = None1061 """The description of the prompt."""1062 readme: Optional[str] = None1063 """The README of the prompt."""1064 id: str1065 """The ID of the prompt."""1066 tenant_id: str1067 """The tenant ID of the prompt owner."""1068 created_at: datetime1069 """The creation time of the prompt."""1070 updated_at: datetime1071 """The last update time of the prompt."""1072 is_public: bool1073 """Whether the prompt is public."""1074 is_archived: bool1075 """Whether the prompt is archived."""1076 tags: list[str]1077 """The tags associated with the prompt."""1078 original_repo_id: Optional[str] = None1079 """The ID of the original prompt, if forked."""1080 upstream_repo_id: Optional[str] = None1081 """The ID of the upstream prompt, if forked."""1082 owner: Optional[str]1083 """The handle of the owner of the prompt."""1084 full_name: str1085 """The full name of the prompt. (owner + repo_handle)"""1086 num_likes: int1087 """The number of likes."""1088 num_downloads: int1089 """The number of downloads."""1090 num_views: int1091 """The number of views."""1092 liked_by_auth_user: Optional[bool] = None1093 """Whether the prompt is liked by the authenticated user."""1094 last_commit_hash: Optional[str] = None1095 """The hash of the last commit."""1096 num_commits: int1097 """The number of commits."""1098 original_repo_full_name: Optional[str] = None1099 """The full name of the original prompt, if forked."""1100 upstream_repo_full_name: Optional[str] = None1101 """The full name of the upstream prompt, if forked."""1102 1103 1104class ListPromptsResponse(BaseModel):1105 """A list of prompts with metadata."""1106 1107 repos: list[Prompt]1108 """The list of prompts."""1109 total: int1110 """The total number of prompts."""1111 1112 1113class PromptSortField(str, Enum):1114 """Enum for sorting fields for prompts."""1115 1116 num_downloads = "num_downloads"1117 """Number of downloads."""1118 num_views = "num_views"1119 """Number of views."""1120 updated_at = "updated_at"1121 """Last updated time."""1122 num_likes = "num_likes"1123 """Number of likes."""1124 1125 1126class FileEntry(BaseModel):1127 """A file with inline content."""1128 1129 type: Literal["file"] = "file"1130 """The entry type."""1131 content: str1132 """The file content."""1133 1134 1135class AgentEntry(BaseModel):1136 """A link to another agent repo."""1137 1138 type: Literal["agent"] = "agent"1139 """The entry type."""1140 repo_handle: str1141 """The handle of the linked repo."""1142 commit_id: Optional[UUID] = None1143 """The commit ID of the linked repo, if pinned."""1144 owner: Optional[str] = None1145 """The owner of the linked repo."""1146 commit_hash: Optional[str] = None1147 """The commit hash of the linked repo."""1148 1149 1150class SkillEntry(BaseModel):1151 """A link to a skill repo."""1152 1153 type: Literal["skill"] = "skill"1154 """The entry type."""1155 repo_handle: str1156 """The handle of the linked repo."""1157 commit_id: Optional[UUID] = None1158 """The commit ID of the linked repo, if pinned."""1159 owner: Optional[str] = None1160 """The owner of the linked repo."""1161 commit_hash: Optional[str] = None1162 """The commit hash of the linked repo."""1163 1164 1165Entry = Annotated[Union[FileEntry, AgentEntry, SkillEntry], Field(discriminator="type")]1166"""A hub directory entry, discriminated by `type`."""1167 1168 1169class AgentContext(BaseModel):1170 """An agent pulled from hub."""1171 1172 commit_id: UUID1173 """The commit ID."""1174 commit_hash: str1175 """The commit hash."""1176 files: dict[str, Entry]1177 """The files in the agent."""1178 1179 1180class SkillContext(BaseModel):1181 """A skill pulled from hub."""1182 1183 commit_id: UUID1184 """The commit ID."""1185 commit_hash: str1186 """The commit hash."""1187 files: dict[str, Entry]1188 """The files in the skill."""1189 1190 1191class DirectoryCommitInfo(BaseModel):1192 """Commit details returned from a directory commit."""1193 1194 id: UUID1195 """The commit ID."""1196 commit_hash: str1197 """The commit hash."""1198 created_at: datetime1199 """When the commit was created."""1200 