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

syntax = "proto3";

package google.cloud.contactcenterinsights.v1;

import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.ContactCenterInsights.V1";
option go_package = "cloud.google.com/go/contactcenterinsights/apiv1/contactcenterinsightspb;contactcenterinsightspb";
option java_multiple_files = true;
option java_outer_classname = "ResourcesProto";
option java_package = "com.google.cloud.contactcenterinsights.v1";
option php_namespace = "Google\\Cloud\\ContactCenterInsights\\V1";
option ruby_package = "Google::Cloud::ContactCenterInsights::V1";
option (google.api.resource_definition) = {
  type: "dialogflow.googleapis.com/ConversationProfile"
  pattern: "projects/{project}/locations/{location}/conversationProfiles/{conversation_profile}"
};
option (google.api.resource_definition) = {
  type: "dialogflow.googleapis.com/Participant"
  pattern: "projects/{project}/conversations/{conversation}/participants/{participant}"
  pattern: "projects/{project}/locations/{location}/conversations/{conversation}/participants/{participant}"
};
option (google.api.resource_definition) = {
  type: "speech.googleapis.com/Recognizer"
  pattern: "projects/{project}/locations/{location}/recognizers/{recognizer}"
};

// Enum for the different types of issues a tuning dataset can have.
// These warnings are currentlyraised when trying to validate a dataset for
// tuning a scorecard.
enum DatasetValidationWarning {
  // Unspecified data validation warning.
  DATASET_VALIDATION_WARNING_UNSPECIFIED = 0;

  // A non-trivial percentage of the feedback labels are invalid.
  TOO_MANY_INVALID_FEEDBACK_LABELS = 1;

  // The quantity of valid feedback labels provided is less than the
  // recommended minimum.
  INSUFFICIENT_FEEDBACK_LABELS = 2;

  // One or more of the answers have less than the recommended minimum of
  // feedback labels.
  INSUFFICIENT_FEEDBACK_LABELS_PER_ANSWER = 3;

  // All the labels in the dataset come from a single answer choice.
  ALL_FEEDBACK_LABELS_HAVE_THE_SAME_ANSWER = 4;
}

// The conversation resource.
message Conversation {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/Conversation"
    pattern: "projects/{project}/locations/{location}/conversations/{conversation}"
    pattern: "projects/{project}/locations/{location}/authorizedViewSets/{authorized_view_set}/authorizedViews/{authorized_view}/conversations/{conversation}"
    plural: "conversations"
    singular: "conversation"
  };

  // Call-specific metadata.
  message CallMetadata {
    // The audio channel that contains the customer.
    int32 customer_channel = 1;

    // The audio channel that contains the agent.
    int32 agent_channel = 2;
  }

  // Conversation metadata related to quality management.
  message QualityMetadata {
    // Information about an agent involved in the conversation.
    message AgentInfo {
      // A user-specified string representing the agent.
      string agent_id = 1;

      // The agent's name.
      string display_name = 2;

      // A user-specified string representing the agent's team.
      string team = 3;

      // A user-provided string indicating the outcome of the agent's segment of
      // the call.
      string disposition_code = 4;

      // The agent type, e.g. HUMAN_AGENT.
      ConversationParticipant.Role agent_type = 5;
    }

    // An arbitrary integer value indicating the customer's satisfaction rating.
    int32 customer_satisfaction_rating = 1;

    // The amount of time the customer waited to connect with an agent.
    google.protobuf.Duration wait_duration = 2;

    // An arbitrary string value specifying the menu path the customer took.
    string menu_path = 3;

    // Information about agents involved in the call.
    repeated AgentInfo agent_info = 4;
  }

  // A message representing the transcript of a conversation.
  message Transcript {
    // A segment of a full transcript.
    message TranscriptSegment {
      // Word-level info for words in a transcript.
      message WordInfo {
        // Time offset of the start of this word relative to the beginning of
        // the total conversation.
        google.protobuf.Duration start_offset = 1;

        // Time offset of the end of this word relative to the beginning of the
        // total conversation.
        google.protobuf.Duration end_offset = 2;

        // The word itself. Includes punctuation marks that surround the word.
        string word = 3;

        // A confidence estimate between 0.0 and 1.0 of the fidelity of this
        // word. A default value of 0.0 indicates that the value is unset.
        float confidence = 4;
      }

      // Metadata from Dialogflow relating to the current transcript segment.
      message DialogflowSegmentMetadata {
        // Whether the transcript segment was covered under the configured smart
        // reply allowlist in Agent Assist.
        bool smart_reply_allowlist_covered = 1;
      }

      // The time that the message occurred, if provided.
      google.protobuf.Timestamp message_time = 6;

      // The text of this segment.
      string text = 1;

      // A confidence estimate between 0.0 and 1.0 of the fidelity of this
      // segment. A default value of 0.0 indicates that the value is unset.
      float confidence = 2;

      // A list of the word-specific information for each word in the segment.
      repeated WordInfo words = 3;

      // The language code of this segment as a
      // [BCP-47](https://www.rfc-editor.org/rfc/bcp/bcp47.txt) language tag.
      // Example: "en-US".
      string language_code = 4;

      // For conversations derived from multi-channel audio, this is the channel
      // number corresponding to the audio from that channel. For
      // audioChannelCount = N, its output values can range from '1' to 'N'. A
      // channel tag of 0 indicates that the audio is mono.
      int32 channel_tag = 5;

      // The participant of this segment.
      ConversationParticipant segment_participant = 9;

      // CCAI metadata relating to the current transcript segment.
      DialogflowSegmentMetadata dialogflow_segment_metadata = 10;

      // The sentiment for this transcript segment.
      SentimentData sentiment = 11;
    }

    // A list of sequential transcript segments that comprise the conversation.
    repeated TranscriptSegment transcript_segments = 1;
  }

  // Possible media for the conversation.
  enum Medium {
    // Default value, if unspecified will default to PHONE_CALL.
    MEDIUM_UNSPECIFIED = 0;

    // The format for conversations that took place over the phone.
    PHONE_CALL = 1;

    // The format for conversations that took place over chat.
    CHAT = 2;
  }

  // Metadata that applies to the conversation.
  oneof metadata {
    // Call-specific metadata.
    CallMetadata call_metadata = 7;
  }

  // A time to live expiration setting, can be either a specified timestamp or a
  // duration from the time that the conversation creation request was received.
  // Conversations with an expiration set will be removed up to 24 hours after
  // the specified time.
  oneof expiration {
    // The time at which this conversation should expire. After this time, the
    // conversation data and any associated analyses will be deleted.
    google.protobuf.Timestamp expire_time = 15;

    // Input only. The TTL for this resource. If specified, then this TTL will
    // be used to calculate the expire time.
    google.protobuf.Duration ttl = 16
        [(google.api.field_behavior) = INPUT_ONLY];
  }

  // Immutable. The resource name of the conversation.
  // Format:
  // projects/{project}/locations/{location}/conversations/{conversation}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // The source of the audio and transcription for the conversation.
  ConversationDataSource data_source = 2;

  // Output only. The time at which the conversation was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which the conversation was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The time at which the conversation started.
  google.protobuf.Timestamp start_time = 17;

  // A user-specified language code for the conversation.
  string language_code = 14;

  // An opaque, user-specified string representing the human agent who handled
  // the conversation.
  string agent_id = 5;

  // A map for the user to specify any custom fields. A maximum of 100 labels
  // per conversation is allowed, with a maximum of 256 characters per entry.
  map<string, string> labels = 6;

  // Conversation metadata related to quality management.
  QualityMetadata quality_metadata = 24;

  // Input only. JSON metadata encoded as a string.
  // This field is primarily used by Insights integrations with various telphony
  // systems and must be in one of Insight's supported formats.
  string metadata_json = 25 [(google.api.field_behavior) = INPUT_ONLY];

  // Output only. The conversation transcript.
  Transcript transcript = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Immutable. The conversation medium, if unspecified will default to
  // PHONE_CALL.
  Medium medium = 9 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The duration of the conversation.
  google.protobuf.Duration duration = 10
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The number of turns in the conversation.
  int32 turn_count = 11 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The conversation's latest analysis, if one exists.
  Analysis latest_analysis = 12 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Latest summary of the conversation.
  ConversationSummarizationSuggestionData latest_summary = 20
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The annotations that were generated during the customer and
  // agent interaction.
  repeated RuntimeAnnotation runtime_annotations = 13
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. All the matched Dialogflow intents in the call. The key
  // corresponds to a Dialogflow intent, format:
  // projects/{project}/agent/{agent}/intents/{intent}
  map<string, DialogflowIntent> dialogflow_intents = 18
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Obfuscated user ID which the customer sent to us.
  string obfuscated_user_id = 21;
}

