

syntax = "proto3";

import "proto/clarifai/api/resources.proto";
import "proto/clarifai/api/status/status.proto";
import "proto/clarifai/api/utils/extensions.proto";
import "proto/clarifai/auth/scope/scope.proto";
import "proto/clarifai/auth/util/extension.proto";
import "proto/clarifai/api/status/status_code.proto";


import "google/api/annotations.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";


package clarifai.api;

option go_package = "github.com/Clarifai/clarifai-go-grpc/proto/clarifai/api";
option java_multiple_files = true;
option java_package = "com.clarifai.grpc.api";
option objc_class_prefix = "CAIP";

/*
  Note: this is based on the google api format defined here. Please
  read this before contributing to this file and other *.proto files
  for the API.
  https://cloud.google.com/service-management/reference/rpc/google.api#google.api.HttpRule

  For the cl_depending_scopes in this file, see the docstring that explains the two types of
  scope dependencies in clarifai/auth/scope/scope.proto

  For new endpoints you should typically only add the fully qualified url that includes the user_id
  and app_id.

  You should typicaly use KeyAuth (the most restricted auth type) for new endpoints unless they are
  for resources not contained in an app or need access from things across apps. See more about the
  auth types here:
  https://clarifai.atlassian.net/wiki/spaces/TT/pages/1821409336/API+Authorizers+and+Resource+Access

 */


