Skip to content

Commit 6b0cfcb

Browse files
committed
added project and ontology creation for prompt response projects
1 parent 5bf3de0 commit 6b0cfcb

File tree

8 files changed

+670
-31
lines changed

8 files changed

+670
-31
lines changed

libs/labelbox/src/labelbox/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
from labelbox.schema.asset_attachment import AssetAttachment
2424
from labelbox.schema.webhook import Webhook
2525
from labelbox.schema.ontology import Ontology, OntologyBuilder, Classification, Option, Tool, FeatureSchema
26+
from labelbox.schema.ontology import PromptResponseClassification
27+
from labelbox.schema.ontology import ResponseOption
2628
from labelbox.schema.role import Role, ProjectRole
2729
from labelbox.schema.invite import Invite, InviteLimit
2830
from labelbox.schema.data_row_metadata import DataRowMetadataOntology, DataRowMetadataField, DataRowMetadata, DeleteDataRowMetadata

libs/labelbox/src/labelbox/client.py

Lines changed: 105 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
from labelbox.schema.model_config import ModelConfig
4242
from labelbox.schema.model_run import ModelRun
4343
from labelbox.schema.ontology import Ontology, DeleteFeatureFromOntologyResult
44-
from labelbox.schema.ontology import Tool, Classification, FeatureSchema
44+
from labelbox.schema.ontology import Tool, Classification, FeatureSchema, PromptResponseClassification
4545
from labelbox.schema.organization import Organization
4646
from labelbox.schema.project import Project
4747
from labelbox.schema.quality_mode import QualityMode, BENCHMARK_AUTO_AUDIT_NUMBER_OF_LABELS, \
@@ -874,6 +874,99 @@ def create_offline_model_evaluation_project(self, **kwargs) -> Project:
874874
kwargs.pop("data_row_count", None)
875875

876876
return self._create_project(**kwargs)
877+
878+
@overload
879+
def create_prompt_response_generation_project(self,
880+
dataset_name: str,
881+
dataset_id: str = None,
882+
data_row_count: int = 100,
883+
**kwargs) -> Project:
884+
pass
885+
886+
@overload
887+
def create_prompt_response_generation_project(self,
888+
dataset_id: str,
889+
dataset_name: str = None,
890+
data_row_count: int = 100,
891+
**kwargs) -> Project:
892+
pass
893+
894+
def create_prompt_response_generation_project(self,
895+
dataset_id: Optional[str] = None,
896+
dataset_name: Optional[str] = None,
897+
data_row_count: int = 100,
898+
**kwargs) -> Project:
899+
"""
900+
Use this method exclusively to create a prompt and response generation project.
901+
902+
Args:
903+
dataset_name: When creating a new dataset, pass the name
904+
dataset_id: When using an existing dataset, pass the id
905+
data_row_count: The number of data row assets to use for the project
906+
**kwargs: Additional parameters to pass to the the create_project method
907+
Returns:
908+
Project: The created project
909+
910+
Examples:
911+
>>> client.create_prompt_response_generation_project(name=project_name, dataset_name="new data set", project_kind=MediaType.LLMPromptResponseCreation)
912+
>>> This creates a new dataset with a default number of rows (100), creates new project and assigns a batch of the newly created datarows to the project.
913+
914+
>>> client.create_prompt_response_generation_project(name=project_name, dataset_name="new data set", data_row_count=10, project_kind=MediaType.LLMPromptCreation)
915+
>>> This creates a new dataset with 10 data rows, creates new project and assigns a batch of the newly created datarows to the project.
916+
917+
>>> client.create_prompt_response_generation_project(name=project_name, dataset_id="clr00u8j0j0j0", project_kind=MediaType.LLMPromptCreation)
918+
>>> This creates a new project, and adds 100 datarows to the dataset with id "clr00u8j0j0j0" and assigns a batch of the newly created data rows to the project.
919+
920+
>>> client.create_prompt_response_generation_project(name=project_name, dataset_id="clr00u8j0j0j0", data_row_count=10, project_kind=MediaType.LLMPromptCreation)
921+
>>> This creates a new project, and adds 100 datarows to the dataset with id "clr00u8j0j0j0" and assigns a batch of the newly created 10 data rows to the project.
922+
923+
"""
924+
if not dataset_id and not dataset_name:
925+
raise ValueError(
926+
"dataset_name or data_set_id must be present and not be an empty string."
927+
)
928+
if data_row_count <= 0:
929+
raise ValueError("data_row_count must be a positive integer.")
930+
931+
if dataset_id:
932+
append_to_existing_dataset = True
933+
dataset_name_or_id = dataset_id
934+
else:
935+
append_to_existing_dataset = False
936+
dataset_name_or_id = dataset_name
937+
938+
if "media_type" in kwargs and kwargs.get("media_type") not in [MediaType.LLMPromptCreation, MediaType.LLMPromptResponseCreation]:
939+
raise ValueError(
940+
"media_type must be either LLMPromptCreation or LLMPromptResponseCreation"
941+
)
942+
943+
kwargs["dataset_name_or_id"] = dataset_name_or_id
944+
kwargs["append_to_existing_dataset"] = append_to_existing_dataset
945+
kwargs["data_row_count"] = data_row_count
946+
947+
kwargs.pop("editor_task_type", None)
948+
949+
return self._create_project(**kwargs)
950+
951+
def create_response_creation_project(self, **kwargs) -> Project:
952+
"""
953+
Creates a project for response creation.
954+
Args:
955+
**kwargs: Additional parameters to pass see the create_project method
956+
Returns:
957+
Project: The created project
958+
"""
959+
kwargs[
960+
"media_type"] = MediaType.Text # Only Text is supported
961+
kwargs[
962+
"editor_task_type"] = EditorTaskType.ResponseCreation.value # Special editor task type for offline model evaluation
963+
964+
# The following arguments are not supported for offline model evaluation
965+
kwargs.pop("dataset_name_or_id", None)
966+
kwargs.pop("append_to_existing_dataset", None)
967+
kwargs.pop("data_row_count", None)
968+
969+
return self._create_project(**kwargs)
877970