// The analysis resource.
message Analysis {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/Analysis"
    pattern: "projects/{project}/locations/{location}/conversations/{conversation}/analyses/{analysis}"
    pattern: "projects/{project}/locations/{location}/authorizedViewSets/{authorized_view_set}/authorizedViews/{authorized_view}/conversations/{conversation}/analyses/{analysis}"
    plural: "analyses"
    singular: "analysis"
  };

  // Immutable. The resource name of the analysis.
  // Format:
  // projects/{project}/locations/{location}/conversations/{conversation}/analyses/{analysis}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time at which the analysis was requested.
  google.protobuf.Timestamp request_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which the analysis was created, which occurs when
  // the long-running operation completes.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The result of the analysis, which is populated when the
  // analysis finishes.
  AnalysisResult analysis_result = 7
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // To select the annotators to run and the phrase matchers to use
  // (if any). If not specified, all annotators will be run.
  AnnotatorSelector annotator_selector = 8;
}

// The conversation source, which is a combination of transcript and audio.
message ConversationDataSource {
  // The source of the conversation.
  oneof source {
    // A Cloud Storage location specification for the audio and transcript.
    GcsSource gcs_source = 1;

    // The source when the conversation comes from Dialogflow.
    DialogflowSource dialogflow_source = 3;
  }
}

// A Cloud Storage source of conversation data.
message GcsSource {
  // Cloud Storage URI that points to a file that contains the conversation
  // audio.
  string audio_uri = 1;

  // Immutable. Cloud Storage URI that points to a file that contains the
  // conversation transcript.
  string transcript_uri = 2 [(google.api.field_behavior) = IMMUTABLE];
}

// A Dialogflow source of conversation data.
message DialogflowSource {
  // Output only. The name of the Dialogflow conversation that this conversation
  // resource is derived from. Format:
  // projects/{project}/locations/{location}/conversations/{conversation}
  string dialogflow_conversation = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Cloud Storage URI that points to a file that contains the conversation
  // audio.
  string audio_uri = 3;
}

// The result of an analysis.
message AnalysisResult {
  // Call-specific metadata created during analysis.
  message CallAnalysisMetadata {
    // A list of call annotations that apply to this call.
    repeated CallAnnotation annotations = 2;

    // All the entities in the call.
    map<string, Entity> entities = 3;

    // Overall conversation-level sentiment for each channel of the call.
    repeated ConversationLevelSentiment sentiments = 4;

    // Overall conversation-level silence during the call.
    ConversationLevelSilence silence = 11;

    // All the matched intents in the call.
    map<string, Intent> intents = 6;

    // All the matched phrase matchers in the call.
    map<string, PhraseMatchData> phrase_matchers = 7;

    // Overall conversation-level issue modeling result.
    IssueModelResult issue_model_result = 8;

    // Results of scoring QaScorecards.
    repeated QaScorecardResult qa_scorecard_results = 10;
  }

  // Metadata discovered during analysis.
  oneof metadata {
    // Call-specific metadata created by the analysis.
    CallAnalysisMetadata call_analysis_metadata = 2;
  }

  // The time at which the analysis ended.
  google.protobuf.Timestamp end_time = 1;
}

// Issue Modeling result on a conversation.
message IssueModelResult {
  // Issue model that generates the result.
  // Format: projects/{project}/locations/{location}/issueModels/{issue_model}
  string issue_model = 1 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/IssueModel"
  }];

  // All the matched issues.
  repeated IssueAssignment issues = 2;
}

// Represents a conversation, resource, and label provided by the user.
message FeedbackLabel {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/FeedbackLabel"
    pattern: "projects/{project}/locations/{location}/conversations/{conversation}/feedbackLabels/{feedback_label}"
    pattern: "projects/{project}/locations/{location}/authorizedViewSets/{authorized_view_set}/authorizedViews/{authorized_view}/conversations/{conversation}/feedbackLabels/{feedback_label}"
    plural: "feedbackLabels"
    singular: "feedbackLabel"
  };

  // Label type.
  oneof label_type {
    // String label.
    string label = 4;

    // QaAnswer label.
    QaAnswer.AnswerValue qa_answer_label = 7;
  }

  // Immutable. Resource name of the FeedbackLabel.
  // Format:
  // projects/{project}/locations/{location}/conversations/{conversation}/feedbackLabels/{feedback_label}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Resource name of the resource to be labeled.
  string labeled_resource = 3;

  // Output only. Create time of the label.
  google.protobuf.Timestamp create_time = 5
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Update time of the label.
  google.protobuf.Timestamp update_time = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// One channel of conversation-level sentiment data.
message ConversationLevelSentiment {
  // The channel of the audio that the data applies to.
  int32 channel_tag = 1;

  // Data specifying sentiment.
  SentimentData sentiment_data = 2;
}

// Conversation-level silence data.
message ConversationLevelSilence {
  // Amount of time calculated to be in silence.
  google.protobuf.Duration silence_duration = 1;

  // Percentage of the total conversation spent in silence.
  float silence_percentage = 2;
}

// Information about the issue.
message IssueAssignment {
  // Resource name of the assigned issue.
  string issue = 1;

  // Score indicating the likelihood of the issue assignment.
  // currently bounded on [0,1].
  double score = 2;

  // Immutable. Display name of the assigned issue. This field is set at time of
  // analyis and immutable since then.
  string display_name = 3 [(google.api.field_behavior) = IMMUTABLE];
}

