Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Cognitive Services - Azure AI Content Safety] - [Private Preview] - Add Image Batch Detection #27353

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 187 additions & 3 deletions specification/cognitiveservices/ContentSafety/models.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,47 @@ enum AnalyzeImageOutputType {
FourSeverityLevels,
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("The type of batch results storage mode.")
enum BatchResultsStorageMode {
@doc("Merge each result into one file.")
CollectiveResultFile,

@doc("Store each result in a single file.")
IndividualResultFiles,
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("The type of batch analysis task status.")
enum BatchTaskStatus {
@doc("The task has not started yet.")
NotStarted,

@doc("The task is in progress.")
Running,

@doc("The task has failed.")
Failed,

@doc("The task has been succeeded.")
Succeeded,
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
enum ModelStatus {
Created,
Training,
mengaims marked this conversation as resolved.
Show resolved Hide resolved
Ready,
Failed,
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
enum GeneratePromptStatus {
Running,
Ready,
Failed,
}

@doc("The text analysis request.")
model AnalyzeTextOptions {
@doc("The text needs to be analyzed. We support a maximum of 10k Unicode characters (Unicode code points) in the text of one request.")
Expand All @@ -61,6 +102,20 @@ model AnalyzeTextOptions {
@added(ContentSafety.Versions.v2023_10_30_Preview)
@doc("The incidents to detect.")
incidents?: IncidentOptions;

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("The customized categories will be analyzed. If they are not assigned, the analysis results for all available customized categories will be returned.")
customizedCategories?: CustomizedCategory[];
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("Customized category for inference.")
model CustomizedCategory {
@doc("Category name")
categoryName: string;

@doc("Model ID for the category. If not provided, the latest available model will be used.")
modelId: string;
mengaims marked this conversation as resolved.
Show resolved Hide resolved
}

@added(ContentSafety.Versions.v2023_10_30_Preview)
Expand Down Expand Up @@ -88,6 +143,29 @@ model AnalyzeTextResult {
@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("Chunks in the original text detected as harmful content. Analysis result and scores are caused by these.")
citation?: string[];

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("Analysis result for customized categories.")
customizedCategoriesAnalysis: TextCustomizedCategoryAnalysis[];
mengaims marked this conversation as resolved.
Show resolved Hide resolved
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("Text customized category analysis result.")
model TextCustomizedCategoryAnalysis {
@doc("Customized category name")
categoryName: string;

@doc("customized category analysis")
customizedCategoriesAnalysis: TextCustomizedCategoryClassResult[];
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("customized category analysis result")
model TextCustomizedCategoryClassResult {
id: int32;

@renamedFrom(Versions.v2024_01_30_Preview, "name")
className: string;
}

@doc("The result of blocklist match.")
Expand Down Expand Up @@ -169,6 +247,51 @@ model ImageCategoriesAnalysis {
severity?: int32;
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("The image batch analysis request.")
model BatchAnalyzeImagesOptions {
@doc("The URL of the Azure Storage Blob containing all the images to be analyzed in the batch task.")
imagesBlobFolderUrl: url;

@doc("The URL of the Azure Storage Blob where the batch task results will be written.")
analysisResultsBlobFolderUrl: url;

@doc("The storage mode for the batch task results, either 'CollectiveResultFile' or 'IndividualResultFiles'.")
resultsStorageMode?: BatchResultsStorageMode = BatchResultsStorageMode.CollectiveResultFile;

@doc("The categories will be analyzed. If they are not assigned, a default set of analysis results for the categories will be returned.")
categories?: ImageCategory[];

@doc("This refers to the type of image analysis output. If no value is assigned, the default value will be \"FourSeverityLevels\".")
outputType?: AnalyzeImageOutputType = AnalyzeImageOutputType.FourSeverityLevels;

@doc("The incidents to detect.")
incidents?: IncidentOptions;
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("Image batch analyze task.")
@resource("image/batchAnalyzeTasks")
model ImageBatchTaskDetail {
@doc("The id of image batch analysis task.")
@key("taskId")
@visibility("read")
@maxLength(64)
taskId: string;

@doc("The status of the batch image analysis task.")
status: BatchTaskStatus;

@doc("The progress of the batch image analysis task, represented as a percentage (0-100).")
mengaims marked this conversation as resolved.
Show resolved Hide resolved
progressPercentage: float64;

@doc("The timestamp of when batch image analysis task was created.")
taskCreatedTime: utcDateTime;

@doc("Return error detail when the task failed.")
error?: Azure.Core.Foundations.Error;
}

@doc("Text Blocklist.")
@resource("text/blocklists")
model TextBlocklist {
Expand Down Expand Up @@ -456,9 +579,13 @@ model PreDefinedConcept {

@added(Versions.v2023_10_30_Preview)
@doc("Label definition.")
model SubCategory {
@renamedFrom(Versions.v2024_01_30_Preview, "SubCategory")
model Class {
mengaims marked this conversation as resolved.
Show resolved Hide resolved
id: int32;
name: string;

@renamedFrom(Versions.v2024_01_30_Preview, "name")
className: string;

statements: string[];
}

Expand All @@ -473,12 +600,55 @@ model TextCustomizedCategory {
@maxLength(64)
categoryName: string;

@doc("A predefined concept with its definition can be used directly in the subcategories.")
@added(Versions.v2023_10_30_Preview)
@removed(Versions.v2024_01_30_Preview)
preDefinedConcepts?: PreDefinedConcept[];
subCategories: SubCategory[];

@doc("Subcategories are detailed classes of the category. It is required there is a class 'safe' with id=0.")
@renamedFrom(Versions.v2024_01_30_Preview, "subCategories")
classes: Class[];
mengaims marked this conversation as resolved.
Show resolved Hide resolved

@added(Versions.v2023_10_30_Preview)
@removed(Versions.v2024_01_30_Preview)
emphases?: string[];

@doc("Blob that stores the examples.")
exampleBlobUrl?: url;
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@doc("The response for async training triggering.")
model SubmitModelTrainingResponse {
...AcceptedResponse;

@header("operation-location")
@doc("The location of the status API for monitoring the triggered model.")
modelUrl: string;
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
model AsyncJobWarning {
code: string;
messgae: string;
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@resource("text/generatePromptTasks")
model GeneratePromptTaskDetail {
@doc("The id of image batch analysis task.")
@key("taskId")
@visibility("read")
@maxLength(64)
taskId: string;

@doc("The status of the batch image analysis task.")
status: GeneratePromptStatus;

@doc("Return error detail when the task failed.")
error?: Azure.Core.Foundations.Error;
}

#suppress "@azure-tools/typespec-azure-core/documentation-required" "MUST fix in next update"
@added(ContentSafety.Versions.v2023_10_30_Preview)
@doc("ImageWithText analyze category.")
Expand All @@ -489,6 +659,20 @@ enum ImageWithTextCategory {
Violence,
}

@added(ContentSafety.Versions.v2024_01_30_Preview)
@parentResource(TextCustomizedCategory)
@resource("models")
model TextTrainedModel {
@key
modelId: string;

status: ModelStatus;
createdTime: utcDateTime;
lastUpdateTime: utcDateTime;
warnings?: AsyncJobWarning[];
errors?: string[];
mengaims marked this conversation as resolved.
Show resolved Hide resolved
}

@added(ContentSafety.Versions.v2023_10_30_Preview)
@doc("The analysis request of the image with text.")
model AnalyzeImageWithTextOptions {
Expand Down
83 changes: 83 additions & 0 deletions specification/cognitiveservices/ContentSafety/routes.tsp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,41 @@ interface ImageOperations {
>;
}

interface ImageBatchOperations {
@added(ContentSafety.Versions.v2024_01_30_Preview)
@summary("Start Batch Analyze Images")
@doc("An asynchronous API for the batch analysis of potentially harmful image content. Currently, it supports four categories: Hate, SelfHarm, Sexual, and Violence.")
@route("/image:batchAnalyze")
batchAnalyzeImage is ContentSafetyLongRunningRpcOperation<
{
@body
@doc("The image batch analysis request.")
body: BatchAnalyzeImagesOptions;
},
ImageBatchTaskDetail
>;

@added(ContentSafety.Versions.v2024_01_30_Preview)
@summary("Get Batch Analyze Status")
@doc("Check the status of a batch image analysis task.")
getBatchTaskStatus is Azure.Core.ResourceRead<ImageBatchTaskDetail>;
}

@doc("Long running RPC operation template")
op ContentSafetyLongRunningRpcOperation<
TParams extends TypeSpec.Reflection.Model,
TResponse extends TypeSpec.Reflection.Model
> is Azure.Core.Foundations.Operation<
TParams,
Azure.Core.Foundations.AcceptedResponse & TResponse,
mengaims marked this conversation as resolved.
Show resolved Hide resolved
Azure.Core.Foundations.ErrorResponse
>;

interface BatchOps
extends Azure.Core.ResourceOperations<NoRepeatableRequests &
NoConditionalRequests &
NoClientRequestId> {}

interface BlockOps
extends Azure.Core.ResourceOperations<NoRepeatableRequests &
NoConditionalRequests &
Expand Down Expand Up @@ -290,6 +325,54 @@ interface TextCategoryCustomization {
TextCustomizedCategory,
ListQueryParametersTrait<StandardListQueryParameters>
>;

@added(Versions.v2024_01_30_Preview)
@action("trainModel")
trainModel is CategoryOps.ResourceAction<
TextCustomizedCategory,
{},
SubmitModelTrainingResponse
>;

@added(ContentSafety.Versions.v2024_01_30_Preview)
@route("/text/categories/{categoryName}:generatePrompt")
@post
@summary("Trigger prompt generation")
@doc("An asynchronous API to generate prompt from customized category.")
generateCustomizedCategoryPrompt is ContentSafetyLongRunningRpcOperation<
{
@path
@doc("The customized category name.")
categoryName: string;
},
GeneratePromptTaskDetail
>;

@added(ContentSafety.Versions.v2024_01_30_Preview)
@summary("Get Generate Prompt Task Status")
@doc("Check the status of a generate prompt task.")
getGeneratePromptTaskStatus is Azure.Core.ResourceRead<GeneratePromptTaskDetail>;
}

interface TextCustomizedMdoelOps
extends Azure.Core.ResourceOperations<NoRepeatableRequests &
NoConditionalRequests &
NoClientRequestId> {}

@added(Versions.v2024_01_30_Preview)
interface TextCustomizedModelOperations {
@summary("List all existing models")
@doc("List existing models.")
listTextCustomizedModels is TextCustomizedMdoelOps.ResourceList<
TextTrainedModel,
ListQueryParametersTrait<StandardListQueryParameters>
>;

@doc("Get a model that is not deleted.")
getTextCustomizedModels is TextCustomizedMdoelOps.ResourceRead<TextTrainedModel>;

@doc("If the model is training, the training process will be cancelled and the model will also be deleted.")
deleteCustomizedModel is TextCustomizedMdoelOps.ResourceDelete<TextTrainedModel>;
}

@added(Versions.v2023_10_30_Preview)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2931,13 +2931,15 @@
},
"preDefinedConcepts": {
"type": "array",
"description": "A predefined concept with its definition can be used directly in the subcategories.",
"items": {
"$ref": "#/definitions/PreDefinedConcept"
},
"x-ms-identifiers": []
},
"subCategories": {
"type": "array",
"description": "Subcategories are detailed classes of the category. It is required there is a class 'safe' with id=0.",
"items": {
"$ref": "#/definitions/SubCategory"
}
Expand All @@ -2950,7 +2952,8 @@
},
"exampleBlobUrl": {
"type": "string",
"format": "uri"
"format": "uri",
"description": "Blob that stores the examples."
}
},
"required": [
Expand Down
Loading
Loading