service V2 {






  // List concept relations between concepts in the platform.
  // MUST be above ListConcepts so that if concept_id is empty this will still match
  // /concepts/relations to list all the concept relations in the app.
  rpc ListConceptRelations (ListConceptRelationsRequest) returns (MultiConceptRelationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/relations"
      additional_bindings1 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/relations"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }



  // Post concept relations to create relations between concepts in the platform.
  rpc PostConceptRelations (PostConceptRelationsRequest) returns (MultiConceptRelationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/relations"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Post concept relations to create relations between concepts in the platform.
  rpc DeleteConceptRelations (DeleteConceptRelationsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/relations"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // List all the concepts with their positive and negative counts
  rpc GetConceptCounts (GetConceptCountsRequest) returns (MultiConceptCountResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/status"
      additional_bindings2 {
        get: "/v2/concepts/status"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Get a specific concept from an app.
  rpc GetConcept (GetConceptRequest) returns (SingleConceptResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}"
      additional_bindings3 {
        get: "/v2/concepts/{concept_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // List all the concepts.
  rpc ListConcepts (ListConceptsRequest) returns (MultiConceptResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts"
      additional_bindings4 {
        get: "/v2/concepts"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // List models concepts.
  rpc ListModelConcepts (ListModelConceptsRequest) returns (MultiConceptResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/concepts"
      additional_bindings5 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/concepts"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Search over the concepts to find one or more you're looking for.
  // This leverage the "body" parameter because we also have page and
  // per_page as url query param variables in this request.
  rpc PostConceptsSearches (PostConceptsSearchesRequest) returns (MultiConceptResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/searches"
      body: "*"
      additional_bindings6 {
        post: "/v2/concepts/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // as it needs to know the concepts in your workflow's models.
  }

  // Add a concept to an app.
  rpc PostConcepts (PostConceptsRequest) returns (MultiConceptResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts"
      body: "*"
      additional_bindings7 {
        post: "/v2/concepts"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Patch one or more concepts.
  rpc PatchConcepts (PatchConceptsRequest) returns (MultiConceptResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts"
      body: "*"
      additional_bindings8 {
        patch: "/v2/concepts"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }











  // Get a specific concept from an app.
  rpc GetConceptLanguage (GetConceptLanguageRequest) returns (SingleConceptLanguageResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/languages/{language}"
      additional_bindings9 {
        get: "/v2/concepts/{concept_id}/languages/{language}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // List the concept in all the translated languages.
  rpc ListConceptLanguages (ListConceptLanguagesRequest) returns (MultiConceptLanguageResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/languages"
      additional_bindings10 {
        get: "/v2/concepts/{concept_id}/languages"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Add a new translation for this concept.
  rpc PostConceptLanguages (PostConceptLanguagesRequest) returns (MultiConceptLanguageResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/languages"
      body: "*"
      additional_bindings11 {
        post: "/v2/concepts/{concept_id}/languages"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Patch the name for a given language names by passing in a list of concepts with the new names
  // for the languages.
  rpc PatchConceptLanguages (PatchConceptLanguagesRequest) returns (MultiConceptLanguageResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/{concept_id}/languages"
      body: "*"
      additional_bindings12 {
        patch: "/v2/concepts/{concept_id}/languages"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }




  // List all domain graphs.
  rpc ListKnowledgeGraphs (ListKnowledgeGraphsRequest) returns (MultiKnowledgeGraphResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/knowledge_graphs"
      additional_bindings13 {
        get: "/v2/concepts/knowledge_graphs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Post domain graphs.
  rpc PostKnowledgeGraphs (PostKnowledgeGraphsRequest) returns (MultiKnowledgeGraphResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/concepts/knowledge_graphs"
      body: "*"
      additional_bindings14 {
        post: "/v2/concepts/knowledge_graphs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }



  // Get a specific annotation from an app.
  rpc GetAnnotation (GetAnnotationRequest) returns (SingleAnnotationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotations/{annotation_id}"
      additional_bindings15 {
        get: "/v2/inputs/{input_id}/annotations/{annotation_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // to get the model for the worker.
  }

  // List all the annotation.
  rpc ListAnnotations (ListAnnotationsRequest) returns (MultiAnnotationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations"
      additional_bindings16 {
        get: "/v2/annotations"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // to get the model for the worker.
  }

  // List video track annotations for a specific input.
  rpc PostTrackAnnotationsSearches (PostTrackAnnotationsSearchesRequest) returns (MultiAnnotationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/track_annotations/searches"
      body: "*"
      additional_bindings17 {
        post: "/v2/inputs/{input_id}/track_annotations/searches",
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // to get the model for the worker.
  }

  // Stream annotations for a specific input one-by-one.
  rpc StreamAnnotations (StreamAnnotationsRequest) returns (stream SingleStreamAnnotationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/track_annotations/searches/stream"
      body: "*"
      additional_bindings18 {
        post: "/v2/inputs/{input_id}/track_annotations/searches/stream",
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = AnnotationTracks_Get;
  }

  // Stream live video annotations as soon as they are available.
  // This endpoint will NOT replay old annotations, but only stream new annotations that are generated after the stream is opened.
  rpc StreamLivestreamAnnotations (StreamLivestreamAnnotationsRequest) returns (stream SingleStreamAnnotationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotations/stream/live"
      body: "*"
      additional_bindings19 {
        post: "/v2/inputs/{input_id}/annotations/stream/live"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
  }

  // Post annotations.
  rpc PostAnnotations (PostAnnotationsRequest) returns (MultiAnnotationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations"
      body: "*"
      additional_bindings20 {
        post: "/v2/annotations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // to know the models in your default workflow.
  }

  // Patch one or more annotations.
  rpc PatchAnnotations (PatchAnnotationsRequest) returns (MultiAnnotationResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations"
      body: "*"
      additional_bindings21 {
        patch: "/v2/annotations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // to know the models in your default workflow.
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // to get the model for the worker.
  }

  // Patch annotations status by worker id and task id.
  // Deprecated: Use PutTaskAssignments to update task annotations.
  //   For example, you can use PutTaskAssignments with action REVIEW_APPROVE
  //   to approve task assignments and associated annotations in bulk.
  rpc PatchAnnotationsStatus (PatchAnnotationsStatusRequest) returns (PatchAnnotationsStatusResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/task/{task_id}/annotations/status"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Delete a single annotation.
  rpc DeleteAnnotation (DeleteAnnotationRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotations/{annotation_id}"
      additional_bindings22 {
        delete: "/v2/inputs/{input_id}/annotations/{annotation_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // for cleaning up some optimizations we have in DB layer for annotations.
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Delete multiple annotations in one request.
  rpc DeleteAnnotations (DeleteAnnotationsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/annotations"
      body: "*"
      additional_bindings23 {
        delete: "/v2/inputs/annotations"
        body: "*"
      }
      additional_bindings24 {
        delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations"
        body: "*"
      }
      additional_bindings25 {
        delete: "/v2/annotations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // for cleaning up some optimizations we have in DB layer for annotations.
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // List all the annotation tracks.
  rpc ListAnnotationTracks (ListAnnotationTracksRequest) returns (MultiAnnotationTrackResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotation_tracks"
      additional_bindings26 {
        get: "/v2/inputs/{input_id}/annotation_tracks"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = AnnotationTracks_Get;
  }

  // Post annotation tracks.
  rpc PostAnnotationTracks (PostAnnotationTracksRequest) returns (MultiAnnotationTrackResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotation_tracks"
      body: "*"
      additional_bindings27 {
        post: "/v2/inputs/{input_id}/annotation_tracks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = AnnotationTracks_Add;
  }

  // Patch one or more annotation tracks.
  rpc PatchAnnotationTracks (PatchAnnotationTracksRequest) returns (MultiAnnotationTrackResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/annotation_tracks"
      body: "*"
      additional_bindings28 {
        patch: "/v2/inputs/{input_id}/annotation_tracks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = AnnotationTracks_Add;
  }

  // Delete multiple annotation tracks in one request.
  rpc DeleteAnnotationTracks (DeleteAnnotationTracksRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_tracks"
      body: "*"
      additional_bindings29 {
        delete: "/v2/inputs/{input_id}/annotation_tracks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = AnnotationTracks_Delete;
  }

  // Patch saved annotations searches by ids.
  rpc PatchAnnotationsSearches (PatchAnnotationsSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations/searches"
      body: "*"
      additional_bindings30 {
        patch: "/v2/annotations/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Execute a search over annotations
  rpc PostAnnotationsSearches(PostAnnotationsSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations/searches"
      body: "*"
      additional_bindings31 {
        post: "/v2/annotations/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Search;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // to know the concepts and models in your default workflow.
  }

  // ListAnnotationWorkers lists users, models, and workflows (collectively
  // known as "workers") that have added annotations to the application.
  rpc ListAnnotationWorkers (ListAnnotationWorkersRequest) returns (MultiWorkerResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotations/workers"
      additional_bindings32 {
        get: "/v2/annotations/workers"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Get input count per status.
  rpc GetInputCount (GetInputCountRequest) returns (SingleInputCountResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/status"
      additional_bindings33 {
        get: "/v2/inputs/status"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Streams all the inputs starting from oldest assets.
  rpc StreamInputs (StreamInputsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/stream"
      additional_bindings34 {
        get: "/v2/inputs/stream"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  rpc GetInputSamples (GetInputSamplesRequest) returns (MultiInputAnnotationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}/inputs/samples"
      additional_bindings35 {
        get: "/v2/tasks/{task_id}/inputs/samples"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Get a specific input from an app.
  rpc GetInput (GetInputRequest) returns (SingleInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}"
      additional_bindings36 {
        get: "/v2/inputs/{input_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Get a MPEG-DASH manifest for video-type inputs that were added via PostInputs and successfully processed
  // Experimental. Manifest is used by browser and desktop clients that implement an efficient streaming playback
  // This means client can switch between low-resolution and high-resolution video streams
  // Depending on network bandwidth or user's preference
  // This also means that reencoded video streams are reencoded in a uniform way, not relying on original format
  // Alternative to MPEG-dash is to stream original file with byte-range header
  rpc GetInputVideoManifest (GetVideoManifestRequest) returns (GetVideoManifestResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}/video_manifest"
      additional_bindings37 {
        get: "/v2/inputs/{input_id}/video_manifest"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // List all the inputs.
  rpc ListInputs (ListInputsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs"
      additional_bindings38 {
        get: "/v2/inputs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // PostInputs adds one or more inputs to the app.
  // Takes a list of image/video/audio/text URLs, image/video/audio bytes or raw text
  // Optionally, include concepts or dataset ids to link them
  // Optionally, include metadata for search
  // Note that inputs processing is asynchronous process
  // See ListInputs, StreamInputs or PostInputSearches to list results
  rpc PostInputs (PostInputsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs"
      body: "*"
      additional_bindings39 {
        post: "/v2/inputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }



  // Patch one or more inputs.
  rpc PatchInputs (PatchInputsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs"
      body: "*"
      additional_bindings40 {
        patch: "/v2/inputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Delete a single input asynchronously.
  rpc DeleteInput (DeleteInputRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/{input_id}"
      additional_bindings41 {
        delete: "/v2/inputs/{input_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Delete multiple inputs in one request.
  // This call is asynchronous.
  rpc DeleteInputs (DeleteInputsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs"
      body: "*"
      additional_bindings42 {
        delete: "/v2/inputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Patch saved inputs searches by ids.
  rpc PatchInputsSearches (PatchInputsSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/searches"
      body: "*"
      additional_bindings43 {
        patch: "/v2/inputs/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Execute a search over inputs
  rpc PostInputsSearches(PostInputsSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/searches"
      body: "*"
      additional_bindings44 {
        post: "/v2/inputs/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Search;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // to know the concepts and models in your default workflow.
  }

  // Get predicted outputs from the model.
  rpc PostModelOutputs (PostModelOutputsRequest) returns (MultiOutputResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/outputs"
      body: "*"
      additional_bindings45 {
        post: "/v2/models/{model_id}/versions/{version_id}/outputs"
        body: "*"
      }
      additional_bindings46 {
        post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/outputs"
        body: "*"
      }
      additional_bindings47 {
        post: "/v2/models/{model_id}/outputs"
        body: "*"
      }
      additional_bindings48 {// call a deployment directly as an endpoint.
        post: "/v2/users/{runner_selector.deployment.user_id}/deployments/{runner_selector.deployment.id}/outputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
  }

  // TODO(zeiler): will need to
  // Single request but streaming responses.
  rpc GenerateModelOutputs (PostModelOutputsRequest) returns (stream MultiOutputResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/outputs/generate"
      body: "*"
      additional_bindings49 {
        post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/outputs/generate"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
  }

  // Stream of requests and stream of responses
  rpc StreamModelOutputs (stream PostModelOutputsRequest) returns (stream MultiOutputResponse) {
    option (google.api.http) = {
      post: "/v2/models/outputs/stream"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
  }

  // List all the datasets.
  rpc ListDatasets (ListDatasetsRequest) returns (MultiDatasetResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets"
      additional_bindings50 {
        get: "/v2/users/{user_app_id.user_id}/datasets"
      }
      additional_bindings51 {
        get: "/v2/datasets"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Get a specific dataset.
  rpc GetDataset (GetDatasetRequest) returns (SingleDatasetResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}"
      additional_bindings52 {
        get: "/v2/datasets/{dataset_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Add datasets to an app.
  // The process is atomic, i.e. either all or no datasets are added.
  // If there is an error for one dataset,
  // the process will stop, revert the transaction and return the error.
  rpc PostDatasets (PostDatasetsRequest) returns (MultiDatasetResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets"
      body: "*"
      additional_bindings53 {
        post: "/v2/datasets"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
  }

  // Patch one or more datasets.
  // The process is atomic, i.e. either all or no datasets are patched.
  // If there is an error for one dataset,
  // the process will stop, revert the transaction and return the error.
  rpc PatchDatasets (PatchDatasetsRequest) returns (MultiDatasetResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets"
      body: "*"
      additional_bindings54 {
        patch: "/v2/datasets"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
  }

  // Delete one or more datasets in a single request.
  rpc DeleteDatasets (DeleteDatasetsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets"
      body: "*"
      additional_bindings55 {
        delete: "/v2/datasets"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Delete;
  }

  // List all the dataset inputs in a dataset.
  rpc ListDatasetInputs (ListDatasetInputsRequest) returns (MultiDatasetInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/inputs"
      additional_bindings56 {
        get: "/v2/datasets/{dataset_id}/inputs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Get a specific dataset input.
  rpc GetDatasetInput (GetDatasetInputRequest) returns (SingleDatasetInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/inputs/{input_id}"
      additional_bindings57 {
        get: "/v2/datasets/{dataset_id}/inputs/{input_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Add dataset inputs to a dataset.
  // The process is not atomic, i.e. if there are errors with some dataset
  // inputs, others might still be added. The response reports
  //   - SUCCESS if all dataset inputs were added,
  //   - MIXED_STATUS if only some dataset inputs were added, and
  //   - FAILURE if no dataset inputs were added.
  // Each individual dataset input in the response has the status set to
  // indicate if it was successful or if there was an error.
  rpc PostDatasetInputs (PostDatasetInputsRequest) returns (MultiDatasetInputResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/inputs"
      body: "*"
      additional_bindings58 {
        post: "/v2/datasets/{dataset_id}/inputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Delete one or more dataset inputs in a single request.
  rpc DeleteDatasetInputs (DeleteDatasetInputsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/inputs"
      body: "*"
      additional_bindings59 {
        delete: "/v2/datasets/{dataset_id}/inputs"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // List all the dataset versions.
  rpc ListDatasetVersions (ListDatasetVersionsRequest) returns (MultiDatasetVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions"
      additional_bindings60 {
        get: "/v2/datasets/{dataset_id}/versions"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Get a specific dataset version.
  rpc GetDatasetVersion (GetDatasetVersionRequest) returns (SingleDatasetVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions/{dataset_version_id}"
      additional_bindings61 {
        get: "/v2/datasets/{dataset_id}/versions/{dataset_version_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  rpc ListDatasetVersionMetricsGroups (ListDatasetVersionMetricsGroupsRequest) returns (MultiDatasetVersionMetricsGroupResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions/{dataset_version_id}/metrics"
      additional_bindings62 {
        get: "/v2/datasets/{dataset_id}/versions/{dataset_version_id}/metrics"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  }

  // Add dataset versions to a dataset.
  rpc PostDatasetVersions (PostDatasetVersionsRequest) returns (MultiDatasetVersionResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions"
      body: "*"
      additional_bindings63 {
        post: "/v2/datasets/{dataset_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Patch one or more dataset versions.
  rpc PatchDatasetVersions (PatchDatasetVersionsRequest) returns (MultiDatasetVersionResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions"
      body: "*"
      additional_bindings64 {
        patch: "/v2/datasets/{dataset_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
  }

  // Delete one or more dataset versions in a single request.
  rpc DeleteDatasetVersions (DeleteDatasetVersionsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions"
      body: "*"
      additional_bindings65 {
        delete: "/v2/datasets/{dataset_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Delete;
  }

  // Create export of a dataset version.
  rpc PutDatasetVersionExports (PutDatasetVersionExportsRequest) returns (MultiDatasetVersionExportResponse) {
    option (google.api.http) = {
      put: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/datasets/{dataset_id}/versions/{dataset_version_id}/exports"
      body: "*"
      additional_bindings66 {
        put: "/v2/datasets/{dataset_id}/versions/{dataset_version_id}/exports"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Add;
  }


  ////////////////////////////////////////
  // Models
  ////////////////////////////////////////

  // Get a specific model type.
  rpc GetModelType (GetModelTypeRequest) returns (SingleModelTypeResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/types/{model_type_id}"
      additional_bindings67 {
        get: "/v2/models/types/{model_type_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // List all the supported open source licenses in the platform.
  rpc ListOpenSourceLicenses (ListOpenSourceLicensesRequest) returns (ListOpenSourceLicensesResponse) {
    option (google.api.http) = {
      get: "/v2/open_source_licenses"
    };
    option (clarifai.auth.util.cl_auth_type) = NoAuth;
  }

  // List all the model types available in the platform.
  // This MUST be above ListModels so that the /models/types endpoint takes precedence.
  rpc ListModelTypes (ListModelTypesRequest) returns (MultiModelTypeResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/types"
      additional_bindings68 {
        get: "/v2/models/types"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Get a specific model from an app.
  rpc GetModel (GetModelRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}"
      additional_bindings69 {
        get: "/v2/models/{model_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Get a the output info for a given model_id or model_id/version_id
  // combo.
  rpc GetModelOutputInfo (GetModelRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/output_info"
      additional_bindings70 {
        get: "/v2/models/{model_id}/output_info"
      }
      additional_bindings71 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/output_info"
      }
      additional_bindings72 {
        get: "/v2/models/{model_id}/versions/{version_id}/output_info"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // List all the models.
  rpc ListModels (ListModelsRequest) returns (MultiModelResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models"
      additional_bindings73 {
        get: "/v2/users/{user_app_id.user_id}/models"
      }
      additional_bindings74 {
        get: "/v2/models"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // List the resource counts for the app.
  rpc GetResourceCounts (GetResourceCountsRequest) returns (GetResourceCountsResponse){
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/resource_counts"
      additional_bindings75 {
        get: "/v2/resource_counts"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;

    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  // Search over the models to find one or more you're looking for.
  // This leverage the "body" parameter because we also have page and
  // per_page as url query param variables in this request.
  rpc PostModelsSearches (PostModelsSearchesRequest) returns (MultiModelResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/searches"
      body: "*"
      additional_bindings76 {
        post: "/v2/models/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Add a models to an app.
  rpc PostModels (PostModelsRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models"
      body: "*"
      additional_bindings77 {
        post: "/v2/models"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;  // Train is needed because it creates a new version.
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // Needs to check the base workflow to build off of.
  }

  // Patch one or more models.
  rpc PatchModels (PatchModelsRequest) returns (MultiModelResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models"
      body: "*"
      additional_bindings78 {
        patch: "/v2/models"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
  }

  // Patch one or more models ids.
  rpc PatchModelIds (PatchModelIdsRequest) returns (MultiModelResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/ids"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Delete a single model.
  rpc DeleteModel (DeleteModelRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}"
      additional_bindings79 {
        delete: "/v2/models/{model_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Delete multiple models in one request.
  rpc DeleteModels (DeleteModelsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models"
      body: "*"
      additional_bindings80 {
        delete: "/v2/models"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Update model check consents
  rpc PatchModelCheckConsents (PatchModelCheckConsentsRequest) returns (MultiModelCheckConsentResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/check_consents"
      body: "*"
      additional_bindings81 {
        patch: "/v2/models/{model_id}/check_consents"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Update model toolkits tags
  rpc PatchModelToolkits (PatchModelToolkitsRequest) returns (MultiModelToolkitResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/toolkits"
      body: "*"
      additional_bindings82 {
        patch: "/v2/models/{model_id}/toolkits"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Update model use_cases tags
  rpc PatchModelUseCases (PatchModelUseCasesRequest) returns (MultiModelUseCaseResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/usecases"
      body: "*"
      additional_bindings83 {
        patch: "/v2/models/{model_id}/usecases"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Update model languages tags
  rpc PatchModelLanguages (PatchModelLanguagesRequest) returns (MultiModelLanguageResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/languages"
      body: "*"
      additional_bindings84 {
        patch: "/v2/models/{model_id}/languages"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // Deprecated: Unmaintained and ideally replaced with usage of datasets
  //   The server may refuse to accept requests to this endpoint.
  rpc ListModelInputs (ListModelInputsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/inputs"
      additional_bindings85 {
        get: "/v2/models/{model_id}/inputs"
      }
      additional_bindings86 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/inputs"
      }
      additional_bindings87 {
        get: "/v2/models/{model_id}/versions/{version_id}/inputs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option deprecated = true;
  }

  // Get a specific model from an app.
  rpc GetModelVersion (GetModelVersionRequest) returns (SingleModelVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}"
      additional_bindings88 {
        get: "/v2/models/{model_id}/versions/{version_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // List all the models.
  rpc ListModelVersions (ListModelVersionsRequest) returns (MultiModelVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions"
      additional_bindings89 {
        get: "/v2/models/{model_id}/versions"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }


  // TODO(zeiler): in future we can add endpoints like this for listing runners for a specific model
  // List all the runners currently handling work for the given model.
  // By default this lists the runners available in your account as well as all the orgs you have
  // access to.
  // Could have RunnerSelector to break it down by Nodepool or Deployment.
  // Addition filters on the request can select specific user/org to list from or nodepool.
  // rpc ListModelVersionRunners (ListModelVersionRunnersRequest) returns (MultiRunnerResponse) {
  //   option (google.api.http) = {
  //     get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/runners"
  //   };
  //   option (clarifai.auth.util.cl_auth_type) = KeyAuth;
  //   option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  //   option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
  //   option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  //   option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  // }

  rpc PostWorkflowVersionsUnPublish (PostWorkflowVersionsUnPublishRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/unpublish"
      body: "*"
      additional_bindings90 {
        post: "/v2/workflows/{workflow_id}/unpublish"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowPublications_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  rpc PostWorkflowVersionsPublish (PostWorkflowVersionsPublishRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/publish"
      body: "*"
      additional_bindings91 {
        post: "/v2/workflows/{workflow_id}/publish"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowPublications_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  // PostModelVersionsPublish
  rpc PostModelVersionsPublish (PostModelVersionsPublishRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/publish"
      body: "*"
      additional_bindings92 {
        post: "/v2/models/{model_id}/publish"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ModelVersionPublications_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  // PostModelVersionsUnPublish
  rpc PostModelVersionsUnPublish (PostModelVersionsUnPublishRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/unpublish"
      body: "*"
      additional_bindings93 {
        post: "/v2/models/{model_id}/unpublish"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ModelVersionPublications_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }


  // NOTE: inconsistency: do we want this to return a SingleModelResponse?

  // Create a new model version to trigger training of the model.
  rpc PostModelVersions (PostModelVersionsRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions"
      body: "*"
      additional_bindings94 {
        post: "/v2/models/{model_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // Needs to check the base workflow to build off of.
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  // PatchModelVersions
  rpc PatchModelVersions (PatchModelVersionsRequest) returns (MultiModelVersionResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
  }

  // Delete a single model.
  rpc DeleteModelVersion (DeleteModelVersionRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}"
      additional_bindings95 {
        delete: "/v2/models/{model_id}/versions/{version_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // This is a streaming endpoint, the request has a field, upload_data, which can either be the config for the upload or the actual data to upload.
  // The config must be sent first before the model_bytes can be uploaded.
  // Once the config has been sent, the server will respond with a confirmation containing the model_version_id.
  // This is so that if your upload is interrupted, you can resume the upload by sending the config again with the model_version_id specified for your model_version.
  // The actual upload will be done via a multipart upload, the latest successful part_id will be sent from the server in the response to the model_bytes.
  rpc PostModelVersionsUpload (stream PostModelVersionsUploadRequest) returns (stream PostModelVersionsUploadResponse) {
    option (google.api.http) = {
      post: "/v2/models/versions/upload"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // Needs to check the base workflow to build off of.
  }

  // Kicks off conversion from the old Triton model format to the new Docker model format.
  rpc PostModelMigration (PostModelMigrationRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/migration"
      body: "*"
      additional_bindings96 {
        post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/migration"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
  }

  // Reverts a model migration from Docker format back to Triton format.
  rpc DeleteModelMigration (DeleteModelMigrationRequest) returns (SingleModelResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/migration"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }



  // Export a model
  rpc PutModelVersionExports (PutModelVersionExportsRequest) returns (SingleModelVersionExportResponse) {
    option (google.api.http) = {
      put: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/exports"
      additional_bindings97 {
        put: "/v2/models/{model_id}/versions/{version_id}/exports"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ModelExports_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ModelExports_Add;
  }

  // GetModelVersionExport
  rpc GetModelVersionExport (GetModelVersionExportRequest) returns (SingleModelVersionExportResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/exports"
      additional_bindings98 {
        get: "/v2/models/{model_id}/versions/{version_id}/exports"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ModelExports_Get;
  }

  // Get the evaluation metrics for a model version.
  // Deprecated: Use GetEvaluation instead
  //   The server may refuse to accept requests to this endpoint.
  rpc GetModelVersionMetrics (GetModelVersionMetricsRequest) returns (SingleModelVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/metrics"
      additional_bindings99 {
        get: "/v2/models/{model_id}/versions/{version_id}/metrics"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
  }

  // Deprecated, use PostEvaluations instead
  // Run the evaluation metrics for a model version.
  rpc PostModelVersionMetrics (PostModelVersionMetricsRequest) returns (SingleModelVersionResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{version_id}/metrics"
      body: "*"
      additional_bindings100 {
        post: "/v2/models/{model_id}/versions/{version_id}/metrics"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // Needs to check the base workflow to build off of.
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  // Deprecated, use PostEvaluations instead
  rpc PostModelVersionEvaluations (PostModelVersionEvaluationsRequest) returns (MultiEvalMetricsResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/evaluations"
      body: "*"
      additional_bindings101 {
        post: "/v2/models/{model_id}/versions/{model_version_id}/evaluations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  // Deprecated, use GetEvaluation instead
  // List the evaluation metrics for a model version.
  rpc ListModelVersionEvaluations (ListModelVersionEvaluationsRequest) returns (MultiEvalMetricsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/evaluations"
      additional_bindings102 {
        get: "/v2/models/{model_id}/versions/{model_version_id}/evaluations"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
  }

  // Deprecated, use GetEvaluation instead
  // Get an evaluation metrics for a model version.
  rpc GetModelVersionEvaluation (GetModelVersionEvaluationRequest) returns (SingleEvalMetricsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/evaluations/{evaluation_id}"
      additional_bindings103 {
        get: "/v2/models/{model_id}/versions/{model_version_id}/evaluations/{evaluation_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
  }

  rpc PostEvaluations (PostEvaluationsRequest) returns (MultiEvalMetricsResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/evaluations"
      body: "*"
      additional_bindings104 {
        post: "/v2/evaluations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Train;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Add;
  }

  rpc ListEvaluations (ListEvaluationsRequest) returns (MultiEvalMetricsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/evaluations"
      additional_bindings105 {
        get: "/v2/users/{user_app_id.user_id}/evaluations"
      }
      additional_bindings106 {
        get: "/v2/evaluations"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
  }

  rpc GetEvaluation (GetEvaluationRequest) returns (SingleEvalMetricsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/evaluations/{evaluation_id}"
      additional_bindings107 {
        get: "/v2/evaluations/{evaluation_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Metrics_Get;
  }

  // Lists model references tied to a particular model id.
  rpc ListModelReferences (ListModelReferencesRequest) returns (MultiModelReferenceResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/references"
      additional_bindings108 {
        get: "/v2/models/{model_id}/references"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }



  // GetModelVersionInputExample
  rpc GetModelVersionInputExample (GetModelVersionInputExampleRequest) returns (SingleModelVersionInputExampleResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/input_examples/{example_id}"
      additional_bindings109 {
        get: "/v2/models/{model_id}/versions/{model_version_id}/input_examples/{example_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

  // ListModelVersionInputExamples
  rpc ListModelVersionInputExamples (ListModelVersionInputExamplesRequest) returns (MultiModelVersionInputExampleResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/input_examples"
      additional_bindings110 {
        get: "/v2/models/{model_id}/versions/{model_version_id}/input_examples"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }

















  ////////////////////////////////////////

  ////////////////////////////////////////
  // Workflows
  ////////////////////////////////////////

  // Get a specific workflow from an app.
  rpc GetWorkflow (GetWorkflowRequest) returns (SingleWorkflowResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}"
      additional_bindings111 {
        get: "/v2/workflows/{workflow_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // List all the workflows.
  rpc ListWorkflows (ListWorkflowsRequest) returns (MultiWorkflowResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows"
      additional_bindings112 {
        get: "/v2/users/{user_app_id.user_id}/workflows"
      }
      additional_bindings113 {
        get: "/v2/workflows"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }


  // Add a workflow to an app.
  // Note(zeiler): the order of the workflows that are returned from this endpoint
  // may be different than the order in which the user provides them. This is because
  // we reorder by a sort that optimizes for performance of the graph and its dependencies.
  // When using the workflow in any future call the order returned by this endpoint
  // will be used.
  rpc PostWorkflows (PostWorkflowsRequest) returns (MultiWorkflowResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows"
      body: "*"
      additional_bindings114 {
        post: "/v2/workflows"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Patch one or more workflows.
  rpc PatchWorkflows (PatchWorkflowsRequest) returns (MultiWorkflowResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows"
      body: "*"
      additional_bindings115 {
        patch: "/v2/workflows"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Patch one or more workflows ids.
  rpc PatchWorkflowIds (PatchWorkflowIdsRequest) returns (MultiWorkflowResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/ids"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Delete a single workflow.
  rpc DeleteWorkflow (DeleteWorkflowRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}"
      additional_bindings116 {
        delete: "/v2/workflows/{workflow_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Delete multiple workflows in one request.
  rpc DeleteWorkflows (DeleteWorkflowsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows"
      body: "*"
      additional_bindings117 {
        delete: "/v2/workflows"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Predict using a workflow.
  rpc PostWorkflowResults (PostWorkflowResultsRequest) returns (PostWorkflowResultsResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{version_id}/results"
      body: "*"
      additional_bindings118 {
        post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/results"
        body: "*"
      }
      additional_bindings119 {
        post: "/v2/workflows/{workflow_id}/results"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // List workflow versions.
  rpc ListWorkflowVersions (ListWorkflowVersionsRequest) returns (MultiWorkflowVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions"
      additional_bindings120 {
        get: "/v2/workflows/{workflow_id}/versions"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Get single workflow version.
  rpc GetWorkflowVersion (GetWorkflowVersionRequest) returns (SingleWorkflowVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}"
      additional_bindings121 {
        get: "/v2/workflows/{workflow_id}/versions/{workflow_version_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Delete workflow versions.
  rpc DeleteWorkflowVersions (DeleteWorkflowVersionsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions"
      body: "*"
      additional_bindings122 {
        delete: "/v2/workflows/{workflow_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Delete;
  }

  // Patch workflow versions.
  rpc PatchWorkflowVersions (PatchWorkflowVersionsRequest) returns (MultiWorkflowVersionResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions"
      body: "*"
      additional_bindings123 {
        patch: "/v2/workflows/{workflow_id}/versions"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
  }

  // Get a specific key from an app.
  rpc GetKey (GetKeyRequest) returns (SingleKeyResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/keys/{key_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // List all the keys.
  rpc ListKeys (ListKeysRequest) returns (MultiKeyResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/keys"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // List keys by app_id
  rpc ListAppKeys (ListAppKeysRequest) returns (MultiKeyResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/keys"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // Search over the keys to find one or more you're looking for.
  // This leverage the "body" parameter because we also have page and
  // per_page as url query param variables in this request.
  rpc DeleteKey (DeleteKeyRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/keys/{key_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // Add a key to an app.
  rpc PostKeys (PostKeysRequest) returns (MultiKeyResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/keys"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // Patch one or more keys.
  rpc PatchKeys (PatchKeysRequest) returns (MultiKeyResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/keys"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // API Keys in the public API -- request is itself Key authorized, and will tell
  // the user the scopes/access of the key/credential they're providing, as computed by
  // our authorizer:
  rpc MyScopes (MyScopesRequest) returns (MultiScopeResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/myscopes"
      additional_bindings124 {
        get: "/v2/myscopes"
      }
      additional_bindings125 {
        get: "/v2/my_scopes"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
  }

  rpc MyScopesUser (MyScopesUserRequest) returns (MultiScopeUserResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/myscopes"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  rpc MyScopesRoot (MyScopesRootRequest) returns (MultiScopeRootResponse) {
    option (google.api.http) = {
      get: "/v2/myscopesroot"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  // List all auth scopes available to me as a user.
  rpc ListScopes (ListScopesRequest) returns (MultiScopeDepsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/scopes"
    };
    option (clarifai.auth.util.cl_auth_type) = SessionTokenAuth;
  }

  // Get a specific app from an app.
  rpc GetApp (GetAppRequest) returns (SingleAppResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}"
      additional_bindings126 {
        get: "/v2/app"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // List all the apps.
  rpc ListApps (ListAppsRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps"
      additional_bindings127 {
        get: "/v2/apps"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Search over the apps to find one or more you're looking for.
  // This leverage the "body" parameter because we also have page and
  // per_page as url query param variables in this request.
  rpc DeleteApp (DeleteAppRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Add a app to an app.
  // This needs to load the default workflow to make a copy, validating all the models in it, and
  // then writing the new workflow back to this new app.
  rpc PostApps (PostAppsRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Add;
  }

  // Patch one or more apps.
  rpc PatchApps (PatchAppsRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // Allows to Patch only the below fields in one or more apps.
  // Allowed fields are notes, description and image
  rpc PatchAppsDetails(PatchAppsDetailsRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/partial"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // Patch apps ids.
  rpc PatchAppsIds (PatchAppsIdsRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/ids"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // Patch one app.
  rpc PatchApp (PatchAppRequest) returns (SingleAppResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }


  // Search over the applications to find one or more you're looking for.
  rpc PostAppsSearches (PostAppsSearchesRequest) returns (MultiAppResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/searches"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Get user information
  rpc GetUser (GetUserRequest) returns (SingleUserResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }














  // Validate new password in real-time for a user
  rpc PostValidatePassword (PostValidatePasswordRequest) returns (SinglePasswordValidationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/validate_password"
      body: "*"
      additional_bindings128 {
        post: "/v2/validate_password"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = SessionTokenAuth;
  }
















































  // Get a saved legacy search.
  rpc GetSearch (GetSearchRequest) returns (SingleSearchResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches/{id}"
      additional_bindings129 {
        get: "/v2/searches/{id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // List all saved legacy searches.
  rpc ListSearches (ListSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches"
      additional_bindings130 {
        get: "/v2/searches"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Patch saved legacy searches by ids.
  rpc PatchSearches (PatchSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches"
      body: "*"
      additional_bindings131 {
        patch: "/v2/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Execute a new search and optionally save it.
  //
  // Deprecated: Use PostInputsSearches or PostAnnotationsSearches instead.
  //  The server may refuse to accept requests to this endpoint.
  rpc PostSearches (PostSearchesRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches"
      body: "*"
      additional_bindings132 {
        post: "/v2/searches"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    // option (clarifai.auth.util.cl_depending_scopes) = Predict; // optional
    option (clarifai.auth.util.cl_depending_scopes) = Search;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get; // to know the concepts and models in your default workflow.
    option deprecated = true;
  }

  // Execute a previously saved legacy search.
  rpc PostSearchesByID (PostSearchesByIDRequest) returns (MultiSearchResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches/{id}"
      body: "*"
      additional_bindings133 {
        post: "/v2/searches/{id}"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Search;
  }

  // Delete a saved search.
  rpc DeleteSearch (DeleteSearchRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/searches/{id}"
      additional_bindings134 {
        delete: "/v2/searches/{id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Delete;
  }

  // List all the annotation filters.
  rpc ListAnnotationFilters (ListAnnotationFiltersRequest) returns (MultiAnnotationFilterResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_filters"
      additional_bindings135 {
        get: "/v2/annotation_filters"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Get a specific annotation filter.
  rpc GetAnnotationFilter (GetAnnotationFilterRequest) returns (SingleAnnotationFilterResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_filters/{annotation_filter_id}"
      additional_bindings136 {
        get: "/v2/annotation_filters/{annotation_filter_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
  }

  // Add annotation filters.
  rpc PostAnnotationFilters (PostAnnotationFiltersRequest) returns (MultiAnnotationFilterResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_filters"
      body: "*"
      additional_bindings137 {
        post: "/v2/annotation_filters"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
  }

  // Patch one or more annotation filters.
  rpc PatchAnnotationFilters (PatchAnnotationFiltersRequest) returns (MultiAnnotationFilterResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_filters"
      body: "*"
      additional_bindings138 {
        patch: "/v2/annotation_filters"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
  }

  // Delete one or more annotation filters in a single request.
  rpc DeleteAnnotationFilters (DeleteAnnotationFiltersRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/annotation_filters"
      body: "*"
      additional_bindings139 {
        delete: "/v2/annotation_filters"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Add;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Delete;
  }





























  // List all status codes.
  rpc ListStatusCodes (ListStatusCodesRequest) returns (MultiStatusCodeResponse) {
    option (google.api.http) = {
      get: "/v2/status_codes"
    };
    option (clarifai.auth.util.cl_auth_type) = NoAuth;
  }

  // Get more details for a status code.
  rpc GetStatusCode (GetStatusCodeRequest) returns (SingleStatusCodeResponse) {
    option (google.api.http) = {
      get: "/v2/status_codes/{status_code_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = NoAuth;
  }









  // owner list users who the app is shared with
  rpc ListCollaborators (ListCollaboratorsRequest) returns (MultiCollaboratorsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/collaborators"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
  }

  // add collaborators to an app.
  rpc PostCollaborators (PostCollaboratorsRequest) returns (MultiCollaboratorsResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/collaborators"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
  }

  // Patch existing collaborators.
  rpc PatchCollaborators (PatchCollaboratorsRequest) returns (MultiCollaboratorsResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/collaborators"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Delete;
  }

  // Delete existing collaborators.
  rpc DeleteCollaborators (DeleteCollaboratorsRequest) returns (clarifai.api.status.BaseResponse){
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/collaborators"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Delete;
  }

  // Collaboration includes the app user are invitied to work on
  rpc ListCollaborations (ListCollaborationsRequest) returns (MultiCollaborationsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/collaborations"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Collaborators_Get;
  }

  // Deprecated: App duplication is no longer supported.
  // PostAppDuplications starts async app duplication jobs which copy resources
  // (inputs, annotations, models etc) from one application to another.
  rpc PostAppDuplications (PostAppDuplicationsRequest) returns (MultiAppDuplicationsResponse) {
    option deprecated = true;
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/duplications"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // Deprecated: App duplication is no longer supported.
  // ListAppDuplications lists all app duplication jobs created by the user.
  rpc ListAppDuplications (ListAppDuplicationsRequest) returns (MultiAppDuplicationsResponse){
    option deprecated = true;
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/duplications"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  // Deprecated: App duplication is no longer supported.
  // GetAppDuplication returns an app duplication job created by the user.
  rpc GetAppDuplication (GetAppDuplicationRequest) returns (SingleAppDuplicationResponse) {
    option deprecated = true;
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/duplications/{app_duplication_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  // Add tasks to an app.
  rpc PostTasks (PostTasksRequest) returns (MultiTaskResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks"
      body: "*"
      additional_bindings140 {
        post: "/v2/tasks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Search;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // needed for converting workers internal ids to external ids
    // option (clarifai.auth.util.cl_depending_scopes) = Predict; // optional, needed for add_task_annotations.go when saved search uses visual search
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add; // needed for add_task_annotations.go
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get; // needed for add_task_annotations.go
  }

  // Task annotation count
  rpc GetTaskAnnotationCount (GetTaskCountRequest) returns (SingleTaskCountResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}/annotations/count"
      additional_bindings141 {
        get: "/v2/tasks/{task_id}/annotations/count"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
  }

  // Task Input count
  rpc GetTaskInputCount (GetTaskCountRequest) returns (SingleTaskCountResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}/inputs/count"
      additional_bindings142 {
        get: "/v2/tasks/{task_id}/inputs/count"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
  }

  // Get a specific task from an app.
  rpc GetTask (GetTaskRequest) returns (SingleTaskResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}"
      additional_bindings143 {
        get: "/v2/tasks/{task_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // needed for converting workers internal ids to external ids
  }

  // List tasks from an app.
  rpc ListTasks (ListTasksRequest) returns (MultiTaskResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks"
      additional_bindings144 {
        get: "/v2/tasks"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // needed for converting workers internal ids to external ids
  }

  // Patch one or more tasks.
  rpc PatchTasks (PatchTasksRequest) returns (MultiTaskResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks"
      body: "*"
      additional_bindings145 {
        patch: "/v2/tasks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // needed for converting workers internal ids to external ids
    // option (clarifai.auth.util.cl_depending_scopes) = Predict; // optional, needed for add_task_annotations.go when saved search uses visual search
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add; // needed for add_task_annotations.go
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get; // needed for add_task_annotations.go
  }

  // Delete multiple tasks in one request.
  rpc DeleteTasks (DeleteTasksRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks"
      body: "*"
      additional_bindings146 {
        delete: "/v2/tasks"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Delete;
  }




  ////////////////////////////////////////
  // Label Order
  ////////////////////////////////////////

  // Add Label orders.
  rpc PostLabelOrders (PostLabelOrdersRequest) returns (MultiLabelOrderResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/label_orders"
      body: "*"
      additional_bindings147 {
        post: "/v2/label_orders"
        body: "*"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = SavedSearch_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get; // needed for converting workers internal ids to external ids
  }

  // Get a label order.
  rpc GetLabelOrder (GetLabelOrderRequest) returns (SingleLabelOrderResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/label_orders/{label_order_id}"
      additional_bindings148 {
        get: "/v2/label_orders/{label_order_id}"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get; // needed because task is embedded
  }

  // List label orders.
  rpc ListLabelOrders (ListLabelOrdersRequest) returns (MultiLabelOrderResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/label_orders"
      additional_bindings149 {
        get: "/v2/label_orders"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get; // needed because task is embedded
  }

  // Patch one or more label orders.
  rpc PatchLabelOrders (PatchLabelOrdersRequest) returns (MultiLabelOrderResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/label_orders"
      body: "*"
      additional_bindings150 {
        patch: "/v2/label_orders"
        body: "*"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Delete;
  }

  // Delete multiple label orders in one request.
  // this do not change task status
  rpc DeleteLabelOrders (DeleteLabelOrdersRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/label_orders"
      body: "*"
      additional_bindings151 {
        delete: "/v2/label_orders"
        body: "*"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Get;
    option (clarifai.auth.util.cl_depending_scopes) = LabelOrders_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
  }











  // Perform bulk operations on a list of inputs based on input source.
  // Operation include add, update, delete of concepts, metadata and geo data.
  // This is an Asynchronous process. Use ListBulkOperations or GetBulkOperation to check the status.
  rpc PostBulkOperations (PostBulkOperationsRequest) returns (MultiBulkOperationsResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/bulk_operations"
      body: "*"
      additional_bindings152 {
        post: "/v2/bulk_operations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
  }

  // List all the bulk operations
  rpc ListBulkOperations (ListBulkOperationsRequest) returns (MultiBulkOperationsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/bulk_operations"
      additional_bindings153 {
        get: "/v2/bulk_operations"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Get;
  }

  // Get the bulk operation details by ID
  rpc GetBulkOperation (GetBulkOperationRequest) returns (SingleBulkOperationsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/bulk_operations/{id}"
      additional_bindings154 {
        get: "/v2/bulk_operations/{id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Get;
  }

  // Cancel one or more bulk operations
  rpc CancelBulkOperations (CancelBulkOperationRequest) returns (MultiBulkOperationsResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/bulk_operations"
      body: "*"
      additional_bindings155 {
        patch: "/v2/bulk_operations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Add;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Get;
  }

  // delete one or more terminated bulk operations
  rpc DeleteBulkOperations (DeleteBulkOperationRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/bulk_operations"
      body: "*"
      additional_bindings156 {
        delete: "/v2/bulk_operations"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Add;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Get;
    option (clarifai.auth.util.cl_depending_scopes) = BulkOperation_Delete;
  }

  // Deprecated: Use PutTaskAssignments with action=LABEL_START.
  //   This endpoint has initially been designed as a GET request,
  //   but has been re-designed to serve a PUT logic.
  //   In order to clearly highlight that this endpoint serves a PUT request,
  //   this endpoint has been deprecated and replaced by PutTaskAssignments with action=LABEL_START.
  rpc ListNextTaskAssignments (ListNextTaskAssignmentsRequest) returns (MultiInputResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}/assignments"
      additional_bindings157 {
        get: "/v2/tasks/{task_id}/assignments"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
  }

  // PutTaskAssignments performs an idempotent action for the task assignments in given task.
  // See PutTaskAssignmentsRequestAction for more details about possible actions.
  rpc PutTaskAssignments (PutTaskAssignmentsRequest) returns (MultiTaskAssignmentResponse) {
    option (google.api.http) = {
      put: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/tasks/{task_id}/assignments"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
  }


  // List all the inputs add jobs
  rpc ListInputsAddJobs (ListInputsAddJobsRequest) returns (MultiInputsAddJobResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/add"
      additional_bindings158 {
        get: "/v2/inputs/jobs/add"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Get the input add job details by ID
  rpc GetInputsAddJob (GetInputsAddJobRequest) returns (SingleInputsAddJobResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/add/{id}"
      additional_bindings159 {
        get: "/v2/inputs/jobs/add/{id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // cancel the input add job by ID
  rpc CancelInputsAddJob (CancelInputsAddJobRequest) returns (SingleInputsAddJobResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/add/{id}"
      body: "*"
      additional_bindings160 {
        patch: "/v2/inputs/jobs/add/{id}"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // PostUploads is used to upload files. Note that this does not create inputs.
  // returns job with uploadID, job has UPLOAD_IN_PROGRESS status
  // Actual upload content can be done in multiple calls with PutUploadContentParts
  // You can get status of upload with GetUpload or ListUploads endpoints
  // See also PostInputsUploads
  rpc PostUploads (PostUploadsRequest) returns (MultiUploadResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/uploads"
      body: "*"
      additional_bindings161 {
        post: "/v2/uploads"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
  }

  // Upload a part of a multipart upload.
  // Behaviour on completion depends on the endpoint that was used to initiate the upload.
  rpc PutUploadContentParts (PutUploadContentPartsRequest) returns (SingleUploadResponse) {
    option (google.api.http) = {
      put: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/uploads/{upload_id}/content_parts"
      additional_bindings162 {
        put: "/v2/uploads/{upload_id}/content_parts"
      }
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
  }

  rpc GetUpload (GetUploadRequest) returns (SingleUploadResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/uploads/{upload_id}"
      additional_bindings163 {
        get: "/v2/uploads/{upload_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
  }

  rpc ListUploads (ListUploadsRequest) returns (MultiUploadResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/uploads"
      additional_bindings164 {
        get: "/v2/uploads"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
  }

  rpc DeleteUploads (DeleteUploadsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/uploads"
      body: "*"
      additional_bindings165 {
        delete: "/v2/uploads"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Delete;
  }

  // Initiates retrieval of inputs from cloud storage from a user provided data source.
  // Will create and return an inputs-add-job for tracking progress.
  // Archives will be extracted and their contents will be processed as inputs.
  //
  // The cloud URL will be treated as a filter prefix. For example s3:/bucket/images_folder/abc will process
  // files in the images_folder beginning with abc or in a subfolder beginning with abc.
  // For example:
  // bucket/images_folder/abcImage.png
  // bucket/images_folder/abc-1/Data.zip
  //
  // If given URL is for a private bucket or file, then credentials should be provided to access the bucket.
  // Credentials should include rights to list the objects in the bucket, except when pointed directly at a file archive,
  // in which case it only requires rights to access that particular file.
  rpc PostInputsDataSources (PostInputsDataSourcesRequest) returns (MultiInputsAddJobResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/data_sources"
      body: "*"
      additional_bindings166 {
        post: "/v2/inputs/data_sources"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  // Get the input extraction job details by ID
  rpc GetInputsExtractionJob (GetInputsExtractionJobRequest) returns (SingleInputsExtractionJobResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/extraction/{inputs_extraction_job_id}"
      additional_bindings167 {
        get: "/v2/inputs/jobs/extraction/{inputs_extraction_job_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // List all the input extraction jobs
  rpc ListInputsExtractionJobs (ListInputsExtractionJobsRequest) returns (MultiInputsExtractionJobResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/extraction"
      additional_bindings168 {
        get: "/v2/inputs/jobs/extraction"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  rpc CancelInputsExtractionJobs (CancelInputsExtractionJobsRequest) returns (MultiInputsExtractionJobResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/jobs/extraction"
      body: "*"
      additional_bindings169 {
        patch: "/v2/inputs/jobs/extraction"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
  }

  // Create new upload job with a file archive containing inputs (images, videos, text, audio)
  // Actual file upload happens in next steps by calling `PutUploadContentParts` endpoint
  // and providing the file content in the request body.
  // This endpoint creates and return an inputs-add-job which contains an upload id needed for upload and further status tracking
  // Completing the upload will automatically begin unpacking the archive and uploading the contents as inputs.
  // See also GetInputsAddJob and then GetInputsExtractionJob
  rpc PostInputsUploads (PostInputsUploadsRequest) returns (MultiInputsAddJobResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/inputs/uploads"
      body: "*"
      additional_bindings170 {
        post: "/v2/inputs/uploads"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Annotations_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Inputs_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Uploads_Get;
  }

  // putting above the Get Nodepool endpoint to make it appear above the other one
  rpc ListPipelineVersionRuns(ListPipelineVersionRunsRequest) returns (MultiPipelineVersionRunResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs"
      additional_bindings171 {
        get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/pipeline_version_runs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  // Get a specific runner.
  // TODO(zeiler): runner_id is a UUID so can list globally as well.
  rpc GetRunner (GetRunnerRequest) returns (SingleRunnerResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners/{runner_id}"
      additional_bindings172 {
        get: "/v2/users/{user_app_id.user_id}/runners/{runner_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // List all the runners for the user.
  rpc ListRunners (ListRunnersRequest) returns (MultiRunnerResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners"
      additional_bindings173 {
        get: "/v2/users/{user_app_id.user_id}/runners"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
  }

  // Add a runners to a user.
  rpc PostRunners (PostRunnersRequest) returns (MultiRunnerResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  // Patch runners of a user.
  rpc PatchRunners (PatchRunnersRequest) returns (MultiRunnerResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  // Delete multiple runners in one request.
  rpc DeleteRunners (DeleteRunnersRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  // List items for the remote runner to work on.
  // since the runner_id is a UUID we can access it directly too.
  rpc ListRunnerItems (ListRunnerItemsRequest) returns (MultiRunnerItemResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners/{runner_id}/items"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = RunnerItems_Get;
  }

  // Post back outputs from remote runners
  // since the runner_id is a UUID we can access it directly too.
  rpc PostRunnerItemOutputs (PostRunnerItemOutputsRequest) returns (MultiRunnerItemOutputResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners/{runner_id}/items/{runner_item_id}/outputs"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = RunnerItems_Get;
    option (clarifai.auth.util.cl_depending_scopes) = RunnerItems_Add;
  }

  // This maintains a single request for asking the API if there is any work to be done, processing
  // it and streaming back results.
  // To do that first handshake the MultiRunnerItemOutputResponse will have RUNNER_STREAM_START
  // status filled in so that the API knows to respond with a MultiRunnerItemResponse.
  // For now there will only be one of those if the model prediction only has one request.
  // NOTE(zeiler): downside of this is you can't use HTTP REST requests to do runner work.
  rpc ProcessRunnerItems (stream PostRunnerItemOutputsRequest) returns (stream MultiRunnerItemResponse) {
    option (google.api.http) = {
      post: "/v2/runners/items/process"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = RunnerItems_Get;
    option (clarifai.auth.util.cl_depending_scopes) = RunnerItems_Add;
  }



  // Get the training time estimate based off train request and estimated input count.
  rpc PostModelVersionsTrainingTimeEstimate (PostModelVersionsTrainingTimeEstimateRequest) returns (MultiTrainingTimeEstimateResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/time_estimate"
      body: "*"
      additional_bindings174 {
        post: "/v2/models/{model_id}/versions/time_estimate"
        body: "*"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
  }


  // List Available Cloud Providers
  rpc ListCloudProviders (ListCloudProvidersRequest) returns (MultiCloudProviderResponse) {
    option (google.api.http) = {
      get: "/v2/cloud_providers"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  // List Regions for given Cloud Provider
  rpc ListCloudRegions (ListCloudRegionsRequest) returns (MultiCloudRegionResponse) {
    option (google.api.http) = {
      get: "/v2/cloud_providers/{cloud_provider.id}/regions"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
  }

  // Get InstanceTypes given Cloud Provider and Region
  rpc ListInstanceTypes (ListInstanceTypesRequest) returns (MultiInstanceTypeResponse) {
    option (google.api.http) = {
      get: "/v2/cloud_providers/{cloud_provider.id}/regions/{region}/instance_types"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
  }

  // ComputeCluster CRUD
  rpc GetComputeCluster (GetComputeClusterRequest) returns (SingleComputeClusterResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  rpc ListComputeClusters (ListComputeClustersRequest) returns (MultiComputeClusterResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters"
      additional_bindings175 {
        get: "/v2/compute_clusters"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  rpc PostComputeClusters (PostComputeClustersRequest) returns (MultiComputeClusterResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
  }

  // Delete multiple compute_clusters in one request.
  rpc DeleteComputeClusters (DeleteComputeClustersRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/compute_clusters"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Add;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Delete;
  }

  rpc PatchComputeClusters (PatchComputeClustersRequest) returns (MultiComputeClusterResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/compute_clusters"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Add;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Keys_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  // Nodepools CRUD
  rpc GetNodepool (GetNodepoolRequest) returns (SingleNodepoolResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  rpc ListNodepools (ListNodepoolsRequest) returns (MultiNodepoolResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools"
      additional_bindings176 {
        get: "/v2/users/{user_app_id.user_id}/nodepools"
      }
      additional_bindings177 {
        get: "/v2/nodepools"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
  }

  rpc PostNodepools (PostNodepoolsRequest) returns (MultiNodepoolResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  rpc PatchNodepools (PatchNodepoolsRequest) returns (MultiNodepoolResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Delete;
  }

  // Delete multiple nodepools in one request.
  rpc DeleteNodepools (DeleteNodepoolsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Delete;
  }

  // Update nodepool status. Called by the agent to report nodepool health/errors.
  rpc PostNodepoolStatus (PostNodepoolStatusRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/status"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Add;
  }

  // Deployments CRUD
  rpc GetDeployment (GetDeploymentRequest) returns (SingleDeploymentResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/deployments/{deployment_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  rpc ListDeployments (ListDeploymentsRequest) returns (MultiDeploymentResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/deployments"
      additional_bindings178 {
        get: "/v2/deployments"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  rpc PostDeployments (PostDeploymentsRequest) returns (MultiDeploymentResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/deployments"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  rpc PatchDeployments (PatchDeploymentsRequest) returns (MultiDeploymentResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/deployments"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = InstanceTypes_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  // Delete multiple deployments in one request.
  rpc DeleteDeployments (DeleteDeploymentsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/deployments"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Deployments_Delete;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  rpc PostAuditLogSearches (PostAuditLogSearchesRequest) returns (MultiAuditLogEntryResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/audit_log/searches"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = AuditLogs_Get;
  }

  rpc ListWorkflowEvaluationTemplates (ListWorkflowEvaluationTemplatesRequest) returns (MultiWorkflowEvaluationTemplateResponse) {
    option (google.api.http) = {
      get: "/v2/workflow-version-evaluation-templates"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
  }

  rpc PostLogEntries (PostLogEntriesRequest) returns (clarifai.api.status.BaseResponse) {
    // Note: http isn't used for posting log entries, but it's required for the proto file to compile.
    option (google.api.http) = {
      post: "/v2/log_entries"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  rpc ListLogEntries (ListLogEntriesRequest) returns (MultiLogEntryResponse) {
    option (google.api.http) = {
      // Endpoint to list runner logs.
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners/{runner_id}/{log_type}/logs"
      // Endpoint to list runner logs by model, model version id.
      additional_bindings179 {
        get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_user_id}/{compute_cluster_id}/nodepools/{nodepool_id}/versions/{model_version_id}/{log_type}/logs"
      }
      // TODO: add convenience endpoint for /users/{user_id}/runners/{runner_id}.
      // TODO: add endpoint for runner replicas.
      // Endpoint to list compute cluster's agent logs.
      additional_bindings180 {
        get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/{log_type}/logs"
      }
      // Endpoint to list builder logs.
      additional_bindings181 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/models/{model_id}/versions/{model_version_id}/{log_type}/logs"
      }

      // Endpoint to list pipeline version run logs
      additional_bindings182 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs/{pipeline_version_run_id}/{log_type}/logs"
      }
      // TODO: add endpoint for workflow.
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;

    option (clarifai.auth.util.cl_depending_scopes) = LogEntries_Get;
  }

  rpc StreamLogEntries (StreamLogEntriesRequest) returns (stream MultiLogEntryResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_id}/nodepools/{nodepool_id}/runners/{runner_id}/{log_type}/logs"
      additional_bindings183 {
        get: "/v2/users/{user_app_id.user_id}/compute_clusters/{compute_cluster_user_id}/{compute_cluster_id}/nodepools/{nodepool_id}/versions/{model_version_id}/{log_type}/logs"
      }
      // Endpoint to stream pipeline version run logs
      additional_bindings184 {
        get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs/{pipeline_version_run_id}/{log_type}/stream/logs"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = LogEntries_Get;
  }

  rpc PostComputePlaneMetrics (PostComputePlaneMetricsRequest) returns (clarifai.api.status.BaseResponse) {
    // Note: http isn't used for posting metrics, but it's required for the proto file to compile.
    option (google.api.http) = {
      post: "/v2/compute_plane_metrics"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
  }

  // Post task metrics from runner replicas.
  rpc PostRunnerReplicaTaskMetrics (PostRunnerReplicaTaskMetricsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/runner_replica_task_metrics"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Runners_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Tasks_Get;
  }

  rpc PostWorkflowVersionEvaluations (PostWorkflowVersionEvaluationsRequest) returns (MultiWorkflowVersionEvaluationResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Get;
  }

  rpc GetWorkflowVersionEvaluation (GetWorkflowVersionEvaluationRequest) returns (SingleWorkflowVersionEvaluationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations/{workflow_version_evaluation_id}"
      additional_bindings185 {
        get: "/v2/workflow-version-evaluations/{workflow_version_evaluation_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Get;
  }

  rpc ListWorkflowVersionEvaluations (ListWorkflowVersionEvaluationsRequest) returns (MultiWorkflowVersionEvaluationResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations"
      additional_bindings186 {
        get: "/v2/workflow-version-evaluations"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Get;
  }

  rpc PatchWorkflowVersionEvaluations (PatchWorkflowVersionEvaluationsRequest) returns (MultiWorkflowVersionEvaluationResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations"
      body: "*"
    };

    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Models_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Concepts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Predict;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Add;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Get;
  }

  rpc ListWorkflowVersionEvaluationData (ListWorkflowVersionEvaluationDataRequest) returns (MultiListWorkflowVersionEvaluationDataResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations/{workflow_version_evaluation_id}/data"
      additional_bindings187 {
        get: "/v2/workflow-version-evaluations/{workflow_version_evaluation_id}/data"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Get;
  }

  rpc PostWorkflowVersionEvaluationData (PostWorkflowVersionEvaluationDataRequest) returns (MultiListWorkflowVersionEvaluationDataResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/workflows/{workflow_id}/versions/{workflow_version_id}/evaluations/{workflow_version_evaluation_id}/data"
      body: "*"
      additional_bindings188 {
        post: "/v2/workflow-version-evaluations/{workflow_version_evaluation_id}/data"
        body: "*"
      }
    };

    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Datasets_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Workflows_Get;
    option (clarifai.auth.util.cl_depending_scopes) = WorkflowVersionEvaluations_Add;
  }

  rpc PostPipelines(PostPipelinesRequest) returns (MultiPipelineResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines"
      body: "*"
      additional_bindings189 {
        get: "/v2/pipelines"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
  }

  rpc GetPipeline(GetPipelineRequest) returns (SinglePipelineResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}"
      additional_bindings190 {
        get: "/v2/pipelines/{pipeline_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  rpc ListPipelines(ListPipelinesRequest) returns (MultiPipelineResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines"
      additional_bindings191 {
        get: "/v2/pipelines"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  rpc PatchPipelines(PatchPipelinesRequest) returns (MultiPipelineResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
  }

  rpc DeletePipelines(DeletePipelinesRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Delete;
  }

  rpc GetPipelineVersion(GetPipelineVersionRequest) returns (SinglePipelineVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}"
      additional_bindings192 {
        get: "/v2/pipelines/{pipeline_id}/versions/{pipeline_version_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  rpc ListPipelineVersions(ListPipelineVersionsRequest) returns (MultiPipelineVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions"
      additional_bindings193 {
        get: "/v2/pipelines/{pipeline_id}/versions"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  rpc PatchPipelineVersions(PatchPipelineVersionsRequest) returns (MultiPipelineVersionResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
  }

  rpc DeletePipelineVersions(DeletePipelineVersionsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Delete;
  }

  rpc GetPipelineVersionRun(GetPipelineVersionRunRequest) returns (SinglePipelineVersionRunResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs/{pipeline_version_run_id}"
      additional_bindings194 {
        get: "/v2/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs/{pipeline_version_run_id}"
      }
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
  }


  // TODO ListPipelineVersionRuns for listing all the runs of a given pipeline version.

  rpc PostPipelineVersionRuns(PostPipelineVersionRunsRequest) returns (MultiPipelineVersionRunResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Pull;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  rpc PatchPipelineVersionRuns(PatchPipelineVersionRunsRequest) returns (MultiPipelineVersionRunResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
  }

  rpc ListPipelineVersionRunStatusLogs(ListPipelineVersionRunStatusLogsRequest) returns (MultiPipelineVersionRunStatusLogResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipelines/{pipeline_id}/versions/{pipeline_version_id}/runs/{pipeline_version_run_id}/status_logs"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineVersionRunStatusLogs_Get;
  }


  rpc PostPipelineSteps(PostPipelineStepsRequest) returns (MultiPipelineStepResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Pull;
  }

  rpc GetPipelineStep(GetPipelineStepRequest) returns (SinglePipelineStepResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps/{pipeline_step_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
  }

  rpc ListPipelineSteps(ListPipelineStepsRequest) returns (MultiPipelineStepResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
  }

  // This is a streaming endpoint, the request has a field, upload_data, which can either be the config for the upload or the actual data to upload.
  // The config must be sent first before the pipeline_step_bytes can be uploaded.
  // Once the config has been sent, the server will respond with a confirmation containing the pipeline_step_version_id.
  // This is so that if your upload is interrupted, you can resume the upload by sending the config again with the pipeline_step_version_id specified for your pipeline_step_version.
  // The actual upload will be done via a multipart upload, the latest successful part_id will be sent from the server in the response to the pipeline_step_bytes.
  rpc PostPipelineStepVersionsUpload(stream PostPipelineStepVersionsUploadRequest) returns (stream PostPipelineStepVersionsUploadResponse) {
    option (google.api.http) = {
      post: "/v2/pipeline_step_versions/upload"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Pull;
  }

  rpc ListPipelineStepVersions(ListPipelineStepVersionsRequest) returns (MultiPipelineStepVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps/{pipeline_step_id}/versions"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
  }

  rpc GetPipelineStepVersion(GetPipelineStepVersionRequest) returns (SinglePipelineStepVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps/{pipeline_step_id}/versions/{pipeline_step_version_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
  }

  rpc DeletePipelineSteps(DeletePipelineStepsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Delete;
  }

  rpc DeletePipelineStepVersions(DeletePipelineStepVersionsRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_steps/{pipeline_step_id}/versions"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Delete;
  }

  // Lists pipeline templates, which are ready-to-use templates that can simply be run on demand.
  rpc ListPipelineTemplates(ListPipelineTemplatesRequest) returns (MultiPipelineTemplateResponse) {
    option (google.api.http) = {
      get: "/v2/pipeline_templates"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
  }

  // Creates a Pipeline, PipelineVersion, and PipelineVersionRun from a PipelineTemplate.
  // This is a convenience endpoint for users to quickly get started with running pipelines.
  rpc PostPipelineVersionRunFromTemplate(PostPipelineVersionRunFromTemplateRequest) returns (PostPipelineVersionRunFromTemplateResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/pipeline_templates/{pipeline_template_name}/pipeline_version_runs"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Pipelines_Add;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = PipelineSteps_Pull;
    option (clarifai.auth.util.cl_depending_scopes) = Nodepools_Get;
    option (clarifai.auth.util.cl_depending_scopes) = ComputeClusters_Get;
  }

  rpc PostArtifacts(PostArtifactsRequest) returns (MultiArtifactResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Add;
  }

  rpc GetArtifact(GetArtifactRequest) returns (SingleArtifactResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts/{artifact_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
  }

  rpc ListArtifacts(ListArtifactsRequest) returns (MultiArtifactResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
  }

  rpc DeleteArtifact(DeleteArtifactRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Delete;
  }

  // This is a streaming endpoint, the request has a field, upload_data, which can either be the config for the upload or the actual data to upload.
  // The config must be sent first before the artifact_bytes can be uploaded.
  // Once the config has been sent, the server will respond with a confirmation containing the artifact_version_id.
  // This is so that if your upload is interrupted, you can resume the upload by sending the config again with the artifact_version_id specified for your artifact_version.
  // The actual upload will be done via a multipart upload, the latest successful part_id will be sent from the server in the response to the artifact_bytes.
  rpc PostArtifactVersionsUpload(stream PostArtifactVersionsUploadRequest) returns (stream PostArtifactVersionsUploadResponse) {
    option (google.api.http) = {
      post: "/v2/artifact_versions/upload"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Add;
  }

  rpc ListArtifactVersions(ListArtifactVersionsRequest) returns (MultiArtifactVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts/{artifact_id}/versions"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
  }

  rpc GetArtifactVersion(GetArtifactVersionRequest) returns (SingleArtifactVersionResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts/{artifact_id}/versions/{artifact_version_id}"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
  }

  rpc DeleteArtifactVersion(DeleteArtifactVersionRequest) returns (clarifai.api.status.BaseResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/apps/{user_app_id.app_id}/artifacts/{artifact_id}/versions"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = KeyAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Apps_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Get;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Add;
    option (clarifai.auth.util.cl_depending_scopes) = Artifacts_Delete;
  }

  rpc GetSecret(GetSecretRequest) returns (SingleSecretResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/secrets/{id}"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Secrets_Get;
  }

  rpc ListSecrets(ListSecretsRequest) returns (MultiSecretResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/secrets"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Secrets_Get;
  }

  rpc PostSecrets(PostSecretsRequest) returns (MultiSecretResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/secrets"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Secrets_Add;
  }

  rpc PatchSecrets(PatchSecretsRequest) returns (MultiSecretResponse) {
    option (google.api.http) = {
      patch: "/v2/users/{user_app_id.user_id}/secrets"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Secrets_Add;
  }

  rpc DeleteSecrets(DeleteSecretsRequest) returns (MultiSecretResponse) {
    option (google.api.http) = {
      delete: "/v2/users/{user_app_id.user_id}/secrets"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = Secrets_Delete;
  }

  rpc PostMetricsQuery(PostMetricsQueryRequest) returns (MetricsQueryResponse) {
    option (google.api.http) = {
      post: "/v2/users/{user_app_id.user_id}/metrics"
      body: "*"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = UserMetrics_Get;
  }

  rpc ListMetricLabels(ListMetricLabelsRequest) returns (MultiMetricLabelsResponse) {
    option (google.api.http) = {
      get: "/v2/users/{user_app_id.user_id}/metrics/labels"
    };
    option (clarifai.auth.util.cl_auth_type) = PATAuth;
    option (clarifai.auth.util.cl_depending_scopes) = UserMetrics_Get;
  }









}


// Split the results into pages.
message Pagination {
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks. Defaults to 1.
  uint32 page = 1;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults to 128.
  uint32 per_page = 2;
}

// GetAnnotationRequest
message GetAnnotationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string annotation_id = 2;
  string input_id = 3;
}

// ListAnnotationsRequest
message ListAnnotationsRequest {
  reserved 4;

  clarifai.api.UserAppIDSet user_app_id = 1;

  // List annotations for these IDs
  repeated string ids = 2;

  // List annotations for these Input IDs
  // Note that 'ids' are optional but if the are provided the number and order in
  // 'ids' and 'input_ids' should match
  // If you do not specify 'ids' all the annotations for 'input_ids' are returned
  // If a you do not specify both 'input_ids' and 'ids' all the annotations in the app are returned
  repeated string input_ids = 3;

  // Only return the annotations that has one of these user IDs, effectively operating as an
  // OR among them to filter down the results.
  // If model_version_ids or workflow_version_ids are also provided, these user_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) annotations in the results of ListAnnotations request.
  // Setting user_ids does also set list_all_annotations=True.
  repeated string user_ids = 9;

  // Only return the annotations that has one of these model version IDs, effectively operating as an
  // OR among them to filter down the results.
  // If user_ids or workflow_version_ids are also provided, these model_version_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) annotations in the results of ListAnnotations request.
  // Setting model_version_ids does also set list_all_annotations=True.
  repeated string model_version_ids = 10;

  // Only return the annotations that has one of these workflow version IDs, effectively operating as an
  // OR among them to filter down the results.
  // If user_ids or model_version_ids are also provided, these workflow_version_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) annotations in the results of ListAnnotations request.
  // Setting workflow_version_ids does also set list_all_annotations=True.
  repeated string workflow_version_ids = 13;

  // Set status to filter by a list of statuses
  // If not statuses are provided then annotations with any status will be returned.
  repeated clarifai.api.status.Status statuses = 5;

  // Set this flag to list both trusted and not trusted annotations
  // by default it's listing only trusted annotations
  bool list_all_annotations = 6;

  // Set this flag to return the model output for model annotations in the response.
  bool return_model_output = 12;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 7;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 8;
  // Flag to filter annotations by task_id
  string task_id = 11;
}

// ListVideoTrackAnnotationsRequest
message PostTrackAnnotationsSearchesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The input ID containing the video track annotations to list
  string input_id = 2;

  // Filter annotations by track_id
  string track_id = 3;

  // Filter annotations starting from this frame number (inclusive)
  uint32 frame_number_start = 4;

  // Filter annotations starting from this time in milliseconds (inclusive)
  uint64 frame_time_start = 5;

  // Filter by annotation type (e.g., "bounding_box", "point", "mask")
  AnnotationDataType annotation_type = 6;

  // Maximum number of frames to return (default and max: 60)
  uint32 max_frames = 7;

  // Maximum duration in milliseconds to return (default and max: 3000)
  uint64 max_duration = 8;

  // Filtering by model version ID within a worker (optional).
  // Point annotations don't need filtering by worker.
  // For non-point types, a model version ID must be provided.
  Worker worker = 9;
}

// StreamAnnotationsRequest
message StreamAnnotationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The input ID containing the annotations to stream
  string input_id = 2;

  // Filter annotations by track_ids (optional - omit to stream all tracks for the input).
  // This is useful for historical playback where you want to stream all annotations in a time range.
  repeated string track_ids = 3;

  // Filter annotations starting from this frame number (inclusive)
  uint32 frame_number_start = 4;

  // Filter annotations starting from this time in milliseconds (inclusive)
  uint64 frame_time_start = 5;

  // Filter by annotation type (e.g., "bounding_box", "point", "mask")
  AnnotationDataType annotation_type = 6;

  // Maximum number of frames to return. Returns annotations from frames in range [frame_number_start, frame_number_start + max_frames - 1] (inclusive on both ends).
  // For example: frame_number_start=5, max_frames=3 returns frames 5, 6, and 7.
  // Default and max: 216000 frames (60 minutes at 60 FPS)
  uint32 max_frames = 7;

  // Maximum duration in milliseconds to return. Returns annotations from time range [frame_time_start, frame_time_start + max_duration - 1] (inclusive on both ends).
  // Default and max: 3600000 ms (60 minutes)
  uint64 max_duration = 8;

  // Filtering by model version ID within a worker (optional).
  // Point annotations don't need filtering by worker.
  // For non-point types, a model version ID must be provided.
  Worker worker = 9;

  // Optional minimum prediction confidence threshold (0.0 to 1.0).
  // When set (> 0), only annotations with at least one concept (tag) having
  // metadata.prediction_score >= this value are returned.
  // When unset (0), all annotations are returned (backwards compatible).
  float min_prediction_score = 10;
}

// StreamLivestreamAnnotationsRequest
// Streams live annotations from Redis as they are being created by the runner
message StreamLivestreamAnnotationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The input ID containing the video being processed
  string input_id = 2;

  // Optional minimum prediction confidence threshold (0.0 to 1.0).
  // When set (> 0), only annotations with at least one concept (tag) having
  // metadata.prediction_score >= this value are streamed.
  // When unset (0), all annotations are streamed (backwards compatible).
  float min_prediction_score = 3;
}

// PostAnnotationsRequest
message PostAnnotationsRequest {

  clarifai.api.UserAppIDSet user_app_id = 1;

  repeated Annotation annotations = 2;
}

// PatchAnnotationsRequest
message PatchAnnotationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  repeated Annotation annotations = 2;

  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 3;

  // If the request is a "remove" action and the annotation is left with empty data,
  // then setting delete_if_empty_data to true will delete the annotation,
  // if possible (for example, will not delete an input-level annotation).
  bool delete_if_empty_data = 4;
}

// PatchAnnotationsStatusRequest
message PatchAnnotationsStatusRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Filter by user IDs
  repeated string user_ids = 3;
  // Filter by task ID
  string task_id = 4;
  // Filter by Status codes
  repeated clarifai.api.status.StatusCode status_codes = 6;

  // 'overwrite' is supported
  string action = 5;

  // Update filtered annotations to this status
  clarifai.api.status.StatusCode status_code = 2;
}

// PatchAnnotationsStatusResponse
message PatchAnnotationsStatusResponse {
  clarifai.api.status.Status status = 1;
  repeated string user_ids = 2;
  uint32 updated_count = 3;
}

// DeleteAnnotationRequest
message DeleteAnnotationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string input_id = 2;

  string annotation_id = 3;
}

// Request to delete several things by the list of ids.
message DeleteAnnotationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Delete annotations with IDs
  repeated string ids = 2;

  // Delete annotations for these Input IDs
  // Note that 'ids' are optional but if the are provided the number and order in
  // 'ids' and 'input_ids' should match
  // If you do not specifiy 'ids' all the annotations for 'input_ids' are deleted
  // However you need to specify at least one value for 'input_ids'
  // i.e. this API does not support deleting all annotations
  repeated string input_ids = 3;
}

// ListAnnotationTracksRequest
message ListAnnotationTracksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
  string input_id = 3;
  uint32 page = 4;
  uint32 per_page = 5;
}

// PostAnnotationTracksRequest
message PostAnnotationTracksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated AnnotationTrack annotation_tracks = 2;
  string input_id = 3;
}

// PatchAnnotationTracksRequest
message PatchAnnotationTracksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated AnnotationTrack annotation_tracks = 2;
  string input_id = 3;

  // Use always 'overwrite'
  string action = 4;
}

// DeleteAnnotationTracksRequest
message DeleteAnnotationTracksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
  string input_id = 3;
}

// MultiAnnotationTrackResponse
message MultiAnnotationTrackResponse {
  clarifai.api.status.Status status = 1;
  repeated AnnotationTrack annotation_tracks = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleAnnotationResponse
message SingleAnnotationResponse {
  clarifai.api.status.Status status = 1;
  Annotation annotation = 2;
}

// SingleStreamAnnotationResponse similar to SingleAnnotationResponse but with an extra field
message SingleStreamAnnotationResponse {
  clarifai.api.status.Status status = 1;
  Annotation annotation = 2;

  // Indicates if this frame has been fully processed
  // Needed in case client needs to decide whether to stop and wait for more data or continue playback
  bool frame_fully_processed = 3 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// MultiAnnotationResponse
message MultiAnnotationResponse {
  clarifai.api.status.Status status = 1;

  repeated Annotation annotations = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// ListAnnotationWorkersRequest
message ListAnnotationWorkersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // (optional URL parameter) List of additional fields to be included in the response.
  // Currently supported: all, names
  repeated string additional_fields = 4;

  // (optional URL parameter) Only list workers that have created trusted annotations.
  bool trusted_only = 5;
}

// MultiWorkerResponse
message MultiWorkerResponse {
  clarifai.api.status.Status status = 1;

  repeated Worker workers = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// GetAppRequest
message GetAppRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars, counts
  repeated string additional_fields = 2;
}

// ListAppsRequest
message ListAppsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars, counts
  repeated string additional_fields = 10;

  // Sorting options:
  // Whether to sort in ascending order. If false, will order in descending order.
  bool sort_ascending = 5;
  oneof sort_by {
    // Whether to order by the name.
    bool sort_by_name = 6;
    // Whether to order by the modified_at time.
    // If none of the sort options is set to true, will sort by modified_at.
    bool sort_by_modified_at = 7;
    // Whether to order by the created_at time.
    bool sort_by_created_at = 12;
    // Whether to order by the number of users stared the app
    bool sort_by_star_count = 13;
    // Whether to order by the id
    bool sort_by_id = 17;
    // Whether to order by search query relevance. Can only be used if search is not empty.
    bool sort_by_relevance = 19;
  }

  // Filtering options:
  // If true, we only return apps that are handpicked by clarifai staff
  bool featured_only = 9;
  // If true, we only return apps that are starred by the requesting user
  bool starred_only = 11;
  // If true, we only return apps that are marked as a template by the app owner.
  bool template_only = 16;
  // Filter by visibility of the app. If set, only return apps with the specified visibility.
  Visibility visibility = 18;

  // Searching options:
  // Specify a search parameter in order to perform keyword search on the
  // following fields of the application:
  //   - id
  //   - name
  //   - description
  //   - notes
  //   - user_id (unless user_app_id.user_id is already set)
  //
  // Keywords are both normalized for search (so searching for "satisfy" matches "satisfied")
  // and used for partial prefix-matching (so searching for "clari" matches "clarifai").
  //
  // NOTE: Both the list of fields searched and the exact keyword matching
  // rules are subject to change and not guaranteed to be backwards-compatible.
  string search = 15;
  // Query various text fields (id, name, description, and notes) that can contain the words in the query string
  // Deprecated: use search instead.
  string query = 8 [deprecated = true];
  // Filter by the id, name and notes of the app. This supports wilcard queries like "gen*" to match "general" as an example.
  // Deprecated: use search instead.
  string name = 4 [deprecated = true];
  // Filter by the user-unique-id of the app. This supports wilcard queries like "gen*" to match "general" as an example.
  // Deprecated: use search instead.
  string id = 14 [deprecated = true];
}

// PostAppsRequest
message PostAppsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated App apps = 2;
}

// DeleteAppRequest
message DeleteAppRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// PatchAppsRequest
message PatchAppsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated App apps = 2;

  // The action to perform on the patched App objects except App.Metadata
  // Supported values: 'overwrite' and 'remove'.
  //
  // Note that 'remove' can only be used to remove the app image by setting
  // 'image.url' in the request to the current value returned for that app.
  string action = 3;

  // The action to perform on the patched App.Metadata
  clarifai.api.PatchAction metadata_action = 4;

  // If set, the app will be automatically reindexed upon change of its base workflow.
  bool reindex = 5;
}

message PatchAppsDetailsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated App apps = 2;

  // The action to perform on the patched App objects
  // Supported values: 'overwrite' and 'remove'.
  //
  // Note that 'remove' can only be used to remove the app image by setting
  // 'image.url' in the request to the current value returned for that app.
  string action = 3;
}

// PatchAppRequest
message PatchAppRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  App app = 2;

  // The action to perform on the patched App object except App.Metadata
  // Supported values: 'overwrite' and 'remove'.
  //
  // Note that 'remove' can only be used to remove the app image by setting
  // 'image.url' in the request to the current value returned for the app.
  string action = 3;

  // The action to perform on the patched App.Metadata
  clarifai.api.PatchAction metadata_action = 4;

  // If set, the app will be automatically reindexed upon change of its base workflow.
  bool reindex = 5;
}


// PatchAppsIdsRequest
message PatchAppsIdsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Array containing 1 entry
  repeated IdUpdateSource ids = 3;

  // The action to perform on the patched objects
  // Only 'overwrite' is supported
  string action = 4;
}

// Search over the available applications.
message PostAppsSearchesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The body of the request.
  AppQuery app_query = 2;
  // Pagination parameters here since there are no url args in this
  // POST request.
  Pagination pagination = 3;
}

// SingleAppResponse
message SingleAppResponse {
  clarifai.api.status.Status status = 1;
  App app = 2;
}

// MultiAppResponse
message MultiAppResponse {
  clarifai.api.status.Status status = 1;
  repeated App apps = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// ListCollaboratorsRequest
message ListCollaboratorsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Set this flag to list both deleted and not deleted collaborators
  // by default it's listing only not deleted collaborators
  bool list_all_collaborators = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

// PostCollaboratorsRequest
message PostCollaboratorsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Collaborator collaborators = 2;
}

// PatchCollaboratorsRequest
message PatchCollaboratorsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Collaborator collaborators = 2;

  // The action to perform on the patched objects
  // For now only action 'overwrite' is supported
  string action = 3;
}

// DeleteCollaboratorsRequest
message DeleteCollaboratorsRequest{
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string collaborator_ids = 2;
  repeated string user_emails = 3;
}

// MultiCollaboratorsResponse
message MultiCollaboratorsResponse {
  clarifai.api.status.Status status = 1;
  repeated Collaborator collaborators = 2 [(clarifai.api.utils.cl_show_if_empty) = true];

  // The owner of the application.
  //
  // When listing users that have access to the application, i.e. collaborators,
  // it is often relevant to also include the application owner, so return
  // their information here for convenience.
  //
  // Note: app_owner is only returned by ListCollaborators and only if the
  // owner is a regular user, not an organization.
  User app_owner = 3;
}

// ListCollaborationsRequest
message ListCollaborationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // Filtering options:
  // If true, we only return collaborations on apps that are marked as a template by the app owner.
  bool template_only = 4;
}

// MultiCollaborationsResponse
message MultiCollaborationsResponse {
  clarifai.api.status.Status status = 1;
  repeated Collaboration collaborations = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}






































// GetStatusCodeRequest
message GetStatusCodeRequest {
  string status_code_id = 1;
}

// ListStatusCodesRequest
message ListStatusCodesRequest {
}

// SingleStatusCodeResponse
message SingleStatusCodeResponse {
  // Status of this request.
  clarifai.api.status.Status status = 1;
}

// MultiStatusCodeResponse
message MultiStatusCodeResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.status.Status statuses = 2;
}

// GetConceptRequest
message GetConceptRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The concept's id.
  string concept_id = 2;
}

// ListConceptsRequest
message ListConceptsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
  // Fuzzy match on concept ID
  string id = 4;
}

// ListModelConceptsRequest
message ListModelConceptsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Model id
  string model_id = 2;
  // Model version Id. Optional, if not provided latest model version is used.
  string version_id = 3;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;

  // Searching options:
  // Specify a search parameter in order to perform keyword search on the
  // following fields of the concept:
  //   - id
  //   - name
  //
  // Keywords are used for partial prefix-matching (so searching for "larif" matches "clarifai").
  //
  // NOTE: Both the list of fields searched and the exact keyword matching
  // rules are subject to change and not guaranteed to be backwards-compatible.
  string search = 6;
}

// PostConceptsSearchesRequest
message PostConceptsSearchesRequest {
  // Ids present in the url of the request.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The body of the request.
  ConceptQuery concept_query = 2;

  // Request additional info to be retrieved for each concept in the response.
  ConceptExtraInfoRequest extra_info = 4;

  // Pagination parameters here since there are no url args in this
  // POST request.
  Pagination pagination = 3;
}

message ConceptExtraInfoRequest {
  // Determine if the concept is searchable by rank using this model.
  // Currently, only embedder models are supported.
  // ########## Supported fields ##########
  // - app_id
  // - id
  // - model_version.id
  // - user_id
  Model rankable_model = 1;
}

// PostConceptsRequest
message PostConceptsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The concepts to add.
  repeated Concept concepts = 2;
}

// PatchConceptsRequest
message PatchConceptsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The concepts to patch.
  repeated Concept concepts = 2;

  // The action to perform on the patched objects
  // For now ony action 'overwrite' is supported
  string action = 3;
}

// GetConceptCountsRequest
message GetConceptCountsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// SingleConceptResponse
message SingleConceptResponse {
  // The response status.
  clarifai.api.status.Status status = 1;
  // The returned concept.
  Concept concept = 2;
}

// MultiConceptResponse
message MultiConceptResponse {
  // The response status.
  clarifai.api.status.Status status = 1;
  // The returned concepts.
  repeated Concept concepts = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// MultiConceptCountResponse
message MultiConceptCountResponse {
  // The response status.
  clarifai.api.status.Status status = 1;
  // The returned concept counts.
  repeated ConceptCount concept_counts = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// GET all relations such that the concept_id refers to the subject of the relation
message ListConceptRelationsRequest {
  // The user_id and app_id information.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The subject concept id in your app to get all the relationships for.
  // Leave as an empty string (GET /concepts/relations) to list ALL the relations in the app.
  //
  // When listing all the relations it will only return one direction of the relationship
  // with the predicate acting on the subject and not the inverse like is done when providing a
  // concept_id so that we can return a reliable page size always.
  //
  // When providing a concept_id, if a hyponym is present in the DB such as:
  // 'honey' (subject), 'hyponym' (predicate for "is a kind of"), 'food' (object)
  // then you can list the concept relations for 'honey' and get hyponym predicate with 'food'
  // object.
  // But you can also list the concept relations for 'food' and it will return the same hyponym
  // relationship with 'honey' as object and 'hypernym' as predicate.
  // Synonyms by nature are symmetrical relationships so either side can be the concept_id (subject)
  // when listing the relations.
  string concept_id = 2;
  // If predicate is provided then only list relations with that predicate.
  //
  // Note that if no subject is set in concept_id and predicate is set to
  // 'hypernym', then it will return any stored hyponyms as hypernyms with
  // just the subject and object swapped since they are reversed relations.
  //
  // Valid predicates are:
  // - 'hypernym'
  // - 'hyponym'
  // - 'synonym'
  string predicate = 3;
  // If knowledge_graph_id is provided then just list relations from that knowledge graph.
  // If not provided then list relations from all knowledge graphs including the global one for this
  // app one (ie. knowledge_graph "") and any specific ones in the app.
  string knowledge_graph_id = 4;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 5;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 6;
}

// POST new concept relations
message PostConceptRelationsRequest {
  // The user_id and app_id information.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The subject concept id you're going to add relations for.
  string concept_id = 2;
  // The relationships you're going to add.
  repeated ConceptRelation concept_relations = 3;
}

// DELETE concept relations
message DeleteConceptRelationsRequest {
  // The user_id and app_id information.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The concept to delete relationship for.
  string concept_id = 2;
  // The concept relationship ids to delete.
  repeated string ids = 3;
}

// GET all knowledge graphs
message ListKnowledgeGraphsRequest {
  // The user_id and app_id information.
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// POST new knowledge graphs
message PostKnowledgeGraphsRequest {
  // The user_id and app_id information.
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated KnowledgeGraph knowledge_graphs = 2;
}




// MultiConceptRelationResponse
message MultiConceptRelationResponse {
  // The response status.
  clarifai.api.status.Status status = 1;
  // The returned concept relations.
  repeated ConceptRelation concept_relations = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}


// MultiKnowledgeGraphResponse
message MultiKnowledgeGraphResponse {
  // The response status.
  clarifai.api.status.Status status = 1;
  // The returned knowledge graphs.
  repeated KnowledgeGraph knowledge_graphs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}



// GET single concept language for the given concept.
message GetConceptLanguageRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string concept_id = 2;
  // This is the language identifier.
  string language = 3;
}

// List multiple concept languages for the given concept.
message ListConceptLanguagesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string concept_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

// PATCH multiple concept languages for the given concept.
message PatchConceptLanguagesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string concept_id = 2;
  repeated ConceptLanguage concept_languages = 3;
  // The action to perform with the objects in the PATCH.
  string action = 4;
}



// // DELETE multiple concept languages for the given concept.
// message DeleteConceptLanguageRequest {
//   clarifai.api.UserAppIDSet user_app_id = 1;
//   string concept_id = 2;
//   // The language code to delete.
//   string language = 3;
// }

// // DELETE multiple concept languages for the given concept.
// message DeleteConceptLanguagesRequest {
//   clarifai.api.UserAppIDSet user_app_id = 1;
//   string concept_id = 2;
//   // The language code(s) to delete.
//   string ids = 3;
//   bool delete_all = 4;
// }

// POST multiple concept languages for the given concept.
message PostConceptLanguagesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string concept_id = 2;
  repeated ConceptLanguage concept_languages = 3;
}

// SingleConceptLanguageResponse
message SingleConceptLanguageResponse {
  clarifai.api.status.Status status = 1;
  ConceptLanguage concept_language = 2;
}

// MultiConceptLanguageResponse
message MultiConceptLanguageResponse {
  clarifai.api.status.Status status = 1;
  repeated ConceptLanguage concept_languages = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}






// GetInputRequest
message GetInputRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string input_id = 2;
}// GetInputRequest
message GetVideoManifestRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string input_id = 2;
}

// GetInputSamplesRequest
message GetInputSamplesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string task_id = 2;
  // URL param. If zero ids provided, returns for all task labelers
  repeated string user_ids = 3;
}

// ListInputsRequest
message ListInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // Set status to filter by status
  clarifai.api.status.Status status = 5;

  repeated string ids = 4;
}

// StreamInputsRequest
message StreamInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 20.
  uint32 per_page = 2;
  string last_id = 3;

  // By default, the endpoint return inputs by the time when it is added.
  // If this is set to true, we will return inputs by id.
  bool order_by_id = 5;
  bool descending = 4;
}

// PostInputsRequest
message PostInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of inputs to post.
  // For each input, the following fields are used:
  // * id
  // * data
  // * dataset_ids
  repeated Input inputs = 2;

  // Collect statistics about created inputs in job with given ID.
  // * If job ID is empty, then job is not created.
  // * If job ID is non-empty and doesn't already exist, then a new job will be created with given ID.
  // * If job ID does already exist, then new inputs statistics are merged with previous inputs statistics.
  string inputs_add_job_id = 3;

  // How to handle input ID conflicts.
  InputIDConflictResolution input_id_conflict_resolution = 4;
}




// PatchInputsRequest
message PatchInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of inputs to patch.
  // Inputs are identified by id field.
  // For each input, the following fields are patchable:
  // * data
  repeated Input inputs = 2;

  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 3;
}

// DeleteInputRequest
message DeleteInputRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string input_id = 2;
}

// Request to delete several things by the list of ids.
message DeleteInputsRequest {
  reserved 3;

  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
}

// SingleInputResponse
message SingleInputResponse {
  clarifai.api.status.Status status = 1;
  Input input = 2;
}

message GetVideoManifestResponse {
  clarifai.api.status.Status status = 1;

  // MPEG-dash manifest as data-URI, base64-encoded
  // Can be empty if status is FAILED
  // Can be fallback manifest if status is MIXED_STATUS
  string manifest_url = 2;
}

// MultiInputResponse
message MultiInputResponse {

  clarifai.api.status.Status status = 1;
  repeated Input inputs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];

  InputsAddJob inputs_add_job = 3;
}

// MultiInputAnnotationResponse
message MultiInputAnnotationResponse {

  clarifai.api.status.Status status = 1;
  repeated Hit hits = 3 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleInputCountResponse
message SingleInputCountResponse {
  clarifai.api.status.Status status = 1;

  InputCount counts = 2;
}

// GetInputCountRequest
message GetInputCountRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// ListDatasetsRequest
message ListDatasetsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  repeated string additional_fields = 5;

  // Sorting options:
  // Whether to sort in ascending order. If false, will order in descending order.
  bool sort_ascending = 6;
  oneof sort_by {
    // Whether to order by the created_at time.
    bool sort_by_created_at = 7;
    // Whether to order by the number of users stared the app
    bool sort_by_star_count = 8;
    // If neither sort option is set to true, will sort by modified_at.
    bool sort_by_modified_at = 9;
    // Whether to order by the external id
    bool sort_by_id = 11;
    // Whether to order by search query relevance. Can only be used if search is not empty.
    bool sort_by_relevance = 14;
  }

  // Filtering options:
  bool starred_only = 4;
  // Filter datasets by bookmark. If set, only return bookmarked datasets. Otherwise none bookmarked datasets only.
  bool bookmark = 10;

  // Searching options:
  // Specify a search parameter in order to perform keyword search on the
  // following fields of the dataset:
  //   - id
  //   - description
  //   - notes
  //   - user_id (unless user_app_id.user_id is already set)
  //
  // Keywords are both normalized for search (so searching for "satisfy" matches "satisfied")
  // and used for partial prefix-matching (so searching for "clari" matches "clarifai").
  //
  // NOTE: Both the list of fields searched and the exact keyword matching
  // rules are subject to change and not guaranteed to be backwards-compatible.
  string search = 13;
  // Fuzzy filter on dataset ID
  // Deprecated: use search instead.
  string id = 12 [deprecated = true];
}

// GetDatasetRequest
message GetDatasetRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;
  repeated string additional_fields = 3;
}

// Request to add one or more datasets.
message PostDatasetsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of datasets that are requested to be added.
  repeated Dataset datasets = 2;
}

// Request to patch several datasets.
message PatchDatasetsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of datasets that are requested to be updated.
  repeated Dataset datasets = 2;

  // The action to perform on the patched objects
  // Supported values: 'overwrite', 'merge', and 'remove'.
  //
  // Note that 'remove' can only be used to remove the dataset image by setting
  // 'image.url' in the request to the current value returned for that dataset.
  string action = 3;
}

// Request to delete several datasets by list of ids.
message DeleteDatasetsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string dataset_ids = 2;
}

// MultiDatasetResponse
message MultiDatasetResponse {
  clarifai.api.status.Status status = 1;
  repeated Dataset datasets = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleDatasetResponse
message SingleDatasetResponse {
  clarifai.api.status.Status status = 1;
  Dataset dataset = 2;
}

// ListDatasetInputsRequest
message ListDatasetInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Identify dataset by id.
  string dataset_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

// GetDatasetInputRequest
message GetDatasetInputRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // Identify dataset input by id.
  string input_id = 3;
}

// Request to add one or more datasets.
message PostDatasetInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // List of inputs that are requested to be added to this dataset.
  // Identify each input by id field. All other inputs fields are ignored.
  repeated DatasetInput dataset_inputs = 3;

  // Query to search inputs to be added to this dataset.
  Search search = 4;
}

// Request to delete several dataset inputs by list of ids.
message DeleteDatasetInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // Specify which inputs to delete from dataset.
  repeated string input_ids = 3;
}

// MultiDatasetInputResponse
message MultiDatasetInputResponse {
  reserved 3;
  clarifai.api.status.Status status = 1;
  repeated DatasetInput dataset_inputs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
  BulkOperation bulk_operation = 4;
}

// SingleDatasetInputResponse
message SingleDatasetInputResponse {
  clarifai.api.status.Status status = 1;
  DatasetInput dataset_input = 2;
}

// ListDatasetVersionsRequest
message ListDatasetVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;

  // (optional URL parameter) Filter by origin of dataset version
  repeated DatasetVersionRequestOrigin request_origins = 5;
}

// GetDatasetVersionRequest
message GetDatasetVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // Identify dataset version by id.
  string dataset_version_id = 3;
}

// ListDatasetVersionMetricsGroupsRequest
message ListDatasetVersionMetricsGroupsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // Identify dataset version by id.
  string dataset_version_id = 3;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;

  // Filter by parent path. Multiple parent paths are OR-ed. Empty list results in no filter.
  repeated string parent_paths = 6;

  // Filter by parent type. Multiple types are OR-ed. Empty list results in no filter.
  repeated DatasetVersionMetricsGroupType types = 7;

  // Filter by value. Multiple values are OR-ed. Empty list results in no filter.
  repeated google.protobuf.Value values = 8;
}

// Request to add one or more dataset versions.
message PostDatasetVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // List of dataset versions that are requested to be added.
  repeated DatasetVersion dataset_versions = 3;
}

// Request to patch several dataset versions.
message PatchDatasetVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // List of dataset versions that are requested to be updated.
  repeated DatasetVersion dataset_versions = 3;

  // The action to perform on the patched objects
  // For now, only 'overwrite' action is supported
  string action = 4;
}

// Request to delete several dataset versions by list of ids.
message DeleteDatasetVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  repeated string dataset_version_ids = 3;
}

// Request to create exports of a dataset version.
message PutDatasetVersionExportsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify dataset by id.
  string dataset_id = 2;

  // Identify dataset version by id.
  string dataset_version_id = 3;

  // exports is the list of requested dataset version exports.
  // Only setting the 'format' field of the export is supported.
  repeated DatasetVersionExport exports = 4;
}

message MultiDatasetVersionResponse {
  clarifai.api.status.Status status = 1;
  repeated DatasetVersion dataset_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message MultiDatasetVersionExportResponse {
  clarifai.api.status.Status status = 1;
  repeated DatasetVersionExport exports = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message MultiDatasetVersionMetricsGroupResponse {
  clarifai.api.status.Status status = 1;
  repeated DatasetVersionMetricsGroup dataset_version_metrics_groups = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message SingleDatasetVersionResponse {
  clarifai.api.status.Status status = 1;
  DatasetVersion dataset_version = 2;
}

////////////////////////////////////////////////////
// Model prediction related stuff needs inputs and produces outputs.
////////////////////////////////////////////////////
// Model prediction.
message PostModelOutputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
  repeated Input inputs = 4;
  // This allows you to specify config options for the model such as
  // the language which appear's in the model's output_info.
  Model model = 5;

  // Allow filtering of prediction requests down to specific Nodepools, Deployments or Runners
  RunnerSelector runner_selector = 6;

  // Configure the prediction cache to avoid expensive compute for predict requests
  bool use_predict_cache = 7;

  // Configuration to provide logs summarization when request errors out
  bool enable_log_summary_on_error = 8;
}

// Listing the inputs that went into training this model.
message ListModelInputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;
}

message PostComputePlaneMetricsRequest {
  // List of ComputePlaneMetrics.
  repeated ComputePlaneMetrics compute_plane_metrics = 1;
}

message PostRunnerReplicaTaskMetricsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of task metrics reported by runner replicas.
  repeated RunnerReplicaTaskMetrics runner_replica_task_metrics = 2;
}

message PostLogEntriesRequest {
  // List of log entries to be stored.
  repeated LogEntry log_entries = 1;
}

message ListLogEntriesRequest {
  reserved 8;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to last page.
  uint32 page = 1;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 32.
  uint32 per_page = 2;

  // The type of log entry. Choose from [agent, builder, builder.events, runner, runner.events, pipeline.version.run]
  string log_type = 3;

  // Who the logs are for.
  // The user app id, if a user produced the logs.
  clarifai.api.UserAppIDSet user_app_id = 4;
  // The Model ID, if a model produced the logs.
  string model_id = 5;
  // The Version ID, if a model version produced the logs.
  string model_version_id = 6;
  // Workflow Id, if a workflow produced the logs.
  string workflow_id = 7;

  // Where the logs came from.
  string compute_cluster_user_id = 17;
  string compute_cluster_id = 9;
  string nodepool_id = 10;
  string runner_id = 11;

  // Pipelines that produced the logs for a given pipeline run with log_type: pipeline.version.run
  // Must include user_app_id with user_id and app_id as well.
  string pipeline_id = 12;
  string pipeline_version_id = 13;
  string pipeline_version_run_id = 14;

  // During pipeline step build provide these IDs.
  string pipeline_step_id = 15;
  string pipeline_step_version_id = 16;
}

message StreamLogEntriesRequest {
  // The type of log entry. Examples: model, agent, build, training.
  string log_type = 1;

  // Who the logs are for.
  // The user app id, if a user produced the logs.
  clarifai.api.UserAppIDSet user_app_id = 2;
  // For models if you set log_type to "builder" then you get the model build logs.
  // The Model ID, if a model produced the logs.
  string model_id = 3;
  // The Version ID, if a model version produced the logs.
  string model_version_id = 4;
  // Workflow Id, if a workflow produced the logs.
  string workflow_id = 5;

  // Where the logs came from.
  string compute_cluster_user_id = 17;
  string compute_cluster_id = 6;
  string nodepool_id = 7;
  string runner_id = 8;

  // Pipelines that produced the logs with log_type: pipeline.version.run
  // Must include user_app_id with user_id and app_id as well.
  string pipeline_id = 12;
  string pipeline_version_id = 13;
  string pipeline_version_run_id = 14;

  // During pipeline step build provide these IDs with log_type: builder
  // Must include user_app_id with user_id and app_id as well.
  string pipeline_step_id = 15;
  string pipeline_step_version_id = 16;
}

// GetKeyRequest
message GetKeyRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string key_id = 2;
}

// ListKeysRequest
message ListKeysRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // Filtering options:
  // If true, only return keys that have not expired.
  bool not_expired = 4;
  // Only return keys that have the listed scopes.
  repeated string scopes = 5;
  // Only return keys that have the listed endpoints.
  repeated string endpoints = 6;
  // Only return keys with the listed type.
  string type = 7;
}

// ListAppKeysRequest
message ListAppKeysRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// PostKeysRequest
message PostKeysRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Key keys = 2;
}

// DeleteKeyRequest
message DeleteKeyRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string key_id = 2;
}

// PatchKeysRequest
message PatchKeysRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Key keys = 2;

  // The action to perform on the patched objects
  // For now only action 'overwrite' is supported
  string action = 3;
}

// SingleKeyResponse
message SingleKeyResponse {
  clarifai.api.status.Status status = 1;
  Key key = 2;
}

// MultiKeyResponse
message MultiKeyResponse {
  clarifai.api.status.Status status = 1;
  repeated Key keys = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}



// GetModelRequest
message GetModelRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  // This is included so that we can re-use this request for multiple
  // rpcs with and without the version_id.
  string version_id = 3;
  string language = 4;
  bool trained_before = 5;
  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars, outputs, presets
  repeated string additional_fields = 19;
}

// ListModelsRequest
message ListModelsRequest {
  reserved 4, 32;
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars, outputs, presets, counts
  repeated string additional_fields = 19;
  // If true, show replica counts for models.
  bool show_replicas = 34;

  // Sorting options:
  // Whether to sort in ascending order. If false, will order in descending order.
  bool sort_ascending = 10;
  oneof sort_by {
    // Whether to order by the name
    bool sort_by_name = 11;
    // Whether to order by the number of training inputs
    bool sort_by_num_inputs = 12;
    // Whether to order by the modified_at time of the latest model version.
    // If none of the sort options is set to true, will sort by modified_at.
    bool sort_by_modified_at = 13;
    // Whether to order by the created_at
    bool sort_by_created_at = 24;
    // Whether to order by count of stars
    bool sort_by_star_count = 25;
    // Whether to order by search query relevance. Can only be used if search is not empty.
    bool sort_by_relevance = 36;
  }

  // Filtering options:
  // Filter models by the specific model_type_id. See ListModelTypes for the list of ModelType.Id's
  // supported.
  string model_type_id = 6;
  // If true, we only return models that have the status MODEL_TRAINED, which includes non-trainable model types.
  bool trained_only = 7;
  // The list of input fields to the model.
  // For example, you can specify 'image', which will return models that make inferences on images like visual-classifier models.
  repeated string input_fields = 8;
  // The list of output fields to the model.
  // For example, you can specify 'regions[...].data.concepts', which will return visual-detector models.
  repeated string output_fields = 9;
  // Filter by the license of the model version
  string license = 15;
  // If true, we only return models that are handpicked by clarifai staff
  bool featured_only = 16;
  // If true, we only return models that are starred by the requesting user
  bool starred_only = 20;
  // List of toolkit tags to filter by
  repeated string toolkits = 17;
  // List of use_case tags to filter by
  repeated string use_cases = 18;
  // List of language tags to filter by
  repeated string languages = 21;
  // Old API behavior resulted in returning clarifai main models when calling ListModels while scoped to an app. While we transition
  // away from that, we can use this flag to not always fetch clarifai main models, unless that is the app we are explicitly listing for.
  bool dont_fetch_from_main = 23 [deprecated = true]; // @exclude TODO (EAGLE-4447): Remove this field
  // Filter models by bookmark. If set, only return bookmarked models. Otherwise none bookmarked models only.
  // Note: you can not filter `trained_only` and bookmark at the same time.
  // When filter by bookmark, we will return trained and untrained models.
  bool bookmark = 26;
  // Filter by the model version ids. If set, only return the model of these versions.
  repeated string model_version_ids = 28;
  // Filter by LicenseType
  LicenseType license_type = 29;
  // Filter by Source
  uint32 source = 30;
  // Filter by Creator
  string creator = 31;
  // Filter by model versions runners with replicas >= min_replicas.
  uint32 min_replicas = 33;
  // Filter by visibility of the model. If set, only return models with the specified visibility.
  Visibility visibility = 35;

  // Searching options:
  // Specify a search parameter in order to perform keyword search on the
  // following fields of the model:
  //   - id
  //   - name
  //   - description
  //   - notes
  //   - user_id (unless user_app_id.user_id is already set)
  //
  // Keywords are both normalized for search (so searching for "satisfy" matches "satisfied")
  // and used for partial prefix-matching (so searching for "clari" matches "clarifai").
  //
  // NOTE: Both the list of fields searched and the exact keyword matching
  // rules are subject to change and not guaranteed to be backwards-compatible.
  string search = 27;
  // Query name, description and id fields, that can contain the words in the query string. Does NOT support wildcards - full words only. Supports operators "OR" and "-" as NOT.
  // Deprecated: use search instead.
  string query = 14 [deprecated = true];
  // Filter by the description and id of the model. This supports wildcard queries like "gen*" to match "general" as an example.
  // Deprecated: use search instead.
  string name = 5 [deprecated = true];
  // Extends the name filter to include the user_id of the application owner that the model belongs to.
  // Deprecated: use search instead of name.
  bool filter_by_user_id = 22 [deprecated = true];
}

// ResourceCountRequest
message GetResourceCountsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// ResourceCountResponse
message GetResourceCountsResponse {
  reserved 5;
  clarifai.api.status.Status status = 1;
  int64 datasets = 2;
  int64 models = 3;
  int64 workflows = 4;
  int64 inputs = 6;
  int64 pipelines = 7;
}

message PatchModelToolkitsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string model_id = 2;

  repeated string toolkits = 3;
  //overwrite supported
  string action = 4;
}

// PatchModelCheckConsentsRequest
message PatchModelCheckConsentsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // the model id
  string model_id = 2;
  // the consents
  repeated string check_consents = 3;
  //overwrite supported
  string action = 4;
}

message PatchModelUseCasesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string model_id = 2;

  repeated string usecases = 3;
  //overwrite supported
  string action = 4;
}

message PatchModelLanguagesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string model_id = 2;

  repeated string languages = 3;
  // Only overwrite supported
  string action = 4;
}



message MultiModelToolkitResponse {
  clarifai.api.status.Status status = 1;
  repeated string toolkits = 2;
}

message MultiModelCheckConsentResponse {
  clarifai.api.status.Status status = 1;
  repeated string check_consents = 2;
}

message MultiModelUseCaseResponse {
  clarifai.api.status.Status status = 1;
  repeated string usecases = 2;
}

message MultiModelLanguageResponse {
  clarifai.api.status.Status status = 1;
  repeated string languages = 2;
}

// PostModelsRequest
message PostModelsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // NOTE: inconsistent since "model" is not plural, please use "models" below.
  // Previously you could only create one model at a time.
  // We still support this but you should pass it as models=[model] so
  // that this endpoint is consistent with the rest of our API.
  Model model = 2 [deprecated = true];
  // This allows you to create one or more model by posting it to the API.
  repeated Model models = 3;
}

// PatchModelsRequest
message PatchModelsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Model models = 2;

  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  //
  // Note that 'remove' can be used to remove the model image by setting
  // 'image.url' in the request to the current value returned for that model.
  // This cannot be used in a request that is patching other fields as well.
  string action = 3;
}

message IdUpdateSource {
  //old id
  string id = 1;
  //new id
  string new_id = 2;
}

// PatchModelIdsRequest
message PatchModelIdsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Array containing 1 entry
  repeated IdUpdateSource ids = 3;

  // The action to perform on the patched objects
  // Only 'overwrite' is supported
  string action = 4;
}

// DeleteModelRequest
message DeleteModelRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
}

// Request to delete several things by the list of ids.
message DeleteModelsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
  bool delete_all = 3;
}

// Search over the available models.
message PostModelsSearchesRequest {
  // Ids present in the url of the request.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The body of the request.
  ModelQuery model_query = 2;
  // Pagination parameters here since there are no url args in this
  // POST request.
  Pagination pagination = 3;
}

// SingleModelResponse
message SingleModelResponse {
  reserved 3;
  clarifai.api.status.Status status = 1;
  Model model = 2;
  int32 workflow_count = 4;
}

// MultiModelResponse
message MultiModelResponse {
  clarifai.api.status.Status status = 1;
  repeated Model models = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// PatchModelVersionsRequest
message PatchModelVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  repeated ModelVersion model_versions = 3;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 4;
}

// request for different endpoints currently.
message GetModelVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
}

// ListModelVersionsRequest
message ListModelVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;

  // Filtering options:
  // To list only the model versions that have these concept ids present in them.
  repeated string concept_ids = 5;
  // To list only the model versions that have been trained.
  bool trained_only = 6;
  // Filter by model versions runners with replicas >= min_replicas.
  uint32 min_replicas = 12;

  // Sorting options:
  // Whether to sort in ascending order. If false, will order in descending order.
  bool sort_ascending = 7;
  oneof sort_by {
    // Whether to order by the status code
    bool sort_by_status_code = 8;
    // Whether to order by the number of training inputs
    bool sort_by_num_inputs = 9;
    // Whether to sort by the description
    bool sort_by_description = 10;
    // Whether to order by the created_at time
    // If neither sort option is set to true, will sort by created_at.
    bool sort_by_created_at = 11;
  }
}

// DeleteModelVersionRequest
message DeleteModelVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 3;
  string version_id = 4;
}

// SingleModelVersionResponse
message SingleModelVersionResponse {
  clarifai.api.status.Status status = 1;
  ModelVersion model_version = 2;
}

// MultiModelVersionResponse
message MultiModelVersionResponse {
  clarifai.api.status.Status status = 1;
  repeated ModelVersion model_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Create (train) a new model version.
message PostModelVersionsRequest {
  reserved 4, 5, 6, 7, 9;
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;

  repeated ModelVersion model_versions = 3;

  // Description about this training run
  string description = 8;

  // When evaluate_after_training set to true, we will do evaluation immediately after training finishes.
  // We will merge this with default_eval_info.
  EvalInfo eval_info = 10;
  // When set to true, we will convert the model into a containerized model after training.
  bool do_migration = 11;
}

message PostModelVersionsUploadRequest {
  oneof upload_data {
    PostModelVersionsUploadConfig upload_config = 1;
    UploadContentPart content_part = 2;
  }
}

message PostModelVersionsUploadResponse {
  clarifai.api.status.Status status = 1;
  uint64 bytes_remaining = 2;
  // ID of the model version being uploaded
  string model_version_id = 3;
}

message PostModelVersionsUploadConfig {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Model to create version for
  string model_id = 2;
  // Specification for the model version to be uploaded
  ModelVersion model_version = 3;
  // Number of bytes in the model files to be uploaded
  uint64 total_size = 4;
  // Whether the uploaded package will be a .tar.gz which contains a Dockerfile or the standard .zip
  bool is_v3 = 5;
  // Number of bytes requested for the build process.
  uint64 storage_request_size = 6;
}

// PutModelVersionExportsRequest
message PutModelVersionExportsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
}

// GetModelVersionExportRequest
message GetModelVersionExportRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
}

// SingleModelVersionExportResponse
message SingleModelVersionExportResponse {
  clarifai.api.status.Status status = 1;
  ModelVersionExport export = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message PostWorkflowVersionsUnPublishRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  repeated WorkflowVersionUnPublishRequest publications = 3;
}



message PostWorkflowVersionsPublishRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  repeated WorkflowVersionPublishRequest publications = 3;
}

message WorkflowVersionPublishRequest {
  string version_id = 1;
}

message WorkflowVersionUnPublishRequest {
  string version_id = 1;
}

// ModelVersionPublishRequest
message ModelVersionPublishRequest {
  string version_id = 1;
}

// PostModelVersionsPublishRequest
message PostModelVersionsPublishRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  repeated ModelVersionPublishRequest publications = 3;
}

// ModelVersionUnpublishRequest
message ModelVersionUnpublishRequest {
  string version_id = 1;
}

// PostModelVersionsUnPublishRequest
message PostModelVersionsUnPublishRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  repeated ModelVersionUnpublishRequest publications = 3;
}

// Evaluate this model vesion
message PostEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // eval_info, id, model, and ground_truth_dataset will be used when creating the evaluation
  // If no dataset is provided, all app data that is annotated with concepts from the model will be used.
  repeated EvalMetrics eval_metrics = 2;
}

message ListEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
  // If true, sort in ascending order, otherwise sort in descending order.
  bool sort_ascending = 4;
  oneof sort_by {
    // Whether to order by application id
    bool sort_by_app_id = 5;
    // Whether to order by eval metric summary.macro_avg_roc_auc
    bool sort_by_roc_auc = 6;
    // Whether to order by eval metric summary.f1
    bool sort_by_f1 = 7;
    // Whether to order by when the metric was created
    bool sort_by_created_at = 8;
    // Whether to order by eval metric summary.mean_avg_precision_iou_50
    bool sort_by_mean_avg_precision = 9;
    // Whether to order by eval metric summary.macro_avg_precision
    bool sort_by_precision = 10;
    // Whether to order by eval metric summary.macro_avg_recall
    bool sort_by_recall = 11;
    bool sort_by_model_id = 16;
    bool sort_by_eval_dataset_id = 17;
    bool sort_by_train_dataset_id = 18;
  }
  // Filter on model type id
  string model_type_id = 12;
  // Filter on dataset ID of the dataset version specified in the metric version
  repeated string eval_dataset_ids = 13;
  // Filter on dataset ID of the dataset version specified by the model version
  repeated string train_dataset_ids = 14;
  // Filter on concept IDs specified in the modele version's output_info
  repeated string concept_ids = 15;
  // Whether to show failed metrics, defaults to false
  bool show_failed_metrics = 19;
}

message GetEvaluationRequest{
  clarifai.api.UserAppIDSet user_app_id = 1;
  string evaluation_id = 2;
  // Any of the fields you wish to return in the metrics
  // By default, only the summary is returned.
  FieldsValue fields = 3;
}



// Evaluate this model vesion
message PostModelVersionEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string model_version_id = 3;
  // EvalInfo and ID will be used when creating the evaluation
  repeated EvalMetrics eval_metrics = 4;
}

message ListModelVersionEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string model_version_id = 3;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;
}

message GetModelVersionEvaluationRequest{
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string model_version_id = 3;
  string evaluation_id = 4;

  // Any of the fields you wish to return from multiclass_metrics
  // By default, only the summary is returned.
  FieldsValue fields = 5;
}

message SingleEvalMetricsResponse {
  clarifai.api.status.Status status = 1;
  EvalMetrics eval_metrics = 2;
}

message MultiEvalMetricsResponse {
  clarifai.api.status.Status status = 1;
  repeated EvalMetrics eval_metrics = 2;
}

// Evaluate this model version.
message PostModelVersionMetricsRequest {
  reserved 4;
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;

  // Use this to filter inputs that are used in evaluation
  clarifai.api.Search test_search = 5;

  // evaluation info. Such as dataset used for evaluation.
  EvalInfo eval_info = 10;
}

// Get the already computed evaluation metrics for this model
// version.
message GetModelVersionMetricsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;

  // Any of the fields you wish to return from multiclass_metrics
  // By default, only the summary will be returned
  FieldsValue fields = 4;
}




// // Request to delete several things by the list of ids.
// message DeleteModelVersionsRequest {
//   clarifai.api.UserAppIDSet user_app_id = 1;
//   repeated string ids = 2;
//   bool delete_all = 3;
// }

// GetModelTypeRequest
message GetModelTypeRequest {
  // use and app combo. Not really used for this endpoint at this time so may go away in future.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The specific ModelType.Id you want to retrieve.
  string model_type_id = 2;
}

// ListModelTypesRequest
message ListModelTypesRequest {
  // use and app combo. Not really used for this endpoint at this time so may go away in future.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// ListOpenSourceLicensesRequest
message ListOpenSourceLicensesRequest {}

// ListOpenSourceLicensesResponse
message ListOpenSourceLicensesResponse {
  clarifai.api.status.Status status = 1;
  repeated string licenses = 2;
}

// SingleModelTypeResponse
message SingleModelTypeResponse {
  // Status of the response.
  clarifai.api.status.Status status = 1;
  // The retrieved ModelType object. .
  ModelType model_type = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// MultiModelTypeResponse
message MultiModelTypeResponse {
  // Status of the response.
  clarifai.api.status.Status status = 1;
  // List of ModelType objects.
  repeated ModelType model_types = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
  // List of model importers
  ModelTypeField model_importers = 3;
  // Triton model envs that can be used for model upload
  repeated TritonCondaEnvInfo triton_conda_envs_info = 4;
}

// GetModelVersionInputExampleRequest
message GetModelVersionInputExampleRequest {
  // authorization field  (contains app/user id info)
  clarifai.api.UserAppIDSet user_app_id = 1;
  // id of model the example belongs to
  string model_id = 2;
  // specific version the example belongs to
  string model_version_id = 3;
  // Id of example to fetch
  string example_id = 4;
}

// ListModelVersionInputExamplesRequest
message ListModelVersionInputExamplesRequest {
  // authorization field  (contains app/user id info)
  clarifai.api.UserAppIDSet user_app_id = 1;
  // id of model the example belongs to
  string model_id = 2;
  // specific version the example belongs to
  string model_version_id = 3;
  // Optional, defaults to 1.
  uint32 page = 4;
  // Optional, defaults to 128 references per page.
  uint32 per_page = 5;
}



// SingleModelVersionInputExampleResponse
message SingleModelVersionInputExampleResponse {
  // status of response
  clarifai.api.status.Status status = 1;
  // model input example message
  ModelVersionInputExample model_version_input_example = 2;
}

// MultiModelVersionInputExampleResponse
message MultiModelVersionInputExampleResponse {
  // status of response
  clarifai.api.status.Status status = 1;
  // model input example messages
  repeated ModelVersionInputExample model_version_input_examples = 2;
}

// ListModelReferencesRequest
message ListModelReferencesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string model_id = 2;
  // Optional, defaults to 1.
  uint32 page = 3;
  // Optional, defaults to 128 references per page.
  uint32 per_page = 4;
}



// MultiModelReferenceResponse
message MultiModelReferenceResponse {
  clarifai.api.status.Status status = 1;
  repeated ModelReference model_references = 2;
}

// MultiOutputResponse
message MultiOutputResponse {
  clarifai.api.status.Status status = 1;
  // For each input processed during model prediction we create one output.
  repeated Output outputs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
  // Information on where the computation is executed down to specific Deployment, Nodepool and ComputeCluster
  RunnerSelector runner_selector = 3;
}// MultiLogEntryResponse
message MultiLogEntryResponse {
  clarifai.api.status.Status status = 1;
  // Log entries.
  repeated LogEntry log_entries = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
  // The page the log entries are from. If the request's page was omitted or greater than the total pages, then this is set to the last page.
  uint32 page = 4;
  // The number of results contained in each page.
  uint32 per_page = 5;
}

// ListScopesRequest
message ListScopesRequest {
  // If "personal_access_token" include scopes and endpoints available to personal access tokens.
  // If "app_specific_key" include scopes and endpoints available to app-specific keys. (default)
  string key_type = 1;

  // For all user specific information we include user_app_id to get the user_id in a consistent way
  clarifai.api.UserAppIDSet user_app_id = 2;
}

// MyScopesRequest
message MyScopesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// MyScopesUserRequest
message MyScopesUserRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
}

// MyScopesRootRequest
message MyScopesRootRequest {
}

// MultiScopeDepsResponse
message MultiScopeDepsResponse {
  // The status of the request.
  clarifai.api.status.Status status = 1;
  // scopes is a list of low-level scopes and their dependencies.
  repeated ScopeDeps scope_deps = 2;
  // endpoint_scopes is a listof all the publicly available endponts which can be
  // used as scopes as well. A call to each of those endpoint depends on a subset
  // of the above "scopes"
  repeated EndpointDeps endpoint_deps = 3;
}

// MultiScopeResponse
message MultiScopeResponse {
  // The status of the request.
  clarifai.api.status.Status status = 1;
  // This is a list of the scopes that your key has.
  repeated string scopes = 2;
  // The app that the key has access to.
  App app = 3;
  // This is a list of endpoint permissions that your key has.
  repeated string endpoints = 4;
  string user_feature_flags = 5;
}

// MultiScopeUserResponse
message MultiScopeUserResponse {
  // The status of the request.
  clarifai.api.status.Status status = 1;
  // This is a list of the scopes that your key has.
  repeated string scopes = 2;
  // This is a list of endpoint permissions that your key has.
  repeated string endpoints = 4;
  string user_feature_flags = 5;
}

// MultiScopeRootResponse
message MultiScopeRootResponse {
  // The status of the request.
  clarifai.api.status.Status status = 1;
  // This is a list of the scopes that your key has.
  repeated string scopes = 2;
  // This is a list of endpoint permissions that your key has.
  repeated string endpoints = 4;
  string user_feature_flags = 5;
}

// GetSearchRequest
message GetSearchRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string id = 2;
}

// ListSearchesRequest
message ListSearchesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// PostSearchesRequest
message PostSearchesRequest {
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The query; this specifies how the data to be searched
  // this will be replaced by "Searches"
  Query query = 2 [deprecated = true];

  // The searched to be executed or saved
  // Eventually the request level fields will be deprecated in favor of this object
  repeated Search searches = 3;

  // Pagination information to paginate through search result Hits.
  Pagination pagination = 4;
}

message PatchInputsSearchesRequest{
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The searches to be patched
  repeated Search searches = 2;

  // The action to perform on the patched Search objects
  // For now only action 'overwrite' is supported
  string action = 3;
}

message PatchAnnotationsSearchesRequest {
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The searches to be patched
  repeated Search searches = 2;

  // The action to perform on the patched Search objects
  // For now only action 'overwrite' is supported
  string action = 3;
}

// PatchSearchesRequest
message PatchSearchesRequest {
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The searches to be patched
  repeated Search searches = 2;

  // The action to perform on the patched Search objects
  // For now only action 'overwrite' is supported
  string action = 3;
}

// PostSearchesByIDRequest performs returns results of a saved search given its ID
message PostSearchesByIDRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // ID for saves search to be executed
  string id = 2;

  // Pagination information to paginate through search result Hits.
  Pagination pagination = 3;
}

// DeleteSearchRequest
message DeleteSearchRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string id = 2;
}



// Execute a new annotation search and optionally save it
// annotation search over annotations using rank and filter proto
message PostAnnotationsSearchesRequest {
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The searched to be executed or saved
  repeated Search searches = 2;

  // Pagination information to paginate through search result Hits.
  Pagination pagination = 3;
}

// Execute a new input search and optionally save it
message PostInputsSearchesRequest {
  // The user_id and app_id to query from.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The searched to be executed or saved
  repeated Search searches = 2;

  // Pagination information to paginate through search result Hits.
  Pagination pagination = 3;

  // If only_count is set, then the response will not contain hits,
  // but hit_counts instead.
  bool only_count = 4;
}

// SingleSearchResponse returns saved search in response to GetSearchRequest
message SingleSearchResponse {
  // Status of whether the search was successful.
  clarifai.api.status.Status status = 1;
  Search search = 5;
}

// MultiSearchResponse
message MultiSearchResponse {
  // Status of whether the search was successful.
  clarifai.api.status.Status status = 1;

  // A unique id which uniquely identifies a search
  string id = 2;

  // The list of search result Hits.
  repeated Hit hits = 3 [(clarifai.api.utils.cl_show_if_empty) = true];

  // The original query provided in the request.
  Query query = 4;

  // The original Searches provided in the request.
  repeated Search searches = 5;

  // The counts of hits for each search, in the same order as searches.
  // Only returned if the request set only_count.
  repeated HitCount hit_counts = 6;
}

// ListAnnotationFiltersRequest
message ListAnnotationFiltersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// GetAnnotationFilterRequest
message GetAnnotationFilterRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Identify annotation filter by id.
  string annotation_filter_id = 2;
}

// Request to add one or more annotation filters.
message PostAnnotationFiltersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of annotation filters that are requested to be added.
  repeated AnnotationFilter annotation_filters = 2;
}

// Request to patch several annotation filters.
message PatchAnnotationFiltersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List of annotation filters that are requested to be updated.
  repeated AnnotationFilter annotation_filters = 2;

  // The action to perform on the patched objects
  // For now, only 'overwrite' action is supported
  string action = 3;
}

// Request to delete several annotation filters by list of ids.
message DeleteAnnotationFiltersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Specify which filters to delete.
  repeated string annotation_filter_ids = 2;
}

// MultiAnnotationFilterResponse
message MultiAnnotationFilterResponse {
  clarifai.api.status.Status status = 1;

  repeated AnnotationFilter annotation_filters = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleAnnotationFilterResponse
message SingleAnnotationFilterResponse {
  clarifai.api.status.Status status = 1;

  AnnotationFilter annotation_filter = 2;
}
























// GetUserRequest
message GetUserRequest {
  // we used to have user_id but moved to the standard convention. Since this endpoint
  // hasn't been exposed and only used by portal as a url this won't effect anything external.
  clarifai.api.UserAppIDSet user_app_id = 1;

  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars
  repeated string additional_fields = 2;
}



// SingleUserResponse
message SingleUserResponse {
  clarifai.api.status.Status status = 1;
  User user = 2;
}


















// PostValidatePasswordRequest
message PostValidatePasswordRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // password to be validated
  Password password = 2;
}

// SinglePasswordValidationResponse
message SinglePasswordValidationResponse {
  // Standard clarifai status code
  clarifai.api.status.Status status = 1;
  PasswordViolations password_violations = 2;
}


























enum OrganizationInvitationStatus {
  NOT_SET = 0;
  PENDING = 1;
  ACCEPTED = 2;
  CANCELLED = 3;
  DECLINED = 4;
  EXPIRED = 5;
}























































// GetWorkflowRequest
message GetWorkflowRequest {
  reserved 3, 5;
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Workflow ID to retrieve
  // If no ID is specified we return default workflow of the application
  // If an ID is specified by default we first looks into Clarifai workflows for a Workflow ID
  string workflow_id = 2;
  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars
  repeated string additional_fields = 4;
}

// ListWorkflowsRequest
message ListWorkflowsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;

  // (optional URL parameter) List of additional fields to be included in the response. Currently supported: all, stars
  repeated string additional_fields = 10;

  // Sorting options:
  // Whether to sort in ascending order. If false, will order in descending order.
  bool sort_ascending = 5;
  oneof sort_by {
    // Whether to order by the name
    bool sort_by_id = 6;
    // Whether to order by the modified_at time.
    // If none of the sort options is set to true, will sort by modified_at.
    bool sort_by_modified_at = 7;
    // Whether to order by the created_at time.
    bool sort_by_created_at = 13;
    // Whether to order by the number of users stared the workflow
    bool sort_by_star_count = 14;
    // Whether to order by search query relevance. Can only be used if search is not empty.
    bool sort_by_relevance = 18;
  }

  // Filtering options:
  // If true, we only return workflows that are handpicked by clarifai staff
  bool featured_only = 9;
  // If true, we only return workflows that are starred by the requesting user
  bool starred_only = 11;
  // Filter workflows by bookmark. If set, only return bookmarked workflows. Otherwise none bookmarked workflows only.
  bool bookmark = 15;
  // Filter by visibility of the workflow. If set, only return workflows with the specified visibility.
  Visibility visibility = 17;

  // Searching options:
  // Specify a search parameter in order to perform keyword search on the
  // following fields of the workflow:
  //   - id
  //   - description
  //   - notes
  //   - user_id (unless user_app_id.user_id is already set)
  //
  // Keywords are both normalized for search (so searching for "satisfy" matches "satisfied")
  // and used for partial prefix-matching (so searching for "clari" matches "clarifai").
  //
  // NOTE: Both the list of fields searched and the exact keyword matching
  // rules are subject to change and not guaranteed to be backwards-compatible.
  string search = 16;
  // Query various text fields (id, description and notes) that can contain the words in the query string.
  // Deprecated: use search instead.
  string query = 8 [deprecated = true];
  // Filter by the id of the workflow. This supports wilcard queries like "gen*" to match "general" as an example.
  // Deprecated: use search instead.
  string id = 4 [deprecated = true];
  // Full text and prefix matching on id, owner id, description and notes. Searchable fields may be added
  // Deprecated: use search instead.
  string search_term = 12 [deprecated = true];
}


// PostWorkflowsRequest
message PostWorkflowsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Workflow workflows = 2;
}

// PatchWorkflowsRequest
message PatchWorkflowsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Workflow workflows = 2;

  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  //
  // Note that 'remove' can be used to remove the workflow image by setting
  // 'image.url' in the request to the current value returned for that workflow.
  // This cannot be used in a request that is patching other fields as well.
  string action = 3;
}

// PatchWorkflowIdsRequest
message PatchWorkflowIdsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Array containing 1 entry
  repeated IdUpdateSource ids = 3;

  // The action to perform on the patched objects
  // Only 'overwrite' is supported
  string action = 4;
}

// DeleteWorkflowRequest
message DeleteWorkflowRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
}

// Request to delete several things by the list of ids.
message DeleteWorkflowsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
  bool delete_all = 3;
}

// SingleWorkflowResponse
message SingleWorkflowResponse {
  clarifai.api.status.Status status = 1;
  Workflow workflow = 2;
}

// MultiWorkflowResponse
message MultiWorkflowResponse {
  clarifai.api.status.Status status = 1;
  repeated Workflow workflows = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// PostWorkflowResultsRequest
message PostWorkflowResultsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Workflow ID to retrieve
  // If no ID is specified we return default workflow of the application
  // If an ID is specified by default we first looks into Clarifai workflows for a Workflow ID
  string workflow_id = 2;

  // Workflow version ID to retrieve
  // If no ID is specified, latest workflow version is used
  string version_id = 7;

  repeated Input inputs = 3;
  // FIXME(zeiler): the request for post workflows is using an outputconfig object that is supposed
  // to be within models. This is not consistent with setting this on the request for post model
  // outputs where it is inside a model object. To make this consistent we would send in the
  // workflow object so that each model can have it's own output config. If nobody is setting
  // this OutputConfig it would probably be easier to just remove it for now to keep things simpler
  // and then it's more consistent we just don't support the OutputConfig on workflows.
  OutputConfig output_config = 4;

  // Use this flag to look into clarifai published workflows first for a Workflow ID
  bool favor_clarifai_workflows = 5 [deprecated = true]; // @exclude TODO (EAGLE-4447): Remove unused fields

  // A workflow state to be maintained across PostWorkflowResults requests/responses.
  // If it is not sent in the initial request with workflow_state.id = "init" then no
  // state will be saved or returned in PostWorkflowResultsResponse.
  WorkflowState workflow_state = 6;

  // Specify which compute to use for processing each node of the workflow:
  // The key is the node.id from the loaded workflow.
  // The value is a RunnerSelector in which you can specify the deployment or specific nodepool
  // that you'd like that node to run on.
  // This allows for use cases like some light models could run on a CPU-only nodepool
  // while other models in the workflow require large GPUs.
  //
  // If node.id is not in the provided map, it will fall back to searching for
  // an adequate deployment the model owner owns or fall back to
  // the shared nodepools provided by Clarifai.
  // We recommend you specify these RunnerSelectors so that you have better understanding of where
  // processing occurs.
  map<string, RunnerSelector> node_runner_selectors = 8;
}

// PostWorkflowResultsResponse
message PostWorkflowResultsResponse {
  // The status of the request.
  clarifai.api.status.Status status = 1;
  // The workflow that was used in predictions with PostWorkflowResults
  Workflow workflow = 2;
  // The resulting predictions of all models in the workflow.
  repeated WorkflowResult results = 3;
  // A workflow state to be maintained across PostWorkflowResults requests/responses.
  // This WorkflowState should be passed in to subsequent PostWorkflowResults calls
  // if you want to keep track of state across requests.
  // If no WorkflowState was initialized in a request then no WorkflowState will be returned in this
  // response.
  WorkflowState workflow_state = 4;
}

// ListWorkflowVersionsRequest
message ListWorkflowVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List versions for the workflow identified by this id
  string workflow_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

// GetWorkflowVersionRequest
message GetWorkflowVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the workflow that has the requested version.
  string workflow_id = 2;
  // Get the identified by this id
  string workflow_version_id = 3;
}

// DeleteWorkflowVersionsRequest
message DeleteWorkflowVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the workflow that has the requested versions to delete.
  string workflow_id = 2;
  // Delete the versions identified by these ids
  repeated string workflow_version_ids = 3;
}

// PatchWorkflowVersionsRequest
message PatchWorkflowVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the workflow that has the requested versions to patch.
  string workflow_id = 2;
  // Patch these versions.
  repeated WorkflowVersion workflow_versions = 3;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 4;
}

// MultiWorkflowVersionResponse
message MultiWorkflowVersionResponse {
  clarifai.api.status.Status status = 1;
  repeated WorkflowVersion workflow_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleWorkflowVersionResponse
message SingleWorkflowVersionResponse {
  clarifai.api.status.Status status = 1;
  WorkflowVersion workflow_version = 2;
}

// Deprecated: App duplication is no longer supported.
// Request to start app duplication jobs.
message PostAppDuplicationsRequest {
  option deprecated = true;
  // The user and application ID of the source application to duplicate.
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated AppDuplication app_duplications = 2;
}

// Deprecated: App duplication is no longer supported.
// Request to get an app duplication job.
message GetAppDuplicationRequest {
  option deprecated = true;
  // The ID of the user that created the app duplication job.
  clarifai.api.UserAppIDSet user_app_id = 1;
  string app_duplication_id = 2;
}

// Deprecated: App duplication is no longer supported.
// Request to list all the app duplication jobs that a user created.
message ListAppDuplicationsRequest {
  option deprecated = true;
  // The ID of the user whose app duplication jobs to list.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// Deprecated: App duplication is no longer supported.
// MultiAppDuplicationsResponse
message MultiAppDuplicationsResponse {
  option deprecated = true;
  clarifai.api.status.Status status = 1;
  repeated AppDuplication app_duplications = 2;
}

// Deprecated: App duplication is no longer supported.
// SingleAppDuplicationResponse
message SingleAppDuplicationResponse {
  option deprecated = true;
  clarifai.api.status.Status status = 1;
  AppDuplication app_duplication = 2;
}

// Request to create Tasks.
message PostTasksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Task tasks = 2;
}

// Request to get one task.
message GetTaskRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string task_id = 2;

  // (optional URL parameter) List of additional fields to be included in the response.
  // Currently supported additional fields:
  // - all
  // - worker.users
  // - review.users
  // - metrics.input_source.inputs_count_estimated
  // - metrics.work.inputs_count_estimated
  // - metrics.work.inputs_percent_estimated
  // - metrics.review.inputs_count_estimated
  // - metrics.review.inputs_count_estimated_per_reviewer
  // - metrics.review.inputs_percent_estimated
  // - metrics.review.inputs_percent_estimated_per_reviewer
  // - metrics.review.inputs_reviewable_count_estimated_per_reviewer
  repeated string additional_fields = 3;
}

// Request to list multiple tasks.
message ListTasksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
  // Get tasks that have ANY user from this list assigned as worker.
  // Deprecated: Use worker_ids.
  repeated string worker_user_ids = 4 [deprecated = true];
  // Get tasks that have ANY user from this list assigned as reviewer.
  repeated string review_user_ids = 5;
  // Get tasks that are associated to ANY label order from this list.
  repeated string label_order_ids = 8;

  // Get label order tasks as well
  // It is automatically set to true if label_order_ids is set.
  bool including_label_order_tasks = 6;

  // (optional URL parameter) List of additional fields to be included in the response.
  // Currently supported additional fields:
  // - all
  // - worker.users
  // - review.users
  // - metrics.input_source.inputs_count_estimated
  // - metrics.work.inputs_count_estimated
  // - metrics.work.inputs_percent_estimated
  // - metrics.review.inputs_count_estimated
  // - metrics.review.inputs_count_estimated_per_reviewer
  // - metrics.review.inputs_percent_estimated
  // - metrics.review.inputs_percent_estimated_per_reviewer
  // - metrics.review.inputs_reviewable_count_estimated_per_reviewer
  repeated string additional_fields = 7;

  // (optional) task IDs to filter on
  repeated string ids = 9;

  // (optional) input source type to filter
  TaskInputSource.TaskInputSourceType input_source_type = 10;

  // (optional) ids of input source to be filtered
  repeated string input_source_ids = 11;

  repeated WorkerIDSet worker_ids = 12;
}

// Request to patch a list of tasks.
message PatchTasksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  repeated Task tasks = 2;

  // The action to perform on the patched tasks
  // Supported operations:
  // * 'overwrite' - overwrite the task with the fields provided in the request
  // * 'merge' - update only the fields provided in the request, leave other fields unchanged
  // For now, the 'merge' operation only supports updating task status.
  string action = 3;
}

// Request to delete a list of tasks.
message DeleteTasksRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
}

// Response with multiple Tasks.
message MultiTaskResponse {
  clarifai.api.status.Status status = 1;
  repeated Task tasks = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Response with a single Task.
message SingleTaskResponse {
  clarifai.api.status.Status status = 1;
  Task task = 2;
}

// GetTaskCountRequest can be used for fetching -
// 1. Task annotation count per user, per status
// 1. Task input count per user (i.e. task assignment count), per status
message GetTaskCountRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // task_id for which count per user per status is needed
  string task_id = 2;

  // Only return counts for these user IDs, effectively operating as an
  // OR among them to filter down the results.
  // If model_version_ids or workflow_version_ids are also provided, these user_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) counts in the results.
  repeated string user_ids = 3;

  // Only return counts for these model version IDs, effectively operating as an
  // OR among them to filter down the results.
  // If user_ids or workflow_version_ids are also provided, these model_version_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) counts in the results.
  repeated string model_version_ids = 4;

  // Only return counts for these workflow version IDs, effectively operating as an
  // OR among them to filter down the results.
  // If user_ids or model_version_ids are also provided, these workflow_version_ids are OR'd with them as well because
  // we want the union of all worker (user, model or workflow) counts in the results.
  repeated string workflow_version_ids = 5;
}

// SingleTaskCountResponse represents counts of task annotations or inputs (i.e. task assignments) for labelers in given task
message SingleTaskCountResponse {
  clarifai.api.status.Status status = 1;
  string app_id = 2;
  string task_id = 3;
  repeated TaskStatusCountPerUser counts = 4;
}





////////////////////////////////////////////////////////////////////////////////
// Label Orders
////////////////////////////////////////////////////////////////////////////////

// Request to create label orders.
message PostLabelOrdersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated LabelOrder label_orders = 2;
}

// Request to get one label order.
message GetLabelOrderRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string label_order_id = 2;
}

// Request to list multiple label orders.
message ListLabelOrdersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// Request to patch a list of label orders.
message PatchLabelOrdersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  repeated LabelOrder label_orders = 2;

  // The action to perform on the patched objects
  // For now, only 'overwrite' option is supported
  string action = 3;
}

// Request to delete a list of label orders.
message DeleteLabelOrdersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
}

// Response with multiple label order.
message MultiLabelOrderResponse {
  clarifai.api.status.Status status = 1;
  repeated LabelOrder label_orders = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Response with a label order.
message SingleLabelOrderResponse {
  clarifai.api.status.Status status = 1;
  LabelOrder label_order = 2;
}





































// ListNextTaskAssignmentsRequest
message ListNextTaskAssignmentsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string task_id = 2;
}

// Request to perform bulk operations on a list of inputs based on input source.
message PostBulkOperationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of bulk operation(s) to be performed e.g bulk update metadata or tags or labels etc.
  repeated clarifai.api.BulkOperation bulk_operations = 2;
}

// Request to list all the bulk operations.
message ListBulkOperationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

// Request to get the details of a bulk operation by ID.
message GetBulkOperationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The bulk operation id
  string id = 2;
}

// Cancel a list of bulk operation ids
message CancelBulkOperationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of bulk operation ids to be cancelled
  repeated string ids = 2;
}

// Request to delete the terminated bulk operations by ID
// Only operations in terminated state can be deleted.
message DeleteBulkOperationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of bulk operation ids to be deleted
  repeated string ids = 2;
}

// SingleBulkOperationsResponse
message SingleBulkOperationsResponse {
  clarifai.api.status.Status status = 1;
  clarifai.api.BulkOperation bulk_operation = 2;
}

// MultiBulkOperationsResponse
message MultiBulkOperationsResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.BulkOperation bulk_operation = 2;
}





// PutTaskAssignmentsRequest
message PutTaskAssignmentsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string task_id = 2;

  // Deprecated: use action and action_config instead.
  // Supported for backwards compatibility: setting this field is equivalent with
  // * action = LABEL_SUBMIT
  // * label_submit_config = [{"task_assignments": {{"id": "<task-assignment-id-for-input-id>"}}]
  string input_id = 3;

  // Action to perform on selected task.
  PutTaskAssignmentsRequestAction action = 4;

  oneof action_config {
    //    LabelStartConfig label_start_config = 5; // no config for label start action
    LabelSubmitConfig label_submit_config = 6;
    ReviewStartConfig review_start_config = 10;
    ReviewApproveConfig review_approve_config = 7;
    ReviewRequestChangesConfig review_request_changes_config = 8;
    ReviewRejectConfig review_reject_config = 9;
  }
}
enum PutTaskAssignmentsRequestAction {
  PUT_TASK_ASSIGNMENTS_REQUEST_ACTION_NOT_SET = 0;

  // Create a list of task assignments for labeler => 10 inputs are assigned to the labeler.
  // This is a fully sync action.
  // If task assignments already exist, then return existing task assignments.
  LABEL_START = 1;

  // Submit task assignments => mark task assignment work as completed.
  // This is a partially sync action.
  // Sync: task assignments are updated as follows:
  // * when review_strategy is NONE, then task assignment status is updated to SUCCESS.
  // * when review strategy is CONSENSUS, then task assignment status is updated to AWAITING_CONSENSUS_REVIEW.
  // * when review strategy is MANUAL, then task assignment status is updated to AWAITING_REVIEW.
  // If task assignments are already submitted, then no update is performed on them.
  // Async: annotations added for the same input as the task assignment are updated as follows:
  // * when review_strategy is NONE, then annotation status is updated to SUCCESS.
  // * when review strategy is CONSENSUS, then annotation status is updated to SUCCESS (if it reaches consensus) or AWAITING_REVIEW (if it does not reach consensus).
  // * when review strategy is MANUAL, then annotation status is updated to AWAITING_REVIEW.
  LABEL_SUBMIT = 2;

  // Assign task assignments for reviewer to review => 10 task assignments are assigned to the reviewer.
  // This is a fully sync action.
  // If task assignments are already assigned for review, then return existing task assignments.
  REVIEW_START = 10;

  // Approve task assignments.
  // There are two types of configurations:
  // * Batch approve: approve a list of task assignment IDs;
  // * Bulk approve: approve all task assignments from a list of workers.
  // This is a partially sync action.
  // Sync: task assignments are updated to SUCCESS
  // Async: annotations added for the same input as the task assignment are updated to SUCCESS
  REVIEW_APPROVE = 11;

  // Request changes for task assignments.
  // There are two types of configurations:
  // * Batch request changes: request changes for a list of task assignment IDs;
  // * Bulk request changes: request changes for all task assignments from a list of workers.
  // This is a partially sync action.
  // Sync: task assignments are updated to PENDING
  // Async: annotations added for the same input as the task assignment are updated to PENDING
  REVIEW_REQUEST_CHANGES = 12;

  // Reject task assignments.
  // There are two types of configurations:
  // * Batch reject: reject a list of task assignment IDs;
  // * Bulk reject: reject all task assignments from a list of workers.
  // This is a partially sync action.
  // Sync: task assignments are updated to REVIEW_DENIED
  // Async: annotations added for the same input as the task assignment are updated to REVIEW_DENIED
  REVIEW_REJECT = 13;
}


message LabelSubmitConfig {
  repeated TaskAssignment task_assignments = 1;
}

message ReviewStartConfig {
  // Review the work done by these workers.
  // If empty, review the work for all workers.
  repeated Worker workers = 1;
}

message ReviewApproveConfig {
  repeated TaskAssignment task_assignments = 1;
  repeated Worker workers = 2;
}

message ReviewRequestChangesConfig {
  repeated TaskAssignment task_assignments = 1;
  repeated Worker workers = 2;
}

message ReviewRejectConfig {
  repeated TaskAssignment task_assignments = 1;
  repeated Worker workers = 2;
}

message MultiTaskAssignmentResponse {
  clarifai.api.status.Status status = 1;
  repeated TaskAssignment task_assignments = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}




// List all the input ingestion jobs
message ListInputsAddJobsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message GetInputsAddJobRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // id of add inputs job
  string id = 2;
}

message CancelInputsAddJobRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // id of add inputs job to be cancelled
  string id = 2;
}

// MultiInputsAddJobResponse
message MultiInputsAddJobResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.InputsAddJob inputs_add_jobs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// SingleInputsAddJobResponse
message SingleInputsAddJobResponse {
  clarifai.api.status.Status status = 1;
  clarifai.api.InputsAddJob inputs_add_job = 2;
}

// Start a multipart upload
message PostUploadsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated clarifai.api.Upload uploads = 2;
}

// Stops or deletes multipart upload
message DeleteUploadsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
}

message ListUploadsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message GetUploadRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Upload ID
  string upload_id = 2;
}

message SingleUploadResponse {
  clarifai.api.status.Status status = 1;
  clarifai.api.Upload upload = 2;
}

message MultiUploadResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.Upload uploads = 2;
}

// Upload a part of a multipart upload.
// Behaviour on completion depends on the endpoint that was used to initiate the upload.
message PutUploadContentPartsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string upload_id = 2;
  repeated UploadContentPart content_parts = 3;
}

// Initiates retrieval of inputs from cloud storage from a user provided data source.
// Will create and return an inputs-add-job for tracking progress.
// Archives will be extracted and their contents will be processed as inputs.
//
// The cloud URL will be treated as a filter prefix. For example s3:/bucket/images_folder/abc will process
// files in the images_folder beginning with abc or in a subfolder beginning with abc.
// For example:
// bucket/images_folder/abcImage.png
// bucket/images_folder/abc-1/Data.zip
//
// If given URL is for a private bucket or file, then credentials should be provided to access the bucket.
// Credentials should include rights to list the objects in the bucket, except when pointed directly at a file archive,
// in which case it only requires rights to access that particular file.
message PostInputsDataSourcesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  repeated InputsDataSource data_sources = 2;

  // If call back url is set, we will send a Post request to this endpoint with job status.
  string call_back_url = 3;

  // Personal Access Token to the application to which inputs are added
  // Deprecated: No need to send app_pat, it will be generated internally if not present
  string app_pat = 4 [deprecated = true];
}

message GetInputsExtractionJobRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  string inputs_extraction_job_id = 2;
}

message ListInputsExtractionJobsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message SingleInputsExtractionJobResponse {
  clarifai.api.status.Status status = 1;
  clarifai.api.InputsExtractionJob inputs_extraction_job = 2;
}

message MultiInputsExtractionJobResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.InputsExtractionJob inputs_extraction_jobs = 2;
}

// Cancel a list of extraction job ids
message CancelInputsExtractionJobsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of extraction job ids to be cancelled
  repeated string ids = 2;
}

// Start uploading a file archive containing inputs.
// Will create and return an inputs-add-job for tracking progress.
//
// Associated inputs-add-job contains an upload id which should be completed through `PutUploadContentParts` endpoint.
// Completing the upload will automatically begin unpacking the archive and uploading the contents as inputs.
message PostInputsUploadsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated clarifai.api.InputsUpload inputs_uploads = 2;
}

// GetRunnerRequest
message GetRunnerRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  string runner_id = 3;
  string compute_cluster_id = 4;
}

// ListRunnersRequest
message ListRunnersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
  string compute_cluster_id = 5;
  // Only return runners whose replicas are >= min_replicas.
  uint32 min_replicas = 6;
  // (optional URL parameter) ModelVersion IDs. To list all runners for the model version
  repeated string model_version_ids = 7;
}


// PostRunnersRequest
message PostRunnersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  // This allows you to create one or more runner by posting it to the API.
  repeated Runner runners = 3;
  string compute_cluster_id = 4;
}

// PatchRunnersRequest
message PatchRunnersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  // This allows you to create one or more runner by posting it to the API.
  repeated Runner runners = 3;
  string compute_cluster_id = 4;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 5;
}

// Request to delete several things by the list of ids.
message DeleteRunnersRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  repeated string ids = 3;
  string compute_cluster_id = 4;
}

// SingleRunnerResponse
message SingleRunnerResponse {
  clarifai.api.status.Status status = 1;
  Runner runner = 2;
}

// MultiRunnerResponse
message MultiRunnerResponse {
  clarifai.api.status.Status status = 1;
  repeated Runner runners = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message ListRunnerItemsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string nodepool_id = 2;
  string runner_id = 3;
  string compute_cluster_id = 4;
}

// PostRunnerItemOutputsRequest
// This is the message that runners send to the API to communicate.
// At the end of the request it will have the RunnerItemOutput filled in
// with results of the workload the runner is processing. Other messages
// from the runner use this same proto to communicate over to the API
// and do handshakes.
message PostRunnerItemOutputsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The particular nodepool that runner belongs to
  string nodepool_id = 2;
  // The particular runner that processed the work.
  string runner_id = 3;
  // The particular item of work processed.
  string runner_item_id = 4;
  // This allows you to create one or more runner by posting it to the API.
  repeated RunnerItemOutput runner_item_outputs = 5;

  // This request has a status so that it can communicate to the API from runners and
  // communicate status, errors, etc. This is on the request since runners operate
  // in a reverse protocol. This status is also used to initiate the
  // ProcessRunnerItems request with RUNNER_STREAM_START code.
  clarifai.api.status.Status status = 6;

  // A unique ID to represent the runner. This may be tied to an underlying compute instance
  // information or just an UUID.
  string runner_replica_id = 7;

  string compute_cluster_id = 8;

  // Used by agent runners to specify their cloud provider.
  string cloud_provider_id = 9;

  // Used by agent runners to specify their region.
  string region = 10;

  // FUTURE
  // Advanced metrics coming back from the runner.
}

// SyncStateRequest is a message that the control plane sends to the agent runner to notify it of
// changes to objects.
message SyncStateRequest{
  // The operation that was performed: create, update, delete.
  string operation_type = 1;

  // Objects that were affected.
  repeated ComputeCluster compute_clusters = 2;
  repeated Nodepool nodepools = 3;
  repeated Runner runners = 4;
  repeated PipelineVersionRun pipeline_version_runs = 5;
  repeated Secret secrets = 6;
}

// MultiRunnerItemResponse
message MultiRunnerItemResponse {
  clarifai.api.status.Status status = 1;
  repeated RunnerItem runner_items = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// This is a unit of work for a runner to process. This comes from the API
// in the MultiRunnerItemResponse and contains the user's requests
// to process.
message RunnerItem {
  // A UUID hash for this work item.
  string id = 1;

  // A description of the work to be done in case needed for UIs.
  string description = 2;

  // Information on how to process the given RunnerItem.
  ProcessingInfo processing_info = 3;

  oneof request {
    // Model prediction request from a user.
    PostModelOutputsRequest post_model_outputs_request = 4;
    // Agent sync request from control plane.
    SyncStateRequest sync_state_request = 5;
    // Auto annotation request from a user.
    AutoAnnotationRequest auto_annotation_request = 6;
    // Workflow request from a user.  // FUTURE
    // training request next, etc.
  }

  // Metadata used for routing and other purposes.
  RunnerItemMetadata metadata = 7;
}

message RunnerItemMetadata {
  // The user ID of the requester. Used for sticky routing to the same runner replica.
  string user_id = 1;
  // chained block hashes of input for prefix cache routing
  repeated uint64 block_hashes = 2;
}

message AutoAnnotationRequest {
  // Perform prediction request and call PostAnnotations endpoint using prediction results.
  PostModelOutputsRequest post_model_outputs_request = 1;

  // Task used to create annotations .
  Task task = 2;

  // Authorization value to be used when calling PostAnnotations endpoint.
  string authorization_value = 3;
}

// This contains the response of the user's request once processing is done.
// The runner should fill in the matching output to the RunnerItem.request
// oneof field. This is sent to the API within PostRunnerItemOutputsRequest
message RunnerItemOutput {
  oneof response {
    // The output of a model prediction request.
    MultiOutputResponse multi_output_response = 1;
    // Workflow response. // FUTURE
    // training response ???
  }
}

message MultiRunnerItemOutputResponse {
  clarifai.api.status.Status status = 1;
  repeated RunnerItemOutput runner_item_outputs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Get the estimated training time for a model version
message PostModelVersionsTrainingTimeEstimateRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  repeated ModelVersion model_versions = 3;
  uint64 estimated_input_count = 4;
}

// Estimated training time in seconds
message MultiTrainingTimeEstimateResponse {
  clarifai.api.status.Status status = 1;
  repeated google.protobuf.Duration training_time_estimates = 2;
}

// List Cloud Providers
message ListCloudProvidersRequest {}

message MultiCloudProviderResponse {
  clarifai.api.status.Status status = 1;
  repeated CloudProvider cloud_providers = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// List CloudProvider Regions
message ListCloudRegionsRequest {
  // The cloud provider to list compute clusters for.
  CloudProvider cloud_provider = 1;
}

message MultiCloudRegionResponse {
  clarifai.api.status.Status status = 1;
  repeated string regions = 2 [deprecated = true, (clarifai.api.utils.cl_show_if_empty) = true];
  repeated CloudRegion cloud_regions = 3 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// List InstanceTypes
message ListInstanceTypesRequest {
  // The cloud provider to list compute clusters for.
  CloudProvider cloud_provider = 1;

  // The region to list for so when there are multiple regions we get only the clusters
  // that are supposed to be up in that region.
  string region = 2;
}

message MultiInstanceTypeResponse {
  clarifai.api.status.Status status = 1;
  repeated InstanceType instance_types = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// ComputeCLuster CRUD requests and responses
message GetComputeClusterRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
}

message ListComputeClustersRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message PostComputeClustersRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // This allows you to create one or more compute_clusters by posting it to the API.
  repeated ComputeCluster compute_clusters = 2;
}

message PatchComputeClustersRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // This allows you to patch one or more compute_clusters
  repeated ComputeCluster compute_clusters = 2;
  // The action to perform on the patched objects
  // For now 'overwrite' is supported
  string action = 3;
}

message DeleteComputeClustersRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of compute cluster ids to be deleted
  repeated string ids = 2;
}

message SingleComputeClusterResponse {
  clarifai.api.status.Status status = 1;
  ComputeCluster compute_cluster = 2;
}

message MultiComputeClusterResponse {
  clarifai.api.status.Status status = 1;
  repeated ComputeCluster compute_clusters = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// TODO(zeiler): these might not be 100% correct and will be updated as we uncomment the endpoints.
// Nodepool CRUD requests and responses
message GetNodepoolRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  string nodepool_id = 3;
  // Only return the nodepool if it is actively being used (having min_instances > 0,
  // runners with replicas >= threshold or pipeline versions scheduled to run)
  bool active_usage = 4;
}

message ListNodepoolsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
  // Only return nodepools that are actively being used (having runners with
  // replicas >= threshold and pipeline versions scheduled to run)
  bool active_usage = 5;

}

message PostNodepoolsRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  // This allows you to create one or more nodepools by posting it to the API.
  repeated Nodepool nodepools = 3;
}

// PatchNodepoolsRequest
message PatchNodepoolsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  repeated Nodepool nodepools = 3;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 4;
}

message DeleteNodepoolsRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  // List of nodepool ids to be deleted
  repeated string ids = 3;
}

message PostNodepoolStatusRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string compute_cluster_id = 2;
  string nodepool_id = 3;
  // New status of the nodepool.
  Nodepool.NodepoolStatus status = 4;
  // Human-readable status description. Contains error details when status is NODEPOOL_STATUS_ERROR.
  string status_description = 5;
}

message SingleNodepoolResponse {
  clarifai.api.status.Status status = 1;
  Nodepool nodepool = 2;
}

message MultiNodepoolResponse {
  clarifai.api.status.Status status = 1;
  repeated Nodepool nodepools = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Deployments CRUD requests and responses
message GetDeploymentRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string deployment_id = 2;
}

message ListDeploymentsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) Nodepool ID. To list all deployed workers in a Nodepool
  string nodepool_id = 2;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
  // (optional URL parameter) ModelVersion IDs. To list all deployments for the model version
  repeated string model_version_ids = 5;
  // (optional URL parameter) WorkflowVersion IDs. To list all deployments for the workflow version
  repeated string workflow_version_ids = 6;
  // (optional URL parameter) ComputeCluster ID. To list all deployed workers in a ComputeCluster
  string compute_cluster_id = 7;
  // (optional URL parameter) Scheduling priorities. To list all deployments with one of the
  // provided scheduling priorities. Valid values are 0-9.
  repeated uint32 scheduling_priorities = 8;
}

message PostDeploymentsRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // This allows you to create one or more deployments by posting it to the API.
  repeated Deployment deployments = 2;
}

message DeleteDeploymentsRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of deployment ids to be deleted
  repeated string ids = 2;
}

message PostAuditLogSearchesRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  AuditLogQuery query = 2;
  // Sorting options:
  // Whether to sort by timestamp in ascending order. If false, will order in descending order.
  bool sort_ascending = 3;

  Pagination pagination = 5;
}

message MultiAuditLogEntryResponse {
  clarifai.api.status.Status status = 1;
  repeated AuditLogEntry entries = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message PatchDeploymentsRequest {
  // Only the user_id is used from this.
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Deployment deployments = 3;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 4;
}

message SingleDeploymentResponse {
  clarifai.api.status.Status status = 1;
  Deployment deployment = 2;
}

message MultiDeploymentResponse {
  clarifai.api.status.Status status = 1;
  repeated Deployment deployments = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}





message ListWorkflowEvaluationTemplatesRequest {}

message MultiWorkflowEvaluationTemplateResponse {
  clarifai.api.status.Status status = 1;
  repeated WorkflowVersionEvaluationTemplate workflow_version_evaluation_templates = 2;
}

message PostWorkflowVersionEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;

  // ########## Supported fields ##########
  // - ground_truth_dataset_version.app_id
  // - ground_truth_dataset_version.dataset_id
  // - ground_truth_dataset_version.id
  // - id
  // - target_node_id
  // - workflow_version_evaluation_template.id
  repeated clarifai.api.WorkflowVersionEvaluation workflow_version_evaluations = 4;
  repeated RunnerSelector runner_selectors = 5;
}

message PatchWorkflowVersionEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;

  // ########## Supported fields ##########
  // - id
  // - predictions_dataset_version.dataset_id
  // - predictions_dataset_version.id
  // - status.code
  // - status.details
  // - workflow_evaluation_result.summary.evaluation_metric_values[].evaluation_metric_id
  // - workflow_evaluation_result.summary.evaluation_metric_values[].explanation
  // - workflow_evaluation_result.summary.evaluation_metric_values[].metric_value.float_value
  // - workflow_evaluation_result.summary.evaluation_metric_values[].metric_value.int_value
  // - workflow_evaluation_result.summary.evaluation_metric_values[].metric_value.string_value
  // - workflow_evaluation_result.summary.evaluation_metric_values[].per_concept_values
  repeated clarifai.api.WorkflowVersionEvaluation workflow_version_evaluations = 4;

  // only overwrite supported
  string action = 5;
}

message MultiWorkflowVersionEvaluationResponse {
  clarifai.api.status.Status status = 1;
  repeated clarifai.api.WorkflowVersionEvaluation workflow_version_evaluations = 2;
}



message SingleWorkflowVersionEvaluationResponse {
  clarifai.api.status.Status status = 1;
  clarifai.api.WorkflowVersionEvaluation workflow_version_evaluation = 2;
}

message GetWorkflowVersionEvaluationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;
  string workflow_version_evaluation_id = 4;
}

message ListWorkflowVersionEvaluationsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;
}

message PostModelMigrationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
  string version_id = 3;
}

message DeleteModelMigrationRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string model_id = 2;
}

message ListWorkflowVersionEvaluationDataRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;
  string workflow_version_evaluation_id = 4;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 5;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 6;
}

message PostWorkflowVersionEvaluationDataRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string workflow_id = 2;
  string workflow_version_id = 3;
  string workflow_version_evaluation_id = 4;

  // ########## Supported fields ##########
  // - id
  // - workflow_evaluation_sample_result
  repeated WorkflowVersionEvaluationData workflow_version_evaluation_data = 5;
}

message MultiListWorkflowVersionEvaluationDataResponse {
  clarifai.api.status.Status status = 1;
  repeated WorkflowVersionEvaluationData workflow_version_evaluation_data = 2;
}

message GetPipelineRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  string pipeline_id = 2;
}

message ListPipelinesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message PostPipelinesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Pipeline pipelines = 2;
}

message PatchPipelinesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Pipeline pipelines = 2;

  // The action to perform on the patched objects
  // For now actions 'overwrite' are supported
  string action = 3;
}

message DeletePipelinesRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated string ids = 2;
}

message SinglePipelineResponse {
  clarifai.api.status.Status status = 1;
  Pipeline pipeline = 2;
}

message MultiPipelineResponse {
  clarifai.api.status.Status status = 1;
  repeated Pipeline pipelines = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message GetPipelineVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The id of the pipeline that has the requested version.
  string pipeline_id = 2;

  // Get the identified by this id
  string pipeline_version_id = 3;
}

message ListPipelineVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List versions for the pipeline identified by this id
  string pipeline_id = 2;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

message PatchPipelineVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the Pipeline that has the requested versions to patch.
  string pipeline_id = 2;
  // Patch these versions
  repeated PipelineVersion pipeline_versions = 3;
  // The action to perform on the patched objects
  // For now actions 'merge', 'overwrite', and 'remove' are supported
  string action = 4;
}

message DeletePipelineVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The id of the Pipeline for which versions are being deleted
  string pipeline_id = 2;

  repeated string pipeline_version_ids = 3;
}

message SinglePipelineVersionResponse {
  clarifai.api.status.Status status = 1;
  PipelineVersion pipeline_version = 2;
}

message MultiPipelineVersionResponse {
  clarifai.api.status.Status status = 1;
  repeated PipelineVersion pipeline_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message GetPipelineVersionRunRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // the ID of the pipeline
  string pipeline_id = 2;

  // The ID of the pipeline version
  string pipeline_version_id = 3;

  // the ID of the pipeline version run
  string pipeline_version_run_id = 4;
}

message ListPipelineVersionRunsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The ID of the pipeline
  string pipeline_id = 2;

  // The ID of the pipeline version
  string pipeline_version_id = 3;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 4;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 5;

  // Filter based on status
  repeated clarifai.api.status.StatusCode status_codes = 6;

  // compute cluster id
  string compute_cluster_id = 7;

  // nodepool id
  string nodepool_id = 8;
}

message PostPipelineVersionRunsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The ID of the pipeline
  string pipeline_id = 2;

  // The ID of the pipeline-version
  string pipeline_version_id = 3;

  repeated PipelineVersionRun pipeline_version_runs = 4;
  RunnerSelector runner_selector = 5; // Allows using specific Nodepools for pipeline version runs
}

message PatchPipelineVersionRunsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // The ID of the pipeline
  string pipeline_id = 2;

  // The ID of the pipeline-version
  string pipeline_version_id = 3;

  // ########## Supported fields ##########
  // - app_id
  // - id
  // - orchestration_status
  // - pipeline_version.id
  // - pipeline_version.pipeline_id
  // - user_id
  repeated PipelineVersionRun pipeline_version_runs = 4;
  // Supported action: 'overwrite' -> allows to overwrite WorkflowStatus of PipelineVersionRun
  string action = 5;
}

message SinglePipelineVersionRunResponse {
  clarifai.api.status.Status status = 1;
  PipelineVersionRun pipeline_version_run = 2;
}

message MultiPipelineVersionRunResponse {
  clarifai.api.status.Status status = 1;
  repeated PipelineVersionRun pipeline_version_runs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message ListPipelineVersionRunStatusLogsRequest {
  // User App ID
  clarifai.api.UserAppIDSet user_app_id = 1;

  // Pipeline ID
  string pipeline_id = 2;

  // Pipeline Version ID
  string pipeline_version_id = 3;

  // Pipeline Version Run ID
  string pipeline_version_run_id = 4;

  // Status codes to filter by (optional)
  repeated clarifai.api.status.StatusCode status_codes = 5;

  // Pagination
  uint32 page = 6;
  uint32 per_page = 7;
}

message MultiPipelineVersionRunStatusLogResponse {
  clarifai.api.status.Status status = 1;
  repeated PipelineVersionRunStatusLog pipeline_version_run_status_logs = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}



message PostPipelineStepsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated PipelineStep pipeline_steps = 3;
}

message MultiPipelineStepResponse {
  clarifai.api.status.Status status = 1;
  repeated PipelineStep pipeline_steps = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message ListPipelineStepsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message ListPipelineStepVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List versions for the pipeline step identified by this id
  string pipeline_step_id = 2;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;

  // Filter based on status
  repeated clarifai.api.status.StatusCode status_codes = 6;
}

message MultiPipelineStepVersionResponse {
  // The status of the request
  clarifai.api.status.Status status = 1;
  // The pipeline step versions that were requested
  repeated PipelineStepVersion pipeline_step_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message PostPipelineStepVersionsUploadRequest {
  oneof upload_data {
    // Upload a new pipeline step version.
    PostPipelineStepVersionsUploadConfig upload_config = 2;

    // Upload a part of a multipart upload.
    UploadContentPart content_part = 3;
  }
}

message PostPipelineStepVersionsUploadResponse {
  // Status of the upload
  clarifai.api.status.Status status = 1;
  // Bytes remaining to be uploaded - This is total_size - bytes_uploaded
  uint64 bytes_remaining = 2;
  // ID of the pipeline step version being uploaded
  string pipeline_step_version_id = 3;
}

message PostPipelineStepVersionsUploadConfig {
  // User ID and App ID of the user uploading the pipeline step
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Pipeline Step to create version for
  string pipeline_step_id = 2;
  // Specification for the pipeline step version to be uploaded
  PipelineStepVersion pipeline_step_version = 3;
  // Number of bytes in the pipeline step files to be uploaded
  uint64 total_size = 4;
  // Number of bytes requested for the build process.
  uint64 storage_request_size = 5;
}

message GetPipelineStepRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the pipeline step that has the requested version.
  string pipeline_step_id = 2;
}

message SinglePipelineStepResponse {
  // The status of the request
  clarifai.api.status.Status status = 1;
  // The pipeline step that was requested
  PipelineStep pipeline_step = 2;
}

message GetPipelineStepVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the pipeline step that has the requested version.
  string pipeline_step_id = 2;
  // Get the identified by this id
  string pipeline_step_version_id = 3;
}

message SinglePipelineStepVersionResponse {
  // The status of the request
  clarifai.api.status.Status status = 1;
  // The pipeline step version that was requested
  PipelineStepVersion pipeline_step_version = 2;
}

message DeletePipelineStepsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The ids of the pipeline steps to delete
  repeated string ids = 2;
}

message DeletePipelineStepVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the pipeline step for which versions are being deleted
  string pipeline_step_id = 2;
  // The ids of the pipeline step versions to delete
  repeated string pipeline_step_version_ids = 3;
}

message GetSecretRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the secret to get
  string id = 2;
}

message ListSecretsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;
  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message PostSecretsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The secrets to create
  repeated Secret secrets = 2;
}

message PatchSecretsRequest {
  reserved 2, 3, 4;
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Secret secret = 5;
  string action = 8;
}

message DeleteSecretsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // List of secret ids to be deleted
  repeated string ids = 2;
}

message SingleSecretResponse {
  clarifai.api.status.Status status = 1;
  Secret secret = 2;
}message MultiSecretResponse {
  clarifai.api.status.Status status = 1;
  repeated Secret secrets = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message ListPipelineTemplatesRequest {
  // Filter based on PipelineTemplateTypes (e.g. TRAINING)
  repeated PipelineTemplate.PipelineTemplateType pipeline_template_type = 1;
}

message MultiPipelineTemplateResponse {
  clarifai.api.status.Status status = 1;
  repeated PipelineTemplate pipeline_templates = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

// Request to create a Pipeline, PipelineVersion, and PipelineVersionRun from a PipelineTemplate
message PostPipelineVersionRunFromTemplateRequest {

  clarifai.api.UserAppIDSet user_app_id = 1;

  // Name of the pipeline template to use (from ListPipelineTemplates)
  string pipeline_template_name = 2;

  // Optional: ID of existing pipeline to create version under
  string pipeline_id = 3;

  // Optional: Description for the pipeline (used if creating new pipeline)
  string pipeline_description = 4;

  // Optional: Description for the pipeline version
  string pipeline_version_description = 5;

  // Optional: Nodepools to use for the pipeline version run
  repeated Nodepool nodepools = 6;

  // Optional: Overrides to input arguments for the orchestration system
  OrchestrationArgsOverride input_args_override = 7;
}

// Response containing the created Pipeline, PipelineVersion, and PipelineVersionRun
message PostPipelineVersionRunFromTemplateResponse {
  clarifai.api.status.Status status = 1;

  // The created or updated pipeline (contains the latest pipeline version)
  Pipeline pipeline = 2;

  // The created pipeline version run
  PipelineVersionRun pipeline_version_run = 3;
}

message PostMetricsQueryRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  MetricSearchQuery query = 2;
}

message MetricsQueryResponse {
  clarifai.api.status.Status status = 1;
  MetricData data = 2;
  string resolution = 3;
}

message ListMetricLabelsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated MetricType metric_types = 2;
}

message MultiMetricLabelsResponse {
  clarifai.api.status.Status status = 1;
  repeated MetricTypeLabels metric_type_labels = 2;
}












// Artifact requests and responses

message PostArtifactsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  repeated Artifact artifacts = 2;
}

message MultiArtifactResponse {
  clarifai.api.status.Status status = 1;
  repeated Artifact artifacts = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message ListArtifactsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 2;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 3;
}

message GetArtifactRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the artifact to get
  string artifact_id = 2;
}

message SingleArtifactResponse {
  clarifai.api.status.Status status = 1;
  Artifact artifact = 2;
}

message DeleteArtifactRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the artifact to be deleted
  string artifact_id = 2;
}

message PostArtifactVersionsUploadRequest {
  oneof upload_data {
    // Upload a new artifact version.
    PostArtifactVersionsUploadConfig upload_config = 2;

    // Upload a part of a multipart upload.
    UploadContentPart content_part = 3;
  }
}

message PostArtifactVersionsUploadResponse {
  // Status of the upload
  clarifai.api.status.Status status = 1;
  // Bytes remaining to be uploaded - This is total_size - bytes_uploaded
  uint64 bytes_remaining = 2;
  // ID of the artifact version being uploaded
  string artifact_version_id = 3;
}

message PostArtifactVersionsUploadConfig {
  // User ID and App ID of the user uploading the artifact
  clarifai.api.UserAppIDSet user_app_id = 1;
  // Artifact to create version for
  string artifact_id = 2;
  // Specification for the artifact version to be uploaded
  ArtifactVersion artifact_version = 3;
  // Number of bytes in the artifact files to be uploaded
  uint64 total_size = 4;
  // Number of bytes requested for the build process.
  uint64 storage_request_size = 5;
}

message ListArtifactVersionsRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;

  // List versions for the artifact identified by this id
  string artifact_id = 2;

  // (optional URL parameter) The page number. Pagination is used to split the results into chunks.
  // Defaults to 1.
  uint32 page = 3;

  // (optional URL parameter) The number of results that will be contained in each page. Defaults
  // to 128.
  uint32 per_page = 4;
}

message MultiArtifactVersionResponse {
  // The status of the request
  clarifai.api.status.Status status = 1;
  // The artifact versions that were requested
  repeated ArtifactVersion artifact_versions = 2 [(clarifai.api.utils.cl_show_if_empty) = true];
}

message GetArtifactVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the artifact that has the requested version.
  string artifact_id = 2;
  // Get the artifact version identified by this id
  string artifact_version_id = 3;
}

message SingleArtifactVersionResponse {
  // The status of the request
  clarifai.api.status.Status status = 1;
  // The artifact version that was requested
  ArtifactVersion artifact_version = 2;
}

message DeleteArtifactVersionRequest {
  clarifai.api.UserAppIDSet user_app_id = 1;
  // The id of the artifact for which versions are being deleted
  string artifact_id = 2;
  // The id of the artifact versions to be deleted
  string artifact_version_id = 3;
}