// A piece of metadata that applies to a window of a call.
message CallAnnotation {
  // The data in the annotation.
  oneof data {
    // Data specifying an interruption.
    InterruptionData interruption_data = 10;

    // Data specifying sentiment.
    SentimentData sentiment_data = 11;

    // Data specifying silence.
    SilenceData silence_data = 12;

    // Data specifying a hold.
    HoldData hold_data = 13;

    // Data specifying an entity mention.
    EntityMentionData entity_mention_data = 15;

    // Data specifying an intent match.
    IntentMatchData intent_match_data = 16;

    // Data specifying a phrase match.
    PhraseMatchData phrase_match_data = 17;

    // Data specifying an issue match.
    IssueMatchData issue_match_data = 18;
  }

  // The channel of the audio where the annotation occurs. For single-channel
  // audio, this field is not populated.
  int32 channel_tag = 1;

  // The boundary in the conversation where the annotation starts, inclusive.
  AnnotationBoundary annotation_start_boundary = 4;

  // The boundary in the conversation where the annotation ends, inclusive.
  AnnotationBoundary annotation_end_boundary = 5;
}

// A point in a conversation that marks the start or the end of an annotation.
message AnnotationBoundary {
  // A detailed boundary, which describes a more specific point.
  oneof detailed_boundary {
    // The word index of this boundary with respect to the first word in the
    // transcript piece. This index starts at zero.
    int32 word_index = 3;
  }

  // The index in the sequence of transcribed pieces of the conversation where
  // the boundary is located. This index starts at zero.
  int32 transcript_index = 1;
}

// The data for an entity annotation.
// Represents a phrase in the conversation that is a known entity, such
// as a person, an organization, or location.
message Entity {
  // The type of the entity. For most entity types, the associated metadata is a
  // Wikipedia URL (`wikipedia_url`) and Knowledge Graph MID (`mid`). The table
  // below lists the associated fields for entities that have different
  // metadata.
  enum Type {
    // Unspecified.
    TYPE_UNSPECIFIED = 0;

    // Person.
    PERSON = 1;

    // Location.
    LOCATION = 2;

    // Organization.
    ORGANIZATION = 3;

    // Event.
    EVENT = 4;

    // Artwork.
    WORK_OF_ART = 5;

    // Consumer product.
    CONSUMER_GOOD = 6;

    // Other types of entities.
    OTHER = 7;

    // Phone number.
    //
    // The metadata lists the phone number (formatted according to local
    // convention), plus whichever additional elements appear in the text:
    //
    // * `number` - The actual number, broken down into sections according to
    // local convention.
    // * `national_prefix` - Country code, if detected.
    // * `area_code` - Region or area code, if detected.
    // * `extension` - Phone extension (to be dialed after connection), if
    // detected.
    PHONE_NUMBER = 9;

    // Address.
    //
    // The metadata identifies the street number and locality plus whichever
    // additional elements appear in the text:
    //
    // * `street_number` - Street number.
    // * `locality` - City or town.
    // * `street_name` - Street/route name, if detected.
    // * `postal_code` - Postal code, if detected.
    // * `country` - Country, if detected.
    // * `broad_region` - Administrative area, such as the state, if detected.
    // * `narrow_region` - Smaller administrative area, such as county, if
    // detected.
    // * `sublocality` - Used in Asian addresses to demark a district within a
    // city, if detected.
    ADDRESS = 10;

    // Date.
    //
    // The metadata identifies the components of the date:
    //
    // * `year` - Four digit year, if detected.
    // * `month` - Two digit month number, if detected.
    // * `day` - Two digit day number, if detected.
    DATE = 11;

    // Number.
    //
    // The metadata is the number itself.
    NUMBER = 12;

    // Price.
    //
    // The metadata identifies the `value` and `currency`.
    PRICE = 13;
  }

  // The representative name for the entity.
  string display_name = 1;

  // The entity type.
  Type type = 2;

  // Metadata associated with the entity.
  //
  // For most entity types, the metadata is a Wikipedia URL (`wikipedia_url`)
  // and Knowledge Graph MID (`mid`), if they are available. For the metadata
  // associated with other entity types, see the Type table below.
  map<string, string> metadata = 3;

  // The salience score associated with the entity in the [0, 1.0] range.
  //
  // The salience score for an entity provides information about the
  // importance or centrality of that entity to the entire document text.
  // Scores closer to 0 are less salient, while scores closer to 1.0 are highly
  // salient.
  float salience = 4;

  // The aggregate sentiment expressed for this entity in the conversation.
  SentimentData sentiment = 5;
}

// The data for an intent.
// Represents a detected intent in the conversation, for example MAKES_PROMISE.
message Intent {
  // The unique identifier of the intent.
  string id = 1;

  // The human-readable name of the intent.
  string display_name = 2;
}

// The data for a matched phrase matcher.
// Represents information identifying a phrase matcher for a given match.
message PhraseMatchData {
  // The unique identifier (the resource name) of the phrase matcher.
  string phrase_matcher = 1;

  // The human-readable name of the phrase matcher.
  string display_name = 2;
}

// The data for a Dialogflow intent.
// Represents a detected intent in the conversation, e.g. MAKES_PROMISE.
message DialogflowIntent {
  // The human-readable name of the intent.
  string display_name = 1;
}

// The data for an interruption annotation.
message InterruptionData {}

// The data for a silence annotation.
message SilenceData {}

// The data for a hold annotation.
message HoldData {}

// The data for an entity mention annotation.
// This represents a mention of an `Entity` in the conversation.
message EntityMentionData {
  // The supported types of mentions.
  enum MentionType {
    // Unspecified.
    MENTION_TYPE_UNSPECIFIED = 0;

    // Proper noun.
    PROPER = 1;

    // Common noun (or noun compound).
    COMMON = 2;
  }

  // The key of this entity in conversation entities.
  // Can be used to retrieve the exact `Entity` this mention is attached to.
  string entity_unique_id = 1;

  // The type of the entity mention.
  MentionType type = 2;

  // Sentiment expressed for this mention of the entity.
  SentimentData sentiment = 3;
}

// The data for an intent match.
// Represents an intent match for a text segment in the conversation. A text
// segment can be part of a sentence, a complete sentence, or an utterance
// with multiple sentences.
message IntentMatchData {
  // The id of the matched intent.
  // Can be used to retrieve the corresponding intent information.
  string intent_unique_id = 1;
}

// The data for a sentiment annotation.
message SentimentData {
  // A non-negative number from 0 to infinity which represents the abolute
  // magnitude of sentiment regardless of score.
  float magnitude = 1;

  // The sentiment score between -1.0 (negative) and 1.0 (positive).
  float score = 2;
}

// The data for an issue match annotation.
message IssueMatchData {
  // Information about the issue's assignment.
  IssueAssignment issue_assignment = 1;
}

