// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.cloud.aiplatform.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/aiplatform/v1/accelerator_type.proto";
import "google/cloud/aiplatform/v1/encryption_spec.proto";
import "google/cloud/aiplatform/v1/job_state.proto";
import "google/cloud/aiplatform/v1/specialist_pool.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/rpc/status.proto";
import "google/type/money.proto";
import "google/api/annotations.proto";

option csharp_namespace = "Google.Cloud.AIPlatform.V1";
option go_package = "google.golang.org/genproto/googleapis/cloud/aiplatform/v1;aiplatform";
option java_multiple_files = true;
option java_outer_classname = "DataLabelingJobProto";
option java_package = "com.google.cloud.aiplatform.v1";
option php_namespace = "Google\\Cloud\\AIPlatform\\V1";
option ruby_package = "Google::Cloud::AIPlatform::V1";

// DataLabelingJob is used to trigger a human labeling job on unlabeled data
// from the following Dataset:
message DataLabelingJob {
  option (google.api.resource) = {
    type: "aiplatform.googleapis.com/DataLabelingJob"
    pattern: "projects/{project}/locations/{location}/dataLabelingJobs/{data_labeling_job}"
  };

  // Output only. Resource name of the DataLabelingJob.
  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Required. The user-defined name of the DataLabelingJob.
  // The name can be up to 128 characters long and can be consist of any UTF-8
  // characters.
  // Display name of a DataLabelingJob.
  string display_name = 2 [(google.api.field_behavior) = REQUIRED];

  // Required. Dataset resource names. Right now we only support labeling from a single
  // Dataset.
  // Format:
  // `projects/{project}/locations/{location}/datasets/{dataset}`
  repeated string datasets = 3 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "aiplatform.googleapis.com/Dataset"
    }
  ];

  // Labels to assign to annotations generated by this DataLabelingJob.
  //
  // Label keys and values can be no longer than 64 characters
  // (Unicode codepoints), can only contain lowercase letters, numeric
  // characters, underscores and dashes. International characters are allowed.
  // See https://goo.gl/xmQnxf for more information and examples of labels.
  // System reserved label keys are prefixed with "aiplatform.googleapis.com/"
  // and are immutable.
  map<string, string> annotation_labels = 12;

  // Required. Number of labelers to work on each DataItem.
  int32 labeler_count = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The Google Cloud Storage location of the instruction pdf. This pdf is
  // shared with labelers, and provides detailed description on how to label
  // DataItems in Datasets.
  string instruction_uri = 5 [(google.api.field_behavior) = REQUIRED];

  // Required. Points to a YAML file stored on Google Cloud Storage describing the
  // config for a specific type of DataLabelingJob.
  // The schema files that can be used here are found in the
  // https://storage.googleapis.com/google-cloud-aiplatform bucket in the
  // /schema/datalabelingjob/inputs/ folder.
  string inputs_schema_uri = 6 [(google.api.field_behavior) = REQUIRED];

  // Required. Input config parameters for the DataLabelingJob.
  google.protobuf.Value inputs = 7 [(google.api.field_behavior) = REQUIRED];

  // Output only. The detailed state of the job.
  JobState state = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Current labeling job progress percentage scaled in interval [0, 100],
  // indicating the percentage of DataItems that has been finished.
  int32 labeling_progress = 13 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Estimated cost(in US dollars) that the DataLabelingJob has incurred to
  // date.
  google.type.Money current_spend = 14 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when this DataLabelingJob was created.
  google.protobuf.Timestamp create_time = 9 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Timestamp when this DataLabelingJob was updated most recently.
  google.protobuf.Timestamp update_time = 10 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. DataLabelingJob errors. It is only populated when job's state is
  // `JOB_STATE_FAILED` or `JOB_STATE_CANCELLED`.
  google.rpc.Status error = 22 [(google.api.field_behavior) = OUTPUT_ONLY];

  // The labels with user-defined metadata to organize your DataLabelingJobs.
  //
  // Label keys and values can be no longer than 64 characters
  // (Unicode codepoints), can only contain lowercase letters, numeric
  // characters, underscores and dashes. International characters are allowed.
  //
  // See https://goo.gl/xmQnxf for more information and examples of labels.
  // System reserved label keys are prefixed with "aiplatform.googleapis.com/"
  // and are immutable. Following system labels exist for each DataLabelingJob:
  //
  // * "aiplatform.googleapis.com/schema": output only, its value is the
  //   [inputs_schema][google.cloud.aiplatform.v1.DataLabelingJob.inputs_schema_uri]'s title.
  map<string, string> labels = 11;

  // The SpecialistPools' resource names associated with this job.
  repeated string specialist_pools = 16;

  // Customer-managed encryption key spec for a DataLabelingJob. If set, this
  // DataLabelingJob will be secured by this key.
  //
  // Note: Annotations created in the DataLabelingJob are associated with
  // the EncryptionSpec of the Dataset they are exported to.
  EncryptionSpec encryption_spec = 20;

  // Parameters that configure the active learning pipeline. Active learning
  // will label the data incrementally via several iterations. For every
  // iteration, it will select a batch of data based on the sampling strategy.
  ActiveLearningConfig active_learning_config = 21;
}

// Parameters that configure the active learning pipeline. Active learning will
//  label the data incrementally by several iterations. For every iteration, it
//  will select a batch of data based on the sampling strategy.
message ActiveLearningConfig {
  // Required. Max human labeling DataItems. The rest part will be labeled by
  // machine.
  oneof human_labeling_budget {
    // Max number of human labeled DataItems.
    int64 max_data_item_count = 1;

    // Max percent of total DataItems for human labeling.
    int32 max_data_item_percentage = 2;
  }

  // Active learning data sampling config. For every active learning labeling
  // iteration, it will select a batch of data based on the sampling strategy.
  SampleConfig sample_config = 3;

  // CMLE training config. For every active learning labeling iteration, system
  // will train a machine learning model on CMLE. The trained model will be used
  // by data sampling algorithm to select DataItems.
  TrainingConfig training_config = 4;
}

// Active learning data sampling config. For every active learning labeling
// iteration, it will select a batch of data based on the sampling strategy.
message SampleConfig {
  // Sample strategy decides which subset of DataItems should be selected for
  // human labeling in every batch.
  enum SampleStrategy {
    // Default will be treated as UNCERTAINTY.
    SAMPLE_STRATEGY_UNSPECIFIED = 0;

    // Sample the most uncertain data to label.
    UNCERTAINTY = 1;
  }

  // Decides sample size for the initial batch. initial_batch_sample_percentage
  // is used by default.
  oneof initial_batch_sample_size {
    // The percentage of data needed to be labeled in the first batch.
    int32 initial_batch_sample_percentage = 1;
  }

  // Decides sample size for the following batches.
  // following_batch_sample_percentage is used by default.
  oneof following_batch_sample_size {
    // The percentage of data needed to be labeled in each following batch
    // (except the first batch).
    int32 following_batch_sample_percentage = 3;
  }

  // Field to choose sampling strategy. Sampling strategy will decide which data
  // should be selected for human labeling in every batch.
  SampleStrategy sample_strategy = 5;
}

// CMLE training config. For every active learning labeling iteration, system
// will train a machine learning model on CMLE. The trained model will be used
// by data sampling algorithm to select DataItems.
message TrainingConfig {
  // The timeout hours for the CMLE training job, expressed in milli hours
  // i.e. 1,000 value in this field means 1 hour.
  int64 timeout_training_milli_hours = 1;
}
