// 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.dialogflow.cx.v3beta1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/dialogflow/cx/v3beta1/environment.proto";
import "google/cloud/dialogflow/cx/v3beta1/flow.proto";
import "google/cloud/dialogflow/cx/v3beta1/intent.proto";
import "google/cloud/dialogflow/cx/v3beta1/page.proto";
import "google/cloud/dialogflow/cx/v3beta1/session.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Dialogflow.Cx.V3Beta1";
option go_package = "cloud.google.com/go/dialogflow/cx/apiv3beta1/cxpb;cxpb";
option java_multiple_files = true;
option java_outer_classname = "ConversationHistoryProto";
option java_package = "com.google.cloud.dialogflow.cx.v3beta1";
option objc_class_prefix = "DF";
option ruby_package = "Google::Cloud::Dialogflow::CX::V3beta1";

// Service for managing conversation history.
service ConversationHistory {
  option (google.api.default_host) = "dialogflow.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/dialogflow";

  // Returns the list of all conversations.
  rpc ListConversations(ListConversationsRequest)
      returns (ListConversationsResponse) {
    option (google.api.http) = {
      get: "/v3beta1/{parent=projects/*/locations/*/agents/*}/conversations"
    };
    option (google.api.method_signature) = "parent";
  }

  // Retrieves the specified conversation.
  rpc GetConversation(GetConversationRequest) returns (Conversation) {
    option (google.api.http) = {
      get: "/v3beta1/{name=projects/*/locations/*/agents/*/conversations/*}"
    };
    option (google.api.method_signature) = "name";
  }

  // Deletes the specified conversation.
  rpc DeleteConversation(DeleteConversationRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v3beta1/{name=projects/*/locations/*/agents/*/conversations/*}"
    };
    option (google.api.method_signature) = "name";
  }
}

// The request message for [Conversations.GetConversation][].
message GetConversationRequest {
  // Required. The name of the conversation.
  // Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/conversations/<ConversationID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Conversation"
    }
  ];
}

// The request message for [Conversations.DeleteConversation][].
message DeleteConversationRequest {
  // Required. The name of the conversation.
  // Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/conversations/<ConversationID>`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "dialogflow.googleapis.com/Conversation"
    }
  ];
}

// The request message for [Conversations.ListConversations][].
message ListConversationsRequest {
  // Required. The agent to list all conversations for.
  // Format: `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      child_type: "dialogflow.googleapis.com/Conversation"
    }
  ];

  // Optional. The filter string. Supports filter by create_time,
  // metrics.has_end_interaction, metrics.has_live_agent_handoff,
  // intents.display_name, pages.display_name and flows.display_name. Timestamps
  // expect an [RFC-3339][https://datatracker.ietf.org/doc/html/rfc3339]
  // formatted string (e.g. 2012-04-21T11:30:00-04:00). UTC offsets are
  // supported. Some examples:
  //   1. By create time:
  //        create_time > "2022-04-21T11:30:00-04:00"
  //   2. By intent display name:
  //        intents.display_name : "billing"
  //   3. By end interaction signal:
  //        metrics.has_end_interaction = true
  string filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The maximum number of items to return in a single page. By
  // default 100 and at most 1000.
  int32 page_size = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The next_page_token value returned from a previous list request.
  string page_token = 4 [(google.api.field_behavior) = OPTIONAL];
}

// The response message for [Conversations.ListConversations][].
message ListConversationsResponse {
  // The list of conversations. There will be a maximum number of items returned
  // based on the
  // [page_size][google.cloud.dialogflow.cx.v3beta1.ListConversationsRequest.page_size]
  // field. The returned conversations will be sorted by start_time in
  // descending order (newest conversation first).
  repeated Conversation conversations = 1;

  // Token to retrieve the next page of results, or empty if there are no more
  // results in the list.
  string next_page_token = 2;
}

// Represents a conversation.
message Conversation {
  option (google.api.resource) = {
    type: "dialogflow.googleapis.com/Conversation"
    pattern: "projects/{project}/locations/{location}/agents/{agent}/conversations/{conversation}"
    plural: "conversations"
    singular: "conversation"
  };

  // Represents the type of a conversation.
  enum Type {
    // Not specified. This value should never be used.
    TYPE_UNSPECIFIED = 0;

    // Audio conversation. A conversation is classified as an audio conversation
    // if any request has STT input audio or any response has TTS output audio.
    AUDIO = 1;

    // Text conversation. A conversation is classified as a text conversation
    // if any request has text input and no request has STT input audio and no
    // response has TTS output audio.
    TEXT = 2;

    // Default conversation type for a conversation. A conversation is
    // classified as undetermined if none of the requests contain text or audio
    // input (eg. event or intent input).
    UNDETERMINED = 3;
  }

  // Represents metrics for the conversation.
  message Metrics {
    // Count by types of
    // [QueryInput][google.cloud.dialogflow.cx.v3beta1.QueryInput] of the
    // requests in the conversation.
    message QueryInputCount {
      // The number of [TextInput][google.cloud.dialogflow.cx.v3beta1.TextInput]
      // in the conversation.
      int32 text_count = 1;

      // The number of
      // [IntentInput][google.cloud.dialogflow.cx.v3beta1.IntentInput] in the
      // conversation.
      int32 intent_count = 2;

      // The number of
      // [AudioInput][google.cloud.dialogflow.cx.v3beta1.AudioInput] in the
      // conversation.
      int32 audio_count = 3;

      // The number of
      // [EventInput][google.cloud.dialogflow.cx.v3beta1.EventInput] in the
      // conversation.
      int32 event_count = 4;

      // The number of [DtmfInput][google.cloud.dialogflow.cx.v3beta1.DtmfInput]
      // in the conversation.
      int32 dtmf_count = 5;
    }

    // Count by
    // [Match.MatchType][google.cloud.dialogflow.cx.v3beta1.Match.MatchType] of
    // the matches in the conversation.
    message MatchTypeCount {
      // The number of matches with type
      // [Match.MatchType.MATCH_TYPE_UNSPECIFIED][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.MATCH_TYPE_UNSPECIFIED].
      int32 unspecified_count = 1;

      // The number of matches with type
      // [Match.MatchType.INTENT][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.INTENT].
      int32 intent_count = 2;

      // The number of matches with type
      // [Match.MatchType.DIRECT_INTENT][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.DIRECT_INTENT].
      int32 direct_intent_count = 3;

      // The number of matches with type
      // [Match.MatchType.PARAMETER_FILLING][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.PARAMETER_FILLING].
      int32 parameter_filling_count = 4;

      // The number of matches with type
      // [Match.MatchType.NO_MATCH][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.NO_MATCH].
      int32 no_match_count = 5;

      // The number of matches with type
      // [Match.MatchType.NO_INPUT][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.NO_INPUT].
      int32 no_input_count = 6;

      // The number of matches with type
      // [Match.MatchType.EVENT][google.cloud.dialogflow.cx.v3beta1.Match.MatchType.EVENT].
      int32 event_count = 7;
    }

    // The number of interactions in the conversation.
    int32 interaction_count = 1;

    // Duration of all the input's audio in the conversation.
    google.protobuf.Duration input_audio_duration = 2;

    // Duration of all the output's audio in the conversation.
    google.protobuf.Duration output_audio_duration = 3;

    // Maximum latency of the
    // [Webhook][google.cloud.dialogflow.cx.v3beta1.Webhook] calls in the
    // conversation.
    google.protobuf.Duration max_webhook_latency = 4;

    // A signal that indicates the interaction with the Dialogflow agent has
    // ended.
    // If any response has the
    // [ResponseMessage.end_interaction][google.cloud.dialogflow.cx.v3beta1.ResponseMessage.end_interaction]
    // signal, this is set to true.
    bool has_end_interaction = 5;

    // Hands off conversation to a human agent.
    // If any response has the
    // [ResponseMessage.live_agent_handoff][google.cloud.dialogflow.cx.v3beta1.ResponseMessage.live_agent_handoff]signal,
    // this is set to true.
    bool has_live_agent_handoff = 6;

    // The average confidence all of the
    // [Match][google.cloud.dialogflow.cx.v3beta1.Match] in the conversation.
    // Values range from 0.0 (completely uncertain) to 1.0 (completely certain).
    float average_match_confidence = 7;

    // Query input counts.
    QueryInputCount query_input_count = 8;

    // Match type counts.
    MatchTypeCount match_type_count = 9;
  }

  // Represents an interaction between an end user and a Dialogflow CX agent
  // using V3 (Streaming)DetectIntent API, or an interaction between an end user
  // and a Dialogflow CX agent using V2 (Streaming)AnalyzeContent API.
  message Interaction {
    // Information collected for DF CX agents in case NLU predicted an intent
    // that was filtered out as being inactive which may indicate a missing
    // transition and/or absent functionality.
    message MissingTransition {
      // Name of the intent that could have triggered.
      string intent_display_name = 1;

      // Score of the above intent. The higher it is the more likely a
      // transition was missed on a given page.
      float score = 2;
    }

    // Metrics of each processing step.
    message StepMetrics {
      // Name of the request processing step.
      string name = 1;

      // Processing latency of the step.
      google.protobuf.Duration latency = 2;
    }

    // The request of the interaction.
    DetectIntentRequest request = 1;

    // The final response of the interaction.
    DetectIntentResponse response = 2;

    // The partial responses of the interaction. Empty if there is no partial
    // response in the interaction.
    // See the
    // [partial response
    // documentation][https://cloud.google.com/dialogflow/cx/docs/concept/fulfillment#queue].
    repeated DetectIntentResponse partial_responses = 3;

    // The input text or the transcript of the input audio in the request.
    string request_utterances = 4;

    // The output text or the transcript of the output audio in the responses.
    // If multiple output messages are returned, they will be concatenated into
    // one.
    string response_utterances = 5;

    // The time that the interaction was created.
    google.protobuf.Timestamp create_time = 6;

    // Answer feedback for the final response.
    AnswerFeedback answer_feedback = 7;

    // Missing transition predicted for the interaction. This field is set only
    // if the interaction match type was no-match.
    MissingTransition missing_transition = 8;

    // Metrics associated with different processing steps. Names and number of
    // steps depend on the request and can change without a notice.
    repeated StepMetrics step_metrics = 9;
  }

  // Identifier. The identifier of the conversation.
  // If conversation ID is reused, interactions happened later than 48 hours of
  // the conversation's create time will be ignored. Format:
  // `projects/<ProjectID>/locations/<LocationID>/agents/<AgentID>/conversations/<ConversationID>`
  string name = 1 [(google.api.field_behavior) = IDENTIFIER];

  // The type of the conversation.
  Type type = 2;

  // The language of the conversation, which is the language of the first
  // request in the conversation.
  string language_code = 3;

  // Start time of the conversation, which is the time of the first request of
  // the conversation.
  google.protobuf.Timestamp start_time = 4;

  // Duration of the conversation.
  google.protobuf.Duration duration = 5;

  // Conversation metrics.
  Metrics metrics = 6;

  // All the matched [Intent][google.cloud.dialogflow.cx.v3beta1.Intent] in the
  // conversation. Only `name` and `display_name` are filled in this message.
  repeated Intent intents = 7;

  // All the [Flow][google.cloud.dialogflow.cx.v3beta1.Flow] the conversation
  // has went through. Only `name` and `display_name` are filled in this
  // message.
  repeated Flow flows = 8;

  // All the [Page][google.cloud.dialogflow.cx.v3beta1.Page] the conversation
  // has went through. Only `name` and `display_name` are filled in this
  // message.
  repeated Page pages = 9;

  // Interactions of the conversation.
  // Only populated for `GetConversation` and empty for `ListConversations`.
  repeated Interaction interactions = 10;

  // Environment of the conversation.
  // Only `name` and `display_name` are filled in this message.
  Environment environment = 11;

  // Flow versions used in the conversation.
  map<string, int64> flow_versions = 12;
}