// The issue model resource.
message IssueModel {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/IssueModel"
    pattern: "projects/{project}/locations/{location}/issueModels/{issue_model}"
  };

  // Configs for the input data used to create the issue model.
  message InputDataConfig {
    // Medium of conversations used in training data. This field is being
    // deprecated. To specify the medium to be used in training a new issue
    // model, set the `medium` field on `filter`.
    Conversation.Medium medium = 1 [deprecated = true];

    // Output only. Number of conversations used in training. Output only.
    int64 training_conversations_count = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // A filter to reduce the conversations used for training the model to a
    // specific subset.
    string filter = 3;
  }

  // State of the model.
  enum State {
    // Unspecified.
    STATE_UNSPECIFIED = 0;

    // Model is not deployed but is ready to deploy.
    UNDEPLOYED = 1;

    // Model is being deployed.
    DEPLOYING = 2;

    // Model is deployed and is ready to be used. A model can only be used in
    // analysis if it's in this state.
    DEPLOYED = 3;

    // Model is being undeployed.
    UNDEPLOYING = 4;

    // Model is being deleted.
    DELETING = 5;
  }

  // Type of the model.
  enum ModelType {
    // Unspecified model type.
    MODEL_TYPE_UNSPECIFIED = 0;

    // Type V1.
    TYPE_V1 = 1;

    // Type V2.
    TYPE_V2 = 2;
  }

  // Immutable. The resource name of the issue model.
  // Format:
  // projects/{project}/locations/{location}/issueModels/{issue_model}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // The representative name for the issue model.
  string display_name = 2;

  // Output only. The time at which this issue model was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which the issue model was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Number of issues in this issue model.
  int64 issue_count = 8 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. State of the model.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Configs for the input data that used to create the issue model.
  InputDataConfig input_data_config = 6;

  // Output only. Immutable. The issue model's label statistics on its training
  // data.
  IssueModelLabelStats training_stats = 7 [
    (google.api.field_behavior) = OUTPUT_ONLY,
    (google.api.field_behavior) = IMMUTABLE
  ];

  // Type of the model.
  ModelType model_type = 9;

  // Language of the model.
  string language_code = 10;
}

// The issue resource.
message Issue {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/Issue"
    pattern: "projects/{project}/locations/{location}/issueModels/{issue_model}/issues/{issue}"
  };

  // Immutable. The resource name of the issue.
  // Format:
  // projects/{project}/locations/{location}/issueModels/{issue_model}/issues/{issue}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // The representative name for the issue.
  string display_name = 2;

  // Output only. The time at which this issue was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time that this issue was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Resource names of the sample representative utterances that
  // match to this issue.
  repeated string sample_utterances = 6
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Representative description of the issue.
  string display_description = 14;
}

// Aggregated statistics about an issue model.
message IssueModelLabelStats {
  // Aggregated statistics about an issue.
  message IssueStats {
    // Issue resource.
    // Format:
    // projects/{project}/locations/{location}/issueModels/{issue_model}/issues/{issue}
    string issue = 1;

    // Number of conversations attached to the issue at this point in time.
    int64 labeled_conversations_count = 2;

    // Display name of the issue.
    string display_name = 3;
  }

  // Number of conversations the issue model has analyzed at this point in time.
  int64 analyzed_conversations_count = 1;

  // Number of analyzed conversations for which no issue was applicable at this
  // point in time.
  int64 unclassified_conversations_count = 2;

  // Statistics on each issue. Key is the issue's resource name.
  map<string, IssueStats> issue_stats = 3;
}

// The phrase matcher resource.
message PhraseMatcher {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/PhraseMatcher"
    pattern: "projects/{project}/locations/{location}/phraseMatchers/{phrase_matcher}"
  };

  // Specifies how to combine each phrase match rule group to determine whether
  // there is a match.
  enum PhraseMatcherType {
    // Unspecified.
    PHRASE_MATCHER_TYPE_UNSPECIFIED = 0;

    // Must meet all phrase match rule groups or there is no match.
    ALL_OF = 1;

    // If any of the phrase match rule groups are met, there is a match.
    ANY_OF = 2;
  }

  // The resource name of the phrase matcher.
  // Format:
  // projects/{project}/locations/{location}/phraseMatchers/{phrase_matcher}
  string name = 1;

  // Output only. Immutable. The revision ID of the phrase matcher.
  // A new revision is committed whenever the matcher is changed, except when it
  // is activated or deactivated. A server generated random ID will be used.
  // Example: locations/global/phraseMatchers/my-first-matcher@1234567
  string revision_id = 2 [
    (google.api.field_behavior) = IMMUTABLE,
    (google.api.field_behavior) = OUTPUT_ONLY
  ];

  // The customized version tag to use for the phrase matcher. If not specified,
  // it will default to `revision_id`.
  string version_tag = 3;

  // Output only. The timestamp of when the revision was created. It is also the
  // create time when a new matcher is added.
  google.protobuf.Timestamp revision_create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The human-readable name of the phrase matcher.
  string display_name = 5;

  // Required. The type of this phrase matcher.
  PhraseMatcherType type = 6 [(google.api.field_behavior) = REQUIRED];

  // Applies the phrase matcher only when it is active.
  bool active = 7;

  // A list of phase match rule groups that are included in this matcher.
  repeated PhraseMatchRuleGroup phrase_match_rule_groups = 8;

  // Output only. The most recent time at which the activation status was
  // updated.
  google.protobuf.Timestamp activation_update_time = 9
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // The role whose utterances the phrase matcher should be matched
  // against. If the role is ROLE_UNSPECIFIED it will be matched against any
  // utterances in the transcript.
  ConversationParticipant.Role role_match = 10;

  // Output only. The most recent time at which the phrase matcher was updated.
  google.protobuf.Timestamp update_time = 11
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A message representing a rule in the phrase matcher.
message PhraseMatchRuleGroup {
  // Specifies how to combine each phrase match rule for whether there is a
  // match.
  enum PhraseMatchRuleGroupType {
    // Unspecified.
    PHRASE_MATCH_RULE_GROUP_TYPE_UNSPECIFIED = 0;

    // Must meet all phrase match rules or there is no match.
    ALL_OF = 1;

    // If any of the phrase match rules are met, there is a match.
    ANY_OF = 2;
  }

  // Required. The type of this phrase match rule group.
  PhraseMatchRuleGroupType type = 1 [(google.api.field_behavior) = REQUIRED];

  // A list of phrase match rules that are included in this group.
  repeated PhraseMatchRule phrase_match_rules = 2;
}

// The data for a phrase match rule.
message PhraseMatchRule {
  // Required. The phrase to be matched.
  string query = 1 [(google.api.field_behavior) = REQUIRED];

  // Specifies whether the phrase must be missing from the transcript segment or
  // present in the transcript segment.
  bool negated = 2;

  // Provides additional information about the rule that specifies how to apply
  // the rule.
  PhraseMatchRuleConfig config = 3;
}

// Configuration information of a phrase match rule.
message PhraseMatchRuleConfig {
  // The configuration of the phrase match rule.
  oneof config {
    // The configuration for the exact match rule.
    ExactMatchConfig exact_match_config = 1;
  }
}

// Exact match configuration.
message ExactMatchConfig {
  // Whether to consider case sensitivity when performing an exact match.
  bool case_sensitive = 1;
}