878971
def _create_project(self, **kwargs) -> Project:
879972
auto_audit_percentage = kwargs.get("auto_audit_percentage")
@@ -1189,11 +1282,13 @@ def create_ontology_from_feature_schemas(
11891282
name (str): Name of the ontology
11901283
feature_schema_ids (List[str]): List of feature schema ids corresponding to
11911284
top level tools and classifications to include in the ontology
1192-
media_type (MediaType or None): Media type of a new ontology. NOTE for chat evaluation, we currently foce media_type to Conversational
1285+
media_type (MediaType or None): Media type of a new ontology.
11931286
ontology_kind (OntologyKind or None): set to OntologyKind.ModelEvaluation if the ontology is for chat evaluation,
11941287
leave as None otherwise.
11951288
Returns:
11961289
The created Ontology
1290+
1291+
NOTE for chat evaluation, we currently force media_type to Conversational and for response creation, we force media_type to Text.
11971292
"""
11981293
tools, classifications = [], []
11991294
for feature_schema_id in feature_schema_ids:
@@ -1209,10 +1304,13 @@ def create_ontology_from_feature_schemas(
12091304
f"Tool `{tool}` not in list of supported tools.")
12101305
elif 'type' in feature_schema.normalized:
12111306
classification = feature_schema.normalized['type']
1212-
try:
1307+
if classification in Classification.Type._value2member_map_.keys():
12131308
Classification.Type(classification)
12141309
classifications.append(feature_schema.normalized)
1215-
except ValueError:
1310+
elif classification in PromptResponseClassification.Type._value2member_map_.keys():
1311+
PromptResponseClassification.Type(classification)
1312+
classifications.append(feature_schema.normalized)
1313+
else:
12161314
raise ValueError(
12171315
f"Classification `{classification}` not in list of supported classifications."
12181316
)
@@ -1222,15 +1320,7 @@ def create_ontology_from_feature_schemas(
12221320
)
12231321
normalized = {'tools': tools, 'classifications': classifications}
12241322

1225-
if ontology_kind and ontology_kind is OntologyKind.ModelEvaluation:
1226-
if media_type is None:
1227-
media_type = MediaType.Conversational
1228-
else:
1229-
if media_type is not MediaType.Conversational:
1230-
raise ValueError(
1231-
"For chat evaluation, media_type must be Conversational."
1232-
)
1233-
1323+
# validation for ontology_kind and media_type is done within self.create_ontology
12341324
return self.create_ontology(name=name,
12351325
normalized=normalized,
12361326
media_type=media_type,
@@ -1424,7 +1514,7 @@ def create_ontology(self,
14241514
Returns:
14251515
The created Ontology
14261516
1427-
NOTE caller of this method is expected to set media_type to Conversational if ontology_kind is ModelEvaluation
1517+
NOTE for chat evaluation, we currently force media_type to Conversational and for response creation, we force media_type to Text.
14281518
"""
14291519

14301520
media_type_value = None
@@ -1435,6 +1525,7 @@ def create_ontology(self,
14351525
raise get_media_type_validation_error(media_type)
14361526

14371527
if ontology_kind and OntologyKind.is_supported(ontology_kind):
1528+
media_type = OntologyKind.evaluate_ontology_kind_with_media_type(ontology_kind, media_type)
14381529
editor_task_type_value = EditorTaskTypeMapper.to_editor_task_type(
14391530
ontology_kind, media_type).value
14401531
elif ontology_kind:

0 commit comments

Comments
 (0)