// The CCAI Insights project wide settings.
// Use these settings to configure the behavior of Insights.
// View these settings with
// [`getsettings`](https://cloud.google.com/contact-center/insights/docs/reference/rest/v1/projects.locations/getSettings)
// and change the settings with
// [`updateSettings`](https://cloud.google.com/contact-center/insights/docs/reference/rest/v1/projects.locations/updateSettings).
message Settings {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/Settings"
    pattern: "projects/{project}/locations/{location}/settings"
  };

  // Default configuration when creating Analyses in Insights.
  message AnalysisConfig {
    // Percentage of conversations created using Dialogflow runtime integration
    // to analyze automatically, between [0, 100].
    double runtime_integration_analysis_percentage = 1;

    // Percentage of conversations created using the UploadConversation endpoint
    // to analyze automatically, between [0, 100].
    double upload_conversation_analysis_percentage = 6;

    // To select the annotators to run and the phrase matchers to use
    // (if any). If not specified, all annotators will be run.
    AnnotatorSelector annotator_selector = 5;
  }

  // Immutable. The resource name of the settings resource.
  // Format:
  // projects/{project}/locations/{location}/settings
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Output only. The time at which the settings was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The time at which the settings were last updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // A language code to be applied to each transcript segment unless the segment
  // already specifies a language code. Language code defaults to "en-US" if it
  // is neither specified on the segment nor here.
  string language_code = 4;

  // The default TTL for newly-created conversations. If a conversation has a
  // specified expiration, that value will be used instead. Changing this
  // value will not change the expiration of existing conversations.
  // Conversations with no expire time persist until they are deleted.
  google.protobuf.Duration conversation_ttl = 5;

  // A map that maps a notification trigger to a Pub/Sub topic. Each time a
  // specified trigger occurs, Insights will notify the corresponding Pub/Sub
  // topic.
  //
  // Keys are notification triggers. Supported keys are:
  //
  // * "all-triggers": Notify each time any of the supported triggers occurs.
  // * "create-analysis": Notify each time an analysis is created.
  // * "create-conversation": Notify each time a conversation is created.
  // * "export-insights-data": Notify each time an export is complete.
  // * "ingest-conversations": Notify each time an IngestConversations LRO is
  // complete.
  // * "update-conversation": Notify each time a conversation is updated via
  // UpdateConversation.
  // * "upload-conversation": Notify when an UploadConversation LRO is complete.
  //
  // Values are Pub/Sub topics. The format of each Pub/Sub topic is:
  // projects/{project}/topics/{topic}
  map<string, string> pubsub_notification_settings = 6;

  // Default analysis settings.
  AnalysisConfig analysis_config = 7;

  // Default DLP redaction resources to be applied while ingesting
  // conversations. This applies to conversations ingested from the
  // `UploadConversation` and `IngestConversations` endpoints, including
  // conversations coming from CCAI Platform.
  RedactionConfig redaction_config = 10;

  // Optional. Default Speech-to-Text resources to use while ingesting audio
  // files. Optional, CCAI Insights will create a default if not provided. This
  // applies to conversations ingested from the `UploadConversation` and
  // `IngestConversations` endpoints, including conversations coming from CCAI
  // Platform.
  SpeechConfig speech_config = 11 [(google.api.field_behavior) = OPTIONAL];
}

// The CCAI Insights project wide analysis rule. This rule will be applied to
// all conversations that match the filter defined in the rule. For a
// conversation matches the filter, the annotators specified in the rule will be
// run. If a conversation matches multiple rules, a union of all the annotators
// will be run. One project can have multiple analysis rules.
message AnalysisRule {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/AnalysisRule"
    pattern: "projects/{project}/locations/{location}/analysisRules/{analysis_rule}"
    plural: "analysisRules"
    singular: "analysisRule"
  };

  // Identifier. The resource name of the analysis rule.
  // Format:
  // projects/{project}/locations/{location}/analysisRules/{analysis_rule}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Output only. The time at which this analysis rule was created.
  google.protobuf.Timestamp create_time = 2
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which this analysis rule was updated.
  google.protobuf.Timestamp update_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Display Name of the analysis rule.
  optional string display_name = 4;

  // Filter for the conversations that should apply this analysis
  // rule. An empty filter means this analysis rule applies to all
  // conversations.
  string conversation_filter = 5;

  // Selector of annotators to run and the phrase matchers to use for
  // conversations that matches the conversation_filter. If not specified, NO
  // annotators will be run.
  AnnotatorSelector annotator_selector = 6;

  // Percentage of conversations that we should apply this analysis setting
  // automatically, between [0, 1]. For example, 0.1 means 10%. Conversations
  // are sampled in a determenestic way. The original runtime_percentage &
  // upload percentage will be replaced by defining filters on the conversation.
  double analysis_percentage = 7;

  // If true, apply this rule to conversations. Otherwise, this rule is
  // inactive and saved as a draft.
  bool active = 8;
}

// A customer-managed encryption key specification that can be applied to all
// created resources (e.g. `Conversation`).
message EncryptionSpec {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/EncryptionSpec"
    pattern: "projects/{project}/locations/{location}/encryptionSpec"
  };

  // Immutable. The resource name of the encryption key specification resource.
  // Format:
  // projects/{project}/locations/{location}/encryptionSpec
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // Required. The name of customer-managed encryption key that is used to
  // secure a resource and its sub-resources. If empty, the resource is secured
  // by our default encryption key. Only the key in the same location as this
  // resource is allowed to be used for encryption. Format:
  // `projects/{project}/locations/{location}/keyRings/{keyRing}/cryptoKeys/{key}`
  string kms_key = 2 [(google.api.field_behavior) = REQUIRED];
}

// DLP resources used for redaction while ingesting conversations.
// DLP settings are applied to conversations ingested from the
// `UploadConversation` and `IngestConversations` endpoints, including
// conversation coming from CCAI Platform. They are not applied to conversations
// ingested from the `CreateConversation` endpoint or the Dialogflow / Agent
// Assist runtime integrations. When using Dialogflow / Agent Assist runtime
// integrations, redaction should be performed in Dialogflow / Agent Assist.
message RedactionConfig {
  // The fully-qualified DLP deidentify template resource name.
  // Format:
  // `projects/{project}/deidentifyTemplates/{template}`
  string deidentify_template = 1;

  // The fully-qualified DLP inspect template resource name.
  // Format:
  // `projects/{project}/locations/{location}/inspectTemplates/{template}`
  string inspect_template = 2;
}

// Speech-to-Text configuration.
// Speech-to-Text settings are applied to conversations ingested from the
// `UploadConversation` and `IngestConversations` endpoints, including
// conversation coming from CCAI Platform. They are not applied to conversations
// ingested from the `CreateConversation` endpoint.
message SpeechConfig {
  // The fully-qualified Speech Recognizer resource name.
  // Format:
  // `projects/{project_id}/locations/{location}/recognizer/{recognizer}`
  string speech_recognizer = 1 [(google.api.resource_reference) = {
    type: "speech.googleapis.com/Recognizer"
  }];
}

// An annotation that was generated during the customer and agent interaction.
message RuntimeAnnotation {
  // Explicit input used for generating the answer
  message UserInput {
    // The source of the query.
    enum QuerySource {
      // Unknown query source.
      QUERY_SOURCE_UNSPECIFIED = 0;

      // The query is from agents.
      AGENT_QUERY = 1;

      // The query is a query from previous suggestions, e.g. from a preceding
      // SuggestKnowledgeAssist response.
      SUGGESTED_QUERY = 2;
    }

    // Query text. Article Search uses this to store the input query used
    // to generate the search results.
    string query = 1;

    // The resource name of associated generator. Format:
    // `projects/<Project ID>/locations/<Location ID>/generators/<Generator ID>`
    string generator_name = 2;

    // Query source for the answer.
    QuerySource query_source = 3;
  }

  // The data in the annotation.
  oneof data {
    // Agent Assist Article Suggestion data.
    ArticleSuggestionData article_suggestion = 6;

    // Agent Assist FAQ answer data.
    FaqAnswerData faq_answer = 7;

    // Agent Assist Smart Reply data.
    SmartReplyData smart_reply = 8;

    // Agent Assist Smart Compose suggestion data.
    SmartComposeSuggestionData smart_compose_suggestion = 9;

    // Dialogflow interaction data.
    DialogflowInteractionData dialogflow_interaction = 10;

    // Conversation summarization suggestion data.
    ConversationSummarizationSuggestionData
        conversation_summarization_suggestion = 12;
  }

  // The unique identifier of the annotation.
  // Format:
  // projects/{project}/locations/{location}/conversationDatasets/{dataset}/conversationDataItems/{data_item}/conversationAnnotations/{annotation}
  string annotation_id = 1;

  // The time at which this annotation was created.
  google.protobuf.Timestamp create_time = 2;

  // The boundary in the conversation where the annotation starts, inclusive.
  AnnotationBoundary start_boundary = 3;

  // The boundary in the conversation where the annotation ends, inclusive.
  AnnotationBoundary end_boundary = 4;

  // The feedback that the customer has about the answer in `data`.
  AnswerFeedback answer_feedback = 5;

  // Explicit input used for generating the answer
  UserInput user_input = 16;
}

// The feedback that the customer has about a certain answer in the
// conversation.
message AnswerFeedback {
  // The correctness level of an answer.
  enum CorrectnessLevel {
    // Correctness level unspecified.
    CORRECTNESS_LEVEL_UNSPECIFIED = 0;

    // Answer is totally wrong.
    NOT_CORRECT = 1;

    // Answer is partially correct.
    PARTIALLY_CORRECT = 2;

    // Answer is fully correct.
    FULLY_CORRECT = 3;
  }

  // The correctness level of an answer.
  CorrectnessLevel correctness_level = 1;

  // Indicates whether an answer or item was clicked by the human agent.
  bool clicked = 2;

  // Indicates whether an answer or item was displayed to the human agent in the
  // agent desktop UI.
  bool displayed = 3;
}

// Agent Assist Article Suggestion data.
message ArticleSuggestionData {
  // Article title.
  string title = 1;

  // Article URI.
  string uri = 2;

  // The system's confidence score that this article is a good match for this
  // conversation, ranging from 0.0 (completely uncertain) to 1.0 (completely
  // certain).
  float confidence_score = 3;

  // Map that contains metadata about the Article Suggestion and the document
  // that it originates from.
  map<string, string> metadata = 4;

  // The name of the answer record.
  // Format:
  // projects/{project}/locations/{location}/answerRecords/{answer_record}
  string query_record = 5;

  // The knowledge document that this answer was extracted from.
  // Format:
  // projects/{project}/knowledgeBases/{knowledge_base}/documents/{document}
  string source = 6;
}

// Agent Assist frequently-asked-question answer data.
message FaqAnswerData {
  // The piece of text from the `source` knowledge base document.
  string answer = 1;

  // The system's confidence score that this answer is a good match for this
  // conversation, ranging from 0.0 (completely uncertain) to 1.0 (completely
  // certain).
  float confidence_score = 2;

  // The corresponding FAQ question.
  string question = 3;

  // Map that contains metadata about the FAQ answer and the document that
  // it originates from.
  map<string, string> metadata = 4;

  // The name of the answer record.
  // Format:
  // projects/{project}/locations/{location}/answerRecords/{answer_record}
  string query_record = 5;

  // The knowledge document that this answer was extracted from.
  // Format:
  // projects/{project}/knowledgeBases/{knowledge_base}/documents/{document}.
  string source = 6;
}

// Agent Assist Smart Reply data.
message SmartReplyData {
  // The content of the reply.
  string reply = 1;

  // The system's confidence score that this reply is a good match for this
  // conversation, ranging from 0.0 (completely uncertain) to 1.0 (completely
  // certain).
  double confidence_score = 2;

  // Map that contains metadata about the Smart Reply and the document from
  // which it originates.
  map<string, string> metadata = 3;

  // The name of the answer record.
  // Format:
  // projects/{project}/locations/{location}/answerRecords/{answer_record}
  string query_record = 4;
}

// Agent Assist Smart Compose suggestion data.
message SmartComposeSuggestionData {
  // The content of the suggestion.
  string suggestion = 1;

  // The system's confidence score that this suggestion is a good match for this
  // conversation, ranging from 0.0 (completely uncertain) to 1.0 (completely
  // certain).
  double confidence_score = 2;

  // Map that contains metadata about the Smart Compose suggestion and the
  // document from which it originates.
  map<string, string> metadata = 3;

  // The name of the answer record.
  // Format:
  // projects/{project}/locations/{location}/answerRecords/{answer_record}
  string query_record = 4;
}

// Dialogflow interaction data.
message DialogflowInteractionData {
  // The Dialogflow intent resource path. Format:
  // projects/{project}/agent/{agent}/intents/{intent}
  string dialogflow_intent_id = 1;

  // The confidence of the match ranging from 0.0 (completely uncertain) to 1.0
  // (completely certain).
  float confidence = 2;
}

// Conversation summarization suggestion data.
message ConversationSummarizationSuggestionData {
  // The summarization content that is concatenated into one string.
  string text = 1;

  // The summarization content that is divided into sections. The key is the
  // section's name and the value is the section's content. There is no
  // specific format for the key or value.
  map<string, string> text_sections = 5;

  // The confidence score of the summarization.
  float confidence = 2;

  // A map that contains metadata about the summarization and the document
  // from which it originates.
  map<string, string> metadata = 3;

  // The name of the answer record.
  // Format:
  // projects/{project}/locations/{location}/answerRecords/{answer_record}
  string answer_record = 4;

  // The name of the model that generates this summary.
  // Format:
  // projects/{project}/locations/{location}/conversationModels/{conversation_model}
  string conversation_model = 6;
}

// The call participant speaking for a given utterance.
message ConversationParticipant {
  // The role of the participant.
  enum Role {
    // Participant's role is not set.
    ROLE_UNSPECIFIED = 0;

    // Participant is a human agent.
    HUMAN_AGENT = 1;

    // Participant is an automated agent.
    AUTOMATED_AGENT = 2;

    // Participant is an end user who conversed with the contact center.
    END_USER = 3;

    // Participant is either a human or automated agent.
    ANY_AGENT = 4;
  }

  oneof participant {
    // The name of the participant provided by Dialogflow. Format:
    // projects/{project}/locations/{location}/conversations/{conversation}/participants/{participant}
    string dialogflow_participant_name = 5 [(google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Participant"
    }];

    // A user-specified ID representing the participant.
    string user_id = 6;
  }

  // Deprecated. Use `dialogflow_participant_name` instead.
  // The name of the Dialogflow participant. Format:
  // projects/{project}/locations/{location}/conversations/{conversation}/participants/{participant}
  string dialogflow_participant = 1 [deprecated = true];

  // Obfuscated user ID from Dialogflow.
  string obfuscated_external_user_id = 3;

  // The role of the participant.
  Role role = 2;
}

// The View resource.
message View {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/View"
    pattern: "projects/{project}/locations/{location}/views/{view}"
  };

  // Immutable. The resource name of the view.
  // Format:
  // projects/{project}/locations/{location}/views/{view}
  string name = 1 [(google.api.field_behavior) = IMMUTABLE];

  // The human-readable display name of the view.
  string display_name = 2;

  // Output only. The time at which this view was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which the view was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // String with specific view properties, must be non-empty.
  string value = 5;
}

// Selector of all available annotators and phrase matchers to run.
message AnnotatorSelector {
  // Configuration for summarization.
  message SummarizationConfig {
    // Summarization model to use, if `conversation_profile` is not used.
    enum SummarizationModel {
      // Unspecified summarization model.
      SUMMARIZATION_MODEL_UNSPECIFIED = 0;

      // The CCAI baseline model.
      BASELINE_MODEL = 1;

      // The CCAI baseline model, V2.0.
      BASELINE_MODEL_V2_0 = 2;
    }

    // Summarization must use either a preexisting conversation profile or one
    // of the supported default models.
    oneof model_source {
      // Resource name of the Dialogflow conversation profile.
      // Format:
      // projects/{project}/locations/{location}/conversationProfiles/{conversation_profile}
      string conversation_profile = 1 [(google.api.resource_reference) = {
        type: "dialogflow.googleapis.com/ConversationProfile"
      }];

      // Default summarization model to be used.
      SummarizationModel summarization_model = 2;
    }
  }

  // Configuration for the QA feature.
  message QaConfig {
    // Container for a list of scorecards.
    message ScorecardList {
      // List of QaScorecardRevisions.
      repeated string qa_scorecard_revisions = 1
          [(google.api.resource_reference) = {
            type: "contactcenterinsights.googleapis.com/QaScorecardRevision"
          }];
    }

    // Which scorecards should be scored.
    oneof scorecard_source {
      // A manual list of scorecards to score.
      ScorecardList scorecard_list = 1;
    }
  }

  // Whether to run the interruption annotator.
  bool run_interruption_annotator = 1;

  // Whether to run the silence annotator.
  bool run_silence_annotator = 2;

  // Whether to run the active phrase matcher annotator(s).
  bool run_phrase_matcher_annotator = 3;

  // The list of phrase matchers to run. If not provided, all active phrase
  // matchers will be used. If inactive phrase matchers are provided, they will
  // not be used. Phrase matchers will be run only if
  // run_phrase_matcher_annotator is set to true. Format:
  // projects/{project}/locations/{location}/phraseMatchers/{phrase_matcher}
  repeated string phrase_matchers = 4 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/PhraseMatcher"
  }];

  // Whether to run the sentiment annotator.
  bool run_sentiment_annotator = 5;

  // Whether to run the entity annotator.
  bool run_entity_annotator = 6;

  // Whether to run the intent annotator.
  bool run_intent_annotator = 7;

  // Whether to run the issue model annotator. A model should have already been
  // deployed for this to take effect.
  bool run_issue_model_annotator = 8;

  // The issue model to run. If not provided, the most recently deployed topic
  // model will be used. The provided issue model will only be used for
  // inference if the issue model is deployed and if run_issue_model_annotator
  // is set to true. If more than one issue model is provided, only the first
  // provided issue model will be used for inference.
  repeated string issue_models = 10 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/IssueModel"
  }];

  // Whether to run the summarization annotator.
  bool run_summarization_annotator = 9;

  // Configuration for the summarization annotator.
  SummarizationConfig summarization_config = 11;

  // Whether to run the QA annotator.
  bool run_qa_annotator = 12;

  // Configuration for the QA annotator.
  QaConfig qa_config = 13;
}

// A single question to be scored by the Insights QA feature.
message QaQuestion {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/QaQuestion"
    pattern: "projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}/revisions/{revision}/qaQuestions/{qa_question}"
    plural: "qaQuestions"
    singular: "qaQuestion"
  };

  // Message representing a possible answer to the question.
  message AnswerChoice {
    // The answer value may be one of a few different types.
    oneof value {
      // String value.
      string str_value = 2;

      // Numerical value.
      double num_value = 3;

      // Boolean value.
      bool bool_value = 4;

      // A value of "Not Applicable (N/A)". If provided, this field may only
      // be set to `true`. If a question receives this answer, it will be
      // excluded from any score calculations.
      bool na_value = 5;
    }

    // A short string used as an identifier.
    string key = 1;

    // Numerical score of the answer, used for generating the overall score of
    // a QaScorecardResult. If the answer uses na_value, this field is unused.
    optional double score = 6;
  }

  // A wrapper representing metrics calculated against a test-set on a LLM that
  // was fine tuned for this question.
  message Metrics {
    // Output only. Accuracy of the model. Measures the percentage of correct
    // answers the model gave on the test set.
    double accuracy = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Metadata about the tuning operation for the question. Will only be set if a
  // scorecard containing this question has been tuned.
  message TuningMetadata {
    // Total number of valid labels provided for the question at the time of
    // tuining.
    int64 total_valid_label_count = 1;

    // A list of any applicable data validation warnings about the question's
    // feedback labels.
    repeated DatasetValidationWarning dataset_validation_warnings = 2;

    // Error status of the tuning operation for the question. Will only be set
    // if the tuning operation failed.
    string tuning_error = 3;
  }

  // Identifier. The resource name of the question.
  // Format:
  // projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}/revisions/{revision}/qaQuestions/{qa_question}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // Short, descriptive string, used in the UI where it's not practical
  // to display the full question body. E.g., "Greeting".
  string abbreviation = 2;

  // Output only. The time at which this question was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which the question was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Question text. E.g., "Did the agent greet the customer?"
  string question_body = 5;

  // Instructions describing how to determine the answer.
  string answer_instructions = 9;

  // A list of valid answers to the question, which the LLM must choose from.
  repeated AnswerChoice answer_choices = 6;

  // User-defined list of arbitrary tags for the question. Used for
  // grouping/organization and for weighting the score of each question.
  repeated string tags = 7;

  // Defines the order of the question within its parent scorecard revision.
  int32 order = 8;

  // Metrics of the underlying tuned LLM over a holdout/test set while fine
  // tuning the underlying LLM for the given question. This field will only be
  // populated if and only if the question is part of a scorecard revision that
  // has been tuned.
  Metrics metrics = 10;

  // Metadata about the tuning operation for the question.This field will only
  // be populated if and only if the question is part of a scorecard revision
  // that has been tuned.
  TuningMetadata tuning_metadata = 11;
}

// A QaScorecard represents a collection of questions to be scored during
// analysis.
message QaScorecard {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/QaScorecard"
    pattern: "projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}"
    plural: "qaScorecards"
    singular: "qaScorecard"
  };

  // Identifier. The scorecard name.
  // Format:
  // projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The user-specified display name of the scorecard.
  string display_name = 7;

  // A text description explaining the intent of the scorecard.
  string description = 2;

  // Output only. The time at which this scorecard was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. The most recent time at which the scorecard was updated.
  google.protobuf.Timestamp update_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A revision of a QaScorecard.
//
// Modifying published scorecard fields would invalidate existing scorecard
// results — the questions may have changed, or the score weighting will make
// existing scores impossible to understand. So changes must create a new
// revision, rather than modifying the existing resource.
message QaScorecardRevision {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/QaScorecardRevision"
    pattern: "projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}/revisions/{revision}"
    plural: "qaScorecardRevisions"
    singular: "qaScorecardRevision"
  };

  // Enum representing the set of states a scorecard revision may be in.
  enum State {
    // Unspecified.
    STATE_UNSPECIFIED = 0;

    // The scorecard revision can be edited.
    EDITABLE = 12;

    // Scorecard model training is in progress.
    TRAINING = 2;

    // Scorecard revision model training failed.
    TRAINING_FAILED = 9;

    // The revision can be used in analysis.
    READY = 11;

    // Scorecard is being deleted.
    DELETING = 7;

    // Scorecard model training was explicitly cancelled by the user.
    TRAINING_CANCELLED = 14;
  }

  // Identifier. The name of the scorecard revision.
  // Format:
  // projects/{project}/locations/{location}/qaScorecards/{qa_scorecard}/revisions/{revision}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The snapshot of the scorecard at the time of this revision's creation.
  QaScorecard snapshot = 2;

  // Output only. The timestamp that the revision was created.
  google.protobuf.Timestamp create_time = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Alternative IDs for this revision of the scorecard, e.g.,
  // `latest`.
  repeated string alternate_ids = 4 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. State of the scorecard revision, indicating whether it's ready
  // to be used in analysis.
  State state = 5 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// An answer to a QaQuestion.
message QaAnswer {
  // Message for holding the value of a
  // [QaAnswer][google.cloud.contactcenterinsights.v1.QaAnswer].
  // [QaQuestion.AnswerChoice][google.cloud.contactcenterinsights.v1.QaQuestion.AnswerChoice]
  // defines the possible answer values for a question.
  message AnswerValue {
    // The answer value may be one of a few different types.
    oneof value {
      // String value.
      string str_value = 2;

      // Numerical value.
      double num_value = 3;

      // Boolean value.
      bool bool_value = 4;

      // A value of "Not Applicable (N/A)". Should only ever be `true`.
      bool na_value = 5;
    }

    // A short string used as an identifier. Matches the value used in
    // QaQuestion.AnswerChoice.key.
    string key = 1;

    // Output only. Numerical score of the answer.
    optional double score = 6 [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The maximum potential score of the question.
    optional double potential_score = 7
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. Normalized score of the questions. Calculated as score /
    // potential_score.
    optional double normalized_score = 8
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // A question may have multiple answers from varying sources, one of which
  // becomes the "main" answer above. AnswerSource represents each individual
  // answer.
  message AnswerSource {
    // What created the answer.
    enum SourceType {
      // Source type is unspecified.
      SOURCE_TYPE_UNSPECIFIED = 0;

      // Answer was system-generated; created during an Insights analysis.
      SYSTEM_GENERATED = 1;

      // Answer was created by a human via manual edit.
      MANUAL_EDIT = 2;
    }

    // What created the answer.
    SourceType source_type = 1;

    // The answer value from this source.
    AnswerValue answer_value = 2;
  }

  // The QaQuestion answered by this answer.
  string qa_question = 7 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/QaQuestion"
  }];

  // The conversation the answer applies to.
  string conversation = 2 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/Conversation"
  }];

  // Question text. E.g., "Did the agent greet the customer?"
  string question_body = 6;

  // The main answer value, incorporating any manual edits if they exist.
  AnswerValue answer_value = 3;

  // User-defined list of arbitrary tags. Matches the value from
  // QaScorecard.ScorecardQuestion.tags. Used for grouping/organization and
  // for weighting the score of each answer.
  repeated string tags = 5;

  // List of all individual answers given to the question.
  repeated AnswerSource answer_sources = 8;
}

// The results of scoring a single conversation against a QaScorecard. Contains
// a collection of QaAnswers and aggregate score.
message QaScorecardResult {
  option (google.api.resource) = {
    type: "contactcenterinsights.googleapis.com/QaScorecardResult"
    pattern: "projects/{project}/locations/{location}/qaScorecardResults/{qa_scorecard_result}"
    plural: "qaScorecardResults"
    singular: "qaScorecardResult"
  };

  // Tags and their corresponding results.
  message QaTagResult {
    // The tag the score applies to.
    string tag = 1;

    // The score the tag applies to.
    optional double score = 2;

    // The potential score the tag applies to.
    optional double potential_score = 3;

    // The normalized score the tag applies to.
    optional double normalized_score = 4;
  }

  // A scorecard result may have multiple sets of scores from varying sources,
  // one of which becomes the "main" answer above. A ScoreSource represents
  // each individual set of scores.
  message ScoreSource {
    // What created the score.
    enum SourceType {
      // Source type is unspecified.
      SOURCE_TYPE_UNSPECIFIED = 0;

      // Score is derived only from system-generated answers.
      SYSTEM_GENERATED_ONLY = 1;

      // Score is derived from both system-generated answers, and includes
      // any manual edits if they exist.
      INCLUDES_MANUAL_EDITS = 2;
    }

    // What created the score.
    SourceType source_type = 1;

    // The overall numerical score of the result.
    optional double score = 2;

    // The maximum potential overall score of the scorecard. Any questions
    // answered using `na_value` are excluded from this calculation.
    optional double potential_score = 3;

    // The normalized score, which is the score divided by the potential score.
    optional double normalized_score = 4;

    // Collection of tags and their scores.
    repeated QaTagResult qa_tag_results = 5;
  }

  // Identifier. The name of the scorecard result.
  // Format:
  // projects/{project}/locations/{location}/qaScorecardResults/{qa_scorecard_result}
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The QaScorecardRevision scored by this result.
  string qa_scorecard_revision = 2 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/QaScorecardRevision"
  }];

  // The conversation scored by this result.
  string conversation = 3 [(google.api.resource_reference) = {
    type: "contactcenterinsights.googleapis.com/Conversation"
  }];

  // Output only. The timestamp that the revision was created.
  google.protobuf.Timestamp create_time = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // ID of the agent that handled the conversation.
  string agent_id = 5;

  // Set of QaAnswers represented in the result.
  repeated QaAnswer qa_answers = 6;

  // The overall numerical score of the result, incorporating any manual edits
  // if they exist.
  optional double score = 7;

  // The maximum potential overall score of the scorecard. Any questions
  // answered using `na_value` are excluded from this calculation.
  optional double potential_score = 8;

  // The normalized score, which is the score divided by the potential score.
  // Any manual edits are included if they exist.
  optional double normalized_score = 9;

  // Collection of tags and their scores.
  repeated QaTagResult qa_tag_results = 10;

  // List of all individual score sets.
  repeated ScoreSource score_sources = 11;
}
